diff --git a/.changeset/new-stingrays-live.md b/.changeset/new-stingrays-live.md new file mode 100644 index 0000000000..e31be610ef --- /dev/null +++ b/.changeset/new-stingrays-live.md @@ -0,0 +1,5 @@ +--- +'@udecode/plate-indent-list': patch +--- + +`someIndentList` support multiple type diff --git a/apps/www/content/docs/cn/components/changelog.mdx b/apps/www/content/docs/cn/components/changelog.mdx index 01be3b5abe..dc4c05df4d 100644 --- a/apps/www/content/docs/cn/components/changelog.mdx +++ b/apps/www/content/docs/cn/components/changelog.mdx @@ -10,10 +10,62 @@ toc: true ## 2024年12月 #17 + +### 12月25日 #17.6 + +- `indent-list-toolbar-button`: 移除 `IndentListToolbarButton`,改用 `NumberedIndentListToolbarButton` 和 `BulletedIndentListToolbarButton`。 +- `table-dropdown-menu`: 新的插入表格界面。 + +### 12月23日 #17.5 + +- `table-element`: 修复选择 +- 修改前: `isSelectingCell && '[&_*::selection]:bg-none'` +- 修改后: `isSelectingCell && '[&_*::selection]:!bg-transparent'` + + +### 12月21日 #17.4 + +更新 `tailwind.config.cjs` 以提供更好的 HTML 导出字体支持: + +```ts +fontFamily: { + heading: [ + 'var(--font-heading)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], + mono: ['var(--font-mono)', ...fontFamily.mono], + sans: [ + 'var(--font-sans)', + 'ui-sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI Variable Display', + 'Segoe UI', + 'Helvetica', + 'Apple Color Emoji', + 'Arial', + 'sans-serif', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji', + ], +``` + ### 12月20日 #17.3 -- `insertColumnGroup`, `toggleColumnGroup`: use `columns` option instead of `layout` -- Remove `with-draggables`. Add [`DraggableAboveNodes`](https://github.com/udecode/plate/pull/3878/files#diff-493c12ebed9c3ef9fd8c3a723909b18ad439a448c0132d2d93e5341ee0888ad2) to `draggable`. Add to `DndPlugin` config: +- `insertColumnGroup`、`toggleColumnGroup`:使用 `columns` 选项替代 `layout` +- 移除 `with-draggables`。将 [`DraggableAboveNodes`](https://github.com/udecode/plate/pull/3878/files#diff-493c12ebed9c3ef9fd8c3a723909b18ad439a448c0132d2d93e5341ee0888ad2) 添加到 `draggable`。添加到 `DndPlugin` 配置中: ```tsx DndPlugin.configure({ render: { aboveNodes: DraggableAboveNodes } }), ``` diff --git a/apps/www/content/docs/cn/indent-list.mdx b/apps/www/content/docs/cn/indent-list.mdx index 50a0c83c72..e26f4ce366 100644 --- a/apps/www/content/docs/cn/indent-list.mdx +++ b/apps/www/content/docs/cn/indent-list.mdx @@ -233,7 +233,7 @@ const plugins = [ 编辑器实例。 - + 要检查的列表样式类型。 diff --git a/apps/www/content/docs/en/components/changelog.mdx b/apps/www/content/docs/en/components/changelog.mdx index f1dcd58d74..8318b69c4f 100644 --- a/apps/www/content/docs/en/components/changelog.mdx +++ b/apps/www/content/docs/en/components/changelog.mdx @@ -10,6 +10,11 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver ## December 2024 #17 +### December 25 #17.6 + +- `indent-list-toolbar-button`: Remove `IndentListToolbarButton` use `NumberedIndentListToolbarButton` and `BulletedIndentListToolbarButton` instead. +- `table-dropdown-menu`: new insert table interface. + ### December 23 #17.5 - `table-element`: fix selection diff --git a/apps/www/content/docs/en/indent-list.mdx b/apps/www/content/docs/en/indent-list.mdx index 0102c250d3..701af26392 100644 --- a/apps/www/content/docs/en/indent-list.mdx +++ b/apps/www/content/docs/en/indent-list.mdx @@ -231,7 +231,7 @@ Checks if some of the selected blocks have a specific list style type. The editor instance. - + The list style type to check. diff --git a/apps/www/public/r/styles/default/comments-plugin.json b/apps/www/public/r/styles/default/comments-plugin.json index ee7eeb91eb..37e5370148 100644 --- a/apps/www/public/r/styles/default/comments-plugin.json +++ b/apps/www/public/r/styles/default/comments-plugin.json @@ -4,7 +4,7 @@ ], "files": [ { - "content": "'use client';\n\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\n\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\n\nexport const commentsPlugin = CommentsPlugin.configure({\n options: {\n myUserId: '1',\n users: {\n 1: {\n id: '1',\n avatarUrl: 'https://avatars.githubusercontent.com/u/19695832?s=96&v=4',\n name: 'zbeyens',\n },\n 2: {\n id: '2',\n avatarUrl: 'https://avatars.githubusercontent.com/u/4272090?v=4',\n name: '12joan',\n },\n },\n },\n render: { afterEditable: () => },\n});\n", + "content": "'use client';\n\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\n\nimport { commentsData } from '@/components/values/comments-value';\nimport { CommentsPopover } from '@/components/plate-ui/comments-popover';\n\nexport const commentsPlugin = CommentsPlugin.configure({\n options: {\n comments: commentsData,\n myUserId: '1',\n users: {\n 1: {\n id: '1',\n avatarUrl: 'https://avatars.githubusercontent.com/u/19695832?s=96&v=4',\n name: 'zbeyens',\n },\n 2: {\n id: '2',\n avatarUrl: 'https://avatars.githubusercontent.com/u/4272090?v=4',\n name: '12joan',\n },\n },\n },\n render: { afterEditable: () => },\n});\n", "path": "components/editor/plugins/comments-plugin.tsx", "target": "components/editor/plugins/comments-plugin.tsx", "type": "registry:component" diff --git a/apps/www/public/r/styles/default/draggable.json b/apps/www/public/r/styles/default/draggable.json index 8341a471d4..c3351d0f19 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 { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { isType, someNode } from '@udecode/plate-common';\nimport {\n type NodeWrapperComponent,\n type PlateRenderElementProps,\n MemoizedChildren,\n ParagraphPlugin,\n useEditorPlugin,\n useEditorRef,\n useElement,\n usePath,\n} from '@udecode/plate-common/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';\nimport { useReadOnly, useSelected } from 'slate-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 = someNode(editor, {\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 = someNode(editor, {\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 { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { CodeBlockPlugin } from '@udecode/plate-code-block/react';\nimport { isType, someNode } from '@udecode/plate-common';\nimport {\n type NodeWrapperComponent,\n type PlateRenderElementProps,\n MemoizedChildren,\n ParagraphPlugin,\n useEditorPlugin,\n useEditorRef,\n useElement,\n usePath,\n} from '@udecode/plate-common/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';\nimport { useReadOnly, useSelected } from 'slate-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 = someNode(editor, {\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 = someNode(editor, {\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", "path": "plate-ui/draggable.tsx", "target": "components/plate-ui/draggable.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/fixed-toolbar-buttons.json b/apps/www/public/r/styles/default/fixed-toolbar-buttons.json index c6e3dda1b5..f22080cbdb 100644 --- a/apps/www/public/r/styles/default/fixed-toolbar-buttons.json +++ b/apps/www/public/r/styles/default/fixed-toolbar-buttons.json @@ -14,7 +14,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { ListStyleType } from '@udecode/plate-indent-list';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n ArrowUpToLineIcon,\n BaselineIcon,\n BoldIcon,\n Code2Icon,\n HighlighterIcon,\n ItalicIcon,\n PaintBucketIcon,\n StrikethroughIcon,\n UnderlineIcon,\n WandSparklesIcon,\n} from 'lucide-react';\n\nimport { MoreDropdownMenu } from '@/components/plate-ui/more-dropdown-menu';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { AlignDropdownMenu } from './align-dropdown-menu';\nimport { ColorDropdownMenu } from './color-dropdown-menu';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { EmojiDropdownMenu } from './emoji-dropdown-menu';\nimport { ExportToolbarButton } from './export-toolbar-button';\nimport { RedoToolbarButton, UndoToolbarButton } from './history-toolbar-button';\nimport { IndentListToolbarButton } from './indent-list-toolbar-button';\nimport { IndentTodoToolbarButton } from './indent-todo-toolbar-button';\nimport { IndentToolbarButton } from './indent-toolbar-button';\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { LineHeightDropdownMenu } from './line-height-dropdown-menu';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MediaToolbarButton } from './media-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { OutdentToolbarButton } from './outdent-toolbar-button';\nimport { TableDropdownMenu } from './table-dropdown-menu';\nimport { ToggleToolbarButton } from './toggle-toolbar-button';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n
\n {!readOnly && (\n <>\n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n \n\n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n )}\n\n
\n\n \n \n \n \n \n \n\n \n \n \n
\n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n ArrowUpToLineIcon,\n BaselineIcon,\n BoldIcon,\n Code2Icon,\n HighlighterIcon,\n ItalicIcon,\n PaintBucketIcon,\n StrikethroughIcon,\n UnderlineIcon,\n WandSparklesIcon,\n} from 'lucide-react';\n\nimport { MoreDropdownMenu } from '@/components/plate-ui/more-dropdown-menu';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { AlignDropdownMenu } from './align-dropdown-menu';\nimport { ColorDropdownMenu } from './color-dropdown-menu';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { EmojiDropdownMenu } from './emoji-dropdown-menu';\nimport { ExportToolbarButton } from './export-toolbar-button';\nimport { RedoToolbarButton, UndoToolbarButton } from './history-toolbar-button';\nimport {\n BulletedIndentListToolbarButton,\n NumberedIndentListToolbarButton,\n} from './indent-list-toolbar-button';\nimport { IndentTodoToolbarButton } from './indent-todo-toolbar-button';\nimport { IndentToolbarButton } from './indent-toolbar-button';\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { LineHeightDropdownMenu } from './line-height-dropdown-menu';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MediaToolbarButton } from './media-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { OutdentToolbarButton } from './outdent-toolbar-button';\nimport { TableDropdownMenu } from './table-dropdown-menu';\nimport { ToggleToolbarButton } from './toggle-toolbar-button';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n
\n {!readOnly && (\n <>\n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n\n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n \n\n \n \n\n \n \n {/* */}\n {/* */}\n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n \n\n \n \n \n \n \n\n \n \n \n \n )}\n\n
\n\n \n \n \n \n \n \n\n \n \n \n
\n );\n}\n", "path": "plate-ui/fixed-toolbar-buttons.tsx", "target": "components/plate-ui/fixed-toolbar-buttons.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/indent-list-toolbar-button.json b/apps/www/public/r/styles/default/indent-list-toolbar-button.json index 0745bd17c1..8b091ef329 100644 --- a/apps/www/public/r/styles/default/indent-list-toolbar-button.json +++ b/apps/www/public/r/styles/default/indent-list-toolbar-button.json @@ -15,7 +15,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport { ListStyleType } from '@udecode/plate-indent-list';\nimport {\n useIndentListToolbarButton,\n useIndentListToolbarButtonState,\n} from '@udecode/plate-indent-list/react';\nimport { List, ListOrdered } from 'lucide-react';\n\nimport { ToolbarButton } from './toolbar';\n\nexport const IndentListToolbarButton = withRef<\n typeof ToolbarButton,\n {\n nodeType?: ListStyleType;\n }\n>(({ nodeType = ListStyleType.Disc }, ref) => {\n const state = useIndentListToolbarButtonState({ nodeType });\n const { props } = useIndentListToolbarButton(state);\n\n return (\n \n {nodeType === ListStyleType.Disc ? : }\n \n );\n});\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { useEditorRef, useEditorSelector } from '@udecode/plate-common/react';\nimport {\n ListStyleType,\n someIndentList,\n toggleIndentList,\n} from '@udecode/plate-indent-list';\nimport { List, ListOrdered } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport {\n ToolbarSplitButton,\n ToolbarSplitButtonPrimary,\n ToolbarSplitButtonSecondary,\n} from './toolbar';\n\nexport function NumberedIndentListToolbarButton() {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n const pressed = useEditorSelector(\n (editor) =>\n someIndentList(editor, [\n ListStyleType.Decimal,\n ListStyleType.LowerAlpha,\n ListStyleType.UpperAlpha,\n ListStyleType.LowerRoman,\n ListStyleType.UpperRoman,\n ]),\n []\n );\n\n return (\n \n {\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Decimal,\n });\n }}\n pressed={pressed}\n >\n \n \n\n \n \n \n \n\n \n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.Decimal,\n })\n }\n >\n Decimal (1, 2, 3)\n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.LowerAlpha,\n })\n }\n >\n Lower Alpha (a, b, c)\n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.UpperAlpha,\n })\n }\n >\n Upper Alpha (A, B, C)\n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.LowerRoman,\n })\n }\n >\n Lower Roman (i, ii, iii)\n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.UpperRoman,\n })\n }\n >\n Upper Roman (I, II, III)\n \n \n \n \n \n );\n}\n\nexport function BulletedIndentListToolbarButton() {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n const pressed = useEditorSelector(\n (editor) =>\n someIndentList(editor, [\n ListStyleType.Disc,\n ListStyleType.Circle,\n ListStyleType.Square,\n ]),\n []\n );\n\n return (\n \n {\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Disc,\n });\n }}\n pressed={pressed}\n >\n \n \n\n \n \n \n \n\n \n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.Disc,\n })\n }\n >\n
\n
\n Default\n
\n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.Circle,\n })\n }\n >\n
\n
\n Circle\n
\n \n \n toggleIndentList(editor, {\n listStyleType: ListStyleType.Square,\n })\n }\n >\n
\n
\n Square\n
\n \n \n \n \n \n );\n}\n", "path": "plate-ui/indent-list-toolbar-button.tsx", "target": "components/plate-ui/indent-list-toolbar-button.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/table-dropdown-menu.json b/apps/www/public/r/styles/default/table-dropdown-menu.json index 40134acc52..01dca91675 100644 --- a/apps/www/public/r/styles/default/table-dropdown-menu.json +++ b/apps/www/public/r/styles/default/table-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 { someNode } from '@udecode/plate-common';\nimport {\n focusEditor,\n useEditorPlugin,\n useEditorSelector,\n} from '@udecode/plate-common/react';\nimport {\n deleteColumn,\n deleteRow,\n deleteTable,\n insertTable,\n insertTableRow,\n} from '@udecode/plate-table';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport {\n Minus,\n Plus,\n RectangleHorizontal,\n RectangleVertical,\n Table,\n Trash,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function TableDropdownMenu(props: DropdownMenuProps) {\n const tableSelected = useEditorSelector(\n (editor) => someNode(editor, { match: { type: TablePlugin.key } }),\n []\n );\n\n const { editor, tf } = useEditorPlugin(TablePlugin);\n\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n \n \n \n
\n Table\n \n \n {\n insertTable(editor, {}, { select: true });\n focusEditor(editor);\n }}\n >\n \n Insert table\n \n {\n deleteTable(editor);\n focusEditor(editor);\n }}\n >\n \n Delete table\n \n \n \n\n \n \n \n Column\n \n \n {\n tf.insert.tableColumn();\n focusEditor(editor);\n }}\n >\n \n Insert column after\n \n {\n deleteColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Delete column\n \n \n \n\n \n \n \n Row\n \n \n {\n insertTableRow(editor);\n focusEditor(editor);\n }}\n >\n \n Insert row after\n \n {\n deleteRow(editor);\n focusEditor(editor);\n }}\n >\n \n Delete row\n \n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React, { useCallback, useState } from 'react';\n\nimport type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\n\nimport { cn } from '@udecode/cn';\nimport { someNode } from '@udecode/plate-common';\nimport {\n focusEditor,\n useEditorPlugin,\n useEditorSelector,\n} from '@udecode/plate-common/react';\nimport {\n deleteColumn,\n deleteRow,\n deleteTable,\n insertTable,\n insertTableRow,\n} from '@udecode/plate-table';\nimport { TablePlugin } from '@udecode/plate-table/react';\nimport {\n Minus,\n Plus,\n RectangleHorizontal,\n RectangleVertical,\n Table,\n Trash,\n} from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst COLS = 8;\n\nexport function TableDropdownMenu(props: DropdownMenuProps) {\n const tableSelected = useEditorSelector(\n (editor) => someNode(editor, { match: { type: TablePlugin.key } }),\n []\n );\n\n const { editor, tf } = useEditorPlugin(TablePlugin);\n\n const openState = useOpenState();\n\n const [table, setTable] = useState(\n Array.from({ length: COLS }, () => Array.from({ length: COLS }).fill(0))\n );\n const [info, setInfo] = useState({ colCount: 0, rowCount: 0 });\n\n const onCellMove = useCallback(\n (rowIndex: number, colIndex: number) => {\n const newTables = [...table];\n\n for (let i = 0; i < newTables.length; i++) {\n for (let j = 0; j < newTables[i].length; j++) {\n newTables[i][j] =\n i >= 0 && i <= rowIndex && j >= 0 && j <= colIndex ? 1 : 0;\n }\n }\n\n setInfo({ colCount: colIndex + 1, rowCount: rowIndex + 1 });\n setTable(newTables);\n },\n [table]\n );\n\n const onInsertTable = useCallback(() => {\n insertTable(editor, info);\n }, [editor, info]);\n\n return (\n \n \n \n
\n \n \n\n \n \n \n \n
\n Table\n \n \n
\n
\n {table.map((rows, rowIndex) =>\n rows.map((value, columIndex) => {\n return (\n {\n onCellMove(rowIndex, columIndex);\n }}\n />\n );\n })\n )}\n
\n\n
\n {info.rowCount} x {info.colCount}\n
\n
\n
\n \n\n \n \n \n Column\n \n \n {\n tf.insert.tableColumn();\n focusEditor(editor);\n }}\n >\n \n Insert column after\n \n {\n deleteColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Delete column\n \n \n \n\n \n \n \n Row\n \n \n {\n insertTableRow(editor);\n focusEditor(editor);\n }}\n >\n \n Insert row after\n \n {\n deleteRow(editor);\n focusEditor(editor);\n }}\n >\n \n Delete row\n \n \n {\n deleteTable(editor);\n focusEditor(editor);\n }}\n >\n \n Delete table\n \n \n \n \n \n );\n}\n", "path": "plate-ui/table-dropdown-menu.tsx", "target": "components/plate-ui/table-dropdown-menu.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/table-element.json b/apps/www/public/r/styles/default/table-element.json index 1f36f11cd0..215cd5f550 100644 --- a/apps/www/public/r/styles/default/table-element.json +++ b/apps/www/public/r/styles/default/table-element.json @@ -20,7 +20,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport type * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\n\nimport { PopoverAnchor } from '@radix-ui/react-popover';\nimport { cn, withRef } from '@udecode/cn';\nimport { isSelectionExpanded } from '@udecode/plate-common';\nimport {\n useEditorRef,\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n withHOC,\n} from '@udecode/plate-common/react';\nimport {\n type TTableElement,\n mergeTableCells,\n unmergeTableCells,\n} from '@udecode/plate-table';\nimport {\n TableProvider,\n useTableBordersDropdownMenuContentState,\n useTableElement,\n useTableElementState,\n useTableMergeState,\n} from '@udecode/plate-table/react';\nimport { type LucideProps, Combine, Trash2Icon, Ungroup } from 'lucide-react';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverContent, popoverVariants } from './popover';\n\nexport const TableBordersDropdownMenuContent = withRef<\n typeof DropdownMenuPrimitive.Content\n>((props, ref) => {\n const {\n getOnSelectTableBorder,\n hasBottomBorder,\n hasLeftBorder,\n hasNoBorders,\n hasOuterBorders,\n hasRightBorder,\n hasTopBorder,\n } = useTableBordersDropdownMenuContentState();\n\n return (\n \n \n \n \n
Bottom Border
\n \n \n \n
Top Border
\n \n \n \n
Left Border
\n \n \n \n
Right Border
\n \n
\n\n \n \n \n
No Border
\n \n \n \n
Outside Borders
\n \n
\n \n );\n});\n\nexport const TableFloatingToolbar = withRef(\n ({ children, ...props }, ref) => {\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n\n const readOnly = useReadOnly();\n const selected = useSelected();\n const editor = useEditorRef();\n\n const collapsed = !readOnly && selected && selectionCollapsed;\n const open = !readOnly && selected;\n\n const { canMerge, canUnmerge } = useTableMergeState();\n\n const mergeContent = canMerge && (\n mergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Merge\n \n );\n\n const unmergeButton = canUnmerge && (\n unmergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Unmerge\n \n );\n\n const bordersContent = collapsed && (\n <>\n \n \n \n \n\n \n \n \n \n\n \n \n );\n\n return (\n \n {children}\n {(canMerge || canUnmerge || collapsed) && (\n e.preventDefault()}\n {...props}\n >\n {unmergeButton}\n {mergeContent}\n {bordersContent}\n \n )}\n \n );\n }\n);\n\nexport const TableElement = withHOC(\n TableProvider,\n withRef(({ children, className, ...props }, ref) => {\n const { colSizes, isSelectingCell, marginLeft, minColumnWidth } =\n useTableElementState();\n const { colGroupProps, props: tableProps } = useTableElement();\n\n return (\n \n \n \n
\n {colSizes.map((width, index) => (\n \n ))}\n \n\n {children}\n
\n \n \n );\n })\n);\n\nconst BorderAll = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderBottom = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderLeft = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderNone = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderRight = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderTop = (props: LucideProps) => (\n \n \n \n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport type * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\n\nimport { PopoverAnchor } from '@radix-ui/react-popover';\nimport { cn, withRef } from '@udecode/cn';\nimport { isSelectionExpanded } from '@udecode/plate-common';\nimport {\n useEditorRef,\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n withHOC,\n} from '@udecode/plate-common/react';\nimport {\n type TTableElement,\n mergeTableCells,\n unmergeTableCells,\n} from '@udecode/plate-table';\nimport {\n TableProvider,\n useTableBordersDropdownMenuContentState,\n useTableElement,\n useTableElementState,\n useTableMergeState,\n} from '@udecode/plate-table/react';\nimport { type LucideProps, Combine, Trash2Icon, Ungroup } from 'lucide-react';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { PlateElement } from './plate-element';\nimport { Popover, PopoverContent, popoverVariants } from './popover';\n\nexport const TableBordersDropdownMenuContent = withRef<\n typeof DropdownMenuPrimitive.Content\n>((props, ref) => {\n const {\n getOnSelectTableBorder,\n hasBottomBorder,\n hasLeftBorder,\n hasNoBorders,\n hasOuterBorders,\n hasRightBorder,\n hasTopBorder,\n } = useTableBordersDropdownMenuContentState();\n\n return (\n \n \n \n \n
Bottom Border
\n \n \n \n
Top Border
\n \n \n \n
Left Border
\n \n \n \n
Right Border
\n \n
\n\n \n \n \n
No Border
\n \n \n \n
Outside Borders
\n \n
\n \n );\n});\n\nexport const TableFloatingToolbar = withRef(\n ({ children, ...props }, ref) => {\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n\n const readOnly = useReadOnly();\n const selected = useSelected();\n const editor = useEditorRef();\n\n const collapsed = !readOnly && selected && selectionCollapsed;\n const open = !readOnly && selected;\n\n const { canMerge, canUnmerge } = useTableMergeState();\n\n const mergeContent = canMerge && (\n mergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Merge\n \n );\n\n const unmergeButton = canUnmerge && (\n unmergeTableCells(editor)}\n contentEditable={false}\n isMenu\n >\n \n Unmerge\n \n );\n\n const bordersContent = collapsed && (\n <>\n \n \n \n \n\n \n \n \n \n\n \n \n );\n\n return (\n \n {children}\n {(canMerge || canUnmerge || collapsed) && (\n e.preventDefault()}\n {...props}\n >\n {unmergeButton}\n {mergeContent}\n {bordersContent}\n \n )}\n \n );\n }\n);\n\nexport const TableElement = withHOC(\n TableProvider,\n withRef(({ children, className, ...props }, ref) => {\n const { colSizes, isSelectingCell, marginLeft, minColumnWidth } =\n useTableElementState();\n const { colGroupProps, props: tableProps } = useTableElement();\n\n return (\n \n \n \n \n {colSizes.map((width, index) => (\n \n ))}\n \n\n {children}\n \n \n \n );\n })\n);\n\nconst BorderAll = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderBottom = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderLeft = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderNone = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderRight = (props: LucideProps) => (\n \n \n \n);\n\nconst BorderTop = (props: LucideProps) => (\n \n \n \n);\n", "path": "plate-ui/table-element.tsx", "target": "components/plate-ui/table-element.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/toolbar.json b/apps/www/public/r/styles/default/toolbar.json index 60d117938c..562b75dfdb 100644 --- a/apps/www/public/r/styles/default/toolbar.json +++ b/apps/www/public/r/styles/default/toolbar.json @@ -7,7 +7,7 @@ }, "files": [ { - "content": "'use client';\n\nimport * as React from 'react';\n\nimport * as ToolbarPrimitive from '@radix-ui/react-toolbar';\nimport { cn, withCn, withRef, withVariants } from '@udecode/cn';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport { ChevronDown } from 'lucide-react';\n\nimport { Separator } from './separator';\nimport { withTooltip } from './tooltip';\n\nexport const Toolbar = withCn(\n ToolbarPrimitive.Root,\n 'relative flex select-none items-center'\n);\n\nexport const ToolbarToggleGroup = withCn(\n ToolbarPrimitive.ToolbarToggleGroup,\n 'flex items-center'\n);\n\nexport const ToolbarLink = withCn(\n ToolbarPrimitive.Link,\n 'font-medium underline underline-offset-4'\n);\n\nexport const ToolbarSeparator = withCn(\n ToolbarPrimitive.Separator,\n 'mx-2 my-1 w-px shrink-0 bg-border'\n);\n\nconst toolbarButtonVariants = cva(\n cn(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium text-foreground ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg:not([data-icon])]:size-4'\n ),\n {\n defaultVariants: {\n size: 'sm',\n variant: 'default',\n },\n variants: {\n size: {\n default: 'h-10 px-3',\n lg: 'h-11 px-5',\n sm: 'h-7 px-2',\n },\n variant: {\n default:\n 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground',\n outline:\n 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n },\n }\n);\n\nconst dropdownArrowVariants = cva(\n cn(\n 'inline-flex items-center justify-center rounded-r-md text-sm font-medium text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'\n ),\n {\n defaultVariants: {\n size: 'sm',\n variant: 'default',\n },\n variants: {\n size: {\n default: 'h-10 w-6',\n lg: 'h-11 w-8',\n sm: 'h-7 w-4',\n },\n variant: {\n default:\n 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground',\n outline:\n 'border border-l-0 border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n },\n }\n);\n\nconst ToolbarButton = withTooltip(\n React.forwardRef<\n React.ElementRef,\n {\n isDropdown?: boolean;\n pressed?: boolean;\n } & Omit<\n React.ComponentPropsWithoutRef,\n 'asChild' | 'value'\n > &\n VariantProps\n >(\n (\n { children, className, isDropdown, pressed, size, variant, ...props },\n ref\n ) => {\n return typeof pressed === 'boolean' ? (\n \n \n {isDropdown ? (\n <>\n
\n {children}\n
\n
\n \n
\n \n ) : (\n children\n )}\n \n \n ) : (\n \n {children}\n \n );\n }\n )\n);\nToolbarButton.displayName = 'ToolbarButton';\n\nexport { ToolbarButton };\n\nexport const ToolbarSplitButton = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ children, className, ...props }, ref) => {\n return (\n \n {children}\n
\n );\n});\n\nexport const ToolbarSplitButtonPrimary = React.forwardRef<\n React.ElementRef,\n Omit, 'value'>\n>(({ children, className, size, variant, ...props }, ref) => {\n return (\n \n {children}\n \n );\n});\n\nexport const ToolbarSplitButtonSecondary = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<'span'> &\n VariantProps\n>(({ className, size, variant, ...props }, ref) => {\n return (\n e.stopPropagation()}\n role=\"button\"\n {...props}\n >\n \n \n );\n});\n\nToolbarSplitButton.displayName = 'ToolbarButton';\n\nexport const ToolbarToggleItem = withVariants(\n ToolbarPrimitive.ToggleItem,\n toolbarButtonVariants,\n ['variant', 'size']\n);\n\nexport const ToolbarGroup = withRef<'div'>(({ children, className }, ref) => {\n return (\n
\n );\n});\n", + "content": "'use client';\n\nimport * as React from 'react';\n\nimport * as ToolbarPrimitive from '@radix-ui/react-toolbar';\nimport { cn, withCn, withRef, withVariants } from '@udecode/cn';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport { ChevronDown } from 'lucide-react';\n\nimport { Separator } from './separator';\nimport { withTooltip } from './tooltip';\n\nexport const Toolbar = withCn(\n ToolbarPrimitive.Root,\n 'relative flex select-none items-center'\n);\n\nexport const ToolbarToggleGroup = withCn(\n ToolbarPrimitive.ToolbarToggleGroup,\n 'flex items-center'\n);\n\nexport const ToolbarLink = withCn(\n ToolbarPrimitive.Link,\n 'font-medium underline underline-offset-4'\n);\n\nexport const ToolbarSeparator = withCn(\n ToolbarPrimitive.Separator,\n 'mx-2 my-1 w-px shrink-0 bg-border'\n);\n\nconst toolbarButtonVariants = cva(\n cn(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium text-foreground ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg:not([data-icon])]:size-4'\n ),\n {\n defaultVariants: {\n size: 'sm',\n variant: 'default',\n },\n variants: {\n size: {\n default: 'h-10 px-3',\n lg: 'h-11 px-5',\n sm: 'h-7 px-2',\n },\n variant: {\n default:\n 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground',\n outline:\n 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n },\n }\n);\n\nconst dropdownArrowVariants = cva(\n cn(\n 'inline-flex items-center justify-center rounded-r-md text-sm font-medium text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'\n ),\n {\n defaultVariants: {\n size: 'sm',\n variant: 'default',\n },\n variants: {\n size: {\n default: 'h-10 w-6',\n lg: 'h-11 w-8',\n sm: 'h-7 w-4',\n },\n variant: {\n default:\n 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground',\n outline:\n 'border border-l-0 border-input bg-transparent hover:bg-accent hover:text-accent-foreground',\n },\n },\n }\n);\n\nconst ToolbarButton = withTooltip(\n React.forwardRef<\n React.ElementRef,\n {\n isDropdown?: boolean;\n pressed?: boolean;\n } & Omit<\n React.ComponentPropsWithoutRef,\n 'asChild' | 'value'\n > &\n VariantProps\n >(\n (\n { children, className, isDropdown, pressed, size, variant, ...props },\n ref\n ) => {\n return typeof pressed === 'boolean' ? (\n \n \n {isDropdown ? (\n <>\n
\n {children}\n
\n
\n \n
\n \n ) : (\n children\n )}\n \n \n ) : (\n \n {children}\n \n );\n }\n )\n);\nToolbarButton.displayName = 'ToolbarButton';\n\nexport { ToolbarButton };\n\nexport const ToolbarSplitButton = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ children, className, ...props }, ref) => {\n return (\n \n {children}\n \n );\n});\n\nexport const ToolbarSplitButtonPrimary = React.forwardRef<\n React.ElementRef,\n Omit, 'value'> & {\n pressed?: boolean;\n }\n>(({ children, className, pressed, size, variant, ...props }, ref) => {\n return (\n \n {children}\n \n );\n});\n\nexport const ToolbarSplitButtonSecondary = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<'span'> &\n VariantProps\n>(({ className, size, variant, ...props }, ref) => {\n return (\n e.stopPropagation()}\n role=\"button\"\n {...props}\n >\n \n \n );\n});\n\nToolbarSplitButton.displayName = 'ToolbarButton';\n\nexport const ToolbarToggleItem = withVariants(\n ToolbarPrimitive.ToggleItem,\n toolbarButtonVariants,\n ['variant', 'size']\n);\n\nexport const ToolbarGroup = withRef<'div'>(({ children, className }, ref) => {\n return (\n
\n );\n});\n", "path": "plate-ui/toolbar.tsx", "target": "components/plate-ui/toolbar.tsx", "type": "registry:ui" diff --git a/apps/www/src/registry/default/example/cards/cards-toolbar.tsx b/apps/www/src/registry/default/example/cards/cards-toolbar.tsx index b4cb6e4ce0..ce46e4f0b2 100644 --- a/apps/www/src/registry/default/example/cards/cards-toolbar.tsx +++ b/apps/www/src/registry/default/example/cards/cards-toolbar.tsx @@ -11,7 +11,6 @@ import { FontBackgroundColorPlugin, FontColorPlugin, } from '@udecode/plate-font/react'; -import { ListStyleType } from '@udecode/plate-indent-list'; import { AudioPlugin, FilePlugin, @@ -33,7 +32,10 @@ import { ColorDropdownMenu } from '@/registry/default/plate-ui/color-dropdown-me import { CommentToolbarButton } from '@/registry/default/plate-ui/comment-toolbar-button'; import { EmojiDropdownMenu } from '@/registry/default/plate-ui/emoji-dropdown-menu'; import { FixedToolbar } from '@/registry/default/plate-ui/fixed-toolbar'; -import { IndentListToolbarButton } from '@/registry/default/plate-ui/indent-list-toolbar-button'; +import { + BulletedIndentListToolbarButton, + NumberedIndentListToolbarButton, +} from '@/registry/default/plate-ui/indent-list-toolbar-button'; import { IndentToolbarButton } from '@/registry/default/plate-ui/indent-toolbar-button'; import { InsertDropdownMenu } from '@/registry/default/plate-ui/insert-dropdown-menu'; import { LineHeightDropdownMenu } from '@/registry/default/plate-ui/line-height-dropdown-menu'; @@ -111,8 +113,8 @@ export function CardsToolbar() { - - + + diff --git a/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx b/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx index ffcba0a6e1..b9c5a2d180 100644 --- a/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx +++ b/apps/www/src/registry/default/plate-ui/fixed-toolbar-buttons.tsx @@ -15,7 +15,6 @@ import { FontColorPlugin, } from '@udecode/plate-font/react'; import { HighlightPlugin } from '@udecode/plate-highlight/react'; -import { ListStyleType } from '@udecode/plate-indent-list'; import { AudioPlugin, FilePlugin, @@ -44,7 +43,10 @@ import { CommentToolbarButton } from './comment-toolbar-button'; import { EmojiDropdownMenu } from './emoji-dropdown-menu'; import { ExportToolbarButton } from './export-toolbar-button'; import { RedoToolbarButton, UndoToolbarButton } from './history-toolbar-button'; -import { IndentListToolbarButton } from './indent-list-toolbar-button'; +import { + BulletedIndentListToolbarButton, + NumberedIndentListToolbarButton, +} from './indent-list-toolbar-button'; import { IndentTodoToolbarButton } from './indent-todo-toolbar-button'; import { IndentToolbarButton } from './indent-toolbar-button'; import { InsertDropdownMenu } from './insert-dropdown-menu'; @@ -136,8 +138,8 @@ export function FixedToolbarButtons() { - - + + diff --git a/apps/www/src/registry/default/plate-ui/indent-list-toolbar-button.tsx b/apps/www/src/registry/default/plate-ui/indent-list-toolbar-button.tsx index 7e863d6ded..c1d809ac33 100644 --- a/apps/www/src/registry/default/plate-ui/indent-list-toolbar-button.tsx +++ b/apps/www/src/registry/default/plate-ui/indent-list-toolbar-button.tsx @@ -2,34 +2,191 @@ import React from 'react'; -import { withRef } from '@udecode/cn'; -import { ListStyleType } from '@udecode/plate-indent-list'; +import { useEditorRef, useEditorSelector } from '@udecode/plate-common/react'; import { - useIndentListToolbarButton, - useIndentListToolbarButtonState, -} from '@udecode/plate-indent-list/react'; + ListStyleType, + someIndentList, + toggleIndentList, +} from '@udecode/plate-indent-list'; import { List, ListOrdered } from 'lucide-react'; -import { ToolbarButton } from './toolbar'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuTrigger, + useOpenState, +} from './dropdown-menu'; +import { + ToolbarSplitButton, + ToolbarSplitButtonPrimary, + ToolbarSplitButtonSecondary, +} from './toolbar'; + +export function NumberedIndentListToolbarButton() { + const editor = useEditorRef(); + const openState = useOpenState(); + + const pressed = useEditorSelector( + (editor) => + someIndentList(editor, [ + ListStyleType.Decimal, + ListStyleType.LowerAlpha, + ListStyleType.UpperAlpha, + ListStyleType.LowerRoman, + ListStyleType.UpperRoman, + ]), + [] + ); + + return ( + + { + toggleIndentList(editor, { + listStyleType: ListStyleType.Decimal, + }); + }} + data-state={pressed ? 'on' : 'off'} + > + + -export const IndentListToolbarButton = withRef< - typeof ToolbarButton, - { - nodeType?: ListStyleType; - } ->(({ nodeType = ListStyleType.Disc }, ref) => { - const state = useIndentListToolbarButtonState({ nodeType }); - const { props } = useIndentListToolbarButton(state); + + + + + + + + + toggleIndentList(editor, { + listStyleType: ListStyleType.Decimal, + }) + } + > + Decimal (1, 2, 3) + + + toggleIndentList(editor, { + listStyleType: ListStyleType.LowerAlpha, + }) + } + > + Lower Alpha (a, b, c) + + + toggleIndentList(editor, { + listStyleType: ListStyleType.UpperAlpha, + }) + } + > + Upper Alpha (A, B, C) + + + toggleIndentList(editor, { + listStyleType: ListStyleType.LowerRoman, + }) + } + > + Lower Roman (i, ii, iii) + + + toggleIndentList(editor, { + listStyleType: ListStyleType.UpperRoman, + }) + } + > + Upper Roman (I, II, III) + + + + + + ); +} + +export function BulletedIndentListToolbarButton() { + const editor = useEditorRef(); + const openState = useOpenState(); + + const pressed = useEditorSelector( + (editor) => + someIndentList(editor, [ + ListStyleType.Disc, + ListStyleType.Circle, + ListStyleType.Square, + ]), + [] + ); return ( - - {nodeType === ListStyleType.Disc ? : } - + + { + toggleIndentList(editor, { + listStyleType: ListStyleType.Disc, + }); + }} + data-state={pressed ? 'on' : 'off'} + > + + + + + + + + + + + + toggleIndentList(editor, { + listStyleType: ListStyleType.Disc, + }) + } + > +
+
+ Default +
+ + + toggleIndentList(editor, { + listStyleType: ListStyleType.Circle, + }) + } + > +
+
+ Circle +
+ + + toggleIndentList(editor, { + listStyleType: ListStyleType.Square, + }) + } + > +
+
+ Square +
+ + + + + ); -}); +} diff --git a/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx b/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx index a6833cb833..229de1fe88 100644 --- a/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx +++ b/apps/www/src/registry/default/plate-ui/table-dropdown-menu.tsx @@ -1,9 +1,10 @@ 'use client'; -import React from 'react'; +import React, { useCallback, useState } from 'react'; import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu'; +import { cn } from '@udecode/cn'; import { someNode } from '@udecode/plate-common'; import { focusEditor, @@ -40,6 +41,8 @@ import { } from './dropdown-menu'; import { ToolbarButton } from './toolbar'; +const COLS = 8; + export function TableDropdownMenu(props: DropdownMenuProps) { const tableSelected = useEditorSelector( (editor) => someNode(editor, { match: { type: TablePlugin.key } }), @@ -50,6 +53,33 @@ export function TableDropdownMenu(props: DropdownMenuProps) { const openState = useOpenState(); + const [table, setTable] = useState( + Array.from({ length: COLS }, () => Array.from({ length: COLS }).fill(0)) + ); + const [size, setSize] = useState({ colCount: 0, rowCount: 0 }); + + const onCellMove = useCallback( + (rowIndex: number, colIndex: number) => { + const newTables = [...table]; + + for (let i = 0; i < newTables.length; i++) { + for (let j = 0; j < newTables[i].length; j++) { + newTables[i][j] = + i >= 0 && i <= rowIndex && j >= 0 && j <= colIndex ? 1 : 0; + } + } + + setSize({ colCount: colIndex + 1, rowCount: rowIndex + 1 }); + setTable(newTables); + }, + [table] + ); + + const onInsertTable = useCallback(() => { + insertTable(editor, size); + focusEditor(editor); + }, [editor, size]); + return ( @@ -68,28 +98,31 @@ export function TableDropdownMenu(props: DropdownMenuProps) { Table - - { - insertTable(editor, {}, { select: true }); - focusEditor(editor); - }} - > - - Insert table - - { - deleteTable(editor); - focusEditor(editor); - }} - > - - Delete table - + +
+
+ {table.map((rows, rowIndex) => + rows.map((value, columIndex) => { + return ( +
{ + onCellMove(rowIndex, columIndex); + }} + /> + ); + }) + )} +
+ +
+ {size.rowCount} x {size.colCount} +
+
@@ -153,6 +186,17 @@ export function TableDropdownMenu(props: DropdownMenuProps) { Delete row + { + deleteTable(editor); + focusEditor(editor); + }} + > + + Delete table + diff --git a/packages/indent-list/src/lib/queries/someIndentList.ts b/packages/indent-list/src/lib/queries/someIndentList.ts index 48cab1de52..8e978d3bc1 100644 --- a/packages/indent-list/src/lib/queries/someIndentList.ts +++ b/packages/indent-list/src/lib/queries/someIndentList.ts @@ -1,25 +1,24 @@ import { type SlateEditor, someNode } from '@udecode/plate-common'; -import { - BaseIndentListPlugin, - INDENT_LIST_KEYS, - ListStyleType, -} from '../../index'; +import { BaseIndentListPlugin, INDENT_LIST_KEYS } from '../../index'; -export const someIndentList = (editor: SlateEditor, type: string) => { +export const someIndentList = ( + editor: SlateEditor, + type: string[] | string +) => { return ( !!editor.selection && someNode(editor, { - match: (n) => { - const list = n[BaseIndentListPlugin.key]; + match: (n: any) => { + const isHasProperty = n.hasOwnProperty(INDENT_LIST_KEYS.checked); - if ((type as any) === ListStyleType.Disc) { - return list === ListStyleType.Disc; + if (isHasProperty) { + return false; } - const isHasProperty = n.hasOwnProperty(INDENT_LIST_KEYS.checked); + const list = n[BaseIndentListPlugin.key]; - return !!list && list !== ListStyleType.Disc && !isHasProperty; + return Array.isArray(type) ? type.includes(list) : list === type; }, }) );