diff --git a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx index 86460612..11799bb5 100644 --- a/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx +++ b/apps/web/components/Objects/Activities/DynamicCanva/DynamicCanva.tsx @@ -27,6 +27,10 @@ import AICanvaToolkit from './AI/AICanvaToolkit' import EmbedObjects from '@components/Objects/Editor/Extensions/EmbedObjects/EmbedObjects' import Badges from '@components/Objects/Editor/Extensions/Badges/Badges' import Buttons from '@components/Objects/Editor/Extensions/Buttons/Buttons' +import Table from '@tiptap/extension-table' +import TableHeader from '@tiptap/extension-table-header' +import TableRow from '@tiptap/extension-table-row' +import TableCell from '@tiptap/extension-table-cell' interface Editor { content: string @@ -100,6 +104,12 @@ function Canva(props: Editor) { editable: isEditable, activity: props.activity, }), + Table.configure({ + resizable: true, + }), + TableRow, + TableHeader, + TableCell, ], content: props.content, @@ -186,6 +196,53 @@ const CanvaWrapper = styled.div` list-style-type: decimal; } + table { + border-collapse: collapse; + margin: 0; + overflow: hidden; + table-layout: fixed; + width: 100%; + + td, + th { + border: 1px solid rgba(139, 139, 139, 0.4); + box-sizing: border-box; + min-width: 1em; + padding: 6px 8px; + position: relative; + vertical-align: top; + + > * { + margin-bottom: 0; + } + } + + th { + background-color: rgba(217, 217, 217, 0.4); + font-weight: bold; + text-align: left; + } + + .selectedCell:after { + background: rgba(139, 139, 139, 0.2); + content: ""; + left: 0; right: 0; top: 0; bottom: 0; + pointer-events: none; + position: absolute; + z-index: 2; + } + + .column-resize-handle { + background-color: #8d78eb; + bottom: -2px; + pointer-events: none; + position: absolute; + right: -2px; + top: 0; + width: 4px; + } + } + &:focus { outline: none !important; outline-style: none !important; diff --git a/apps/web/components/Objects/Editor/Editor.tsx b/apps/web/components/Objects/Editor/Editor.tsx index 14948aff..8b07ca46 100644 --- a/apps/web/components/Objects/Editor/Editor.tsx +++ b/apps/web/components/Objects/Editor/Editor.tsx @@ -151,7 +151,6 @@ function Editor(props: Editor) { immediatelyRender: false, }) - console.log(props.content) const isMobile = useMediaQuery('(max-width: 767px)') if (isMobile) { diff --git a/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx b/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx index 0dc54119..56c195b8 100644 --- a/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx +++ b/apps/web/components/Objects/Editor/Toolbar/ToolbarButtons.tsx @@ -12,6 +12,7 @@ import { ColumnsIcon, SectionIcon, ContainerIcon, + ChevronDownIcon, } from '@radix-ui/react-icons' import { AlertCircle, @@ -24,14 +25,18 @@ import { Lightbulb, MousePointerClick, Sigma, + Table, Tag, Tags, Video, } from 'lucide-react' import { SiYoutube } from '@icons-pack/react-simple-icons' import ToolTip from '@components/Objects/StyledElements/Tooltip/Tooltip' +import React from 'react' export const ToolbarButtons = ({ editor, props }: any) => { + const [showTableMenu, setShowTableMenu] = React.useState(false) + if (!editor) { return null } @@ -49,6 +54,34 @@ export const ToolbarButtons = ({ editor, props }: any) => { } } + const tableOptions = [ + { + label: 'Insert new table (3×3)', + icon: , + action: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run() + }, + { + label: 'Add row below', + icon: , + action: () => editor.chain().focus().addRowAfter().run() + }, + { + label: 'Add column right', + icon: , + action: () => editor.chain().focus().addColumnAfter().run() + }, + { + label: 'Delete current row', + icon: , + action: () => editor.chain().focus().deleteRow().run() + }, + { + label: 'Delete current column', + icon: , + action: () => editor.chain().focus().deleteColumn().run() + } + ] + return ( editor.chain().focus().undo().run()}> @@ -97,35 +130,31 @@ export const ToolbarButtons = ({ editor, props }: any) => { - - editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()} - > - - - editor.chain().focus().addRowAfter().run()} - > - - - editor.chain().focus().addColumnAfter().run()} - > - - - editor.chain().focus().deleteColumn().run()} - > - - - editor.chain().focus().deleteRow().run()} - > - - - {/* TODO: fix this : toggling only works one-way */} + + setShowTableMenu(!showTableMenu)} + className={showTableMenu ? 'is-active' : ''} + > + + + + {showTableMenu && ( + + {tableOptions.map((option, index) => ( + { + option.action() + setShowTableMenu(false) + }} + > + {option.icon} + {option.label} + + ))} + + )} + @@ -285,7 +314,7 @@ const ToolBtn = styled.div` display: flex; background: rgba(217, 217, 217, 0.24); border-radius: 6px; - width: 25px; + min-width: 25px; height: 25px; padding: 5px; margin-right: 5px; @@ -322,3 +351,44 @@ const ToolSelect = styled.select` font-family: 'DM Sans'; margin-right: 5px; ` + +const TableMenuWrapper = styled.div` + position: relative; + display: inline-block; +` + +const TableDropdown = styled.div` + position: absolute; + top: 100%; + left: 0; + background: white; + border: 1px solid rgba(217, 217, 217, 0.5); + border-radius: 6px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + z-index: 1000; + min-width: 180px; + margin-top: 4px; +` + +const TableMenuItem = styled.div` + display: flex; + align-items: center; + padding: 8px 12px; + cursor: pointer; + transition: background 0.2s; + + &:hover { + background: rgba(217, 217, 217, 0.24); + } + + .icon { + margin-right: 8px; + display: flex; + align-items: center; + } + + .label { + font-size: 12px; + font-family: 'DM Sans'; + } +` \ No newline at end of file