diff --git a/.changeset/seven-eels-enjoy.md b/.changeset/seven-eels-enjoy.md new file mode 100644 index 0000000000..1f5d74aea6 --- /dev/null +++ b/.changeset/seven-eels-enjoy.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-alignment': patch +--- + +Deprecate useAlignDropdownMenuState, useAlignDropdownMenu diff --git a/.changeset/tidy-spies-walk.md b/.changeset/tidy-spies-walk.md new file mode 100644 index 0000000000..c96c8c4045 --- /dev/null +++ b/.changeset/tidy-spies-walk.md @@ -0,0 +1,12 @@ +--- +'@udecode/plate-autoformat': patch +'@udecode/plate-suggestion': patch +'@udecode/plate-selection': patch +'@udecode/plate-combobox': patch +'@udecode/plate-table': patch +'@udecode/plate-link': patch +'@udecode/plate-dnd': patch +'@udecode/plate-ai': patch +--- + +Fix overrideEditor insertText missing options diff --git a/apps/www/content/docs/en/alignment.mdx b/apps/www/content/docs/en/alignment.mdx index 14302a727f..07ae473ea2 100644 --- a/apps/www/content/docs/en/alignment.mdx +++ b/apps/www/content/docs/en/alignment.mdx @@ -71,43 +71,3 @@ Options for the `setNodes` function. - -## API Components - -### useAlignDropdownMenuState - - - - The alignment value. - - - -### useAlignDropdownMenu - - - - The alignment value. - - - - - - Props for the radio group. - - - The alignment value. - - - Callback to set the alignment value. - - - - diff --git a/apps/www/content/docs/en/components/changelog.mdx b/apps/www/content/docs/en/components/changelog.mdx index 82024d4c99..582192b3ac 100644 --- a/apps/www/content/docs/en/components/changelog.mdx +++ b/apps/www/content/docs/en/components/changelog.mdx @@ -12,7 +12,8 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver ### January 21 #18.7 -- `table-row-element`: support row dnd +- `table-element`, `table-row-element`: support row dnd and selection +- `plate-element`: add `blockSelectionClassName` prop - `editor`: z-50 for selection area - `draggable`: - Replace `editor.api.blockSelection.replaceSelectedIds` with `editor.api.blockSelection.clear` @@ -24,7 +25,7 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver - Replace `editor.api.blockSelection.addSelectedRow` with `editor.api.blockSelection.set`: - `ai-menu` - `equation-popover` - +- `align-dropdown-menu`: deprecate ### January 18 #18.6 diff --git a/apps/www/content/docs/en/migration/slate-to-plate.mdx b/apps/www/content/docs/en/migration/slate-to-plate.mdx index 8d00cba934..8007594ae4 100644 --- a/apps/www/content/docs/en/migration/slate-to-plate.mdx +++ b/apps/www/content/docs/en/migration/slate-to-plate.mdx @@ -125,9 +125,9 @@ const MyPlugin = createPlatePlugin({ key: 'myPlugin', }).overrideEditor(({ editor, tf: { insertText } }) => ({ transforms: { - insertText(text) { + insertText(text, options) { // Custom logic - insertText(text); + insertText(text, options); }, } })); diff --git a/apps/www/content/docs/en/plugin-methods.mdx b/apps/www/content/docs/en/plugin-methods.mdx index 073442fbbe..eeef249a17 100644 --- a/apps/www/content/docs/en/plugin-methods.mdx +++ b/apps/www/content/docs/en/plugin-methods.mdx @@ -255,9 +255,9 @@ const MyPlugin = createPlatePlugin({ key: 'myPlugin', }).overrideEditor(({ editor, tf: { insertText }, api: { isInline } }) => ({ transforms: { - insertText(text) { + insertText(text, options) { // Override insertText behavior - insertText(text); + insertText(text, options); }, }, api: { diff --git a/apps/www/content/docs/en/table.mdx b/apps/www/content/docs/en/table.mdx index 2a7a573695..d779e279ef 100644 --- a/apps/www/content/docs/en/table.mdx +++ b/apps/www/content/docs/en/table.mdx @@ -22,6 +22,8 @@ docs: - Grid cell selection. - Cell selection expansion with `Shift+Arrow` keys. - Copying and pasting cells. +- Row drag-and-drop reordering +- Row selection via drag handle diff --git a/apps/www/public/r/styles/default/ai-menu.json b/apps/www/public/r/styles/default/ai-menu.json index 4964dec929..2b7c6ba69c 100644 --- a/apps/www/public/r/styles/default/ai-menu.json +++ b/apps/www/public/r/styles/default/ai-menu.json @@ -27,7 +27,7 @@ }, "files": [ { - "content": "'use client';\n\nimport * as React from 'react';\n\nimport { type NodeEntry, isHotkey } from '@udecode/plate';\nimport { useEditorPlugin, useHotkeys } from '@udecode/plate/react';\nimport {\n AIChatPlugin,\n useEditorChat,\n useLastAssistantMessage,\n} from '@udecode/plate-ai/react';\nimport {\n BlockSelectionPlugin,\n useIsSelecting,\n} from '@udecode/plate-selection/react';\nimport { Loader2Icon } from 'lucide-react';\n\nimport { useChat } from '@/components/editor/use-chat';\n\nimport { AIChatEditor } from './ai-chat-editor';\nimport { AIMenuItems } from './ai-menu-items';\nimport { Command, CommandList, InputCommand } from './command';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\n\nexport function AIMenu() {\n const { api, editor, useOption } = useEditorPlugin(AIChatPlugin);\n const open = useOption('open');\n const mode = useOption('mode');\n const isSelecting = useIsSelecting();\n\n const [value, setValue] = React.useState('');\n\n const chat = useChat();\n\n const { input, isLoading, messages, setInput } = chat;\n const [anchorElement, setAnchorElement] = React.useState(\n null\n );\n\n const content = useLastAssistantMessage()?.content;\n\n const setOpen = (open: boolean) => {\n if (open) {\n api.aiChat.show();\n } else {\n api.aiChat.hide();\n }\n };\n\n const show = (anchorElement: HTMLElement) => {\n setAnchorElement(anchorElement);\n setOpen(true);\n };\n\n useEditorChat({\n chat,\n onOpenBlockSelection: (blocks: NodeEntry[]) => {\n show(editor.api.toDOMNode(blocks.at(-1)![0])!);\n },\n onOpenChange: (open) => {\n if (!open) {\n setAnchorElement(null);\n setInput('');\n }\n },\n onOpenCursor: () => {\n const [ancestor] = editor.api.block({ highest: true })!;\n\n if (!editor.api.isAt({ end: true }) && !editor.api.isEmpty(ancestor)) {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.addSelectedRow(ancestor.id as string);\n }\n\n show(editor.api.toDOMNode(ancestor)!);\n },\n onOpenSelection: () => {\n show(editor.api.toDOMNode(editor.api.blocks().at(-1)![0])!);\n },\n });\n\n useHotkeys(\n 'meta+j',\n () => {\n api.aiChat.show();\n },\n { enableOnContentEditable: true, enableOnFormTags: true }\n );\n\n return (\n \n \n\n {\n e.preventDefault();\n\n if (isLoading) {\n api.aiChat.stop();\n } else {\n api.aiChat.hide();\n }\n }}\n align=\"center\"\n // avoidCollisions={false}\n side=\"bottom\"\n >\n \n {mode === 'chat' && isSelecting && content && (\n \n )}\n\n {isLoading ? (\n
\n \n {messages.length > 1 ? 'Editing...' : 'Thinking...'}\n
\n ) : (\n {\n if (isHotkey('backspace')(e) && input.length === 0) {\n e.preventDefault();\n api.aiChat.hide();\n }\n if (isHotkey('enter')(e) && !e.shiftKey && !value) {\n e.preventDefault();\n void api.aiChat.submit();\n }\n }}\n onValueChange={setInput}\n placeholder=\"Ask AI anything...\"\n data-plate-focus\n autoFocus\n />\n )}\n\n {!isLoading && (\n \n \n \n )}\n \n \n
\n );\n}\n", + "content": "'use client';\n\nimport * as React from 'react';\n\nimport { type NodeEntry, isHotkey } from '@udecode/plate';\nimport { useEditorPlugin, useHotkeys } from '@udecode/plate/react';\nimport {\n AIChatPlugin,\n useEditorChat,\n useLastAssistantMessage,\n} from '@udecode/plate-ai/react';\nimport {\n BlockSelectionPlugin,\n useIsSelecting,\n} from '@udecode/plate-selection/react';\nimport { Loader2Icon } from 'lucide-react';\n\nimport { useChat } from '@/components/editor/use-chat';\n\nimport { AIChatEditor } from './ai-chat-editor';\nimport { AIMenuItems } from './ai-menu-items';\nimport { Command, CommandList, InputCommand } from './command';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\n\nexport function AIMenu() {\n const { api, editor, useOption } = useEditorPlugin(AIChatPlugin);\n const open = useOption('open');\n const mode = useOption('mode');\n const isSelecting = useIsSelecting();\n\n const [value, setValue] = React.useState('');\n\n const chat = useChat();\n\n const { input, isLoading, messages, setInput } = chat;\n const [anchorElement, setAnchorElement] = React.useState(\n null\n );\n\n const content = useLastAssistantMessage()?.content;\n\n const setOpen = (open: boolean) => {\n if (open) {\n api.aiChat.show();\n } else {\n api.aiChat.hide();\n }\n };\n\n const show = (anchorElement: HTMLElement) => {\n setAnchorElement(anchorElement);\n setOpen(true);\n };\n\n useEditorChat({\n chat,\n onOpenBlockSelection: (blocks: NodeEntry[]) => {\n show(editor.api.toDOMNode(blocks.at(-1)![0])!);\n },\n onOpenChange: (open) => {\n if (!open) {\n setAnchorElement(null);\n setInput('');\n }\n },\n onOpenCursor: () => {\n const [ancestor] = editor.api.block({ highest: true })!;\n\n if (!editor.api.isAt({ end: true }) && !editor.api.isEmpty(ancestor)) {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.set(ancestor.id as string);\n }\n\n show(editor.api.toDOMNode(ancestor)!);\n },\n onOpenSelection: () => {\n show(editor.api.toDOMNode(editor.api.blocks().at(-1)![0])!);\n },\n });\n\n useHotkeys(\n 'meta+j',\n () => {\n api.aiChat.show();\n },\n { enableOnContentEditable: true, enableOnFormTags: true }\n );\n\n return (\n \n \n\n {\n e.preventDefault();\n\n if (isLoading) {\n api.aiChat.stop();\n } else {\n api.aiChat.hide();\n }\n }}\n align=\"center\"\n // avoidCollisions={false}\n side=\"bottom\"\n >\n \n {mode === 'chat' && isSelecting && content && (\n \n )}\n\n {isLoading ? (\n
\n \n {messages.length > 1 ? 'Editing...' : 'Thinking...'}\n
\n ) : (\n {\n if (isHotkey('backspace')(e) && input.length === 0) {\n e.preventDefault();\n api.aiChat.hide();\n }\n if (isHotkey('enter')(e) && !e.shiftKey && !value) {\n e.preventDefault();\n void api.aiChat.submit();\n }\n }}\n onValueChange={setInput}\n placeholder=\"Ask AI anything...\"\n data-plate-focus\n autoFocus\n />\n )}\n\n {!isLoading && (\n \n \n \n )}\n \n \n
\n );\n}\n", "path": "plate-ui/ai-menu.tsx", "target": "components/plate-ui/ai-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/align-dropdown-menu.json b/apps/www/public/r/styles/default/align-dropdown-menu.json index 3d4dba6aaf..9171c2ac8d 100644 --- a/apps/www/public/r/styles/default/align-dropdown-menu.json +++ b/apps/www/public/r/styles/default/align-dropdown-menu.json @@ -16,7 +16,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport {\n useAlignDropdownMenu,\n useAlignDropdownMenuState,\n} from '@udecode/plate-alignment/react';\nimport {\n AlignCenterIcon,\n AlignJustifyIcon,\n AlignLeftIcon,\n AlignRightIcon,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n icon: AlignLeftIcon,\n value: 'left',\n },\n {\n icon: AlignCenterIcon,\n value: 'center',\n },\n {\n icon: AlignRightIcon,\n value: 'right',\n },\n {\n icon: AlignJustifyIcon,\n value: 'justify',\n },\n];\n\nexport function AlignDropdownMenu({ children, ...props }: DropdownMenuProps) {\n const state = useAlignDropdownMenuState();\n const { radioGroupProps } = useAlignDropdownMenu(state);\n\n const openState = useOpenState();\n const IconValue =\n items.find((item) => item.value === radioGroupProps.value)?.icon ??\n AlignLeftIcon;\n\n return (\n \n \n \n \n \n \n\n \n \n {items.map(({ icon: Icon, value: itemValue }) => (\n \n \n \n ))}\n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { useEditorRef, useSelectionFragmentProp } from '@udecode/plate/react';\nimport { setAlign } from '@udecode/plate-alignment';\nimport {\n AlignCenterIcon,\n AlignJustifyIcon,\n AlignLeftIcon,\n AlignRightIcon,\n} from 'lucide-react';\n\nimport { STRUCTURAL_TYPES } from '@/components/editor/transforms';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n icon: AlignLeftIcon,\n value: 'left',\n },\n {\n icon: AlignCenterIcon,\n value: 'center',\n },\n {\n icon: AlignRightIcon,\n value: 'right',\n },\n {\n icon: AlignJustifyIcon,\n value: 'justify',\n },\n];\n\nexport function AlignDropdownMenu({ children, ...props }: DropdownMenuProps) {\n const editor = useEditorRef();\n const value = useSelectionFragmentProp({\n defaultValue: 'start',\n getProp: (node) => node.align,\n structuralTypes: STRUCTURAL_TYPES,\n });\n\n const openState = useOpenState();\n const IconValue =\n items.find((item) => item.value === value)?.icon ?? AlignLeftIcon;\n\n return (\n \n \n \n \n \n \n\n \n {\n setAlign(editor, { value: value });\n editor.tf.focus();\n }}\n >\n {items.map(({ icon: Icon, value: itemValue }) => (\n \n \n \n ))}\n \n \n \n );\n}\n", "path": "plate-ui/align-dropdown-menu.tsx", "target": "components/plate-ui/align-dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/block-selection.json b/apps/www/public/r/styles/default/block-selection.json index 848a108ad9..dc0e1649e5 100644 --- a/apps/www/public/r/styles/default/block-selection.json +++ b/apps/www/public/r/styles/default/block-selection.json @@ -20,7 +20,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn } from '@udecode/cn';\nimport { useBlockSelected } from '@udecode/plate-selection/react';\nimport { type VariantProps, cva } from 'class-variance-authority';\n\nexport const blockSelectionVariants = cva(\n 'pointer-events-none absolute inset-0 z-[1] bg-brand/[.13] transition-opacity',\n {\n defaultVariants: {\n active: true,\n },\n variants: {\n active: {\n false: 'opacity-0',\n true: 'opacity-100',\n },\n },\n }\n);\n\nexport function BlockSelection({\n className,\n ...props\n}: React.HTMLAttributes &\n VariantProps) {\n const isBlockSelected = useBlockSelected();\n\n if (!isBlockSelected) return null;\n\n return (\n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn } from '@udecode/cn';\nimport { useEditorPlugin } from '@udecode/plate-core/react';\nimport { DndPlugin } from '@udecode/plate-dnd';\nimport { useBlockSelected } from '@udecode/plate-selection/react';\nimport { type VariantProps, cva } from 'class-variance-authority';\n\nexport const blockSelectionVariants = cva(\n 'pointer-events-none absolute inset-0 z-[1] bg-brand/[.13] transition-opacity',\n {\n defaultVariants: {\n active: true,\n },\n variants: {\n active: {\n false: 'opacity-0',\n true: 'opacity-100',\n },\n },\n }\n);\n\nexport function BlockSelection({\n className,\n ...props\n}: React.HTMLAttributes &\n VariantProps) {\n const isBlockSelected = useBlockSelected();\n const { useOption } = useEditorPlugin(DndPlugin);\n const isDragging = useOption('isDragging');\n\n if (!isBlockSelected) return null;\n\n return (\n \n );\n}\n", "path": "plate-ui/block-selection.tsx", "target": "components/plate-ui/block-selection.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/column-element.json b/apps/www/public/r/styles/default/column-element.json index 7bacb4f81d..28c100b4de 100644 --- a/apps/www/public/r/styles/default/column-element.json +++ b/apps/www/public/r/styles/default/column-element.json @@ -19,7 +19,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { TColumnElement } from '@udecode/plate-layout';\n\nimport { cn, useComposedRef, withRef } from '@udecode/cn';\nimport { PathApi } from '@udecode/plate';\nimport { useReadOnly, withHOC } from '@udecode/plate/react';\nimport { useDraggable, useDropLine } from '@udecode/plate-dnd';\nimport { ResizableProvider } from '@udecode/plate-resizable';\nimport { GripHorizontal } from 'lucide-react';\n\nimport { Button } from './button';\nimport { PlateElement } from './plate-element';\nimport {\n Tooltip,\n TooltipContent,\n TooltipPortal,\n TooltipProvider,\n TooltipTrigger,\n} from './tooltip';\n\nexport const ColumnElement = withHOC(\n ResizableProvider,\n withRef(({ children, className, ...props }, ref) => {\n const readOnly = useReadOnly();\n const { width } = props.element as TColumnElement;\n\n const { isDragging, previewRef, handleRef } = useDraggable({\n canDropNode: ({ dragEntry, dropEntry }) =>\n PathApi.equals(\n PathApi.parent(dragEntry[1]),\n PathApi.parent(dropEntry[1])\n ),\n element: props.element,\n orientation: 'horizontal',\n type: 'column',\n });\n\n return (\n
\n \n \n
\n\n \n \n {children}\n \n \n \n \n );\n })\n);\n\nconst ColumnDragHandle = React.memo(() => {\n return (\n \n \n \n \n \n \n Drag to move column\n \n \n \n );\n});\n\nconst DropLine = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => {\n const { dropLine } = useDropLine({ orientation: 'horizontal' });\n\n if (!dropLine) return null;\n\n return (\n \n );\n});\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { TColumnElement } from '@udecode/plate-layout';\n\nimport { cn, useComposedRef, withRef } from '@udecode/cn';\nimport { PathApi } from '@udecode/plate';\nimport { useReadOnly, withHOC } from '@udecode/plate/react';\nimport { useDraggable, useDropLine } from '@udecode/plate-dnd';\nimport { ResizableProvider } from '@udecode/plate-resizable';\nimport { BlockSelectionPlugin } from '@udecode/plate-selection/react';\nimport { GripHorizontal } from 'lucide-react';\n\nimport { Button } from './button';\nimport { PlateElement } from './plate-element';\nimport {\n Tooltip,\n TooltipContent,\n TooltipPortal,\n TooltipProvider,\n TooltipTrigger,\n} from './tooltip';\n\nexport const ColumnElement = withHOC(\n ResizableProvider,\n withRef(({ children, className, ...props }, ref) => {\n const { width } = props.element as TColumnElement;\n const readOnly = useReadOnly();\n const isSelectionAreaVisible = props.editor.useOption(\n BlockSelectionPlugin,\n 'isSelectionAreaVisible'\n );\n\n const { isDragging, previewRef, handleRef } = useDraggable({\n canDropNode: ({ dragEntry, dropEntry }) =>\n PathApi.equals(\n PathApi.parent(dragEntry[1]),\n PathApi.parent(dropEntry[1])\n ),\n element: props.element,\n orientation: 'horizontal',\n type: 'column',\n });\n\n return (\n
\n {!readOnly && !isSelectionAreaVisible && (\n \n \n
\n )}\n\n \n \n {children}\n\n {!readOnly && !isSelectionAreaVisible && }\n \n \n \n );\n })\n);\n\nconst ColumnDragHandle = React.memo(() => {\n return (\n \n \n \n \n \n \n Drag to move column\n \n \n \n );\n});\n\nconst DropLine = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => {\n const { dropLine } = useDropLine({ orientation: 'horizontal' });\n\n if (!dropLine) return null;\n\n return (\n \n );\n});\n", "path": "plate-ui/column-element.tsx", "target": "components/plate-ui/column-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/draggable.json b/apps/www/public/r/styles/default/draggable.json index bbbc9064ff..68cb5ca4d9 100644 --- a/apps/www/public/r/styles/default/draggable.json +++ b/apps/www/public/r/styles/default/draggable.json @@ -34,7 +34,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React, { useMemo } from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { isType } from '@udecode/plate';\nimport {\n type NodeWrapperComponent,\n type PlateRenderElementProps,\n MemoizedChildren,\n ParagraphPlugin,\n useEditorPlugin,\n useEditorRef,\n useElement,\n usePath,\n} from '@udecode/plate/react';\nimport { useReadOnly, useSelected } from '@udecode/plate/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { useDraggable, useDropLine } from '@udecode/plate-dnd';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport {\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n} from '@udecode/plate-media/react';\nimport { BlockSelectionPlugin } from '@udecode/plate-selection/react';\nimport {\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { GripVertical } from 'lucide-react';\n\nimport { STRUCTURAL_TYPES } from '@/components/editor/transforms';\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipPortal,\n TooltipProvider,\n TooltipTrigger,\n} from './tooltip';\n\nconst UNDRAGGABLE_KEYS = [\n ColumnItemPlugin.key,\n TableRowPlugin.key,\n TableCellPlugin.key,\n];\n\nexport const DraggableAboveNodes: NodeWrapperComponent = (props) => {\n const { editor, element, path } = props;\n const readOnly = useReadOnly();\n\n const enabled = useMemo(() => {\n if (readOnly) return false;\n if (path.length === 1 && !isType(editor, element, UNDRAGGABLE_KEYS)) {\n return true;\n }\n if (path.length === 3 && !isType(editor, element, UNDRAGGABLE_KEYS)) {\n const block = editor.api.some({\n at: path,\n match: {\n type: editor.getType(ColumnPlugin),\n },\n });\n\n if (block) {\n return true;\n }\n }\n if (path.length === 4 && !isType(editor, element, UNDRAGGABLE_KEYS)) {\n const block = editor.api.some({\n at: path,\n match: {\n type: editor.getType(TablePlugin),\n },\n });\n\n if (block) {\n return true;\n }\n }\n\n return false;\n }, [editor, element, path, readOnly]);\n\n if (!enabled) return;\n\n return (props) => ;\n};\n\nexport const Draggable = withRef<'div', PlateRenderElementProps>(\n ({ className, ...props }, ref) => {\n const { children, editor, element, path } = props;\n const { isDragging, previewRef, handleRef } = useDraggable({ element });\n\n const isInColumn = path.length === 3;\n const isInTable = path.length === 4;\n\n return (\n \n \n \n \n
\n \n
\n \n \n
\n\n
\n {children}\n\n \n
\n \n );\n }\n);\n\nconst Gutter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ children, className, ...props }, ref) => {\n const { editor, useOption } = useEditorPlugin(BlockSelectionPlugin);\n const element = useElement();\n const path = usePath();\n const isSelectionAreaVisible = useOption('isSelectionAreaVisible');\n const selected = useSelected();\n\n const isNodeType = (keys: string[] | string) => isType(editor, element, keys);\n\n const isInColumn = path.length === 3;\n const isInTable = path.length === 4;\n\n return (\n \n {children}\n \n );\n});\n\nconst DragHandle = React.memo(() => {\n const editor = useEditorRef();\n\n return (\n \n \n \n {\n event.stopPropagation();\n event.preventDefault();\n }}\n onMouseDown={() => {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection?.resetSelectedIds();\n }}\n />\n \n \n Drag to move\n \n \n \n );\n});\n\nconst DropLine = React.memo(\n React.forwardRef>(\n ({ className, ...props }, ref) => {\n const { dropLine } = useDropLine();\n\n if (!dropLine) return null;\n\n return (\n \n );\n }\n )\n);\n", + "content": "'use client';\n\nimport React, { useMemo } from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { isType } from '@udecode/plate';\nimport {\n type NodeWrapperComponent,\n type PlateRenderElementProps,\n MemoizedChildren,\n ParagraphPlugin,\n useEditorPlugin,\n useEditorRef,\n useElement,\n usePath,\n} from '@udecode/plate/react';\nimport { useReadOnly, useSelected } from '@udecode/plate/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { useDraggable, useDropLine } from '@udecode/plate-dnd';\nimport { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport {\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n} from '@udecode/plate-media/react';\nimport { BlockSelectionPlugin } from '@udecode/plate-selection/react';\nimport {\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { GripVertical } from 'lucide-react';\n\nimport { STRUCTURAL_TYPES } from '@/components/editor/transforms';\n\nimport { TooltipButton } from './tooltip';\n\nconst UNDRAGGABLE_KEYS = [\n ColumnItemPlugin.key,\n TableRowPlugin.key,\n TableCellPlugin.key,\n];\n\nexport const DraggableAboveNodes: NodeWrapperComponent = (props) => {\n const { editor, element, path } = props;\n const readOnly = useReadOnly();\n\n const enabled = useMemo(() => {\n if (readOnly) return false;\n if (path.length === 1 && !isType(editor, element, UNDRAGGABLE_KEYS)) {\n return true;\n }\n if (path.length === 3 && !isType(editor, element, UNDRAGGABLE_KEYS)) {\n const block = editor.api.some({\n at: path,\n match: {\n type: editor.getType(ColumnPlugin),\n },\n });\n\n if (block) {\n return true;\n }\n }\n if (path.length === 4 && !isType(editor, element, UNDRAGGABLE_KEYS)) {\n const block = editor.api.some({\n at: path,\n match: {\n type: editor.getType(TablePlugin),\n },\n });\n\n if (block) {\n return true;\n }\n }\n\n return false;\n }, [editor, element, path, readOnly]);\n\n if (!enabled) return;\n\n return (props) => ;\n};\n\nexport const Draggable = withRef<'div', PlateRenderElementProps>(\n ({ className, ...props }, ref) => {\n const { children, editor, element, path } = props;\n const blockSelectionApi =\n editor.getApi(BlockSelectionPlugin).blockSelection;\n const { isDragging, previewRef, handleRef } = useDraggable({\n element,\n onDropHandler: (_, { dragItem }) => {\n const id = (dragItem as any).id;\n\n if (blockSelectionApi && id) {\n blockSelectionApi.set(id);\n }\n },\n });\n\n const isInColumn = path.length === 3;\n const isInTable = path.length === 4;\n\n return (\n \n {!isInTable && (\n \n \n \n
\n \n
\n \n \n
\n )}\n\n
\n {children}\n\n \n
\n \n );\n }\n);\n\nconst Gutter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ children, className, ...props }, ref) => {\n const { editor, useOption } = useEditorPlugin(BlockSelectionPlugin);\n const element = useElement();\n const path = usePath();\n const isSelectionAreaVisible = useOption('isSelectionAreaVisible');\n const selected = useSelected();\n\n const isNodeType = (keys: string[] | string) => isType(editor, element, keys);\n\n const isInColumn = path.length === 3;\n\n return (\n \n {children}\n \n );\n});\n\nconst DragHandle = React.memo(() => {\n const editor = useEditorRef();\n const element = useElement();\n\n return (\n {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.set(element.id as string);\n }}\n data-plate-prevent-deselect\n tooltip=\"Drag to move\"\n >\n \n \n );\n});\n\nconst DropLine = React.memo(\n React.forwardRef>(\n ({ className, ...props }, ref) => {\n const { dropLine } = useDropLine();\n\n if (!dropLine) return null;\n\n return (\n \n );\n }\n )\n);\n", "path": "plate-ui/draggable.tsx", "target": "components/plate-ui/draggable.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/editor.json b/apps/www/public/r/styles/default/editor.json index d69773a4ad..703f2c8081 100644 --- a/apps/www/public/r/styles/default/editor.json +++ b/apps/www/public/r/styles/default/editor.json @@ -15,7 +15,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { PlateContentProps } from '@udecode/plate/react';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@udecode/cn';\nimport {\n PlateContent,\n useEditorContainerRef,\n useEditorRef,\n} from '@udecode/plate/react';\nimport { cva } from 'class-variance-authority';\n\nconst editorContainerVariants = cva(\n 'relative w-full cursor-text select-text overflow-y-auto caret-primary selection:bg-brand/25 focus-visible:outline-none [&_.slate-selection-area]:border [&_.slate-selection-area]:border-brand/25 [&_.slate-selection-area]:bg-brand/15',\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: 'h-full',\n demo: 'h-[650px]',\n select: cn(\n 'group rounded-md border border-input ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2',\n 'has-[[data-readonly]]:w-fit has-[[data-readonly]]:cursor-default has-[[data-readonly]]:border-transparent has-[[data-readonly]]:focus-within:[box-shadow:none]'\n ),\n },\n },\n }\n);\n\nexport const EditorContainer = ({\n className,\n variant,\n ...props\n}: React.HTMLAttributes &\n VariantProps) => {\n const editor = useEditorRef();\n const containerRef = useEditorContainerRef();\n\n return (\n \n );\n};\n\nEditorContainer.displayName = 'EditorContainer';\n\nconst editorVariants = cva(\n cn(\n 'group/editor',\n 'relative w-full cursor-text select-text overflow-x-hidden whitespace-pre-wrap break-words',\n 'rounded-md ring-offset-background focus-visible:outline-none',\n 'placeholder:text-muted-foreground/80 [&_[data-slate-placeholder]]:top-[auto_!important] [&_[data-slate-placeholder]]:text-muted-foreground/80 [&_[data-slate-placeholder]]:!opacity-100',\n '[&_strong]:font-bold'\n ),\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n },\n focused: {\n true: 'ring-2 ring-ring ring-offset-2',\n },\n variant: {\n ai: 'w-full px-0 text-base md:text-sm',\n aiChat:\n 'max-h-[min(70vh,320px)] w-full max-w-[700px] overflow-y-auto px-3 py-2 text-base md:text-sm',\n default:\n 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n demo: 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n fullWidth: 'size-full px-16 pb-72 pt-4 text-base sm:px-24',\n none: '',\n select: 'px-3 py-2 text-base data-[readonly]:w-fit',\n },\n },\n }\n);\n\nexport type EditorProps = PlateContentProps &\n VariantProps;\n\nexport const Editor = React.forwardRef(\n ({ className, disabled, focused, variant, ...props }, ref) => {\n return (\n \n );\n }\n);\n\nEditor.displayName = 'Editor';\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { PlateContentProps } from '@udecode/plate/react';\nimport type { VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@udecode/cn';\nimport {\n PlateContent,\n useEditorContainerRef,\n useEditorRef,\n} from '@udecode/plate/react';\nimport { cva } from 'class-variance-authority';\n\nconst editorContainerVariants = cva(\n 'relative w-full cursor-text select-text overflow-y-auto caret-primary selection:bg-brand/25 focus-visible:outline-none [&_.slate-selection-area]:z-50 [&_.slate-selection-area]:border [&_.slate-selection-area]:border-brand/25 [&_.slate-selection-area]:bg-brand/15',\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n variant: {\n default: 'h-full',\n demo: 'h-[650px]',\n select: cn(\n 'group rounded-md border border-input ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2',\n 'has-[[data-readonly]]:w-fit has-[[data-readonly]]:cursor-default has-[[data-readonly]]:border-transparent has-[[data-readonly]]:focus-within:[box-shadow:none]'\n ),\n },\n },\n }\n);\n\nexport const EditorContainer = ({\n className,\n variant,\n ...props\n}: React.HTMLAttributes &\n VariantProps) => {\n const editor = useEditorRef();\n const containerRef = useEditorContainerRef();\n\n return (\n \n );\n};\n\nEditorContainer.displayName = 'EditorContainer';\n\nconst editorVariants = cva(\n cn(\n 'group/editor',\n 'relative w-full cursor-text select-text overflow-x-hidden whitespace-pre-wrap break-words',\n 'rounded-md ring-offset-background focus-visible:outline-none',\n 'placeholder:text-muted-foreground/80 [&_[data-slate-placeholder]]:top-[auto_!important] [&_[data-slate-placeholder]]:text-muted-foreground/80 [&_[data-slate-placeholder]]:!opacity-100',\n '[&_strong]:font-bold'\n ),\n {\n defaultVariants: {\n variant: 'default',\n },\n variants: {\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n },\n focused: {\n true: 'ring-2 ring-ring ring-offset-2',\n },\n variant: {\n ai: 'w-full px-0 text-base md:text-sm',\n aiChat:\n 'max-h-[min(70vh,320px)] w-full max-w-[700px] overflow-y-auto px-3 py-2 text-base md:text-sm',\n default:\n 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n demo: 'size-full px-16 pb-72 pt-4 text-base sm:px-[max(64px,calc(50%-350px))]',\n fullWidth: 'size-full px-16 pb-72 pt-4 text-base sm:px-24',\n none: '',\n select: 'px-3 py-2 text-base data-[readonly]:w-fit',\n },\n },\n }\n);\n\nexport type EditorProps = PlateContentProps &\n VariantProps;\n\nexport const Editor = React.forwardRef(\n ({ className, disabled, focused, variant, ...props }, ref) => {\n return (\n \n );\n }\n);\n\nEditor.displayName = 'Editor';\n", "path": "plate-ui/editor.tsx", "target": "components/plate-ui/editor.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/equation-element.json b/apps/www/public/r/styles/default/equation-element.json index 617b51d1ee..3943267549 100644 --- a/apps/www/public/r/styles/default/equation-element.json +++ b/apps/www/public/r/styles/default/equation-element.json @@ -29,7 +29,7 @@ "type": "registry:ui" }, { - "content": "'use client';\n\nimport React, { useEffect } from 'react';\nimport TextareaAutosize, {\n type TextareaAutosizeProps,\n} from 'react-textarea-autosize';\n\nimport type { TEquationElement } from '@udecode/plate-math';\n\nimport { cn } from '@udecode/cn';\nimport {\n createPrimitiveComponent,\n useEditorRef,\n useElement,\n useReadOnly,\n useSelected,\n} from '@udecode/plate/react';\nimport { useEquationInput } from '@udecode/plate-math/react';\nimport { BlockSelectionPlugin } from '@udecode/plate-selection/react';\nimport { CornerDownLeftIcon } from 'lucide-react';\n\nimport { Button } from './button';\nimport { PopoverContent } from './popover';\n\nconst EquationInput = createPrimitiveComponent(TextareaAutosize)({\n propsHook: useEquationInput,\n});\n\nconst EquationPopoverContent = ({\n className,\n isInline,\n open,\n setOpen,\n ...props\n}: {\n isInline: boolean;\n open: boolean;\n setOpen: (open: boolean) => void;\n} & TextareaAutosizeProps) => {\n const editor = useEditorRef();\n const readOnly = useReadOnly();\n const element = useElement();\n const selected = useSelected();\n\n useEffect(() => {\n if (isInline && selected) {\n setOpen(true);\n }\n }, [selected, isInline, setOpen]);\n\n if (readOnly) return null;\n\n const onClose = () => {\n setOpen(false);\n\n if (isInline) {\n editor.tf.select(element, { next: true });\n } else {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.addSelectedRow(element.id as string);\n }\n };\n\n return (\n {\n e.preventDefault();\n }}\n contentEditable={false}\n >\n \n\n \n \n );\n};\n\nexport { EquationPopoverContent };\n", + "content": "'use client';\n\nimport React, { useEffect } from 'react';\nimport TextareaAutosize, {\n type TextareaAutosizeProps,\n} from 'react-textarea-autosize';\n\nimport type { TEquationElement } from '@udecode/plate-math';\n\nimport { cn } from '@udecode/cn';\nimport {\n createPrimitiveComponent,\n useEditorRef,\n useElement,\n useReadOnly,\n} from '@udecode/plate/react';\nimport { useEquationInput } from '@udecode/plate-math/react';\nimport { BlockSelectionPlugin } from '@udecode/plate-selection/react';\nimport { CornerDownLeftIcon } from 'lucide-react';\n\nimport { Button } from './button';\nimport { PopoverContent } from './popover';\n\nconst EquationInput = createPrimitiveComponent(TextareaAutosize)({\n propsHook: useEquationInput,\n});\n\nconst EquationPopoverContent = ({\n className,\n isInline,\n open,\n setOpen,\n ...props\n}: {\n isInline: boolean;\n open: boolean;\n setOpen: (open: boolean) => void;\n} & TextareaAutosizeProps) => {\n const editor = useEditorRef();\n const readOnly = useReadOnly();\n const element = useElement();\n\n useEffect(() => {\n if (isInline && open) {\n setOpen(true);\n }\n }, [isInline, open, setOpen]);\n\n if (readOnly) return null;\n\n const onClose = () => {\n setOpen(false);\n\n if (isInline) {\n editor.tf.select(element, { next: true });\n } else {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.set(element.id as string);\n }\n };\n\n return (\n {\n e.preventDefault();\n }}\n contentEditable={false}\n >\n \n\n \n \n );\n};\n\nexport { EquationPopoverContent };\n", "path": "plate-ui/equation-popover.tsx", "target": "components/plate-ui/equation-popover.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/inline-equation-element.json b/apps/www/public/r/styles/default/inline-equation-element.json index 9275d3a61f..0d41d114fc 100644 --- a/apps/www/public/r/styles/default/inline-equation-element.json +++ b/apps/www/public/r/styles/default/inline-equation-element.json @@ -16,7 +16,7 @@ }, "files": [ { - "content": "'use client';\n\nimport { useRef, useState } from 'react';\n\nimport type { TEquationElement } from '@udecode/plate-math';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { useElement, useSelected } from '@udecode/plate/react';\nimport { useEquationElement } from '@udecode/plate-math/react';\nimport { RadicalIcon } from 'lucide-react';\n\nimport { EquationPopoverContent } from './equation-popover';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverTrigger } from './popover';\n\nexport const InlineEquationElement = withRef(\n ({ children, className, ...props }, ref) => {\n const element = useElement();\n const katexRef = useRef(null);\n const selected = useSelected();\n const [open, setOpen] = useState(selected);\n\n useEquationElement({\n element,\n katexRef: katexRef,\n options: {\n displayMode: true,\n errorColor: '#cc0000',\n fleqn: false,\n leqno: false,\n macros: { '\\\\f': '#1f(#2)' },\n output: 'htmlAndMathml',\n strict: 'warn',\n throwOnError: false,\n trust: false,\n },\n });\n\n return (\n \n \n \n 0 && open && 'after:bg-brand/15',\n element.texExpression.length === 0 &&\n 'text-muted-foreground after:bg-neutral-500/10',\n className\n )}\n contentEditable={false}\n >\n \n {element.texExpression.length === 0 && (\n \n \n New equation\n \n )}\n \n \n\n \n \n\n {children}\n \n );\n }\n);\n", + "content": "'use client';\n\nimport { useRef, useState } from 'react';\n\nimport type { TEquationElement } from '@udecode/plate-math';\n\nimport { cn, withRef } from '@udecode/cn';\nimport {\n useEditorSelector,\n useElement,\n useSelected,\n} from '@udecode/plate/react';\nimport { useEquationElement } from '@udecode/plate-math/react';\nimport { RadicalIcon } from 'lucide-react';\n\nimport { EquationPopoverContent } from './equation-popover';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverTrigger } from './popover';\n\nexport const InlineEquationElement = withRef(\n ({ children, className, ...props }, ref) => {\n const element = useElement();\n const katexRef = useRef(null);\n const selected = useSelected();\n const isCollapsed = useEditorSelector(\n (editor) => editor.api.isCollapsed(),\n []\n );\n const [open, setOpen] = useState(selected && isCollapsed);\n\n useEquationElement({\n element,\n katexRef: katexRef,\n options: {\n displayMode: true,\n errorColor: '#cc0000',\n fleqn: false,\n leqno: false,\n macros: { '\\\\f': '#1f(#2)' },\n output: 'htmlAndMathml',\n strict: 'warn',\n throwOnError: false,\n trust: false,\n },\n });\n\n return (\n \n \n \n 0 && open && 'after:bg-brand/15',\n element.texExpression.length === 0 &&\n 'text-muted-foreground after:bg-neutral-500/10',\n className\n )}\n contentEditable={false}\n >\n \n {element.texExpression.length === 0 && (\n \n \n New equation\n \n )}\n \n \n\n \n \n\n {children}\n \n );\n }\n);\n", "path": "plate-ui/inline-equation-element.tsx", "target": "components/plate-ui/inline-equation-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/plate-element.json b/apps/www/public/r/styles/default/plate-element.json index 5a25b11eba..2ef4cd0666 100644 --- a/apps/www/public/r/styles/default/plate-element.json +++ b/apps/www/public/r/styles/default/plate-element.json @@ -16,7 +16,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { PlateElementProps } from '@udecode/plate/react';\n\nimport { PlateElement as PlateElementPrimitive } from '@udecode/plate/react';\n\nimport { BlockSelection } from './block-selection';\n\nexport const PlateElement = React.forwardRef(\n ({ children, ...props }: PlateElementProps, ref) => {\n return (\n \n {children}\n\n {props.className?.includes('slate-selectable') && }\n \n );\n }\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type { PlateElementProps } from '@udecode/plate/react';\n\nimport { PlateElement as PlateElementPrimitive } from '@udecode/plate/react';\n\nimport { BlockSelection } from './block-selection';\n\nexport const PlateElement = React.forwardRef<\n HTMLDivElement,\n PlateElementProps & { blockSelectionClassName?: string }\n>(({ blockSelectionClassName, children, ...props }, ref) => {\n return (\n \n {children}\n\n {props.className?.includes('slate-selectable') && (\n \n )}\n \n );\n});\n", "path": "plate-ui/plate-element.tsx", "target": "components/plate-ui/plate-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/table-cell-element.json b/apps/www/public/r/styles/default/table-cell-element.json index 9630e76fd6..6bdd6b91ad 100644 --- a/apps/www/public/r/styles/default/table-cell-element.json +++ b/apps/www/public/r/styles/default/table-cell-element.json @@ -18,7 +18,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type { TTableCellElement } from '@udecode/plate-table';\n\nimport { cn, withProps, withRef } from '@udecode/cn';\nimport {\n useEditorPlugin,\n useElementSelector,\n useReadOnly,\n} from '@udecode/plate/react';\nimport { useBlockSelected } from '@udecode/plate-selection/react';\nimport {\n TablePlugin,\n TableRowPlugin,\n useTableCellElement,\n useTableCellElementResizable,\n} from '@udecode/plate-table/react';\nimport { cva } from 'class-variance-authority';\n\nimport { blockSelectionVariants } from './block-selection';\nimport { PlateElement } from './plate-element';\nimport { ResizeHandle } from './resizable';\n\nexport const TableCellElement = withRef<\n typeof PlateElement,\n {\n isHeader?: boolean;\n }\n>(({ children, className, isHeader, style, ...props }, ref) => {\n const { api } = useEditorPlugin(TablePlugin);\n const readOnly = useReadOnly();\n const element = props.element as TTableCellElement;\n\n const rowId = useElementSelector(([node]) => node.id as string, [], {\n key: TableRowPlugin.key,\n });\n const isSelectingRow = useBlockSelected(rowId);\n\n const {\n borders,\n colIndex,\n colSpan,\n isSelectingCell,\n minHeight,\n rowIndex,\n selected,\n width,\n } = useTableCellElement();\n\n const { bottomProps, hiddenLeft, leftProps, rightProps } =\n useTableCellElementResizable({\n colIndex,\n colSpan,\n rowIndex,\n });\n\n return (\n _*]:m-0',\n 'before:size-full',\n selected && 'before:z-10 before:bg-muted',\n \"before:absolute before:box-border before:select-none before:content-['']\",\n borders &&\n cn(\n borders.bottom?.size && `before:border-b before:border-b-border`,\n borders.right?.size && `before:border-r before:border-r-border`,\n borders.left?.size && `before:border-l before:border-l-border`,\n borders.top?.size && `before:border-t before:border-t-border`\n )\n )\n )}\n style={\n {\n '--cellBackground': element.background,\n maxWidth: width || 240,\n minWidth: width || 120,\n ...style,\n } as React.CSSProperties\n }\n {...{\n colSpan: api.table.getColSpan(element),\n rowSpan: api.table.getRowSpan(element),\n }}\n {...props}\n >\n \n {children}\n \n\n {!isSelectingCell && (\n \n {!readOnly && (\n <>\n \n \n {!hiddenLeft && (\n \n )}\n\n