From 46a54c49f418d175ef8903d8a71263f65b10de6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=C3=A1=C5=A1=20Nobile?= Date: Wed, 17 Apr 2024 18:25:15 +0200 Subject: [PATCH 1/5] feat(playground): add plate to playground --- .../admin/lib/components/form/ui.tsx | 2 +- .../lib/auto-format-utils.ts | 34 + .../richt-text-editor/lib/auto-format.ts | 91 ++ .../richt-text-editor/lib/drag-over-plugin.ts | 38 + .../richt-text-editor/lib/helpers.ts | 17 + .../richt-text-editor/plate-editor.tsx | 81 ++ .../richt-text-editor/plate-plugins.tsx | 106 ++ .../plate-ui/cursor-overlay.tsx | 69 + .../richt-text-editor/plate-ui/draggable.tsx | 140 ++ .../richt-text-editor/plate-ui/editor.tsx | 82 ++ .../plate-ui/fixed-toolbar-buttons.tsx | 61 + .../plate-ui/fixed-toolbar.tsx | 7 + .../plate-ui/floating-toolbar-buttons.tsx | 42 + .../plate-ui/floating-toolbar.tsx | 122 ++ .../plate-ui/heading-element.tsx | 45 + .../plate-ui/insert-dropdown-menu.tsx | 99 ++ .../plate-ui/link-element.tsx | 25 + .../plate-ui/link-floating-toolbar.tsx | 143 ++ .../plate-ui/link-toolbar-button.tsx | 16 + .../plate-ui/list-element.tsx | 20 + .../plate-ui/list-toolbar-button.tsx | 31 + .../plate-ui/mark-toolbar-button.tsx | 17 + .../plate-ui/paragraph-element.tsx | 4 + .../richt-text-editor/plate-ui/placeholder.ts | 45 + .../richt-text-editor/plate-ui/popover.tsx | 26 + .../richt-text-editor/plate-ui/separator.tsx | 23 + .../richt-text-editor/plate-ui/toolbar.tsx | 152 ++ .../richt-text-editor/plate-ui/tooltip.tsx | 59 + .../plate-ui/turn-into-dropdown-menu.tsx | 122 ++ .../plate-ui/with-draggables.ts | 62 + .../richt-text-editor/plate-ui/with-list.ts | 61 + .../lib/components/richt-text-editor/utils.ts | 13 + packages/playground/package.json | 19 + yarn.lock | 1276 ++++++++++++++++- 34 files changed, 3104 insertions(+), 46 deletions(-) create mode 100644 packages/playground/admin/lib/components/richt-text-editor/lib/auto-format-utils.ts create mode 100644 packages/playground/admin/lib/components/richt-text-editor/lib/auto-format.ts create mode 100644 packages/playground/admin/lib/components/richt-text-editor/lib/drag-over-plugin.ts create mode 100644 packages/playground/admin/lib/components/richt-text-editor/lib/helpers.ts create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/cursor-overlay.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/draggable.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/editor.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar-buttons.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar-buttons.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/heading-element.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/insert-dropdown-menu.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-element.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-toolbar-button.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-element.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-toolbar-button.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/mark-toolbar-button.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/paragraph-element.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/placeholder.ts create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/popover.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/separator.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/toolbar.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/tooltip.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-draggables.ts create mode 100644 packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-list.ts create mode 100644 packages/playground/admin/lib/components/richt-text-editor/utils.ts diff --git a/packages/playground/admin/lib/components/form/ui.tsx b/packages/playground/admin/lib/components/form/ui.tsx index d85252e0f..ef720857e 100644 --- a/packages/playground/admin/lib/components/form/ui.tsx +++ b/packages/playground/admin/lib/components/form/ui.tsx @@ -20,7 +20,7 @@ export const FormLabelWrapperUI = uic('div', { displayName: 'FormLabelWrapper', }) export const FormLabelUI = uic(Label, { - baseClass: 'data-[invalid]:text-destructive text-right', + baseClass: 'data-[invalid]:text-destructive text-left', displayName: 'FormLabel', }) export const FormContainerUI = uic('div', { diff --git a/packages/playground/admin/lib/components/richt-text-editor/lib/auto-format-utils.ts b/packages/playground/admin/lib/components/richt-text-editor/lib/auto-format-utils.ts new file mode 100644 index 000000000..781ec1eb3 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/lib/auto-format-utils.ts @@ -0,0 +1,34 @@ +import { AutoformatBlockRule } from '@udecode/plate-autoformat' +import { ELEMENT_CODE_BLOCK, ELEMENT_CODE_LINE } from '@udecode/plate-code-block' +import { getParentNode, isElement, isType, PlateEditor } from '@udecode/plate-common' +import { toggleList, unwrapList } from '@udecode/plate-list' + +export const preFormat: AutoformatBlockRule['preFormat'] = editor => + unwrapList(editor) + +export const format = (editor: PlateEditor, customFormatting: any) => { + if (editor.selection) { + const parentEntry = getParentNode(editor, editor.selection) + if (!parentEntry) return + const [node] = parentEntry + if ( + isElement(node) && + !isType(editor, node, ELEMENT_CODE_BLOCK) && + !isType(editor, node, ELEMENT_CODE_LINE) + ) { + customFormatting() + } + } +} + +export const formatList = (editor: PlateEditor, elementType: string) => { + format(editor, () => + toggleList(editor, { + type: elementType, + }), + ) +} + +export const formatText = (editor: PlateEditor, text: string) => { + format(editor, () => editor.insertText(text)) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/lib/auto-format.ts b/packages/playground/admin/lib/components/richt-text-editor/lib/auto-format.ts new file mode 100644 index 000000000..a8256aa7b --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/lib/auto-format.ts @@ -0,0 +1,91 @@ +import { AutoformatRule } from '@udecode/plate-autoformat' +import { MARK_BOLD, MARK_ITALIC, MARK_STRIKETHROUGH, MARK_UNDERLINE } from '@udecode/plate-basic-marks' +import { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3, ELEMENT_H4, ELEMENT_H5, ELEMENT_H6 } from '@udecode/plate-heading' +import { preFormat } from './auto-format-utils' + +export const autoFormatBlocks: AutoformatRule[] = [ + { + mode: 'block', + type: ELEMENT_H1, + match: '# ', + preFormat, + }, + { + mode: 'block', + type: ELEMENT_H2, + match: '## ', + preFormat, + }, + { + mode: 'block', + type: ELEMENT_H3, + match: '### ', + preFormat, + }, + { + mode: 'block', + type: ELEMENT_H4, + match: '#### ', + preFormat, + }, + { + mode: 'block', + type: ELEMENT_H5, + match: '##### ', + preFormat, + }, + { + mode: 'block', + type: ELEMENT_H6, + match: '###### ', + preFormat, + }, +] + +export const autoFormatMarks: AutoformatRule[] = [ + { + mode: 'mark', + type: [MARK_BOLD, MARK_ITALIC], + match: '***', + }, + { + mode: 'mark', + type: [MARK_UNDERLINE, MARK_ITALIC], + match: '__*', + }, + { + mode: 'mark', + type: [MARK_UNDERLINE, MARK_BOLD], + match: '__**', + }, + { + mode: 'mark', + type: [MARK_UNDERLINE, MARK_BOLD, MARK_ITALIC], + match: '___***', + }, + { + mode: 'mark', + type: MARK_BOLD, + match: '**', + }, + { + mode: 'mark', + type: MARK_UNDERLINE, + match: '__', + }, + { + mode: 'mark', + type: MARK_ITALIC, + match: '*', + }, + { + mode: 'mark', + type: MARK_ITALIC, + match: '_', + }, + { + mode: 'mark', + type: MARK_STRIKETHROUGH, + match: '~~', + }, +] diff --git a/packages/playground/admin/lib/components/richt-text-editor/lib/drag-over-plugin.ts b/packages/playground/admin/lib/components/richt-text-editor/lib/drag-over-plugin.ts new file mode 100644 index 000000000..a07dd0ea3 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/lib/drag-over-plugin.ts @@ -0,0 +1,38 @@ +import { findEventRange, PlatePlugin } from '@udecode/plate-common' +import { cursorStore } from '../plate-ui/cursor-overlay' + +export const KEY_DRAG_OVER_CURSOR = 'dragOverCursor' + +export const dragOverCursorPlugin: PlatePlugin = { + key: KEY_DRAG_OVER_CURSOR, + handlers: { + onDragOver: editor => event => { + if (editor.isDragging) return + + const range = findEventRange(editor, event) + if (!range) return + + cursorStore.set.cursors({ + drag: { + key: 'drag', + data: { + style: { + backgroundColor: 'hsl(222.2 47.4% 11.2%)', + width: 3, + }, + }, + selection: range, + }, + }) + }, + onDragLeave: () => () => { + cursorStore.set.cursors({}) + }, + onDragEnd: () => () => { + cursorStore.set.cursors({}) + }, + onDrop: () => () => { + cursorStore.set.cursors({}) + }, + }, +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/lib/helpers.ts b/packages/playground/admin/lib/components/richt-text-editor/lib/helpers.ts new file mode 100644 index 000000000..19b1437e0 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/lib/helpers.ts @@ -0,0 +1,17 @@ +import { useCallback, useState } from 'react' + +export const useOpenState = () => { + const [open, setOpen] = useState(false) + + const onOpenChange = useCallback( + (_value = !open) => { + setOpen(_value) + }, + [open], + ) + + return { + open, + onOpenChange, + } +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx new file mode 100644 index 000000000..3cb788826 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx @@ -0,0 +1,81 @@ +import { Component, Field, SugarableRelativeSingleField, useField } from '@contember/interface' +import { cn } from '@udecode/cn' +import { Plate } from '@udecode/plate-common' +import { useRef } from 'react' +import { DndProvider } from 'react-dnd' +import { HTML5Backend } from 'react-dnd-html5-backend' +import { plugins } from './plate-plugins' +import { Editor } from './plate-ui/editor' +import { FixedToolbar } from './plate-ui/fixed-toolbar' +import { FixedToolbarButtons } from './plate-ui/fixed-toolbar-buttons' +import { FloatingToolbar } from './plate-ui/floating-toolbar' +import { FloatingToolbarButtons } from './plate-ui/floating-toolbar-buttons' +import { TooltipProvider } from './plate-ui/tooltip' +import { isJsonContent, isJsonObject } from './utils' + + +export interface PlateEditorProps { + field: string | SugarableRelativeSingleField +} + +export const PlateEditor = Component( + ({ field }: PlateEditorProps) => { + const containerRef = useRef(null) + const contentField = useField(field) + + const handleEditorOnChange = (value: any) => { + const contentJson = isJsonObject(value) ? { children: value } : null + + if (contentJson && contentField.value && (isJsonContent(contentField.value) && contentField.value.children === value)) return + + contentField.updateValue(contentJson) + } + + return ( + + + +
+ +
+ + + + + + + + + +
+
+
+
+
+ ) + }, + ({ field }) => ( + <> + + + ), + 'PlateEditor', +) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx new file mode 100644 index 000000000..a99b6a79c --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx @@ -0,0 +1,106 @@ +import { withProps } from '@udecode/cn' +import { + autoformatArrow, + autoformatLegal, + autoformatMath, + autoformatPunctuation, + createAutoformatPlugin, +} from '@udecode/plate-autoformat' +import { + createBoldPlugin, + createItalicPlugin, + createStrikethroughPlugin, + createUnderlinePlugin, + MARK_BOLD, + MARK_ITALIC, + MARK_STRIKETHROUGH, + MARK_UNDERLINE, +} from '@udecode/plate-basic-marks' +import { createPlugins, PlateElement, PlateLeaf, RenderAfterEditable } from '@udecode/plate-common' +import { createDndPlugin } from '@udecode/plate-dnd' +import { + createHeadingPlugin, + ELEMENT_H1, + ELEMENT_H2, + ELEMENT_H3, + ELEMENT_H4, + ELEMENT_H5, + ELEMENT_H6, +} from '@udecode/plate-heading' +import { createLinkPlugin, ELEMENT_LINK } from '@udecode/plate-link' +import { createListPlugin, ELEMENT_LI, ELEMENT_OL, ELEMENT_UL } from '@udecode/plate-list' +import { createNodeIdPlugin } from '@udecode/plate-node-id' +import { createParagraphPlugin, ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph' +import { createDeserializeDocxPlugin } from '@udecode/plate-serializer-docx' +import { createDeserializeMdPlugin } from '@udecode/plate-serializer-md' +import { autoFormatBlocks, autoFormatMarks } from './lib/auto-format' +import { dragOverCursorPlugin } from './lib/drag-over-plugin' +import { HeadingElement } from './plate-ui/heading-element' +import { LinkElement } from './plate-ui/link-element' +import { LinkFloatingToolbar } from './plate-ui/link-floating-toolbar' +import { ListElement } from './plate-ui/list-element' +import { ParagraphElement } from './plate-ui/paragraph-element' +import { withPlaceholders } from './plate-ui/placeholder' +import { withDraggables } from './plate-ui/with-draggables' + +export const plugins = createPlugins([ + // Nodes + createParagraphPlugin(), + createHeadingPlugin(), + createNodeIdPlugin(), + createDndPlugin({ + options: { enableScroller: true }, + }), + createLinkPlugin({ + renderAfterEditable: LinkFloatingToolbar as RenderAfterEditable, + }), + + // Marks + createBoldPlugin(), + createItalicPlugin(), + createStrikethroughPlugin(), + createUnderlinePlugin(), + + // Block style + createListPlugin(), + + // Functionality + createAutoformatPlugin({ + options: { + rules: [ + ...autoFormatBlocks, + ...autoFormatMarks, + ...autoformatPunctuation, + ...autoformatLegal, + ...autoformatArrow, + ...autoformatMath, + ], + enableUndoOnDelete: true, + }, + }), + dragOverCursorPlugin, + + // Deserialization + createDeserializeDocxPlugin(), + createDeserializeMdPlugin(), +], { + components: withDraggables( + withPlaceholders({ + [ELEMENT_LINK]: LinkElement, + [ELEMENT_H1]: withProps(HeadingElement, { variant: 'h1' }), + [ELEMENT_H2]: withProps(HeadingElement, { variant: 'h2' }), + [ELEMENT_H3]: withProps(HeadingElement, { variant: 'h3' }), + [ELEMENT_H4]: withProps(HeadingElement, { variant: 'h4' }), + [ELEMENT_H5]: withProps(HeadingElement, { variant: 'h5' }), + [ELEMENT_H6]: withProps(HeadingElement, { variant: 'h6' }), + [ELEMENT_PARAGRAPH]: ParagraphElement, + [MARK_BOLD]: withProps(PlateLeaf, { as: 'strong' }), + [MARK_ITALIC]: withProps(PlateLeaf, { as: 'em' }), + [MARK_STRIKETHROUGH]: withProps(PlateLeaf, { as: 's' }), + [MARK_UNDERLINE]: withProps(PlateLeaf, { as: 'u' }), + [ELEMENT_UL]: withProps(ListElement, { variant: 'ul' }), + [ELEMENT_OL]: withProps(ListElement, { variant: 'ol' }), + [ELEMENT_LI]: withProps(PlateElement, { as: 'li' }), + }), + ), +}) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/cursor-overlay.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/cursor-overlay.tsx new file mode 100644 index 000000000..51b2cabdb --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/cursor-overlay.tsx @@ -0,0 +1,69 @@ +import { createZustandStore } from '@udecode/plate-common' +import { + CursorData, + CursorOverlay as CursorOverlayPrimitive, + CursorOverlayProps, + CursorProps, +} from '@udecode/plate-cursor' +import { cn } from '../../../utils/cn' + +export const cursorStore = createZustandStore('cursor')({ + cursors: {}, +}) + +export function Cursor({ + data, + selectionRects, + caretPosition, + disableCaret, + disableSelection, + classNames, +}: CursorProps) { + if (!data) { + return null + } + + const { style, selectionStyle = style } = data + + return ( + <> + {!disableSelection && + selectionRects.map((position, i) => ( +
+ ))} + {!disableCaret && caretPosition && ( +
+ )} + + ) +} + +export function CursorOverlay({ cursors, ...props }: CursorOverlayProps) { + const dynamicCursors = cursorStore.use.cursors() + + const allCursors = { ...cursors, ...dynamicCursors } + + return ( + + ) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/draggable.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/draggable.tsx new file mode 100644 index 000000000..1ce2548c1 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/draggable.tsx @@ -0,0 +1,140 @@ +import { cn, withRef } from '@udecode/cn' +import { ClassNames, PlateElementProps, TEditor } from '@udecode/plate-common' +import { DragItemNode, useDraggable, useDraggableState } from '@udecode/plate-dnd' +import { GripVerticalIcon } from 'lucide-react' +import { DropTargetMonitor } from 'react-dnd' + +import { Tooltip, TooltipContent, TooltipTrigger } from './tooltip' + +export interface DraggableProps + extends PlateElementProps, + ClassNames<{ + /** + * Block and gutter. + */ + blockAndGutter: string; + + /** + * Block. + */ + block: string; + + /** + * Gutter at the left side of the editor. + * It has the height of the block + */ + gutterLeft: string; + + /** + * Block toolbar wrapper in the gutter left. + * It has the height of a line of the block. + */ + blockToolbarWrapper: string; + + /** + * Block toolbar in the gutter. + */ + blockToolbar: string; + + blockWrapper: string; + + /** + * Button to dnd the block, in the block toolbar. + */ + dragHandle: string; + + /** + * Icon of the drag button, in the drag icon. + */ + dragIcon: string; + + /** + * Show a dropline above or below the block when dragging a block. + */ + dropLine: string; + }> { + /** + * Intercepts the drop handling. + * If `false` is returned, the default drop behavior is called after. + * If `true` is returned, the default behavior is not called. + */ + onDropHandler?: ( + editor: TEditor, + props: { + monitor: DropTargetMonitor; + dragItem: DragItemNode; + nodeRef: any; + id: string; + }, + ) => boolean; +} + +const dragHandle = ( + + + + + Drag to move + +) + +export const Draggable = withRef<'div', DraggableProps>( + ({ className, classNames = {}, onDropHandler, ...props }, ref) => { + const { children, element } = props + + const state = useDraggableState({ element, onDropHandler }) + const { dropLine, isDragging, isHovered } = state + const { groupProps, droplineProps, gutterLeftProps, previewRef, handleRef } = useDraggable(state) + + return ( +
+
+
+
+
+ {isHovered && dragHandle} +
+
+
+
+ +
+ {children} + + {!!dropLine && ( +
+ )} +
+
+ ) + }, +) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/editor.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/editor.tsx new file mode 100644 index 000000000..701685327 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/editor.tsx @@ -0,0 +1,82 @@ +import { cn } from '@udecode/cn' +import { PlateContent, PlateContentProps } from '@udecode/plate-common' +import type { VariantProps } from 'class-variance-authority' +import { cva } from 'class-variance-authority' +import { forwardRef } from 'react' + +const editorVariants = cva( + cn( + 'relative overflow-x-auto whitespace-pre-wrap break-words', + 'min-h-[80px] w-full rounded-md bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none', + '[&_[data-slate-placeholder]]:text-muted-foreground [&_[data-slate-placeholder]]:!opacity-100', + '[&_[data-slate-placeholder]]:top-[auto_!important]', + '[&_strong]:font-bold', + ), + { + variants: { + variant: { + outline: 'border border-input', + ghost: '', + }, + focused: { + true: 'ring-2 ring-ring ring-offset-2', + }, + disabled: { + true: 'cursor-not-allowed opacity-50', + }, + focusRing: { + true: 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', + false: '', + }, + size: { + sm: 'text-sm', + md: 'text-base', + }, + }, + defaultVariants: { + variant: 'outline', + focusRing: true, + size: 'sm', + }, + }, +) + +export type EditorProps = PlateContentProps & + VariantProps & {}; + +const Editor = forwardRef( + ( + { + className, + disabled, + focused, + focusRing, + readOnly, + size, + variant, + ...props + }, + ref, + ) => { + return ( +
+ +
+ ) + }, +) +Editor.displayName = 'Editor' + +export { Editor } diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar-buttons.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar-buttons.tsx new file mode 100644 index 000000000..eb763f387 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar-buttons.tsx @@ -0,0 +1,61 @@ +import { ListToolbarButton } from './list-toolbar-button' +import { TurnIntoDropdownMenu } from './turn-into-dropdown-menu' +import { MARK_BOLD, MARK_ITALIC, MARK_STRIKETHROUGH, MARK_UNDERLINE } from '@udecode/plate-basic-marks' +import { useEditorReadOnly } from '@udecode/plate-common' +import { BoldIcon, ItalicIcon, StrikethroughIcon, UnderlineIcon } from 'lucide-react' +import { LinkToolbarButton } from './link-toolbar-button' +import { MarkToolbarButton } from './mark-toolbar-button' +import { ToolbarGroup } from './toolbar' +import { InsertDropdownMenu } from './insert-dropdown-menu' + +export function FixedToolbarButtons() { + const readOnly = useEditorReadOnly() + + return ( +
+
+ {!readOnly && ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} +
+
+ ) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar.tsx new file mode 100644 index 000000000..c19735637 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/fixed-toolbar.tsx @@ -0,0 +1,7 @@ +import { uic } from '../../../utils/uic' +import { Toolbar } from './toolbar' + +export const FixedToolbar = uic( + Toolbar, + { baseClass: 'supports-backdrop-blur:bg-background/60 sticky left-0 top-[57px] z-50 w-full justify-between overflow-x-auto rounded-t-lg border-b border-b-border bg-background/95 backdrop-blur' }, +) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar-buttons.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar-buttons.tsx new file mode 100644 index 000000000..a6c4677c7 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar-buttons.tsx @@ -0,0 +1,42 @@ +import { MARK_BOLD, MARK_ITALIC, MARK_STRIKETHROUGH, MARK_UNDERLINE } from '@udecode/plate-basic-marks' +import { useEditorReadOnly } from '@udecode/plate-common' +import { BoldIcon, ItalicIcon, StrikethroughIcon, UnderlineIcon } from 'lucide-react' +import { LinkToolbarButton } from './link-toolbar-button' + +import { MarkToolbarButton } from './mark-toolbar-button' +import { TurnIntoDropdownMenu } from './turn-into-dropdown-menu' + +export function FloatingToolbarButtons() { + const readOnly = useEditorReadOnly() + + return ( + <> + {!readOnly && ( + <> + + + + + + + + + + + + + + + + + + )} + + ) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx new file mode 100644 index 000000000..558d0dfb7 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx @@ -0,0 +1,122 @@ +import { DropdownMenuProps } from '@radix-ui/react-dropdown-menu' +import { + collapseSelection, + findNode, + focusEditor, + isBlock, + isCollapsed, + TElement, + toggleNodeType, + useEditorRef, + useEditorSelector, +} from '@udecode/plate-common' +import { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading' +import { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph' +import { Heading1Icon, Heading2Icon, Heading3Icon, PilcrowIcon } from 'lucide-react' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from '../../ui/dropdown' +import { useOpenState } from '../lib/helpers' +import { ToolbarButton } from './toolbar' + +const items = [ + { + value: ELEMENT_PARAGRAPH, + label: 'Paragraph', + description: 'Paragraph', + icon: PilcrowIcon, + }, + { + value: ELEMENT_H1, + label: 'Heading 1', + description: 'Heading 1', + icon: Heading1Icon, + }, + { + value: ELEMENT_H2, + label: 'Heading 2', + description: 'Heading 2', + icon: Heading2Icon, + }, + { + value: ELEMENT_H3, + label: 'Heading 3', + description: 'Heading 3', + icon: Heading3Icon, + }, +] + +const defaultItem = items.find(item => item.value === ELEMENT_PARAGRAPH)! + +export function TurnIntoDropdownMenu(props: DropdownMenuProps) { + const value: string = useEditorSelector(editor => { + if (isCollapsed(editor.selection)) { + const entry = findNode(editor, { + match: n => isBlock(editor, n), + }) + + if (entry) { + return ( + items.find(item => item.value === entry[0].type)?.value ?? + ELEMENT_PARAGRAPH + ) + } + } + + return ELEMENT_PARAGRAPH + }, []) + + const editor = useEditorRef() + const openState = useOpenState() + + const selectedItem = + items.find(item => item.value === value) ?? defaultItem + const { icon: SelectedItemIcon, label: selectedItemLabel } = selectedItem + + return ( + + + + + {selectedItemLabel} + + + + + Turn into + + { + toggleNodeType(editor, { activeType: type }) + + collapseSelection(editor) + focusEditor(editor) + }} + > + {items.map(({ value: itemValue, label, icon: Icon }) => ( + + + {label} + + ))} + + + + ) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/heading-element.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/heading-element.tsx new file mode 100644 index 000000000..1487a4913 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/heading-element.tsx @@ -0,0 +1,45 @@ +import { withRef, withVariants } from '@udecode/cn' +import { PlateElement } from '@udecode/plate-common' +import { cva } from 'class-variance-authority' + +const headingVariants = cva('', { + variants: { + variant: { + h1: 'mb-1 mt-[2em] font-heading text-4xl font-bold', + h2: 'mb-px mt-[1.4em] font-heading text-2xl font-semibold tracking-tight', + h3: 'mb-px mt-[1em] font-heading text-xl font-semibold tracking-tight', + h4: 'mt-[0.75em] font-heading text-lg font-semibold tracking-tight', + h5: 'mt-[0.75em] text-lg font-semibold tracking-tight', + h6: 'mt-[0.75em] text-base font-semibold tracking-tight', + }, + isFirstBlock: { + true: 'mt-0', + false: '', + }, + }, +}) + +const HeadingElementVariants = withVariants(PlateElement, headingVariants, [ + 'isFirstBlock', + 'variant', +]) + +export const HeadingElement = withRef( + ({ variant = 'h1', isFirstBlock, children, ...props }, ref) => { + const { element, editor } = props + + const Element = variant! + + return ( + + {children} + + ) + }, +) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/insert-dropdown-menu.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/insert-dropdown-menu.tsx new file mode 100644 index 000000000..e357961f1 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/insert-dropdown-menu.tsx @@ -0,0 +1,99 @@ +import { DropdownMenuProps } from '@radix-ui/react-dropdown-menu' +import { focusEditor, insertEmptyElement, useEditorRef } from '@udecode/plate-common' +import { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading' +import { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph' +import { Heading1Icon, Heading2Icon, Heading3Icon, PilcrowIcon, PlusIcon } from 'lucide-react' +import { Fragment } from 'react' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '../../ui/dropdown' +import { useOpenState } from '../lib/helpers' +import { ToolbarButton } from './toolbar' + +const items = [ + { + label: 'Basic blocks', + items: [ + { + value: ELEMENT_PARAGRAPH, + label: 'Paragraph', + description: 'Paragraph', + icon: PilcrowIcon, + }, + { + value: ELEMENT_H1, + label: 'Heading 1', + description: 'Heading 1', + icon: Heading1Icon, + }, + { + value: ELEMENT_H2, + label: 'Heading 2', + description: 'Heading 2', + icon: Heading2Icon, + }, + { + value: ELEMENT_H3, + label: 'Heading 3', + description: 'Heading 3', + icon: Heading3Icon, + }, + ], + }, +] + +export function InsertDropdownMenu(props: DropdownMenuProps) { + const editor = useEditorRef() + const openState = useOpenState() + + return ( + + + + + + + + + {items.map(({ items: nestedItems, label }, index) => ( + + {index !== 0 && } + + {label} + {nestedItems.map( + ({ value: type, label: itemLabel, icon: Icon }) => ( + { + switch (type) { + default: { + insertEmptyElement(editor, type, { + select: true, + nextBlock: true, + }) + } + } + + focusEditor(editor) + }} + > + + {itemLabel} + + ), + )} + + ))} + + + ) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-element.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-element.tsx new file mode 100644 index 000000000..6c29472e6 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-element.tsx @@ -0,0 +1,25 @@ +import { cn, withRef } from '@udecode/cn' +import { PlateElement, useElement } from '@udecode/plate-common' +import { TLinkElement, useLink } from '@udecode/plate-link' + +export const LinkElement = withRef( + ({ className, children, ...props }, ref) => { + const element = useElement() + const { props: linkProps } = useLink({ element }) + + return ( + + {children} + + ) + }, +) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx new file mode 100644 index 000000000..ddf9c2d64 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx @@ -0,0 +1,143 @@ +import { cn } from '@udecode/cn' +import { flip, offset, UseVirtualFloatingOptions } from '@udecode/plate-floating' +import { + FloatingLinkUrlInput, + LinkFloatingToolbarState, + LinkOpenButton, + useFloatingLinkEdit, + useFloatingLinkEditState, + useFloatingLinkInsert, + useFloatingLinkInsertState, +} from '@udecode/plate-link' +import { ExternalLinkIcon, LinkIcon, TextIcon, UnlinkIcon } from 'lucide-react' +import { Button, buttonConfig } from '../../ui/button' +import { Input } from '../../ui/input' +import { popoverVariants } from './popover' + +import { Separator } from './separator' + +const floatingOptions: UseVirtualFloatingOptions = { + placement: 'bottom-start', + middleware: [ + offset(12), + flip({ + padding: 12, + fallbackPlacements: ['bottom-end', 'top-start', 'top-end'], + }), + ], +} + +export interface LinkFloatingToolbarProps { + state?: LinkFloatingToolbarState; +} + +export function LinkFloatingToolbar({ state }: LinkFloatingToolbarProps) { + const insertState = useFloatingLinkInsertState({ + ...state, + floatingOptions: { + ...floatingOptions, + ...state?.floatingOptions, + }, + }) + const { + props: insertProps, + ref: insertRef, + hidden, + textInputProps, + } = useFloatingLinkInsert(insertState) + + const editState = useFloatingLinkEditState({ + ...state, + floatingOptions: { + ...floatingOptions, + ...state?.floatingOptions, + }, + }) + const { + props: editProps, + ref: editRef, + editButtonProps, + unlinkButtonProps, + } = useFloatingLinkEdit(editState) + + if (hidden) return null + + const input = ( +
+
+
+ +
+ + +
+ + + +
+
+ +
+ +
+
+ ) + + const editContent = editState.isEditing ? ( + input + ) : ( +
+ + + + + + + + + + + +
+ ) + + return ( + <> +
+ {input} +
+ +
+ {editContent} +
+ + ) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-toolbar-button.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-toolbar-button.tsx new file mode 100644 index 000000000..40bb9cd34 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-toolbar-button.tsx @@ -0,0 +1,16 @@ +import { withRef } from '@udecode/cn' +import { useLinkToolbarButton, useLinkToolbarButtonState } from '@udecode/plate-link' +import { LinkIcon } from 'lucide-react' + +import { ToolbarButton } from './toolbar' + +export const LinkToolbarButton = withRef((rest, ref) => { + const state = useLinkToolbarButtonState() + const { props } = useLinkToolbarButton(state) + + return ( + + + + ) +}) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-element.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-element.tsx new file mode 100644 index 000000000..94337c57b --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-element.tsx @@ -0,0 +1,20 @@ +import { uic } from '../../../utils/uic' +import { PlateElement } from '@udecode/plate-common' + +export const ListElement = uic(PlateElement, { + baseClass: 'm-0 ps-6', + variants: { + variant: { + ul: 'list-disc [&_ul]:list-[circle] [&_ul_ul]:list-[square]', + ol: 'list-decimal', + }, + }, + defaultVariants: { + variant: 'ul', + }, + wrapOuter: props => { + const Component = props.variant! + + return {props.children} + }, +}) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-toolbar-button.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-toolbar-button.tsx new file mode 100644 index 000000000..0d7e854ce --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/list-toolbar-button.tsx @@ -0,0 +1,31 @@ +import { ListIcon, ListOrderedIcon } from 'lucide-react' +import React from 'react' +import { withRef } from '@udecode/cn' +import { + ELEMENT_UL, + useListToolbarButton, + useListToolbarButtonState, +} from '@udecode/plate-list' + +import { ToolbarButton } from './toolbar' + +export const ListToolbarButton = withRef< + typeof ToolbarButton, + { + nodeType?: string; + } +>(({ nodeType = ELEMENT_UL, ...rest }, ref) => { + const state = useListToolbarButtonState({ nodeType }) + const { props } = useListToolbarButton(state) + + return ( + + {nodeType === ELEMENT_UL ? : } + + ) +}) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/mark-toolbar-button.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/mark-toolbar-button.tsx new file mode 100644 index 000000000..2195ee488 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/mark-toolbar-button.tsx @@ -0,0 +1,17 @@ +import { withRef } from '@udecode/cn' +import { useMarkToolbarButton, useMarkToolbarButtonState } from '@udecode/plate-common' + +import { ToolbarButton } from './toolbar' + +export const MarkToolbarButton = withRef< + typeof ToolbarButton, + { + nodeType: string; + clear?: string | string[]; + } +>(({ clear, nodeType, ...rest }, ref) => { + const state = useMarkToolbarButtonState({ clear, nodeType }) + const { props } = useMarkToolbarButton(state) + + return +}) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/paragraph-element.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/paragraph-element.tsx new file mode 100644 index 000000000..b6b03597d --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/paragraph-element.tsx @@ -0,0 +1,4 @@ +import { withCn } from '@udecode/cn' +import { PlateElement } from '@udecode/plate-common' + +export const ParagraphElement = withCn(PlateElement, 'm-0 px-0 py-1') diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/placeholder.ts b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/placeholder.ts new file mode 100644 index 000000000..f1bf08960 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/placeholder.ts @@ -0,0 +1,45 @@ +import { cn } from '@udecode/cn' +import { createNodeHOC, createNodesHOC, PlaceholderProps, usePlaceholderState } from '@udecode/plate-common' +import { ELEMENT_H1 } from '@udecode/plate-heading' +import { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph' +import { Children, cloneElement } from 'react' + +export const Placeholder = (props: PlaceholderProps) => { + const { children, placeholder, nodeProps } = props + + const { enabled } = usePlaceholderState(props) + + return Children.map(children, child => { + return cloneElement(child, { + className: child.props.className, + nodeProps: { + ...nodeProps, + className: cn( + enabled && + 'before:absolute before:cursor-text before:opacity-30 before:content-[attr(placeholder)]', + ), + placeholder, + }, + }) + }) +} + +export const withPlaceholder = createNodeHOC(Placeholder) +export const withPlaceholdersPrimitive = createNodesHOC(Placeholder) + +export const withPlaceholders = (components: any) => + withPlaceholdersPrimitive(components, [ + { + key: ELEMENT_PARAGRAPH, + placeholder: 'Type a paragraph', + hideOnBlur: true, + query: { + maxLevel: 1, + }, + }, + { + key: ELEMENT_H1, + placeholder: 'Untitled', + hideOnBlur: false, + }, + ]) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/popover.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/popover.tsx new file mode 100644 index 000000000..bc51009d7 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/popover.tsx @@ -0,0 +1,26 @@ +import * as PopoverPrimitive from '@radix-ui/react-popover' +import { cn, withRef } from '@udecode/cn' +import { cva } from 'class-variance-authority' + +export const Popover = PopoverPrimitive.Root +export const PopoverTrigger = PopoverPrimitive.Trigger +export const PopoverAnchor = PopoverPrimitive.Anchor + +export const popoverVariants = cva( + 'w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 print:hidden', +) + +export const PopoverContent = withRef( + ({ className, style, align = 'center', sideOffset = 4, ...props }, ref) => ( + + + + ), +) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/separator.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/separator.tsx new file mode 100644 index 000000000..42e333f77 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/separator.tsx @@ -0,0 +1,23 @@ +import * as SeparatorPrimitive from '@radix-ui/react-separator' +import { withProps, withVariants } from '@udecode/cn' +import { cva } from 'class-variance-authority' + +const separatorVariants = cva('shrink-0 bg-border', { + variants: { + orientation: { + horizontal: 'h-px w-full', + vertical: 'h-full w-px', + }, + }, + defaultVariants: { + orientation: 'horizontal', + }, +}) + +export const Separator = withVariants( + withProps(SeparatorPrimitive.Root, { + orientation: 'horizontal', + decorative: true, + }), + separatorVariants, +) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/toolbar.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/toolbar.tsx new file mode 100644 index 000000000..e2637e331 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/toolbar.tsx @@ -0,0 +1,152 @@ +import { Children, forwardRef } from 'react' +import { uic } from '../../../utils/uic' +import * as ToolbarPrimitive from '@radix-ui/react-toolbar' +import { cn, withCn, withRef, withVariants } from '@udecode/cn' +import { cva, VariantProps } from 'class-variance-authority' +import { ArrowDownIcon } from 'lucide-react' + +import { Separator } from './separator' +import { withTooltip } from './tooltip' + +export const Toolbar = uic( + ToolbarPrimitive.Root, + { baseClass: 'relative flex select-none items-center gap-1 bg-background' }, +) + +export const ToolbarToggleGroup = withCn( + ToolbarPrimitive.ToolbarToggleGroup, + 'flex items-center', +) + +export const ToolbarLink = withCn( + ToolbarPrimitive.Link, + 'font-medium underline underline-offset-4', +) + +export const ToolbarSeparator = withCn( + ToolbarPrimitive.Separator, + 'my-1 w-px shrink-0 bg-border', +) + +const toolbarButtonVariants = cva( + cn( + 'inline-flex items-center justify-center rounded-md text-sm font-medium 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-5', + ), + { + variants: { + variant: { + default: + 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground', + outline: + 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground', + }, + size: { + default: 'h-10 px-3', + sm: 'h-9 px-2', + lg: 'h-11 px-5', + }, + }, + defaultVariants: { + variant: 'default', + size: 'sm', + }, + }, +) + +const ToolbarButton = withTooltip( + forwardRef< + React.ElementRef, + Omit< + React.ComponentPropsWithoutRef, + 'asChild' | 'value' + > & + VariantProps & { + pressed?: boolean; + isDropdown?: boolean; + } + >( + ( + { className, variant, size, isDropdown, children, pressed, ...props }, + ref, + ) => { + return typeof pressed === 'boolean' ? ( + + + {isDropdown ? ( + <> +
{children}
+
+ +
+ + ) : ( + children + )} +
+
+ ) : ( + + {children} + + ) + }, + ), +) +ToolbarButton.displayName = 'ToolbarButton' +export { ToolbarButton } + +export const ToolbarToggleItem = withVariants( + ToolbarPrimitive.ToggleItem, + toolbarButtonVariants, + ['variant', 'size'], +) + +export const ToolbarGroup = withRef< + 'div', + { + noSeparator?: boolean; + } +>(({ className, children, noSeparator }, ref) => { + const childArr = Children.map(children, c => c) + if (!childArr || childArr.length === 0) return null + + return ( +
+ {!noSeparator && ( +
+ +
+ )} + +
{children}
+
+ ) +}) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/tooltip.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/tooltip.tsx new file mode 100644 index 000000000..22a35bc91 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/tooltip.tsx @@ -0,0 +1,59 @@ +import * as TooltipPrimitive from '@radix-ui/react-tooltip' +import { withCn, withProps } from '@udecode/cn' +import { forwardRef, useEffect, useState } from 'react' + +export const TooltipProvider = TooltipPrimitive.Provider +export const Tooltip = TooltipPrimitive.Root +export const TooltipTrigger = TooltipPrimitive.Trigger +export const TooltipPortal = TooltipPrimitive.Portal + +export const TooltipContent = withCn( + withProps(TooltipPrimitive.Content, { + sideOffset: 4, + }), + 'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md', +) + +export function withTooltip< + T extends React.ComponentType | keyof HTMLElementTagNameMap, +>(Component: T) { + return forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + tooltip?: React.ReactNode; + tooltipContentProps?: Omit< + React.ComponentPropsWithoutRef, + 'children' + >; + tooltipProps?: Omit< + React.ComponentPropsWithoutRef, + 'children' + >; + } + >(function ExtendComponent( + { tooltip, tooltipContentProps, tooltipProps, ...props }, + ref, + ) { + const [mounted, setMounted] = useState(false) + + useEffect(() => { + setMounted(true) + }, []) + + const component = + + if (tooltip && mounted) { + return ( + + {component} + + + {tooltip} + + + ) + } + + return component + }) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx new file mode 100644 index 000000000..558d0dfb7 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx @@ -0,0 +1,122 @@ +import { DropdownMenuProps } from '@radix-ui/react-dropdown-menu' +import { + collapseSelection, + findNode, + focusEditor, + isBlock, + isCollapsed, + TElement, + toggleNodeType, + useEditorRef, + useEditorSelector, +} from '@udecode/plate-common' +import { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading' +import { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph' +import { Heading1Icon, Heading2Icon, Heading3Icon, PilcrowIcon } from 'lucide-react' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from '../../ui/dropdown' +import { useOpenState } from '../lib/helpers' +import { ToolbarButton } from './toolbar' + +const items = [ + { + value: ELEMENT_PARAGRAPH, + label: 'Paragraph', + description: 'Paragraph', + icon: PilcrowIcon, + }, + { + value: ELEMENT_H1, + label: 'Heading 1', + description: 'Heading 1', + icon: Heading1Icon, + }, + { + value: ELEMENT_H2, + label: 'Heading 2', + description: 'Heading 2', + icon: Heading2Icon, + }, + { + value: ELEMENT_H3, + label: 'Heading 3', + description: 'Heading 3', + icon: Heading3Icon, + }, +] + +const defaultItem = items.find(item => item.value === ELEMENT_PARAGRAPH)! + +export function TurnIntoDropdownMenu(props: DropdownMenuProps) { + const value: string = useEditorSelector(editor => { + if (isCollapsed(editor.selection)) { + const entry = findNode(editor, { + match: n => isBlock(editor, n), + }) + + if (entry) { + return ( + items.find(item => item.value === entry[0].type)?.value ?? + ELEMENT_PARAGRAPH + ) + } + } + + return ELEMENT_PARAGRAPH + }, []) + + const editor = useEditorRef() + const openState = useOpenState() + + const selectedItem = + items.find(item => item.value === value) ?? defaultItem + const { icon: SelectedItemIcon, label: selectedItemLabel } = selectedItem + + return ( + + + + + {selectedItemLabel} + + + + + Turn into + + { + toggleNodeType(editor, { activeType: type }) + + collapseSelection(editor) + focusEditor(editor) + }} + > + {items.map(({ value: itemValue, label, icon: Icon }) => ( + + + {label} + + ))} + + + + ) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-draggables.ts b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-draggables.ts new file mode 100644 index 000000000..50269d604 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-draggables.ts @@ -0,0 +1,62 @@ +import { createNodesWithHOC } from '@udecode/plate-common' +import { withDraggable as withDraggablePrimitive, WithDraggableOptions } from '@udecode/plate-dnd' +import { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading' +import { ELEMENT_OL, ELEMENT_UL } from '@udecode/plate-list' +import { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph' +import { FC } from 'react' + +import { Draggable, DraggableProps } from './draggable' + +export const withDraggable = ( + Component: FC, + options?: WithDraggableOptions< + Partial> + >, +) => + withDraggablePrimitive(Draggable, Component, options as any) + +export const withDraggablesPrimitive = createNodesWithHOC(withDraggable) + +export const withDraggables = (components: any) => { + return withDraggablesPrimitive(components, [ + { + keys: [ELEMENT_PARAGRAPH, ELEMENT_UL, ELEMENT_OL], + level: 0, + }, + { + key: ELEMENT_H1, + draggableProps: { + classNames: { + gutterLeft: 'px-0 pb-1 text-[1.875em]', + blockToolbarWrapper: 'h-[1.3em]', + }, + }, + }, + { + key: ELEMENT_H2, + draggableProps: { + classNames: { + gutterLeft: 'px-0 pb-1 text-[1.5em]', + blockToolbarWrapper: 'h-[1.3em]', + }, + }, + }, + { + key: ELEMENT_H3, + draggableProps: { + classNames: { + gutterLeft: 'pt-[2px] px-0 pb-1 text-[1.25em]', + blockToolbarWrapper: 'h-[1.3em]', + }, + }, + }, + { + keys: [ELEMENT_PARAGRAPH], + draggableProps: { + classNames: { + gutterLeft: 'pt-[3px] px-0 pb-0', + }, + }, + }, + ]) +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-list.ts b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-list.ts new file mode 100644 index 000000000..2dd11ee35 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/with-list.ts @@ -0,0 +1,61 @@ +import { HotkeyPlugin, PlateEditor, Value, WithPlatePlugin } from '@udecode/plate-common' +import { + deleteBackwardList, + deleteForwardList, + deleteFragmentList, + insertBreakList, + insertFragmentList, normalizeList, +} from '@udecode/plate-list' + +interface ListPlugin extends HotkeyPlugin { + /** + * Valid children types for list items, in addition to p and ul types. + */ + validLiChildrenTypes?: string[]; + enableResetOnShiftTab?: boolean; +} + +export interface TodoListPlugin extends HotkeyPlugin { + inheritCheckStateOnLineStartBreak?: boolean; + inheritCheckStateOnLineEndBreak?: boolean; +} + +export const withList = < + V extends Value = Value, + E extends PlateEditor = PlateEditor, +>( + editor: E, + { options: { validLiChildrenTypes } }: WithPlatePlugin, +) => { + const { insertBreak, deleteBackward, deleteForward, deleteFragment } = editor + + editor.insertBreak = () => { + if (insertBreakList(editor)) return + + insertBreak() + } + + editor.deleteBackward = unit => { + if (deleteBackwardList(editor, unit)) return + + deleteBackward(unit) + } + + editor.deleteForward = unit => { + if (deleteForwardList(editor, deleteForward, unit)) return + + deleteForward(unit) + } + + editor.deleteFragment = direction => { + if (deleteFragmentList(editor)) return + + deleteFragment(direction) + } + + editor.insertFragment = insertFragmentList(editor) + + editor.normalizeNode = normalizeList(editor, { validLiChildrenTypes }) + + return editor +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/utils.ts b/packages/playground/admin/lib/components/richt-text-editor/utils.ts new file mode 100644 index 000000000..b26ee3fb0 --- /dev/null +++ b/packages/playground/admin/lib/components/richt-text-editor/utils.ts @@ -0,0 +1,13 @@ +import { JsonObject } from '@contember/interface' + +export const isJsonContent = (value: unknown): value is { children: any } => { + if (typeof value !== 'object' || value === null) { + return false + } + + return 'children' in value +} + +export const isJsonObject = (value: unknown): value is JsonObject => { + return typeof value === 'object' && value !== null +} diff --git a/packages/playground/package.json b/packages/playground/package.json index 948f9bab9..02d87d3f9 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -44,16 +44,35 @@ "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toolbar": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", + "@udecode/cn": "^31.0.0", + "@udecode/plate-autoformat": "^31.0.0", + "@udecode/plate-basic-marks": "^31.0.0", + "@udecode/plate-common": "^31.0.0", + "@udecode/plate-cursor": "^31.0.0", + "@udecode/plate-dnd": "^31.0.0", + "@udecode/plate-floating": "^31.0.0", + "@udecode/plate-font": "^31.0.0", + "@udecode/plate-heading": "^31.0.0", + "@udecode/plate-link": "^31.0.0", + "@udecode/plate-list": "^31.1.3", + "@udecode/plate-node-id": "^31.0.0", + "@udecode/plate-paragraph": "^31.0.0", + "@udecode/plate-serializer-docx": "^31.1.2", + "@udecode/plate-serializer-md": "^31.0.0", "autoprefixer": "^10", "class-variance-authority": "^0.7.0", "downshift": "^8.3.1", "lucide-react": "^0.302.0", "postcss": "^8", "react": "^18.2.0", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.2.0", "react-twc": "^1.3.0", "tailwind-merge": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index 5602fedcc..51b58fd24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -919,12 +919,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.22.15, @babel/runtime@npm:^7.23.5, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": - version: 7.23.9 - resolution: "@babel/runtime@npm:7.23.9" +"@babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.22.15, @babel/runtime@npm:^7.23.5, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" dependencies: regenerator-runtime: ^0.14.0 - checksum: 6bbebe8d27c0c2dd275d1ac197fc1a6c00e18dab68cc7aaff0adc3195b45862bae9c4cc58975629004b0213955b2ed91e99eccb3d9b39cabea246c657323d667 + checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3 languageName: node linkType: hard @@ -1310,10 +1310,27 @@ __metadata: "@radix-ui/react-progress": ^1.0.3 "@radix-ui/react-scroll-area": ^1.0.5 "@radix-ui/react-select": ^2.0.0 + "@radix-ui/react-separator": ^1.0.3 "@radix-ui/react-slot": ^1.0.2 "@radix-ui/react-switch": ^1.0.3 "@radix-ui/react-toast": ^1.1.5 + "@radix-ui/react-toolbar": ^1.0.4 "@radix-ui/react-tooltip": ^1.0.7 + "@udecode/cn": ^31.0.0 + "@udecode/plate-autoformat": ^31.0.0 + "@udecode/plate-basic-marks": ^31.0.0 + "@udecode/plate-common": ^31.0.0 + "@udecode/plate-cursor": ^31.0.0 + "@udecode/plate-dnd": ^31.0.0 + "@udecode/plate-floating": ^31.0.0 + "@udecode/plate-font": ^31.0.0 + "@udecode/plate-heading": ^31.0.0 + "@udecode/plate-link": ^31.0.0 + "@udecode/plate-list": ^31.1.3 + "@udecode/plate-node-id": ^31.0.0 + "@udecode/plate-paragraph": ^31.0.0 + "@udecode/plate-serializer-docx": ^31.1.2 + "@udecode/plate-serializer-md": ^31.0.0 autoprefixer: ^10 class-variance-authority: ^0.7.0 downshift: ^8.3.1 @@ -1321,6 +1338,8 @@ __metadata: lucide-react: ^0.302.0 postcss: ^8 react: ^18.2.0 + react-dnd: ^16.0.1 + react-dnd-html5-backend: ^16.0.1 react-dom: ^18.2.0 react-twc: ^1.3.0 tailwind-merge: ^2.2.0 @@ -2338,22 +2357,34 @@ __metadata: languageName: node linkType: hard -"@floating-ui/core@npm:^1.5.3": - version: 1.5.3 - resolution: "@floating-ui/core@npm:1.5.3" +"@floating-ui/core@npm:^1.0.0, @floating-ui/core@npm:^1.6.0": + version: 1.6.0 + resolution: "@floating-ui/core@npm:1.6.0" dependencies: - "@floating-ui/utils": ^0.2.0 - checksum: 72af8563e1742791acee82e86f82a0fbca7445809988d31eea3fd5771909463aa7655a6cb001cc244f8fe3a9de600420257e4dfb887ca33e2a31ac47b52e39a2 + "@floating-ui/utils": ^0.2.1 + checksum: 2e25c53b0c124c5c9577972f8ae21d081f2f7895e6695836a53074463e8c65b47722744d6d2b5a993164936da006a268bcfe87fe68fd24dc235b1cb86bed3127 languageName: node linkType: hard -"@floating-ui/dom@npm:^1.0.1, @floating-ui/dom@npm:^1.5.4": - version: 1.5.4 - resolution: "@floating-ui/dom@npm:1.5.4" +"@floating-ui/dom@npm:^1.0.1, @floating-ui/dom@npm:^1.2.1, @floating-ui/dom@npm:^1.5.4": + version: 1.6.3 + resolution: "@floating-ui/dom@npm:1.6.3" dependencies: - "@floating-ui/core": ^1.5.3 + "@floating-ui/core": ^1.0.0 "@floating-ui/utils": ^0.2.0 - checksum: 5e6f05532ff4e6daf9f2d91534184d8f942ddb8fd260c2543a49bdf0c0ff69fd0867937ce1d023126008724ac238f8fc89b5e48f82cdf9f8355a1d04edd085bd + checksum: 81cbb18ece3afc37992f436e469e7fabab2e433248e46fff4302d12493a175b0c64310f8a971e6e1eda7218df28ace6b70237b0f3c22fe12a21bba05b5579555 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^1.3.0": + version: 1.3.0 + resolution: "@floating-ui/react-dom@npm:1.3.0" + dependencies: + "@floating-ui/dom": ^1.2.1 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: ce0ad3e3bbe43cfd15a6a0d5cccede02175c845862bfab52027995ab99c6b29630180dc7d146f76ebb34730f90a6ab9bf193c8984fe8d7f56062308e4ca98f77 languageName: node linkType: hard @@ -2369,7 +2400,21 @@ __metadata: languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.0": +"@floating-ui/react@npm:^0.22.3": + version: 0.22.3 + resolution: "@floating-ui/react@npm:0.22.3" + dependencies: + "@floating-ui/react-dom": ^1.3.0 + aria-hidden: ^1.1.3 + tabbable: ^6.0.1 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 9e1384e183e066f11e5f5aef72e98ffbb9dbc8f5cac1764de43054773ec3c2407eb54ff8322636060e852869101bdf112b02260575fcce44bd4171451e2d7409 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": version: 0.2.1 resolution: "@floating-ui/utils@npm:0.2.1" checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06 @@ -3308,6 +3353,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-separator@npm:1.0.3, @radix-ui/react-separator@npm:^1.0.3": + version: 1.0.3 + resolution: "@radix-ui/react-separator@npm:1.0.3" + dependencies: + "@babel/runtime": ^7.13.10 + "@radix-ui/react-primitive": 1.0.3 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 42f8c95e404de2ce9387040d78049808a48d423cd4c3bad8cca92c4b0bcbdcb3566b5b52a920d4e939a74b51188697f20a012221f0e630fc7f56de64096c15d2 + languageName: node + linkType: hard + "@radix-ui/react-slot@npm:1.0.2, @radix-ui/react-slot@npm:^1.0.2": version: 1.0.2 resolution: "@radix-ui/react-slot@npm:1.0.2" @@ -3381,6 +3446,80 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-toggle-group@npm:1.0.4": + version: 1.0.4 + resolution: "@radix-ui/react-toggle-group@npm:1.0.4" + dependencies: + "@babel/runtime": ^7.13.10 + "@radix-ui/primitive": 1.0.1 + "@radix-ui/react-context": 1.0.1 + "@radix-ui/react-direction": 1.0.1 + "@radix-ui/react-primitive": 1.0.3 + "@radix-ui/react-roving-focus": 1.0.4 + "@radix-ui/react-toggle": 1.0.3 + "@radix-ui/react-use-controllable-state": 1.0.1 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: b6c11fbbc3ca857ff68c0fa31f293c0d0111bcc8aa0cde2566214c090907530bfcb3b862f81585c2b02d8989b5c7971acff4d5c07c429870d80bd5602e30d376 + languageName: node + linkType: hard + +"@radix-ui/react-toggle@npm:1.0.3": + version: 1.0.3 + resolution: "@radix-ui/react-toggle@npm:1.0.3" + dependencies: + "@babel/runtime": ^7.13.10 + "@radix-ui/primitive": 1.0.1 + "@radix-ui/react-primitive": 1.0.3 + "@radix-ui/react-use-controllable-state": 1.0.1 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: ed5407f48254f20cda542017774f259d0b2c0007ea4bd7287d10d751016dbf269cb13d1142591432c269c3ab768cde2f1ba0344743027d36bbec10af909f19de + languageName: node + linkType: hard + +"@radix-ui/react-toolbar@npm:^1.0.4": + version: 1.0.4 + resolution: "@radix-ui/react-toolbar@npm:1.0.4" + dependencies: + "@babel/runtime": ^7.13.10 + "@radix-ui/primitive": 1.0.1 + "@radix-ui/react-context": 1.0.1 + "@radix-ui/react-direction": 1.0.1 + "@radix-ui/react-primitive": 1.0.3 + "@radix-ui/react-roving-focus": 1.0.4 + "@radix-ui/react-separator": 1.0.3 + "@radix-ui/react-toggle-group": 1.0.4 + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 7ebee1f8add6510108979433c5b38627e2de9d48ef2172ca15274b9edbbc106ff43bcd47ff733b03ed2215b92e7af364ff82c79e5a1728374847e2b1e315552c + languageName: node + linkType: hard + "@radix-ui/react-tooltip@npm:^1.0.7": version: 1.0.7 resolution: "@radix-ui/react-tooltip@npm:1.0.7" @@ -4283,6 +4422,27 @@ __metadata: languageName: node linkType: hard +"@react-dnd/asap@npm:^5.0.1": + version: 5.0.2 + resolution: "@react-dnd/asap@npm:5.0.2" + checksum: 18f040e53512983f11c542ef21e6e4cac605d585a10cd764b13bc1b2f3ac7490e0fa40503adc348d8387aa45bc8e7eebe9cb33003b960a30bb5fde666ff2adde + languageName: node + linkType: hard + +"@react-dnd/invariant@npm:^4.0.1": + version: 4.0.2 + resolution: "@react-dnd/invariant@npm:4.0.2" + checksum: 594f6d78896c19bb8f023e101334fd91a9fdff686117bd8e830ba53737ec0a6042dab66971d3d63c7afbc622103909aff7a64c5c6767e0aa8d9561fd42705016 + languageName: node + linkType: hard + +"@react-dnd/shallowequal@npm:^4.0.1": + version: 4.0.2 + resolution: "@react-dnd/shallowequal@npm:4.0.2" + checksum: 7f21d691bddbfd4d2830948cbeefecca1600b2b46bcb1934926795f07ae8a1fa60a3dfd3a2112be5ef682c3820c80a99711e9fa15843f7e300acb25a4ecb70ab + languageName: node + linkType: hard + "@react-leaflet/core@npm:^2.1.0": version: 2.1.0 resolution: "@react-leaflet/core@npm:2.1.0" @@ -5847,6 +6007,15 @@ __metadata: languageName: node linkType: hard +"@types/mdast@npm:^3.0.0": + version: 3.0.15 + resolution: "@types/mdast@npm:3.0.15" + dependencies: + "@types/unist": ^2 + checksum: af85042a4e3af3f879bde4059fa9e76c71cb552dffc896cdcc6cf9dc1fd38e37035c2dbd6245cfa6535b433f1f0478f5549696234ccace47a64055a10c656530 + languageName: node + linkType: hard + "@types/micromatch@npm:^4.0.6": version: 4.0.6 resolution: "@types/micromatch@npm:4.0.6" @@ -5947,6 +6116,13 @@ __metadata: languageName: node linkType: hard +"@types/unist@npm:^2, @types/unist@npm:^2.0.0, @types/unist@npm:^2.0.2": + version: 2.0.10 + resolution: "@types/unist@npm:2.0.10" + checksum: e2924e18dedf45f68a5c6ccd6015cd62f1643b1b43baac1854efa21ae9e70505db94290434a23da1137d9e31eb58e54ca175982005698ac37300a1c889f6c4aa + languageName: node + linkType: hard + "@types/uuid@npm:9.0.7": version: 9.0.7 resolution: "@types/uuid@npm:9.0.7" @@ -6059,30 +6235,581 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/utils@npm:6.16.0" +"@typescript-eslint/utils@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/utils@npm:6.16.0" + dependencies: + "@eslint-community/eslint-utils": ^4.4.0 + "@types/json-schema": ^7.0.12 + "@types/semver": ^7.5.0 + "@typescript-eslint/scope-manager": 6.16.0 + "@typescript-eslint/types": 6.16.0 + "@typescript-eslint/typescript-estree": 6.16.0 + semver: ^7.5.4 + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + checksum: d7efa112a1356024cde5306d032c6028d41671ece7ecda5c726cbfed26a9f3f8d317388a3c743cfaeeee1766db303c4a489b6825ad8275ee148d060afa57af4d + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.16.0" + dependencies: + "@typescript-eslint/types": 6.16.0 + eslint-visitor-keys: ^3.4.1 + checksum: 2863e6d145a79bb12485b39417e30710996d8576894d67a484fde7cef417e3c67fd9fd99cb57736f0667e4425ddb2ab1f0954340ec5f4e08b8cb2ce7378a1977 + languageName: node + linkType: hard + +"@udecode/cn@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/cn@npm:31.0.0" + dependencies: + "@udecode/react-utils": 31.0.0 + peerDependencies: + class-variance-authority: ">=0.7.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + tailwind-merge: ">=2.2.0" + checksum: f3517520b9987be87ea923b58a40555d9b5eb30c8f5d4c8313b62275fc68396d3e12abe76f97e3b0f2238c5aabe8980ce8d2e60d8fa5c948727fde6d26654678 + languageName: node + linkType: hard + +"@udecode/plate-autoformat@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-autoformat@npm:31.0.0" + dependencies: + lodash: ^4.17.21 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: e757b2eaf2095719cee2e15837b4a5cc5b6a8492723442b76416fcae134e8892947338ee4bfbad6ddd2d839a03ea6a335d9fd684c88f4f02272edf094c05eb8a + languageName: node + linkType: hard + +"@udecode/plate-basic-marks@npm:31.0.0, @udecode/plate-basic-marks@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-basic-marks@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: cf8f71d814727a9b6dc526cc5097dde7f7021135d1fda71ad55374fe84e1bbef4be830130718ec79ae54e026d9b865c76c184934741f333142f47e9662c55205 + languageName: node + linkType: hard + +"@udecode/plate-block-quote@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-block-quote@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 163065003aefdc017a43a2b15a553fc7d6e9d2088ed210a075695acdbd85525799c70410e27ebb88ef31c993c7b5133e733345cce4fdcab73ebdea7cd5c4eb5a + languageName: node + linkType: hard + +"@udecode/plate-code-block@npm:31.3.4": + version: 31.3.4 + resolution: "@udecode/plate-code-block@npm:31.3.4" + dependencies: + prismjs: ^1.29.0 + peerDependencies: + "@udecode/plate-common": ">=31.3.2" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 3e32717f373acf6bc89b0714d096fc4c297cc35c3dbd5d2f5d7e5844f99daa072ff41951b383fa90a338f6df7a347d0f2978a6517e8426a3b7e6ef8fd50a5f74 + languageName: node + linkType: hard + +"@udecode/plate-common@npm:^31.0.0": + version: 31.3.2 + resolution: "@udecode/plate-common@npm:31.3.2" + dependencies: + "@udecode/plate-core": 31.3.2 + "@udecode/plate-utils": 31.3.2 + "@udecode/react-utils": 31.0.0 + "@udecode/slate": 31.0.0 + "@udecode/slate-react": 31.0.0 + "@udecode/slate-utils": 31.3.2 + "@udecode/utils": 31.0.0 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: b8845458c05a31cae62696505c877ebd2b4014662706962ab2ab6e2b2cb72be2e2b8477ccb4630e8368ef03d11b3d50263f6344c3448a87daf31a4f99ffefa58 + languageName: node + linkType: hard + +"@udecode/plate-core@npm:31.3.2": + version: 31.3.2 + resolution: "@udecode/plate-core@npm:31.3.2" + dependencies: + "@udecode/slate": 31.0.0 + "@udecode/slate-react": 31.0.0 + "@udecode/slate-utils": 31.3.2 + "@udecode/utils": 31.0.0 + clsx: ^1.2.1 + is-hotkey: ^0.2.0 + jotai: ^2.7.1 + jotai-optics: 0.3.2 + jotai-x: ^1.2.2 + lodash: ^4.17.21 + nanoid: ^3.3.7 + optics-ts: 2.4.1 + react-hotkeys-hook: ^4.5.0 + use-deep-compare: ^1.2.1 + zustand: ^4.5.2 + zustand-x: ^3.0.2 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: d1df706405f5bf32e212bf0ef53a18a64faa51f9f778ead4195520173e51005c66d5e98eb0285854276593974505ae67334d3c7559019b874aec75da3c55bada + languageName: node + linkType: hard + +"@udecode/plate-cursor@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-cursor@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: ba3c9a7cb0b78292cfd0f4bff6550d0976175d7bf638f77935c2a7effa771c4e692c270bc733aeb482d3a64fb085a8c47a5033d2a204e9a401b6326d5e022d52 + languageName: node + linkType: hard + +"@udecode/plate-dnd@npm:^31.0.0": + version: 31.2.1 + resolution: "@udecode/plate-dnd@npm:31.2.1" + dependencies: + lodash: ^4.17.21 + raf: ^3.4.1 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dnd: ">=14.0.0" + react-dnd-html5-backend: ">=14.0.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 73439e3f8fc61739e98f2eda253a0cd84806d20d0115f4d1f769aba0975e2d3d746b2b1ecdd215e35ab53e30516f406d3908eb340b1cc6758dc1e85db6382e05 + languageName: node + linkType: hard + +"@udecode/plate-floating@npm:31.0.0, @udecode/plate-floating@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-floating@npm:31.0.0" + dependencies: + "@floating-ui/core": ^1.6.0 + "@floating-ui/react": ^0.22.3 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 4f5b247d29f5eb66c8c08d0e6fcf57874b06f766e9c510cc2f123e9b488937105daad6de844a6794a93f25592bed4c0d4331b0f57cae3fb3ec4aff2948d4e356 + languageName: node + linkType: hard + +"@udecode/plate-font@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-font@npm:31.0.0" + dependencies: + lodash: ^4.17.21 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: cb36dc063dc8c4b4bffc0bd1c0c7a95c99f5fb91954bd6168db70de40e11f691759bd16125d42b9ad39d9b7b2759a38c4e3cd8d6861eea0b8e74dc81b6fa6417 + languageName: node + linkType: hard + +"@udecode/plate-heading@npm:31.0.0, @udecode/plate-heading@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-heading@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 1e56d38b486a299c561e1ae95d456ab0e3e39961eb7cf6f49c2bbf437db38478c26e96d19d52e94f8911c3dd9bedb80e92b4300fb8585d46b9f2b81a504e85d2 + languageName: node + linkType: hard + +"@udecode/plate-horizontal-rule@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-horizontal-rule@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: e8ac6772713e187194021f8215a707c7b65d97500316e8bbd8bcdf1bdaa89a65eb76310251a56e15e186f410ebff1eb42aacb46d46df0fc952d889b330f77226 + languageName: node + linkType: hard + +"@udecode/plate-indent-list@npm:31.2.2": + version: 31.2.2 + resolution: "@udecode/plate-indent-list@npm:31.2.2" + dependencies: + "@udecode/plate-indent": 31.1.0 + "@udecode/plate-list": 31.1.3 + clsx: ^1.2.1 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 74c12293cf1cf706675aa9f8130661f08b0ae6a63839df5b329c58d293432c809754bf2b47f5e863bd4d66e1f6064c3c9bd00f3842a0a2bff6dc493e31e708db + languageName: node + linkType: hard + +"@udecode/plate-indent@npm:31.1.0": + version: 31.1.0 + resolution: "@udecode/plate-indent@npm:31.1.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 98a23d9d39180b514d80df2c3f54a02657cfb798696d40102bfde2e87b5662dafc13f81cb7983f0ccd382c86a1131c1768ccc0f8f8f44eb66ba6e7e3a591bb13 + languageName: node + linkType: hard + +"@udecode/plate-link@npm:31.0.0, @udecode/plate-link@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-link@npm:31.0.0" + dependencies: + "@udecode/plate-floating": 31.0.0 + "@udecode/plate-normalizers": 31.0.0 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: d356fc8a3ebec8ec33ea5a1c2b3f083c5eaaf13085423cc077b32ac2b8e72d475322bb262990529ba34ab85254cd6ccee28b99a3d907569ed02a054a3bf538a5 + languageName: node + linkType: hard + +"@udecode/plate-list@npm:31.1.3, @udecode/plate-list@npm:^31.1.3": + version: 31.1.3 + resolution: "@udecode/plate-list@npm:31.1.3" + dependencies: + "@udecode/plate-reset-node": 31.0.0 + lodash: ^4.17.21 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: dbb3b895b5d5afcddfc2626c09b2d1af8d8a0d17698265163c79e9a7efe8a742fdd7c5aa9cb4c2051c336b82d4f38b55c5b7eea3c1c0dc2b7c7b19000f0aa8c1 + languageName: node + linkType: hard + +"@udecode/plate-media@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-media@npm:31.0.0" + dependencies: + js-video-url-parser: ^0.5.1 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 9db69cef6ad42cc6a7798df5f622eef12b4d581fe33d4d971dd97e9262872bd094868f3a2c1b40da9882291448da1cafc9bf0e04dea37a901a42093d15124487 + languageName: node + linkType: hard + +"@udecode/plate-node-id@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-node-id@npm:31.0.0" + dependencies: + lodash: ^4.17.21 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 496ea7b93c28ec792a6e25fe78bad96aebab21abb45480e0b74dab499a8751aadee5a7ec46460bf09f7225559c78a69e86fe1568c8957163f7fd0ca4a2fff830 + languageName: node + linkType: hard + +"@udecode/plate-normalizers@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-normalizers@npm:31.0.0" + dependencies: + lodash: ^4.17.21 + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 5d24bff95c80760cbc1a84ef168ea561c2ecb3511f055a3ea4e62705747ea304edd3707f570b8e43f805496e336cfadb532ba6975baa9e4f7b515aa61cf78dc8 + languageName: node + linkType: hard + +"@udecode/plate-paragraph@npm:31.0.0, @udecode/plate-paragraph@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-paragraph@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 275267dfe44cc7ef15427cc98ad4d6acc1421d5451b6d862f8645f7c00894b528061a80f8c50bc2492deeba9bd4a86fb9bde4e0b75a9e3260c2eca62356997d0 + languageName: node + linkType: hard + +"@udecode/plate-reset-node@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-reset-node@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 4ce17786405768add3b579e08af489c03ce97953388d240058aec50864d01825518d05477908e13b93399f4a57ca086f43caa3b34a093a3f0a10d8012e756e42 + languageName: node + linkType: hard + +"@udecode/plate-resizable@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-resizable@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: edcf0fb9531ed86d01ebcb1c6c045deae1993e17907126c77cc02ed2f9c04cfb6d7ce279e05339f6797dbe1a3526521e76b1952b13ed4f5089f481bd9e3bdaf7 + languageName: node + linkType: hard + +"@udecode/plate-serializer-docx@npm:^31.1.2": + version: 31.3.3 + resolution: "@udecode/plate-serializer-docx@npm:31.3.3" + dependencies: + "@udecode/plate-heading": 31.0.0 + "@udecode/plate-indent": 31.1.0 + "@udecode/plate-indent-list": 31.2.2 + "@udecode/plate-media": 31.0.0 + "@udecode/plate-paragraph": 31.0.0 + "@udecode/plate-table": 31.3.3 + validator: ^13.11.0 + peerDependencies: + "@udecode/plate-common": ">=31.3.2" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: c1fc0ce9c2076a2c9f0351d6eb3e08ebb682cfc72c207fd75c553627352bbe7b0966d5a1b3bbc04f0b308aaef46c3cd29531d6e27537a44ea08edc03aee667b0 + languageName: node + linkType: hard + +"@udecode/plate-serializer-md@npm:^31.0.0": + version: 31.3.4 + resolution: "@udecode/plate-serializer-md@npm:31.3.4" + dependencies: + "@udecode/plate-basic-marks": 31.0.0 + "@udecode/plate-block-quote": 31.0.0 + "@udecode/plate-code-block": 31.3.4 + "@udecode/plate-heading": 31.0.0 + "@udecode/plate-horizontal-rule": 31.0.0 + "@udecode/plate-link": 31.0.0 + "@udecode/plate-list": 31.1.3 + "@udecode/plate-media": 31.0.0 + "@udecode/plate-paragraph": 31.0.0 + remark-parse: ^9.0.0 + unified: ^9.2.2 + peerDependencies: + "@udecode/plate-common": ">=31.3.2" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: cd54a45ce43fb3dca688e6b9f28192f732fb1077405a88b75c26e1a9f98a7b880e1b05579ae262f9587942f2db65f0cd61a2cb70730ba24d1c29fd7d3af45098 + languageName: node + linkType: hard + +"@udecode/plate-table@npm:31.3.3": + version: 31.3.3 + resolution: "@udecode/plate-table@npm:31.3.3" + dependencies: + "@udecode/plate-resizable": 31.0.0 + lodash: ^4.17.21 + peerDependencies: + "@udecode/plate-common": ">=31.3.2" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-react: ">=0.99.0" + checksum: c847f66bf1500343dfa6a0f8fc396a8178d75cacfad51f0167e9fc3f9b531c152aa911a87159977396150f91824285394a30fdfe3866a075b1bc8d8930623bad + languageName: node + linkType: hard + +"@udecode/plate-utils@npm:31.3.2": + version: 31.3.2 + resolution: "@udecode/plate-utils@npm:31.3.2" + dependencies: + "@udecode/plate-core": 31.3.2 + "@udecode/react-utils": 31.0.0 + "@udecode/slate": 31.0.0 + "@udecode/slate-react": 31.0.0 + "@udecode/slate-utils": 31.3.2 + "@udecode/utils": 31.0.0 + clsx: ^1.2.1 + lodash: ^4.17.21 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 28d7fb28e95b32f90836a7136d6787b598ee1082901cb3d896353a692edb721cc4391c15ba354116d20dd65c0c239b19250ad749d260bb581b29384878a2033e + languageName: node + linkType: hard + +"@udecode/react-utils@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/react-utils@npm:31.0.0" + dependencies: + "@radix-ui/react-slot": ^1.0.2 + "@udecode/utils": 31.0.0 + clsx: ^1.2.1 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: ec70c7d321a6f50d6a27d4bb4b9435a131378bca9c151515a954c66b5630e8d81ca0eb7f56b42095b1e8c2373bd2026a23594d9f7b6268c4fbff233349a38c5f + languageName: node + linkType: hard + +"@udecode/slate-react@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/slate-react@npm:31.0.0" + dependencies: + "@udecode/react-utils": 31.0.0 + "@udecode/slate": 31.0.0 + "@udecode/utils": 31.0.0 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-react: ">=0.99.0" + checksum: 757761ec442659070b4edb0a210e093b1bd7104eed5ccb6b557607b9014bd53f7598c25593dd957e284700b102cf7eba36bdca081651ed4ad7d95d5bdab52ffc + languageName: node + linkType: hard + +"@udecode/slate-utils@npm:31.3.2": + version: 31.3.2 + resolution: "@udecode/slate-utils@npm:31.3.2" dependencies: - "@eslint-community/eslint-utils": ^4.4.0 - "@types/json-schema": ^7.0.12 - "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.16.0 - "@typescript-eslint/types": 6.16.0 - "@typescript-eslint/typescript-estree": 6.16.0 - semver: ^7.5.4 + "@udecode/slate": 31.0.0 + "@udecode/utils": 31.0.0 + lodash: ^4.17.21 peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - checksum: d7efa112a1356024cde5306d032c6028d41671ece7ecda5c726cbfed26a9f3f8d317388a3c743cfaeeee1766db303c4a489b6825ad8275ee148d060afa57af4d + slate: ">=0.94.0" + slate-history: ">=0.93.0" + checksum: dcb7d88074965b5c96e0aa73bb71657f3d4fd094f5fa742799a802aba3b5400610515451f5dc0bf34aef2c59b226cc59106d39fd5d624884cc91d75faf57f2c1 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.16.0" +"@udecode/slate@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/slate@npm:31.0.0" dependencies: - "@typescript-eslint/types": 6.16.0 - eslint-visitor-keys: ^3.4.1 - checksum: 2863e6d145a79bb12485b39417e30710996d8576894d67a484fde7cef417e3c67fd9fd99cb57736f0667e4425ddb2ab1f0954340ec5f4e08b8cb2ce7378a1977 + "@udecode/utils": 31.0.0 + peerDependencies: + slate: ">=0.94.0" + slate-history: ">=0.93.0" + checksum: 261abfac09014ddb1577a3dd5a116928e24b114fccf2fe2a68af9e6fa0661cddeb59519fb69bd2f2c3dbc96b52e0e0ab93255df9370727a593f1ca69c7a4c859 + languageName: node + linkType: hard + +"@udecode/utils@npm:31.0.0": + version: 31.0.0 + resolution: "@udecode/utils@npm:31.0.0" + checksum: c01722ff51ce1d964b13cc828e81f73671e2a37c65a5bce7667f8b46bede5f9411b88f96ffb652f33e5e86376a7ed7f5af45c16750bffb7b7bbfb617bbe10242 languageName: node linkType: hard @@ -6354,12 +7081,12 @@ __metadata: languageName: node linkType: hard -"aria-hidden@npm:^1.1.1": - version: 1.2.3 - resolution: "aria-hidden@npm:1.2.3" +"aria-hidden@npm:^1.1.1, aria-hidden@npm:^1.1.3": + version: 1.2.4 + resolution: "aria-hidden@npm:1.2.4" dependencies: tslib: ^2.0.0 - checksum: 7d7d211629eef315e94ed3b064c6823d13617e609d3f9afab1c2ed86399bb8e90405f9bdd358a85506802766f3ecb468af985c67c846045a34b973bcc0289db9 + checksum: 2ac90b70d29c6349d86d90e022cf01f4885f9be193932d943a14127cf28560dd0baf068a6625f084163437a4be0578f513cf7892f4cc63bfe91aa41dce27c6b2 languageName: node linkType: hard @@ -6543,6 +7270,13 @@ __metadata: languageName: node linkType: hard +"bail@npm:^1.0.0": + version: 1.0.5 + resolution: "bail@npm:1.0.5" + checksum: 6c334940d7eaa4e656a12fb12407b6555649b6deb6df04270fa806e0da82684ebe4a4e47815b271c794b40f8d6fa286e0c248b14ddbabb324a917fab09b7301a + languageName: node + linkType: hard + "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -6766,6 +7500,27 @@ __metadata: languageName: node linkType: hard +"character-entities-legacy@npm:^1.0.0": + version: 1.1.4 + resolution: "character-entities-legacy@npm:1.1.4" + checksum: fe03a82c154414da3a0c8ab3188e4237ec68006cbcd681cf23c7cfb9502a0e76cd30ab69a2e50857ca10d984d57de3b307680fff5328ccd427f400e559c3a811 + languageName: node + linkType: hard + +"character-entities@npm:^1.0.0": + version: 1.2.4 + resolution: "character-entities@npm:1.2.4" + checksum: e1545716571ead57beac008433c1ff69517cd8ca5b336889321c5b8ff4a99c29b65589a701e9c086cda8a5e346a67295e2684f6c7ea96819fe85cbf49bf8686d + languageName: node + linkType: hard + +"character-reference-invalid@npm:^1.0.0": + version: 1.1.4 + resolution: "character-reference-invalid@npm:1.1.4" + checksum: 20274574c70e05e2f81135f3b93285536bc8ff70f37f0809b0d17791a832838f1e49938382899ed4cb444e5bbd4314ca1415231344ba29f4222ce2ccf24fea0b + languageName: node + linkType: hard + "check-error@npm:^1.0.3": version: 1.0.3 resolution: "check-error@npm:1.0.3" @@ -6851,6 +7606,13 @@ __metadata: languageName: node linkType: hard +"clsx@npm:^1.2.1": + version: 1.2.1 + resolution: "clsx@npm:1.2.1" + checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12 + languageName: node + linkType: hard + "cluster-key-slot@npm:1.1.2": version: 1.1.2 resolution: "cluster-key-slot@npm:1.1.2" @@ -7097,7 +7859,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -7208,6 +7970,13 @@ __metadata: languageName: node linkType: hard +"dequal@npm:2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 + languageName: node + linkType: hard + "detect-node-es@npm:^1.1.0": version: 1.1.0 resolution: "detect-node-es@npm:1.1.0" @@ -7254,6 +8023,17 @@ __metadata: languageName: node linkType: hard +"dnd-core@npm:^16.0.1": + version: 16.0.1 + resolution: "dnd-core@npm:16.0.1" + dependencies: + "@react-dnd/asap": ^5.0.1 + "@react-dnd/invariant": ^4.0.1 + redux: ^4.2.0 + checksum: b7d3ef4664f433af796f440ddd27ad9d7fef0205f26c4b7c0af6ebf612ffa9b33e64d095d3e79190c4baaed34aa36570f321ebe0d2cc8ff1031ff158a0907b3f + languageName: node + linkType: hard + "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -7789,6 +8569,13 @@ __metadata: languageName: node linkType: hard +"extend@npm:^3.0.0": + version: 3.0.2 + resolution: "extend@npm:3.0.2" + checksum: a50a8309ca65ea5d426382ff09f33586527882cf532931cb08ca786ea3146c0553310bda688710ff61d7668eba9f96b923fe1420cdf56a2c3eaf30fcab87b515 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -8374,7 +9161,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.3.1": +"hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -8479,6 +9266,13 @@ __metadata: languageName: node linkType: hard +"immer@npm:^10.0.3": + version: 10.0.4 + resolution: "immer@npm:10.0.4" + checksum: 8c69cad9adde7296b6857aadc0837b792840d46d5b5759002cfc168abe58815bd5b944a9533a03df4738d6ce3dc918cc0a88437324fd71e1fcbd2e77273c39f0 + languageName: node + linkType: hard + "immer@npm:^9.0.6": version: 9.0.19 resolution: "immer@npm:9.0.19" @@ -8587,6 +9381,23 @@ __metadata: languageName: node linkType: hard +"is-alphabetical@npm:^1.0.0": + version: 1.0.4 + resolution: "is-alphabetical@npm:1.0.4" + checksum: 6508cce44fd348f06705d377b260974f4ce68c74000e7da4045f0d919e568226dc3ce9685c5a2af272195384df6930f748ce9213fc9f399b5d31b362c66312cb + languageName: node + linkType: hard + +"is-alphanumerical@npm:^1.0.0": + version: 1.0.4 + resolution: "is-alphanumerical@npm:1.0.4" + dependencies: + is-alphabetical: ^1.0.0 + is-decimal: ^1.0.0 + checksum: e2e491acc16fcf5b363f7c726f666a9538dba0a043665740feb45bba1652457a73441e7c5179c6768a638ed396db3437e9905f403644ec7c468fb41f4813d03f + languageName: node + linkType: hard + "is-arguments@npm:^1.1.1": version: 1.1.1 resolution: "is-arguments@npm:1.1.1" @@ -8652,6 +9463,13 @@ __metadata: languageName: node linkType: hard +"is-buffer@npm:^2.0.0": + version: 2.0.5 + resolution: "is-buffer@npm:2.0.5" + checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42 + languageName: node + linkType: hard + "is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" @@ -8677,6 +9495,13 @@ __metadata: languageName: node linkType: hard +"is-decimal@npm:^1.0.0": + version: 1.0.4 + resolution: "is-decimal@npm:1.0.4" + checksum: ed483a387517856dc395c68403a10201fddcc1b63dc56513fbe2fe86ab38766120090ecdbfed89223d84ca8b1cd28b0641b93cb6597b6e8f4c097a7c24e3fb96 + languageName: node + linkType: hard + "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -8718,7 +9543,14 @@ __metadata: languageName: node linkType: hard -"is-hotkey@npm:0.2.0": +"is-hexadecimal@npm:^1.0.0": + version: 1.0.4 + resolution: "is-hexadecimal@npm:1.0.4" + checksum: a452e047587b6069332d83130f54d30da4faf2f2ebaa2ce6d073c27b5703d030d58ed9e0b729c8e4e5b52c6f1dab26781bb77b7bc6c7805f14f320e328ff8cd5 + languageName: node + linkType: hard + +"is-hotkey@npm:0.2.0, is-hotkey@npm:^0.2.0": version: 0.2.0 resolution: "is-hotkey@npm:0.2.0" checksum: 97d295cfd8c3eb2c9b218daee5bff0ddaf47210930e3eb1eff36d2e6ad74854028203c640f35ea2d183d0cba94ac4c4bcd291925bc3a343d8a4c7d2c5ab3e2a6 @@ -8776,6 +9608,13 @@ __metadata: languageName: node linkType: hard +"is-plain-obj@npm:^2.0.0": + version: 2.1.0 + resolution: "is-plain-obj@npm:2.1.0" + checksum: cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa + languageName: node + linkType: hard + "is-plain-object@npm:^5.0.0": version: 5.0.0 resolution: "is-plain-object@npm:5.0.0" @@ -8955,6 +9794,47 @@ __metadata: languageName: node linkType: hard +"jotai-optics@npm:0.3.2": + version: 0.3.2 + resolution: "jotai-optics@npm:0.3.2" + peerDependencies: + jotai: ">=1.11.0" + optics-ts: "*" + checksum: c46f5faa017d252100eba2da88d87c9871175e545ba5e1b5232a973cc18ea66dbe87e6aa3ff53a960971811bceea832743976a93c7d6c2a9aa6ce58945a9b52f + languageName: node + linkType: hard + +"jotai-x@npm:^1.2.2": + version: 1.2.3 + resolution: "jotai-x@npm:1.2.3" + peerDependencies: + "@types/react": ">=17.0.0" + jotai: ">=2.0.0" + react: ">=17.0.0" + peerDependenciesMeta: + "@types/react": + optional: true + react: + optional: true + checksum: 52d42db5370fee2eb9d876636107b2a161b97e6174ec38b031024005747ef9b5aa810b7f99781844d810311c7ee7356ff072c4055814144bfa864b5957e445c5 + languageName: node + linkType: hard + +"jotai@npm:^2.7.1": + version: 2.8.0 + resolution: "jotai@npm:2.8.0" + peerDependencies: + "@types/react": ">=17.0.0" + react: ">=17.0.0" + peerDependenciesMeta: + "@types/react": + optional: true + react: + optional: true + checksum: b24e7676fb659e72fcd6ccd57b1e120b80fa9172353e5d9e9f980b29d4d176238e3fd0c1b555c51476a0a8dc0d2ea391c6b2840d3e7bfb315892e8a621fd8dfb + languageName: node + linkType: hard + "js-base64@npm:^3.7.2": version: 3.7.5 resolution: "js-base64@npm:3.7.5" @@ -8983,6 +9863,13 @@ __metadata: languageName: node linkType: hard +"js-video-url-parser@npm:^0.5.1": + version: 0.5.1 + resolution: "js-video-url-parser@npm:0.5.1" + checksum: dc8f32fee85f9fd6fbc7ad865eef668aeed2806159b4cc867c4d7ad64e90c20606a264f82f9cf0cddf785f45d74e10255e8f597cd75059620ec18854ffd3a624 + languageName: node + linkType: hard + "js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" @@ -9223,6 +10110,13 @@ __metadata: languageName: node linkType: hard +"lodash.mapvalues@npm:^4.6.0": + version: 4.6.0 + resolution: "lodash.mapvalues@npm:4.6.0" + checksum: 0ff1b252fda318fc36e47c296984925e98fbb0fc5a2ecc4ef458f3c739a9476d47e40c95ac653e8314d132aa59c746d4276527b99d6e271940555c6e12d2babd + languageName: node + linkType: hard + "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -9247,7 +10141,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.4, lodash@npm:~4.17.15": +"lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.15": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -9373,6 +10267,26 @@ __metadata: languageName: node linkType: hard +"mdast-util-from-markdown@npm:^0.8.0": + version: 0.8.5 + resolution: "mdast-util-from-markdown@npm:0.8.5" + dependencies: + "@types/mdast": ^3.0.0 + mdast-util-to-string: ^2.0.0 + micromark: ~2.11.0 + parse-entities: ^2.0.0 + unist-util-stringify-position: ^2.0.0 + checksum: 5a9d0d753a42db763761e874c22365d0c7c9934a5a18b5ff76a0643610108a208a041ffdb2f3d3dd1863d3d915225a4020a0aade282af0facfd0df110601eee6 + languageName: node + linkType: hard + +"mdast-util-to-string@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-to-string@npm:2.0.0" + checksum: 0b2113ada10e002fbccb014170506dabe2f2ddacaacbe4bc1045c33f986652c5a162732a2c057c5335cdb58419e2ad23e368e5be226855d4d4e280b81c4e9ec2 + languageName: node + linkType: hard + "memoize-one@npm:^6.0.0": version: 6.0.0 resolution: "memoize-one@npm:6.0.0" @@ -9394,6 +10308,16 @@ __metadata: languageName: node linkType: hard +"micromark@npm:~2.11.0": + version: 2.11.4 + resolution: "micromark@npm:2.11.4" + dependencies: + debug: ^4.0.0 + parse-entities: ^2.0.0 + checksum: f8a5477d394908a5d770227aea71657a76423d420227c67ea0699e659a5f62eb39d504c1f7d69ec525a6af5aaeb6a7bffcdba95614968c03d41d3851edecb0d6 + languageName: node + linkType: hard + "micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": version: 4.0.5 resolution: "micromatch@npm:4.0.5" @@ -9880,6 +10804,13 @@ __metadata: languageName: node linkType: hard +"optics-ts@npm:2.4.1": + version: 2.4.1 + resolution: "optics-ts@npm:2.4.1" + checksum: 6c2289aa54521617b79e314b4bd97d7ad03838a2b27662a93b76d1d48814a8ae6d1ae547d7f167d5093f8acba4630eadadaeb32a8d2b35ba1a78284760088435 + languageName: node + linkType: hard + "optionator@npm:^0.9.3": version: 0.9.3 resolution: "optionator@npm:0.9.3" @@ -9946,6 +10877,20 @@ __metadata: languageName: node linkType: hard +"parse-entities@npm:^2.0.0": + version: 2.0.0 + resolution: "parse-entities@npm:2.0.0" + dependencies: + character-entities: ^1.0.0 + character-entities-legacy: ^1.0.0 + character-reference-invalid: ^1.0.0 + is-alphanumerical: ^1.0.0 + is-decimal: ^1.0.0 + is-hexadecimal: ^1.0.0 + checksum: 7addfd3e7d747521afac33c8121a5f23043c6973809756920d37e806639b4898385d386fcf4b3c8e2ecf1bc28aac5ae97df0b112d5042034efbe80f44081ebce + languageName: node + linkType: hard + "parse-json@npm:^5.0.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" @@ -10040,6 +10985,13 @@ __metadata: languageName: node linkType: hard +"performance-now@npm:^2.1.0": + version: 2.1.0 + resolution: "performance-now@npm:2.1.0" + checksum: 534e641aa8f7cba160f0afec0599b6cecefbb516a2e837b512be0adbe6c1da5550e89c78059c7fabc5c9ffdf6627edabe23eb7c518c4500067a898fa65c2b550 + languageName: node + linkType: hard + "pg-cloudflare@npm:^1.1.1": version: 1.1.1 resolution: "pg-cloudflare@npm:1.1.1" @@ -10333,6 +11285,13 @@ __metadata: languageName: node linkType: hard +"prismjs@npm:^1.29.0": + version: 1.29.0 + resolution: "prismjs@npm:1.29.0" + checksum: 007a8869d4456ff8049dc59404e32d5666a07d99c3b0e30a18bd3b7676dfa07d1daae9d0f407f20983865fd8da56de91d09cb08e6aa61f5bc420a27c0beeaf93 + languageName: node + linkType: hard + "process-nextick-args@npm:^2.0.1, process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" @@ -10386,6 +11345,13 @@ __metadata: languageName: node linkType: hard +"proxy-compare@npm:2.6.0": + version: 2.6.0 + resolution: "proxy-compare@npm:2.6.0" + checksum: 244dc49b45749ebf9dd2c6890e600c16a7d7432a8f535be9dc72db616469685bb5db4bbdb61f211b14c59034b601508f826007715df441d6e3f089b880e265d8 + languageName: node + linkType: hard + "proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -10438,6 +11404,15 @@ __metadata: languageName: node linkType: hard +"raf@npm:^3.4.1": + version: 3.4.1 + resolution: "raf@npm:3.4.1" + dependencies: + performance-now: ^2.1.0 + checksum: 50ba284e481c8185dbcf45fc4618ba3aec580bb50c9121385d5698cb6012fe516d2015b1df6dd407a7b7c58d44be8086108236affbce1861edd6b44637c8cd52 + languageName: node + linkType: hard + "react-aria@npm:^3.31.0": version: 3.31.0 resolution: "react-aria@npm:3.31.0" @@ -10495,6 +11470,40 @@ __metadata: languageName: node linkType: hard +"react-dnd-html5-backend@npm:^16.0.1": + version: 16.0.1 + resolution: "react-dnd-html5-backend@npm:16.0.1" + dependencies: + dnd-core: ^16.0.1 + checksum: e2368bf85d5632a5cd867b743feb54c9052d909ea5331608860fa455edf3c633ac791f5b338e3db29b19ea8670c0ba5fb43c9c1c2510760bea030811d726cdfa + languageName: node + linkType: hard + +"react-dnd@npm:^16.0.1": + version: 16.0.1 + resolution: "react-dnd@npm:16.0.1" + dependencies: + "@react-dnd/invariant": ^4.0.1 + "@react-dnd/shallowequal": ^4.0.1 + dnd-core: ^16.0.1 + fast-deep-equal: ^3.1.3 + hoist-non-react-statics: ^3.3.2 + peerDependencies: + "@types/hoist-non-react-statics": ">= 3.3.1" + "@types/node": ">= 12" + "@types/react": ">= 16" + react: ">= 16.14" + peerDependenciesMeta: + "@types/hoist-non-react-statics": + optional: true + "@types/node": + optional: true + "@types/react": + optional: true + checksum: e8da2186aaafcd5bb41c090a995c963a7c3c73c20991667a2cfc0c800d7f7f73913414b2e61c437cdb6221bb2151bd5174088b8b42c17056a896fc4d1da5729f + languageName: node + linkType: hard + "react-dom@npm:^18.2.0": version: 18.2.0 resolution: "react-dom@npm:18.2.0" @@ -10549,6 +11558,16 @@ __metadata: languageName: node linkType: hard +"react-hotkeys-hook@npm:^4.5.0": + version: 4.5.0 + resolution: "react-hotkeys-hook@npm:4.5.0" + peerDependencies: + react: ">=16.8.1" + react-dom: ">=16.8.1" + checksum: 38e331c729606ad427c852aa45bfa43fe6090c35bf7c98f202599680b81f2614d4a4f565c11c9f4cf41ccc497c1e8001fff0ad2d3a7af78a2cc8e251e30143e0 + languageName: node + linkType: hard + "react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" @@ -10724,6 +11743,26 @@ __metadata: languageName: node linkType: hard +"react-tracked@npm:^1.7.11": + version: 1.7.14 + resolution: "react-tracked@npm:1.7.14" + dependencies: + proxy-compare: 2.6.0 + use-context-selector: 1.4.4 + peerDependencies: + react: ">=16.8.0" + react-dom: "*" + react-native: "*" + scheduler: ">=0.19.0" + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + checksum: a0cf6c58a71b274a5f7169034526aa757dea9c8a5890797b9da23dabdb9c2e7dd47c3a2179a2d2a2c239fabba21c3b50cfc7e9eff99729800f217f2e5404d230 + languageName: node + linkType: hard + "react-transition-group@npm:^4.3.0": version: 4.4.5 resolution: "react-transition-group@npm:4.4.5" @@ -10816,6 +11855,15 @@ __metadata: languageName: node linkType: hard +"redux@npm:^4.2.0": + version: 4.2.1 + resolution: "redux@npm:4.2.1" + dependencies: + "@babel/runtime": ^7.9.2 + checksum: f63b9060c3a1d930ae775252bb6e579b42415aee7a23c4114e21a0b4ba7ec12f0ec76936c00f546893f06e139819f0e2855e0d55ebfce34ca9c026241a6950dd + languageName: node + linkType: hard + "reflect-metadata@npm:^0.1.13": version: 0.1.13 resolution: "reflect-metadata@npm:0.1.13" @@ -10869,6 +11917,15 @@ __metadata: languageName: node linkType: hard +"remark-parse@npm:^9.0.0": + version: 9.0.0 + resolution: "remark-parse@npm:9.0.0" + dependencies: + mdast-util-from-markdown: ^0.8.0 + checksum: 50104880549639b7dd7ae6f1e23c214915fe9c054f02f3328abdaee3f6de6d7282bf4357c3c5b106958fe75e644a3c248c2197755df34f9955e8e028fc74868f + languageName: node + linkType: hard + "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" @@ -11618,6 +12675,13 @@ __metadata: languageName: node linkType: hard +"tabbable@npm:^6.0.1": + version: 6.2.0 + resolution: "tabbable@npm:6.2.0" + checksum: f8440277d223949272c74bb627a3371be21735ca9ad34c2570f7e1752bd646ccfc23a9d8b1ee65d6561243f4134f5fbbf1ad6b39ac3c4b586554accaff4a1300 + languageName: node + linkType: hard + "tailwind-merge@npm:^2.2.0": version: 2.2.0 resolution: "tailwind-merge@npm:2.2.0" @@ -11780,6 +12844,13 @@ __metadata: languageName: node linkType: hard +"trough@npm:^1.0.0": + version: 1.0.5 + resolution: "trough@npm:1.0.5" + checksum: d6c8564903ed00e5258bab92134b020724dbbe83148dc72e4bf6306c03ed8843efa1bcc773fa62410dd89161ecb067432dd5916501793508a9506cacbc408e25 + languageName: node + linkType: hard + "ts-api-utils@npm:^1.0.1": version: 1.0.3 resolution: "ts-api-utils@npm:1.0.3" @@ -11994,6 +13065,20 @@ __metadata: languageName: node linkType: hard +"unified@npm:^9.2.2": + version: 9.2.2 + resolution: "unified@npm:9.2.2" + dependencies: + bail: ^1.0.0 + extend: ^3.0.0 + is-buffer: ^2.0.0 + is-plain-obj: ^2.0.0 + trough: ^1.0.0 + vfile: ^4.0.0 + checksum: 7c24461be7de4145939739ce50d18227c5fbdf9b3bc5a29dabb1ce26dd3e8bd4a1c385865f6f825f3b49230953ee8b591f23beab3bb3643e3e9dc37aa8a089d5 + languageName: node + linkType: hard + "unique-filename@npm:^2.0.0": version: 2.0.1 resolution: "unique-filename@npm:2.0.1" @@ -12012,6 +13097,15 @@ __metadata: languageName: node linkType: hard +"unist-util-stringify-position@npm:^2.0.0": + version: 2.0.3 + resolution: "unist-util-stringify-position@npm:2.0.3" + dependencies: + "@types/unist": ^2.0.2 + checksum: f755cadc959f9074fe999578a1a242761296705a7fe87f333a37c00044de74ab4b184b3812989a57d4cd12211f0b14ad397b327c3a594c7af84361b1c25a7f09 + languageName: node + linkType: hard + "universalify@npm:^0.1.0": version: 0.1.2 resolution: "universalify@npm:0.1.2" @@ -12074,6 +13168,34 @@ __metadata: languageName: node linkType: hard +"use-context-selector@npm:1.4.4": + version: 1.4.4 + resolution: "use-context-selector@npm:1.4.4" + peerDependencies: + react: ">=16.8.0" + react-dom: "*" + react-native: "*" + scheduler: ">=0.19.0" + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + checksum: c1f891a41a6dfadecabf258343ff57ab6caa463ab2e4e38ace8ad72b7e8393e7895411e2edea9c3f9c30371eca096d922db7636414e8c894b8e10c93fa8ac1bd + languageName: node + linkType: hard + +"use-deep-compare@npm:^1.2.1": + version: 1.2.1 + resolution: "use-deep-compare@npm:1.2.1" + dependencies: + dequal: 2.0.3 + peerDependencies: + react: ">=16.8.0" + checksum: f65a880d0cf126484f5a5772c665f7d05ea7834e73d2a76a26c1c6a4101604f9f75fb836903a191ddca9eeafe5f8faa648cc712079046147affa1ea6b4b84d2f + languageName: node + linkType: hard + "use-isomorphic-layout-effect@npm:^1.1.2": version: 1.1.2 resolution: "use-isomorphic-layout-effect@npm:1.1.2" @@ -12102,6 +13224,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:1.2.0": + version: 1.2.0 + resolution: "use-sync-external-store@npm:1.2.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 5c639e0f8da3521d605f59ce5be9e094ca772bd44a4ce7322b055a6f58eeed8dda3c94cabd90c7a41fb6fa852210092008afe48f7038792fd47501f33299116a + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -12127,10 +13258,32 @@ __metadata: languageName: node linkType: hard -"validator@npm:^13.7.0": - version: 13.9.0 - resolution: "validator@npm:13.9.0" - checksum: e2c936f041f61faa42bafd17c6faddf939498666cd82e88d733621c286893730b008959f4cb12ab3e236148a4f3805c30b85e3dcf5e0efd8b0cbcd36c02bfc0c +"validator@npm:^13.11.0, validator@npm:^13.7.0": + version: 13.11.0 + resolution: "validator@npm:13.11.0" + checksum: d1e0c27022681420756da25bc03eb08d5f0c66fb008f8ff02ebc95812b77c6be6e03d3bd05cf80ca702e23eeb73dadd66b4b3683173ea2a0bc7cc72820bee131 + languageName: node + linkType: hard + +"vfile-message@npm:^2.0.0": + version: 2.0.4 + resolution: "vfile-message@npm:2.0.4" + dependencies: + "@types/unist": ^2.0.0 + unist-util-stringify-position: ^2.0.0 + checksum: 1bade499790f46ca5aba04bdce07a1e37c2636a8872e05cf32c26becc912826710b7eb063d30c5754fdfaeedc8a7658e78df10b3bc535c844890ec8a184f5643 + languageName: node + linkType: hard + +"vfile@npm:^4.0.0": + version: 4.2.1 + resolution: "vfile@npm:4.2.1" + dependencies: + "@types/unist": ^2.0.0 + is-buffer: ^2.0.0 + unist-util-stringify-position: ^2.0.0 + vfile-message: ^2.0.0 + checksum: ee5726e10d170472cde778fc22e0f7499caa096eb85babea5d0ce0941455b721037ee1c9e6ae506ca2803250acd313d0f464328ead0b55cfe7cb6315f1b462d6 languageName: node linkType: hard @@ -12562,3 +13715,36 @@ __metadata: checksum: 8a1d66817ae4384dc3f63311f0cccaadd95cc9640eaade5fd3fbf91aa80d6bb82fb95d9b9171fa82ac371a0155b32b7f5f77bbe84dabaca611b66f74c628f0b8 languageName: node linkType: hard + +"zustand-x@npm:^3.0.2": + version: 3.0.2 + resolution: "zustand-x@npm:3.0.2" + dependencies: + immer: ^10.0.3 + lodash.mapvalues: ^4.6.0 + react-tracked: ^1.7.11 + peerDependencies: + zustand: ">=4.3.9" + checksum: c5d3d76ba011f3eca80697ceb80976050205eb7fbff300f4f9f7d3ff0e41a5a02e978ca62dcebc8334ba033bfea687be7e6bd14bc0a79538c71877df647fc907 + languageName: node + linkType: hard + +"zustand@npm:^4.5.2": + version: 4.5.2 + resolution: "zustand@npm:4.5.2" + dependencies: + use-sync-external-store: 1.2.0 + peerDependencies: + "@types/react": ">=16.8" + immer: ">=9.0.6" + react: ">=16.8" + peerDependenciesMeta: + "@types/react": + optional: true + immer: + optional: true + react: + optional: true + checksum: 160052a7faaefbaad1071e890a06e5d7a04f6ff6985def30a7b4471f4ddbdd1d30bb05b3688a2777cd0b717d1f0d98dad24883a5caa3deeb3afb4d83b6dabc55 + languageName: node + linkType: hard From c93e7f7c97f9e9ba5531370834ad988c3dd61959 Mon Sep 17 00:00:00 2001 From: David Matejka Date: Fri, 19 Apr 2024 13:35:08 +0200 Subject: [PATCH 2/5] refactor(playground): slate editor up --- .../admin/app/components/navigation.tsx | 5 +- .../playground/admin/app/pages/editor.tsx | 52 + .../plate-ui/floating-toolbar.tsx | 171 +-- .../plate-ui/link-floating-toolbar.tsx | 11 +- .../plate-ui/turn-into-dropdown-menu.tsx | 2 +- .../admin/lib/components/ui/input.tsx | 15 +- packages/playground/api/index.ts | 11 + .../migrations/2024-04-18-153923-editor.json | 227 ++++ .../api/migrations/2024-04-22-142354-acl.json | 1016 +++++++++++++++++ packages/playground/api/model/Editor.ts | 24 + packages/playground/api/model/index.ts | 1 + packages/playground/package.json | 4 + yarn.lock | 94 +- 13 files changed, 1505 insertions(+), 128 deletions(-) create mode 100644 packages/playground/admin/app/pages/editor.tsx create mode 100644 packages/playground/api/migrations/2024-04-18-153923-editor.json create mode 100644 packages/playground/api/migrations/2024-04-22-142354-acl.json create mode 100644 packages/playground/api/model/Editor.ts diff --git a/packages/playground/admin/app/components/navigation.tsx b/packages/playground/admin/app/components/navigation.tsx index 70d741023..279fb84bd 100644 --- a/packages/playground/admin/app/components/navigation.tsx +++ b/packages/playground/admin/app/components/navigation.tsx @@ -1,5 +1,5 @@ -import { ArchiveIcon, BrushIcon, FormInputIcon, GripVertical, HomeIcon, KanbanIcon, LanguagesIcon, TableIcon, UploadIcon } from 'lucide-react' -import { Menu, MenuItem, MenuList } from '../../lib/components/ui/menu' +import { ArchiveIcon, BrushIcon, FormInputIcon, GripVertical, HomeIcon, KanbanIcon, LanguagesIcon, PencilIcon, TableIcon, UploadIcon } from 'lucide-react' +import { Menu, MenuItem } from '../../lib/components/ui/menu' export const Navigation = () => { @@ -49,6 +49,7 @@ export const Navigation = () => { } label={'Dimensions'} to={'dimensions'} /> + } label={'Editor'} to={'editor'} />
) diff --git a/packages/playground/admin/app/pages/editor.tsx b/packages/playground/admin/app/pages/editor.tsx new file mode 100644 index 000000000..80ba37aaf --- /dev/null +++ b/packages/playground/admin/app/pages/editor.tsx @@ -0,0 +1,52 @@ +import { Binding, PersistButton } from '../../lib/components/binding' +import { Slots } from '../../lib/components/slots' +import { InputField } from '../../lib/components/form' +import * as React from 'react' +import { EntitySubTree, useField } from '@contember/interface' +import { PlateEditor } from '../../lib/components/richt-text-editor/plate-editor' +import { Button } from '../../lib/components/ui/button' + +export default () => <> + + + + + + + + + + + + + + + +const PlateJson = () => { + const data = useField('data') + + return ( +
+			{JSON.stringify(data.value, null, 2)}
+		
+ ) +} + + +const PasteSample = () => { + const data = useField('data') + return +} diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx index 558d0dfb7..3e4ded5a8 100644 --- a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/floating-toolbar.tsx @@ -1,122 +1,59 @@ -import { DropdownMenuProps } from '@radix-ui/react-dropdown-menu' -import { - collapseSelection, - findNode, - focusEditor, - isBlock, - isCollapsed, - TElement, - toggleNodeType, - useEditorRef, - useEditorSelector, -} from '@udecode/plate-common' -import { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading' -import { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph' -import { Heading1Icon, Heading2Icon, Heading3Icon, PilcrowIcon } from 'lucide-react' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuLabel, - DropdownMenuRadioGroup, - DropdownMenuRadioItem, - DropdownMenuTrigger, -} from '../../ui/dropdown' -import { useOpenState } from '../lib/helpers' -import { ToolbarButton } from './toolbar' +import React from 'react' +import { withRef } from '@udecode/cn' +import { PortalBody, useComposedRef } from '@udecode/plate-common' +import { flip, FloatingToolbarState, offset, useFloatingToolbar, useFloatingToolbarState } from '@udecode/plate-floating' -const items = [ - { - value: ELEMENT_PARAGRAPH, - label: 'Paragraph', - description: 'Paragraph', - icon: PilcrowIcon, - }, - { - value: ELEMENT_H1, - label: 'Heading 1', - description: 'Heading 1', - icon: Heading1Icon, - }, - { - value: ELEMENT_H2, - label: 'Heading 2', - description: 'Heading 2', - icon: Heading2Icon, - }, - { - value: ELEMENT_H3, - label: 'Heading 3', - description: 'Heading 3', - icon: Heading3Icon, - }, -] - -const defaultItem = items.find(item => item.value === ELEMENT_PARAGRAPH)! - -export function TurnIntoDropdownMenu(props: DropdownMenuProps) { - const value: string = useEditorSelector(editor => { - if (isCollapsed(editor.selection)) { - const entry = findNode(editor, { - match: n => isBlock(editor, n), - }) - - if (entry) { - return ( - items.find(item => item.value === entry[0].type)?.value ?? - ELEMENT_PARAGRAPH - ) - } - } +import { Toolbar } from './toolbar' +import { cn } from '../../../utils/cn' - return ELEMENT_PARAGRAPH - }, []) - - const editor = useEditorRef() - const openState = useOpenState() - - const selectedItem = - items.find(item => item.value === value) ?? defaultItem - const { icon: SelectedItemIcon, label: selectedItemLabel } = selectedItem +export const FloatingToolbar = withRef< + typeof Toolbar, + { + state?: FloatingToolbarState; + } +>(({ state, children, ...props }, componentRef) => { + const floatingToolbarState = useFloatingToolbarState({ + ...state, + floatingOptions: { + placement: 'top', + middleware: [ + offset(12), + flip({ + padding: 12, + fallbackPlacements: [ + 'top-start', + 'top-end', + 'bottom-start', + 'bottom-end', + ], + }), + ], + ...state?.floatingOptions, + }, + }) + + const { + ref: floatingRef, + props: rootProps, + hidden, + } = useFloatingToolbar(floatingToolbarState) + + const ref = useComposedRef(componentRef, floatingRef) + + if (hidden) return null return ( - - - - - {selectedItemLabel} - - - - - Turn into - - { - toggleNodeType(editor, { activeType: type }) - - collapseSelection(editor) - focusEditor(editor) - }} - > - {items.map(({ value: itemValue, label, icon: Icon }) => ( - - - {label} - - ))} - - - + + + {children} + + ) -} +}) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx index ddf9c2d64..518a43543 100644 --- a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/link-floating-toolbar.tsx @@ -11,10 +11,11 @@ import { } from '@udecode/plate-link' import { ExternalLinkIcon, LinkIcon, TextIcon, UnlinkIcon } from 'lucide-react' import { Button, buttonConfig } from '../../ui/button' -import { Input } from '../../ui/input' +import { Input, inputConfig } from '../../ui/input' import { popoverVariants } from './popover' import { Separator } from './separator' +import { uic } from '../../../utils/uic' const floatingOptions: UseVirtualFloatingOptions = { placement: 'bottom-start', @@ -31,6 +32,10 @@ export interface LinkFloatingToolbarProps { state?: LinkFloatingToolbarState; } +const FloatingLinkUrlInputUi = uic(FloatingLinkUrlInput, { + ...inputConfig, +}) + export function LinkFloatingToolbar({ state }: LinkFloatingToolbarProps) { const insertState = useFloatingLinkInsertState({ ...state, @@ -69,8 +74,10 @@ export function LinkFloatingToolbar({ state }: LinkFloatingToolbarProps) {
-
diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx index 558d0dfb7..83158faea 100644 --- a/packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-ui/turn-into-dropdown-menu.tsx @@ -57,7 +57,7 @@ export function TurnIntoDropdownMenu(props: DropdownMenuProps) { const value: string = useEditorSelector(editor => { if (isCollapsed(editor.selection)) { const entry = findNode(editor, { - match: n => isBlock(editor, n), + match: (n: any) => isBlock(editor, n), }) if (entry) { diff --git a/packages/playground/admin/lib/components/ui/input.tsx b/packages/playground/admin/lib/components/ui/input.tsx index 77aac7307..39b1306e7 100644 --- a/packages/playground/admin/lib/components/ui/input.tsx +++ b/packages/playground/admin/lib/components/ui/input.tsx @@ -1,16 +1,25 @@ -import { uic } from '../../../lib/utils/uic' +import { uic, uiconfig } from '../../../lib/utils/uic' -export const Input = uic('input', { - baseClass: 'flex w-full border border-input bg-background ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[invalid]:border-destructive data-[invalid]:ring-destructive', +export const inputConfig = uiconfig({ + baseClass: 'flex w-full border bg-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 data-[invalid]:border-destructive data-[invalid]:ring-destructive', variants: { + variant: { + default: 'border border-input ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', + ghost: 'border-none focus-visible:ring-transparent', + }, inputSize: { default: 'h-10 rounded-md p-2 text-sm', sm: 'h-8 rounded p-1 text-sm', }, }, defaultVariants: { + variant: 'default', inputSize: 'default', }, +}) + +export const Input = uic('input', { + ...inputConfig, displayName: 'Input', }) diff --git a/packages/playground/api/index.ts b/packages/playground/api/index.ts index 3a3ca97d6..d9ef4bca5 100644 --- a/packages/playground/api/index.ts +++ b/packages/playground/api/index.ts @@ -1,7 +1,18 @@ import { createSchema, settingsPresets } from '@contember/schema-definition' import * as model from './model' +import { AllowAllPermissionFactory } from '@contember/schema-utils' export default createSchema(model, schema => ({ ...schema, + acl: { + ...schema.acl, + roles: { + ...schema.acl.roles, + admin: { + entities: new AllowAllPermissionFactory().create(schema.model, true), + variables: {}, + }, + }, + }, settings: settingsPresets['v1.3'], })) diff --git a/packages/playground/api/migrations/2024-04-18-153923-editor.json b/packages/playground/api/migrations/2024-04-18-153923-editor.json new file mode 100644 index 000000000..7cb12e26a --- /dev/null +++ b/packages/playground/api/migrations/2024-04-18-153923-editor.json @@ -0,0 +1,227 @@ +{ + "formatVersion": 5, + "modifications": [ + { + "modification": "createEnum", + "enumName": "EditorReferenceType", + "values": [ + "image", + "link" + ] + }, + { + "modification": "createEnum", + "enumName": "EditorContentUnique", + "values": [ + "unique" + ] + }, + { + "modification": "createEntity", + "entity": { + "name": "EditorContent", + "primary": "id", + "primaryColumn": "id", + "tableName": "editor_content", + "fields": { + "id": { + "name": "id", + "columnName": "id", + "columnType": "uuid", + "nullable": false, + "type": "Uuid" + } + }, + "unique": [], + "indexes": [], + "eventLog": { + "enabled": true + } + } + }, + { + "modification": "createEntity", + "entity": { + "name": "EditorImage", + "primary": "id", + "primaryColumn": "id", + "tableName": "editor_image", + "fields": { + "id": { + "name": "id", + "columnName": "id", + "columnType": "uuid", + "nullable": false, + "type": "Uuid" + } + }, + "unique": [], + "indexes": [], + "eventLog": { + "enabled": true + } + } + }, + { + "modification": "createEntity", + "entity": { + "name": "EditorLink", + "primary": "id", + "primaryColumn": "id", + "tableName": "editor_link", + "fields": { + "id": { + "name": "id", + "columnName": "id", + "columnType": "uuid", + "nullable": false, + "type": "Uuid" + } + }, + "unique": [], + "indexes": [], + "eventLog": { + "enabled": true + } + } + }, + { + "modification": "createEntity", + "entity": { + "name": "EditorReference", + "primary": "id", + "primaryColumn": "id", + "tableName": "editor_reference", + "fields": { + "id": { + "name": "id", + "columnName": "id", + "columnType": "uuid", + "nullable": false, + "type": "Uuid" + } + }, + "unique": [], + "indexes": [], + "eventLog": { + "enabled": true + } + } + }, + { + "modification": "createColumn", + "entityName": "EditorContent", + "field": { + "name": "unique", + "columnName": "unique", + "columnType": "EditorContentUnique", + "nullable": false, + "type": "Enum", + "default": "unique" + }, + "fillValue": "unique" + }, + { + "modification": "createColumn", + "entityName": "EditorContent", + "field": { + "name": "data", + "columnName": "data", + "columnType": "jsonb", + "nullable": false, + "type": "Json" + } + }, + { + "modification": "createColumn", + "entityName": "EditorImage", + "field": { + "name": "url", + "columnName": "url", + "columnType": "text", + "nullable": false, + "type": "String" + } + }, + { + "modification": "createColumn", + "entityName": "EditorLink", + "field": { + "name": "url", + "columnName": "url", + "columnType": "text", + "nullable": false, + "type": "String" + } + }, + { + "modification": "createColumn", + "entityName": "EditorReference", + "field": { + "name": "type", + "columnName": "type", + "columnType": "EditorReferenceType", + "nullable": false, + "type": "Enum" + } + }, + { + "modification": "createRelation", + "entityName": "EditorReference", + "owningSide": { + "type": "ManyHasOne", + "name": "content", + "target": "EditorContent", + "joiningColumn": { + "columnName": "content_id", + "onDelete": "restrict" + }, + "nullable": false, + "inversedBy": "references" + }, + "inverseSide": { + "type": "OneHasMany", + "name": "references", + "target": "EditorReference", + "ownedBy": "content" + } + }, + { + "modification": "createRelation", + "entityName": "EditorReference", + "owningSide": { + "type": "ManyHasOne", + "name": "image", + "target": "EditorImage", + "joiningColumn": { + "columnName": "image_id", + "onDelete": "restrict" + }, + "nullable": true + } + }, + { + "modification": "createRelation", + "entityName": "EditorReference", + "owningSide": { + "type": "ManyHasOne", + "name": "link", + "target": "EditorLink", + "joiningColumn": { + "columnName": "link_id", + "onDelete": "restrict" + }, + "nullable": true + } + }, + { + "modification": "createUniqueConstraint", + "entityName": "EditorContent", + "unique": { + "fields": [ + "unique" + ] + } + } + ] +} diff --git a/packages/playground/api/migrations/2024-04-22-142354-acl.json b/packages/playground/api/migrations/2024-04-22-142354-acl.json new file mode 100644 index 000000000..f8bddfad0 --- /dev/null +++ b/packages/playground/api/migrations/2024-04-22-142354-acl.json @@ -0,0 +1,1016 @@ +{ + "formatVersion": 5, + "modifications": [ + { + "modification": "patchAclSchema", + "patch": [ + { + "op": "add", + "path": "/roles/admin", + "value": { + "entities": { + "Block": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "list": true, + "order": true, + "type": true, + "title": true, + "content": true, + "image": true, + "imagePosition": true, + "color": true + }, + "create": { + "id": true, + "list": true, + "order": true, + "type": true, + "title": true, + "content": true, + "image": true, + "imagePosition": true, + "color": true + }, + "update": { + "id": true, + "list": true, + "order": true, + "type": true, + "title": true, + "content": true, + "image": true, + "imagePosition": true, + "color": true + }, + "delete": true, + "customPrimary": true + } + }, + "BlockImage": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "url": true + }, + "create": { + "id": true, + "url": true + }, + "update": { + "id": true, + "url": true + }, + "delete": true, + "customPrimary": true + } + }, + "BlockList": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "unique": true, + "blocks": true + }, + "create": { + "id": true, + "unique": true, + "blocks": true + }, + "update": { + "id": true, + "unique": true, + "blocks": true + }, + "delete": true, + "customPrimary": true + } + }, + "BoardTag": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "name": true, + "slug": true, + "color": true + }, + "create": { + "id": true, + "name": true, + "slug": true, + "color": true + }, + "update": { + "id": true, + "name": true, + "slug": true, + "color": true + }, + "delete": true, + "customPrimary": true + } + }, + "BoardTask": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "title": true, + "description": true, + "status": true, + "assignee": true, + "tags": true, + "order": true + }, + "create": { + "id": true, + "title": true, + "description": true, + "status": true, + "assignee": true, + "tags": true, + "order": true + }, + "update": { + "id": true, + "title": true, + "description": true, + "status": true, + "assignee": true, + "tags": true, + "order": true + }, + "delete": true, + "customPrimary": true + } + }, + "BoardUser": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "name": true, + "username": true, + "order": true + }, + "create": { + "id": true, + "name": true, + "username": true, + "order": true + }, + "update": { + "id": true, + "name": true, + "username": true, + "order": true + }, + "delete": true, + "customPrimary": true + } + }, + "DimensionsItem": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "unique": true, + "locales": true + }, + "create": { + "id": true, + "unique": true, + "locales": true + }, + "update": { + "id": true, + "unique": true, + "locales": true + }, + "delete": true, + "customPrimary": true + } + }, + "DimensionsItemLocale": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "item": true, + "locale": true, + "title": true, + "content": true + }, + "create": { + "id": true, + "item": true, + "locale": true, + "title": true, + "content": true + }, + "update": { + "id": true, + "item": true, + "locale": true, + "title": true, + "content": true + }, + "delete": true, + "customPrimary": true + } + }, + "DimensionsLocale": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "code": true, + "label": true + }, + "create": { + "id": true, + "code": true, + "label": true + }, + "update": { + "id": true, + "code": true, + "label": true + }, + "delete": true, + "customPrimary": true + } + }, + "EditorContent": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "unique": true, + "data": true, + "references": true + }, + "create": { + "id": true, + "unique": true, + "data": true, + "references": true + }, + "update": { + "id": true, + "unique": true, + "data": true, + "references": true + }, + "delete": true, + "customPrimary": true + } + }, + "EditorImage": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "url": true + }, + "create": { + "id": true, + "url": true + }, + "update": { + "id": true, + "url": true + }, + "delete": true, + "customPrimary": true + } + }, + "EditorLink": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "url": true + }, + "create": { + "id": true, + "url": true + }, + "update": { + "id": true, + "url": true + }, + "delete": true, + "customPrimary": true + } + }, + "EditorReference": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "content": true, + "type": true, + "image": true, + "link": true + }, + "create": { + "id": true, + "content": true, + "type": true, + "image": true, + "link": true + }, + "update": { + "id": true, + "content": true, + "type": true, + "image": true, + "link": true + }, + "delete": true, + "customPrimary": true + } + }, + "GridArticle": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "title": true, + "slug": true, + "state": true, + "locked": true, + "publishedAt": true, + "publishDate": true, + "author": true, + "category": true, + "tags": true, + "views": true, + "comments": true + }, + "create": { + "id": true, + "title": true, + "slug": true, + "state": true, + "locked": true, + "publishedAt": true, + "publishDate": true, + "author": true, + "category": true, + "tags": true, + "views": true, + "comments": true + }, + "update": { + "id": true, + "title": true, + "slug": true, + "state": true, + "locked": true, + "publishedAt": true, + "publishDate": true, + "author": true, + "category": true, + "tags": true, + "views": true, + "comments": true + }, + "delete": true, + "customPrimary": true + } + }, + "GridArticleComment": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "article": true, + "author": true, + "content": true, + "createdAt": true + }, + "create": { + "id": true, + "article": true, + "author": true, + "content": true, + "createdAt": true + }, + "update": { + "id": true, + "article": true, + "author": true, + "content": true, + "createdAt": true + }, + "delete": true, + "customPrimary": true + } + }, + "GridAuthor": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "name": true, + "slug": true + }, + "create": { + "id": true, + "name": true, + "slug": true + }, + "update": { + "id": true, + "name": true, + "slug": true + }, + "delete": true, + "customPrimary": true + } + }, + "GridCategory": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "name": true, + "slug": true + }, + "create": { + "id": true, + "name": true, + "slug": true + }, + "update": { + "id": true, + "name": true, + "slug": true + }, + "delete": true, + "customPrimary": true + } + }, + "GridTag": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "name": true, + "slug": true + }, + "create": { + "id": true, + "name": true, + "slug": true + }, + "update": { + "id": true, + "name": true, + "slug": true + }, + "delete": true, + "customPrimary": true + } + }, + "InputRoot": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "unique": true, + "textValue": true, + "intValue": true, + "floatValue": true, + "boolValue": true, + "dateValue": true, + "datetimeValue": true, + "jsonValue": true, + "enumValue": true, + "uuidValue": true + }, + "create": { + "id": true, + "unique": true, + "textValue": true, + "intValue": true, + "floatValue": true, + "boolValue": true, + "dateValue": true, + "datetimeValue": true, + "jsonValue": true, + "enumValue": true, + "uuidValue": true + }, + "update": { + "id": true, + "unique": true, + "textValue": true, + "intValue": true, + "floatValue": true, + "boolValue": true, + "dateValue": true, + "datetimeValue": true, + "jsonValue": true, + "enumValue": true, + "uuidValue": true + }, + "delete": true, + "customPrimary": true + } + }, + "InputRules": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "unique": true, + "notNullValue": true, + "uniqueValue": true, + "validationValue": true + }, + "create": { + "id": true, + "unique": true, + "notNullValue": true, + "uniqueValue": true, + "validationValue": true + }, + "update": { + "id": true, + "unique": true, + "notNullValue": true, + "uniqueValue": true, + "validationValue": true + }, + "delete": true, + "customPrimary": true + } + }, + "RepeaterItem": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "title": true, + "order": true + }, + "create": { + "id": true, + "title": true, + "order": true + }, + "update": { + "id": true, + "title": true, + "order": true + }, + "delete": true, + "customPrimary": true + } + }, + "SelectItem": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "root": true, + "value": true, + "order": true + }, + "create": { + "id": true, + "root": true, + "value": true, + "order": true + }, + "update": { + "id": true, + "root": true, + "value": true, + "order": true + }, + "delete": true, + "customPrimary": true + } + }, + "SelectRoot": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "unique": true, + "hasOne": true, + "hasMany": true, + "hasManySorted": true + }, + "create": { + "id": true, + "unique": true, + "hasOne": true, + "hasMany": true, + "hasManySorted": true + }, + "update": { + "id": true, + "unique": true, + "hasOne": true, + "hasMany": true, + "hasManySorted": true + }, + "delete": true, + "customPrimary": true + } + }, + "SelectValue": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "name": true, + "slug": true + }, + "create": { + "id": true, + "name": true, + "slug": true + }, + "update": { + "id": true, + "name": true, + "slug": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadAudio": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "url": true, + "duration": true, + "meta": true + }, + "create": { + "id": true, + "url": true, + "duration": true, + "meta": true + }, + "update": { + "id": true, + "url": true, + "duration": true, + "meta": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadFile": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "url": true, + "meta": true + }, + "create": { + "id": true, + "url": true, + "meta": true + }, + "update": { + "id": true, + "url": true, + "meta": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadFileMetadata": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "fileName": true, + "lastModified": true, + "fileSize": true, + "fileType": true + }, + "create": { + "id": true, + "fileName": true, + "lastModified": true, + "fileSize": true, + "fileType": true + }, + "update": { + "id": true, + "fileName": true, + "lastModified": true, + "fileSize": true, + "fileType": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadGallery": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "items": true + }, + "create": { + "id": true, + "items": true + }, + "update": { + "id": true, + "items": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadGalleryItem": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "gallery": true, + "type": true, + "image": true, + "video": true, + "audio": true, + "file": true + }, + "create": { + "id": true, + "gallery": true, + "type": true, + "image": true, + "video": true, + "audio": true, + "file": true + }, + "update": { + "id": true, + "gallery": true, + "type": true, + "image": true, + "video": true, + "audio": true, + "file": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadImage": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "url": true, + "width": true, + "height": true, + "alt": true, + "meta": true + }, + "create": { + "id": true, + "url": true, + "width": true, + "height": true, + "alt": true, + "meta": true + }, + "update": { + "id": true, + "url": true, + "width": true, + "height": true, + "alt": true, + "meta": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadImageList": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "items": true + }, + "create": { + "id": true, + "items": true + }, + "update": { + "id": true, + "items": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadImageListItem": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "list": true, + "order": true, + "image": true + }, + "create": { + "id": true, + "list": true, + "order": true, + "image": true + }, + "update": { + "id": true, + "list": true, + "order": true, + "image": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadList": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "items": true + }, + "create": { + "id": true, + "items": true + }, + "update": { + "id": true, + "items": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadListItem": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "list": true, + "order": true, + "item": true + }, + "create": { + "id": true, + "list": true, + "order": true, + "item": true + }, + "update": { + "id": true, + "list": true, + "order": true, + "item": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadMedium": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "type": true, + "image": true, + "video": true, + "audio": true, + "file": true + }, + "create": { + "id": true, + "type": true, + "image": true, + "video": true, + "audio": true, + "file": true + }, + "update": { + "id": true, + "type": true, + "image": true, + "video": true, + "audio": true, + "file": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadRoot": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "unique": true, + "image": true, + "audio": true, + "video": true, + "file": true, + "imageTrivial": true, + "imageList": true, + "medium": true, + "gallery": true, + "list": true + }, + "create": { + "id": true, + "unique": true, + "image": true, + "audio": true, + "video": true, + "file": true, + "imageTrivial": true, + "imageList": true, + "medium": true, + "gallery": true, + "list": true + }, + "update": { + "id": true, + "unique": true, + "image": true, + "audio": true, + "video": true, + "file": true, + "imageTrivial": true, + "imageList": true, + "medium": true, + "gallery": true, + "list": true + }, + "delete": true, + "customPrimary": true + } + }, + "UploadVideo": { + "predicates": {}, + "operations": { + "read": { + "id": true, + "url": true, + "width": true, + "height": true, + "duration": true, + "meta": true + }, + "create": { + "id": true, + "url": true, + "width": true, + "height": true, + "duration": true, + "meta": true + }, + "update": { + "id": true, + "url": true, + "width": true, + "height": true, + "duration": true, + "meta": true + }, + "delete": true, + "customPrimary": true + } + } + }, + "variables": {} + } + } + ] + } + ] +} diff --git a/packages/playground/api/model/Editor.ts b/packages/playground/api/model/Editor.ts new file mode 100644 index 000000000..930a656ed --- /dev/null +++ b/packages/playground/api/model/Editor.ts @@ -0,0 +1,24 @@ +import { c } from '@contember/schema-definition' + +export class EditorContent { + unique = c.enumColumn(c.createEnum('unique')).unique().notNull().default('unique') + data = c.jsonColumn().notNull() + references = c.oneHasMany(EditorReference, 'content') +} + +export const EditorReferenceType = c.createEnum('image', 'link') + +export class EditorReference { + content = c.manyHasOne(EditorContent, 'references').notNull() + type = c.enumColumn(EditorReferenceType).notNull() + image = c.manyHasOne(EditorImage) + link = c.manyHasOne(EditorLink) +} + +export class EditorImage { + url = c.stringColumn().notNull() +} + +export class EditorLink { + url = c.stringColumn().notNull() +} diff --git a/packages/playground/api/model/index.ts b/packages/playground/api/model/index.ts index 4fa13bf7c..7dbd1c1c8 100644 --- a/packages/playground/api/model/index.ts +++ b/packages/playground/api/model/index.ts @@ -1,6 +1,7 @@ export * from './Blocks' export * from './Board' export * from './Dimensions' +export * from './Editor' export * from './Grid' export * from './Repeater' export * from './Input' diff --git a/packages/playground/package.json b/packages/playground/package.json index 02d87d3f9..fbdb01798 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -75,6 +75,10 @@ "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.2.0", "react-twc": "^1.3.0", + "slate": "^0.102.0", + "slate-history": "^0.100.0", + "slate-hyperscript": "^0.100.0", + "slate-react": "^0.102.0", "tailwind-merge": "^2.2.0", "tailwindcss": "^3", "tailwindcss-animate": "^1.0.7" diff --git a/yarn.lock b/yarn.lock index 51b58fd24..10c514145 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1342,6 +1342,10 @@ __metadata: react-dnd-html5-backend: ^16.0.1 react-dom: ^18.2.0 react-twc: ^1.3.0 + slate: ^0.102.0 + slate-history: ^0.100.0 + slate-hyperscript: ^0.100.0 + slate-react: ^0.102.0 tailwind-merge: ^2.2.0 tailwindcss: ^3 tailwindcss-animate: ^1.0.7 @@ -2637,6 +2641,13 @@ __metadata: languageName: node linkType: hard +"@juggle/resize-observer@npm:^3.4.0": + version: 3.4.0 + resolution: "@juggle/resize-observer@npm:3.4.0" + checksum: 2505028c05cc2e17639fcad06218b1c4b60f932a4ebb4b41ab546ef8c157031ae377e3f560903801f6d01706dbefd4943b6c4704bf19ed86dfa1c62f1473a570 + languageName: node + linkType: hard + "@microsoft/api-extractor-model@npm:7.28.3": version: 7.28.3 resolution: "@microsoft/api-extractor-model@npm:7.28.3" @@ -5959,7 +5970,7 @@ __metadata: languageName: node linkType: hard -"@types/is-hotkey@npm:0.1.10, @types/is-hotkey@npm:^0.1.1": +"@types/is-hotkey@npm:0.1.10, @types/is-hotkey@npm:^0.1.1, @types/is-hotkey@npm:^0.1.8": version: 0.1.10 resolution: "@types/is-hotkey@npm:0.1.10" checksum: 9ecc49fb3822b3cfa8335132d54c6e577d0b14bb52d0bf1f817cdd19c442555b7523945e2ae72f6098e3c7f64b4777390f38afec3e4660343cfb471377e7fd82 @@ -6007,6 +6018,13 @@ __metadata: languageName: node linkType: hard +"@types/lodash@npm:^4.14.200": + version: 4.17.0 + resolution: "@types/lodash@npm:4.17.0" + checksum: 3f98c0b67a93994cbc3403d4fa9dbaf52b0b6bb7f07a764d73875c2dcd5ef91222621bd5bcf8eee7b417a74d175c2f7191b9f595f8603956fd06f0674c0cba93 + languageName: node + linkType: hard + "@types/mdast@npm:^3.0.0": version: 3.0.15 resolution: "@types/mdast@npm:3.0.15" @@ -7718,7 +7736,7 @@ __metadata: languageName: node linkType: hard -"compute-scroll-into-view@npm:^3.0.3": +"compute-scroll-into-view@npm:^3.0.2, compute-scroll-into-view@npm:^3.0.3": version: 3.1.0 resolution: "compute-scroll-into-view@npm:3.1.0" checksum: 224549d6dd1d40342230de5c6d69cac5c3ed5c2f6a4437310f959aadc8db1d20b03da44a6e0de14d9419c6f9130ce51ec99a91b11bde55d4640f10551c89c213 @@ -8007,7 +8025,7 @@ __metadata: languageName: node linkType: hard -"direction@npm:^1.0.3": +"direction@npm:^1.0.3, direction@npm:^1.0.4": version: 1.0.4 resolution: "direction@npm:1.0.4" bin: @@ -12194,6 +12212,15 @@ __metadata: languageName: node linkType: hard +"scroll-into-view-if-needed@npm:^3.1.0": + version: 3.1.0 + resolution: "scroll-into-view-if-needed@npm:3.1.0" + dependencies: + compute-scroll-into-view: ^3.0.2 + checksum: edc0f68dc170d0c153ce4ae2929cbdfaf3426d1fc842b67d5f092c5ec38fbb8408e6cb8467f86d8dfb23de3f77a2f2a9e79cbf80bc49b35a39f3092e18b4c3d5 + languageName: node + linkType: hard + "semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -12322,6 +12349,28 @@ __metadata: languageName: node linkType: hard +"slate-history@npm:^0.100.0": + version: 0.100.0 + resolution: "slate-history@npm:0.100.0" + dependencies: + is-plain-object: ^5.0.0 + peerDependencies: + slate: ">=0.65.3" + checksum: 266973817861489b2c85a55c29c02f092c639d01660d1d4636384f9cce097ad91eac9664a02170b33d99b629619fe29a61b183c65cb325385dadd8e8e1f4b9e4 + languageName: node + linkType: hard + +"slate-hyperscript@npm:^0.100.0": + version: 0.100.0 + resolution: "slate-hyperscript@npm:0.100.0" + dependencies: + is-plain-object: ^5.0.0 + peerDependencies: + slate: ">=0.65.3" + checksum: 25c88fea4b9c6a8a57b2b6d5b1151190af815e84ebed76f43cc3c13b4831f26f55196a2a85a832692f3b6c9937aa9e75ee5db92fa603522c3ebdeecc692ff908 + languageName: node + linkType: hard + "slate-react@npm:0.74.2": version: 0.74.2 resolution: "slate-react@npm:0.74.2" @@ -12342,6 +12391,27 @@ __metadata: languageName: node linkType: hard +"slate-react@npm:^0.102.0": + version: 0.102.0 + resolution: "slate-react@npm:0.102.0" + dependencies: + "@juggle/resize-observer": ^3.4.0 + "@types/is-hotkey": ^0.1.8 + "@types/lodash": ^4.14.200 + direction: ^1.0.4 + is-hotkey: ^0.2.0 + is-plain-object: ^5.0.0 + lodash: ^4.17.21 + scroll-into-view-if-needed: ^3.1.0 + tiny-invariant: 1.3.1 + peerDependencies: + react: ">=18.2.0" + react-dom: ">=18.2.0" + slate: ">=0.99.0" + checksum: ac7248a0be1b258a01c12c19cfa974f3645bf0c0cc0ada5e6271cf6ba6ba2e1a26d9d4e062c4d9b3e4c0947c361269eca54e864d8717113e910feed1193edbd8 + languageName: node + linkType: hard + "slate@npm:0.73.1": version: 0.73.1 resolution: "slate@npm:0.73.1" @@ -12353,6 +12423,17 @@ __metadata: languageName: node linkType: hard +"slate@npm:^0.102.0": + version: 0.102.0 + resolution: "slate@npm:0.102.0" + dependencies: + immer: ^10.0.3 + is-plain-object: ^5.0.0 + tiny-warning: ^1.0.3 + checksum: 69bb9160c24342804a3771d9ef69d9f58749b361181576a58b60e8fdcdfe3ee4f8afddb4745f5b3cd7e1d99af0ff949586c5720d1c15c600f4e121a59a488369 + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -12779,6 +12860,13 @@ __metadata: languageName: node linkType: hard +"tiny-invariant@npm:1.3.1": + version: 1.3.1 + resolution: "tiny-invariant@npm:1.3.1" + checksum: 872dbd1ff20a21303a2fd20ce3a15602cfa7fcf9b228bd694a52e2938224313b5385a1078cb667ed7375d1612194feaca81c4ecbe93121ca1baebe344de4f84c + languageName: node + linkType: hard + "tiny-warning@npm:^1.0.3": version: 1.0.3 resolution: "tiny-warning@npm:1.0.3" From 2c51f5f67a5e6ef34a7c2c114d34d30449eb2250 Mon Sep 17 00:00:00 2001 From: David Matejka Date: Wed, 24 Apr 2024 14:46:48 +0200 Subject: [PATCH 3/5] feat(playground): plate editor binding sync --- .../richt-text-editor/plate-editor.tsx | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx index 3cb788826..4ec569743 100644 --- a/packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-editor.tsx @@ -1,7 +1,7 @@ import { Component, Field, SugarableRelativeSingleField, useField } from '@contember/interface' import { cn } from '@udecode/cn' -import { Plate } from '@udecode/plate-common' -import { useRef } from 'react' +import { normalizeInitialValue, Plate, replaceNodeChildren, useEditorRef } from '@udecode/plate-common' +import { useEffect, useRef } from 'react' import { DndProvider } from 'react-dnd' import { HTML5Backend } from 'react-dnd-html5-backend' import { plugins } from './plate-plugins' @@ -26,7 +26,9 @@ export const PlateEditor = Component( const handleEditorOnChange = (value: any) => { const contentJson = isJsonObject(value) ? { children: value } : null - if (contentJson && contentField.value && (isJsonContent(contentField.value) && contentField.value.children === value)) return + if (contentJson && contentField.value && (isJsonContent(contentField.value) && contentField.value.children === value)) { + return + } contentField.updateValue(contentJson) } @@ -40,6 +42,7 @@ export const PlateEditor = Component( onChange={handleEditorOnChange} normalizeInitialValue > +
{ + const field = useField('data') + const fieldAccessor = field.getAccessor + const fieldValue = field.value + const editor = useEditorRef() + + useEffect(() => { + if (fieldValue !== fieldAccessor().value) { + return + } + const currValue = isJsonContent(fieldValue) && fieldValue.children.length > 0 + ? fieldValue.children + : editor.childrenFactory() + if (currValue === editor.children) { + return + } + const normalizedValue = normalizeInitialValue(editor, currValue) ?? currValue + replaceNodeChildren(editor, { + at: [], + nodes: normalizedValue, + } as any) + }, [editor, fieldAccessor, fieldValue]) + + return null +} From 2a6abed588f1a8f7ee53917718014dc27a95aec8 Mon Sep 17 00:00:00 2001 From: David Matejka Date: Wed, 24 Apr 2024 14:47:26 +0200 Subject: [PATCH 4/5] feat(playground): add more plate plugins --- .../richt-text-editor/plate-plugins.tsx | 65 +++++++++++-------- packages/playground/package.json | 2 + yarn.lock | 19 +++++- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx b/packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx index a99b6a79c..1dca52b82 100644 --- a/packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx +++ b/packages/playground/admin/lib/components/richt-text-editor/plate-plugins.tsx @@ -1,32 +1,9 @@ import { withProps } from '@udecode/cn' -import { - autoformatArrow, - autoformatLegal, - autoformatMath, - autoformatPunctuation, - createAutoformatPlugin, -} from '@udecode/plate-autoformat' -import { - createBoldPlugin, - createItalicPlugin, - createStrikethroughPlugin, - createUnderlinePlugin, - MARK_BOLD, - MARK_ITALIC, - MARK_STRIKETHROUGH, - MARK_UNDERLINE, -} from '@udecode/plate-basic-marks' +import { autoformatArrow, autoformatLegal, autoformatMath, autoformatPunctuation, createAutoformatPlugin } from '@udecode/plate-autoformat' +import { createBoldPlugin, createItalicPlugin, createStrikethroughPlugin, createUnderlinePlugin, MARK_BOLD, MARK_ITALIC, MARK_STRIKETHROUGH, MARK_UNDERLINE } from '@udecode/plate-basic-marks' import { createPlugins, PlateElement, PlateLeaf, RenderAfterEditable } from '@udecode/plate-common' import { createDndPlugin } from '@udecode/plate-dnd' -import { - createHeadingPlugin, - ELEMENT_H1, - ELEMENT_H2, - ELEMENT_H3, - ELEMENT_H4, - ELEMENT_H5, - ELEMENT_H6, -} from '@udecode/plate-heading' +import { createHeadingPlugin, ELEMENT_H1, ELEMENT_H2, ELEMENT_H3, ELEMENT_H4, ELEMENT_H5, ELEMENT_H6 } from '@udecode/plate-heading' import { createLinkPlugin, ELEMENT_LINK } from '@udecode/plate-link' import { createListPlugin, ELEMENT_LI, ELEMENT_OL, ELEMENT_UL } from '@udecode/plate-list' import { createNodeIdPlugin } from '@udecode/plate-node-id' @@ -42,6 +19,8 @@ import { ListElement } from './plate-ui/list-element' import { ParagraphElement } from './plate-ui/paragraph-element' import { withPlaceholders } from './plate-ui/placeholder' import { withDraggables } from './plate-ui/with-draggables' +import { createExitBreakPlugin } from '@udecode/plate-break' +import { createIndentPlugin } from '@udecode/plate-indent' export const plugins = createPlugins([ // Nodes @@ -78,6 +57,40 @@ export const plugins = createPlugins([ enableUndoOnDelete: true, }, }), + createIndentPlugin({ + inject: { + props: { + validTypes: [ + ELEMENT_PARAGRAPH, + // ELEMENT_H1, ELEMENT_H2, ELEMENT_H3, ELEMENT_BLOCKQUOTE, ELEMENT_CODE_BLOCK + ], + }, + }, + }), + createExitBreakPlugin({ + options: { + rules: [ + { + hotkey: 'mod+enter', + }, + { + hotkey: 'mod+shift+enter', + before: true, + }, + { + hotkey: 'enter', + query: { + start: true, + end: true, + // allow: KEYS_HEADING, + }, + relative: true, + level: 1, + }, + ], + }, + }), + dragOverCursorPlugin, // Deserialization diff --git a/packages/playground/package.json b/packages/playground/package.json index fbdb01798..f33dfdf5a 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -53,12 +53,14 @@ "@udecode/cn": "^31.0.0", "@udecode/plate-autoformat": "^31.0.0", "@udecode/plate-basic-marks": "^31.0.0", + "@udecode/plate-break": "^31.0.0", "@udecode/plate-common": "^31.0.0", "@udecode/plate-cursor": "^31.0.0", "@udecode/plate-dnd": "^31.0.0", "@udecode/plate-floating": "^31.0.0", "@udecode/plate-font": "^31.0.0", "@udecode/plate-heading": "^31.0.0", + "@udecode/plate-indent": "^31.1.0", "@udecode/plate-link": "^31.0.0", "@udecode/plate-list": "^31.1.3", "@udecode/plate-node-id": "^31.0.0", diff --git a/yarn.lock b/yarn.lock index 10c514145..0e9bd39f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1319,12 +1319,14 @@ __metadata: "@udecode/cn": ^31.0.0 "@udecode/plate-autoformat": ^31.0.0 "@udecode/plate-basic-marks": ^31.0.0 + "@udecode/plate-break": ^31.0.0 "@udecode/plate-common": ^31.0.0 "@udecode/plate-cursor": ^31.0.0 "@udecode/plate-dnd": ^31.0.0 "@udecode/plate-floating": ^31.0.0 "@udecode/plate-font": ^31.0.0 "@udecode/plate-heading": ^31.0.0 + "@udecode/plate-indent": ^31.1.0 "@udecode/plate-link": ^31.0.0 "@udecode/plate-list": ^31.1.3 "@udecode/plate-node-id": ^31.0.0 @@ -6341,6 +6343,21 @@ __metadata: languageName: node linkType: hard +"@udecode/plate-break@npm:^31.0.0": + version: 31.0.0 + resolution: "@udecode/plate-break@npm:31.0.0" + peerDependencies: + "@udecode/plate-common": ">=31.0.0" + react: ">=16.8.0" + react-dom: ">=16.8.0" + slate: ">=0.94.0" + slate-history: ">=0.93.0" + slate-hyperscript: ">=0.66.0" + slate-react: ">=0.99.0" + checksum: 1536e5f59891c68e3f40428959f38d6836f48572a568869f0eaa52f9e25cbe1fcc6042a592d4aa737151b7fc35c68f46c41ff14daf938dd1aa7ebd85deaf6b42 + languageName: node + linkType: hard + "@udecode/plate-code-block@npm:31.3.4": version: 31.3.4 resolution: "@udecode/plate-code-block@npm:31.3.4" @@ -6530,7 +6547,7 @@ __metadata: languageName: node linkType: hard -"@udecode/plate-indent@npm:31.1.0": +"@udecode/plate-indent@npm:31.1.0, @udecode/plate-indent@npm:^31.1.0": version: 31.1.0 resolution: "@udecode/plate-indent@npm:31.1.0" peerDependencies: From 84878e482b4dbbe452a897a83bd2cc62bfedacb6 Mon Sep 17 00:00:00 2001 From: David Matejka Date: Fri, 26 Apr 2024 13:27:47 +0200 Subject: [PATCH 5/5] chore: yarn dedupe --- yarn.lock | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0e9bd39f8..2b362896d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6013,14 +6013,7 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:^4.14.149": - version: 4.14.191 - resolution: "@types/lodash@npm:4.14.191" - checksum: ba0d5434e10690869f32d5ea49095250157cae502f10d57de0a723fd72229ce6c6a4979576f0f13e0aa9fbe3ce2457bfb9fa7d4ec3d6daba56730a51906d1491 - languageName: node - linkType: hard - -"@types/lodash@npm:^4.14.200": +"@types/lodash@npm:^4.14.149, @types/lodash@npm:^4.14.200": version: 4.17.0 resolution: "@types/lodash@npm:4.17.0" checksum: 3f98c0b67a93994cbc3403d4fa9dbaf52b0b6bb7f07a764d73875c2dcd5ef91222621bd5bcf8eee7b417a74d175c2f7191b9f595f8603956fd06f0674c0cba93