diff --git a/packages/outstatic/src/components/editor/menu/table-menu.tsx b/packages/outstatic/src/components/editor/menu/table-menu.tsx index a0f04475..6a005acf 100644 --- a/packages/outstatic/src/components/editor/menu/table-menu.tsx +++ b/packages/outstatic/src/components/editor/menu/table-menu.tsx @@ -9,11 +9,33 @@ import { } from 'lucide-react' import { useCallback } from 'react' import { EditorBubbleButton } from '../ui/editor-bubble-button' +import { Transaction } from '@tiptap/pm/state' type TableMenuProps = { editor: Editor } +function isInTableFirstRow(tr: Transaction): boolean { + const { anchor } = tr.selection; + let activeRow; + let activeTable; + tr.doc.descendants((node, pos) => { + if (node.type.name === "table" && anchor >= pos && anchor <= (pos + node.nodeSize)) { + activeTable = pos; + } + if (node.type.name === "tableRow" && anchor >= pos && anchor <= (pos + node.nodeSize)) { + activeRow = pos; + } + }); + + // we are not in a table + if (activeTable === undefined || activeRow === undefined) { + return false + } + + return activeTable + 1 === activeRow; +} + const TableMenu = ({ editor }: TableMenuProps) => { const shouldShow = useCallback(() => { return ( @@ -53,7 +75,16 @@ const TableMenu = ({ editor }: TableMenuProps) => { editor.chain().focus().addRowBefore().run()} + onSelect={() => editor.chain().focus().command(({ tr, chain }) => { + // if we are in first row, we need to toggle header row off first + if (isInTableFirstRow(tr)) { + chain().toggleHeaderRow().addRowBefore().toggleHeaderRow(); + } else { + chain().addRowBefore(); + } + + return true + }).run()} name="Add row before" > @@ -65,7 +96,14 @@ const TableMenu = ({ editor }: TableMenuProps) => { editor.chain().focus().deleteRow().run()} + onSelect={() => editor.chain().focus().deleteRow().command(({ tr, chain }) => { + // if we are in first row, that means we deleted the header row + if (isInTableFirstRow(tr)) { + chain().toggleHeaderRow(); + } + + return true + }).run()} name="Delete row" >