diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index e36ecf2f1c..8b99bd55b8 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,5 +1,631 @@ For older changelogs, see https://github.com/udecode/plate/blob/main/docs +# 42.0.1 + +## @udecode/plate-ai@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – AI plugins are now experimental: pin the dependency to avoid breaking changes. No breaking changes for this release. + +## @udecode/plate-common@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – This package is now deprecated and will be renamed to `@udecode/plate`. Migration: + + - Remove `@udecode/plate-common` and install `@udecode/plate` + - Replace all `'@udecode/plate-common'` with `'@udecode/plate'`, + +## @udecode/plate-core@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – + + - **Plugin `normalizeInitialValue`** now returns `void` instead of `Value`. When mutating nodes, keep their references (e.g., use `Object.assign` instead of spread). + - **Editor methods have moved** to `editor.tf` and `editor.api`. They still exist at the top level for **slate backward compatibility**, but are no longer redundantly typed. If you truly need the top-level method types, extend your editor type with `LegacyEditorMethods` (e.g. `editor as Editor & LegacyEditorMethods`). Since these methods can be overridden by `extendEditor`, `with...`, or slate plugins, consider migrating to the following approaches: + + ```tsx + // For overriding existing methods only: + overrideEditor(({ editor, tf: { deleteForward }, api: { isInline } }) => ({ + transforms: { + deleteForward(options) { + // ...conditional override + deleteForward(options); + }, + }, + api: { + isInline(element) { + // ...conditional override + return isInline(element); + }, + }, + })); + ``` + + This was previously done in `extendEditor` using top-level methods, which still works but now throws a type error due to the move to `editor.tf/editor.api`. A workaround is to extend your editor with `LegacyEditorMethods`. + + **Why?** Having all methods at the top-level (next to `children`, `marks`, etc.) would clutter the editor interface. Slate splits transforms in three places (`editor`, `Editor`, and `Transforms`), which is also confusing. We've reorganized them into `tf` and `api` for better DX, but also to support transform-only middlewares in the future. This also lets us leverage `extendEditorTransforms`, `extendEditorApi`, and `overrideEditor` to modify those methods. + + Migration example: + + ```tsx + // From: + export const withInlineVoid: ExtendEditor = ({ editor }) => { + const { isInline, isSelectable, isVoid, markableVoid } = editor; + + const voidTypes: string[] = []; + const inlineTypes: string[] = []; + + editor.pluginList.forEach((plugin) => { + if (plugin.node.isInline) { + inlineTypes.push(plugin.node.type); + } + if (plugin.node.isVoid) { + voidTypes.push(plugin.node.type); + } + }); + + editor.isInline = (element) => { + return inlineTypes.includes(element.type as any) + ? true + : isInline(element); + }; + + editor.isVoid = (element) => { + return voidTypes.includes(element.type as any) ? true : isVoid(element); + }; + + return editor; + }; + + export const InlineVoidPlugin = createSlatePlugin({ + key: 'inlineVoid', + extendEditor: withInlineVoid, + }); + + // After (using overrideEditor since we're only overriding existing methods): + export const withInlineVoid: OverrideEditor = ({ + api: { isInline, isSelectable, isVoid, markableVoid }, + editor, + }) => { + const voidTypes: string[] = []; + const inlineTypes: string[] = []; + + editor.pluginList.forEach((plugin) => { + if (plugin.node.isInline) { + inlineTypes.push(plugin.node.type); + } + if (plugin.node.isVoid) { + voidTypes.push(plugin.node.type); + } + }); + + return { + api: { + isInline(element) { + return inlineTypes.includes(element.type as any) + ? true + : isInline(element); + }, + isVoid(element) { + return voidTypes.includes(element.type as any) + ? true + : isVoid(element); + }, + }, + }; + }; + + export const InlineVoidPlugin = createSlatePlugin({ + key: 'inlineVoid', + }).overrideEditor(withInlineVoid); + ``` + + - Move `editor.redecorate` to `editor.api.redecorate` + + Types: + + - Rename `TRenderElementProps` to `RenderElementProps` + - Rename `TRenderLeafProps` to `RenderLeafProps` + - Rename `TEditableProps` to `EditableProps` + +## @udecode/plate@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – **This package is now the new common package**, so all plugin packages are being removed. **Migration**: + + - Add the following dependencies: + + ```json + "@udecode/plate-alignment": "42.0.0", + "@udecode/plate-autoformat": "42.0.0", + "@udecode/plate-basic-elements": "42.0.0", + "@udecode/plate-basic-marks": "42.0.0", + "@udecode/plate-block-quote": "42.0.0", + "@udecode/plate-break": "42.0.0", + "@udecode/plate-code-block": "42.0.0", + "@udecode/plate-combobox": "42.0.0", + "@udecode/plate-comments": "42.0.0", + "@udecode/plate-csv": "42.0.0", + "@udecode/plate-diff": "42.0.0", + "@udecode/plate-docx": "42.0.0", + "@udecode/plate-find-replace": "42.0.0", + "@udecode/plate-floating": "42.0.0", + "@udecode/plate-font": "42.0.0", + "@udecode/plate-heading": "42.0.0", + "@udecode/plate-highlight": "42.0.0", + "@udecode/plate-horizontal-rule": "42.0.0", + "@udecode/plate-indent": "42.0.0", + "@udecode/plate-indent-list": "42.0.0", + "@udecode/plate-kbd": "42.0.0", + "@udecode/plate-layout": "42.0.0", + "@udecode/plate-line-height": "42.0.0", + "@udecode/plate-link": "42.0.0", + "@udecode/plate-list": "42.0.0", + "@udecode/plate-markdown": "42.0.0", + "@udecode/plate-media": "42.0.0", + "@udecode/plate-mention": "42.0.0", + "@udecode/plate-node-id": "42.0.0", + "@udecode/plate-normalizers": "42.0.0", + "@udecode/plate-reset-node": "42.0.0", + "@udecode/plate-resizable": "42.0.0", + "@udecode/plate-select": "42.0.0", + "@udecode/plate-selection": "42.0.0", + "@udecode/plate-slash-command": "42.0.0", + "@udecode/plate-suggestion": "42.0.0", + "@udecode/plate-tabbable": "42.0.0", + "@udecode/plate-table": "42.0.0", + "@udecode/plate-toggle": "42.0.0", + "@udecode/plate-trailing-block": "42.0.0" + ``` + + - Either replace all `@udecode/plate` imports with the individual package imports, or export the following in a new file (e.g. `src/plate.ts`): + + ```ts + export * from '@udecode/plate-alignment'; + export * from '@udecode/plate-autoformat'; + export * from '@udecode/plate-basic-elements'; + export * from '@udecode/plate-basic-marks'; + export * from '@udecode/plate-block-quote'; + export * from '@udecode/plate-break'; + export * from '@udecode/plate-code-block'; + export * from '@udecode/plate-combobox'; + export * from '@udecode/plate-comments'; + export * from '@udecode/plate-diff'; + export * from '@udecode/plate-find-replace'; + export * from '@udecode/plate-font'; + export * from '@udecode/plate-heading'; + export * from '@udecode/plate-highlight'; + export * from '@udecode/plate-horizontal-rule'; + export * from '@udecode/plate-indent'; + export * from '@udecode/plate-indent-list'; + export * from '@udecode/plate-kbd'; + export * from '@udecode/plate-layout'; + export * from '@udecode/plate-line-height'; + export * from '@udecode/plate-link'; + export * from '@udecode/plate-list'; + export * from '@udecode/plate-media'; + export * from '@udecode/plate-mention'; + export * from '@udecode/plate-node-id'; + export * from '@udecode/plate-normalizers'; + export * from '@udecode/plate-reset-node'; + export * from '@udecode/plate-select'; + export * from '@udecode/plate-csv'; + export * from '@udecode/plate-docx'; + export * from '@udecode/plate-markdown'; + export * from '@udecode/plate-slash-command'; + export * from '@udecode/plate-suggestion'; + export * from '@udecode/plate-tabbable'; + export * from '@udecode/plate-table'; + export * from '@udecode/plate-toggle'; + export * from '@udecode/plate-trailing-block'; + export * from '@udecode/plate-alignment/react'; + export * from '@udecode/plate-autoformat/react'; + export * from '@udecode/plate-basic-elements/react'; + export * from '@udecode/plate-basic-marks/react'; + export * from '@udecode/plate-block-quote/react'; + export * from '@udecode/plate-break/react'; + export * from '@udecode/plate-code-block/react'; + export * from '@udecode/plate-combobox/react'; + export * from '@udecode/plate-comments/react'; + export * from '@udecode/plate-floating'; + export * from '@udecode/plate-font/react'; + export * from '@udecode/plate-heading/react'; + export * from '@udecode/plate-highlight/react'; + export * from '@udecode/plate-layout/react'; + export * from '@udecode/plate-slash-command/react'; + export * from '@udecode/plate-indent/react'; + export * from '@udecode/plate-indent-list/react'; + export * from '@udecode/plate-kbd/react'; + export * from '@udecode/plate-line-height/react'; + export * from '@udecode/plate-link/react'; + export * from '@udecode/plate-list/react'; + export * from '@udecode/plate-media/react'; + export * from '@udecode/plate-reset-node/react'; + export * from '@udecode/plate-selection'; + export * from '@udecode/plate-suggestion/react'; + export * from '@udecode/plate-tabbable/react'; + export * from '@udecode/plate-table/react'; + export * from '@udecode/plate-toggle/react'; + export * from '@udecode/plate-resizable'; + ``` + + - Replace all `'@udecode/plate'` and `'@udecode/plate/react'` with `'@/plate'` in your codebase. + +## @udecode/plate-utils@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – + - Removed unused `moveSelectionByOffset`, `getLastBlockDOMNode`, `useLastBlock`, `useLastBlockDOMNode` + +## @udecode/plate-selection@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – Remove first parameter of editor.api.blockSelection.duplicate + +## @udecode/slate@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – + + - Remove `slate`, `slate-dom`, `slate-react`, `slate-history` and `slate-hyperscript` from your dependencies. It's now part of this package and `@udecode/plate`. All exports remain the same or have equivalents (see below). + - Renamed `createTEditor` to `createEditor`. + - `createEditor` now returns an editor (`Editor`) with all queries under `editor.api` and transforms under `editor.tf`. You can see or override them at a glance. For example, we now use `editor.tf.setNodes` instead of importing `setNodes`. This marks the completion of generic typing and the removal of error throws from `slate`, `slate-dom`, and `slate-history` queries/transforms, without forking implementations. We’ve also reduced the number of queries/transforms by merging a bunch of them. + + The following interfaces from `slate` and `slate-dom` are now part of `Editor`: + + - `Editor`, `EditorInterface` + + - `Transforms` + + - `HistoryEditor` (noop, unchanged), `HistoryEditorInterface` + + - `DOMEditor` (noop, unchanged), `DOMEditorInterface` + + - `editor.findPath` now returns `DOMEditor.findPath` (memo) and falls back to `findNodePath` (traversal, less performant) if not found. + + - Removed the first parameter (`editor`) from: + + - `editor.hasEditableTarget` + - `editor.hasSelectableTarget` + - `editor.isTargetInsideNonReadonlyVoid` + - `editor.hasRange` + - `editor.hasTarget` + + - `editor.api.node(options)` (previously `findNode`) `at` option is now `at ?? editor.selection` instead of `at ?? editor.selection ?? []`. That means if you want to lookup the entire document, you need to pass `[]` explicitly. + + - Removed `setNode` in favor of `setNodes` (you can now pass a `TNode` to `at` directly). + + - Removed `setElements` in favor of `setNodes`. + + - Removed unused `isWordAfterTrigger`, `setBlockAboveNode`, `setBlockAboveTexts`, `setBlockNodes`, `getPointNextToVoid`. + + - Replaced `Path` from slate with `Path` (type) and `PathApi` (static methods). + + - Replaced `Operation` from slate with `Operation` (type) and `OperationApi` (static methods). + + - Replaced `Point` from slate with `Point` (type) and `PointApi` (static methods). + + - Replaced `Text` from slate with `TText` (type) and `TextApi` (static methods). We also export `Text` type like `slate` but we don't recommend it as it's conflicting with the DOM type. + + - Replaced `Range` from slate with `TRange` (type) and `RangeApi` (static methods). We also export `Range` type like `slate` but we don't recommend it as it's conflicting with the DOM type. + + - Replaced `Location` from slate with `TLocation` (type) and `LocationApi` (static methods). We also export `Location` type like `slate` but we don't recommend it as it's conflicting with the DOM type. + + - Replaced `Span` from slate with `Span` (type) and `SpanApi` (static methods). + + - Replaced `Node` from slate with `TNode` (type) and `NodeApi` (static methods). We also export `Node` type like `slate` but we don't recommend it as it's conflicting with the DOM type. + + - Replaced `Element` from slate with `TElement` (type) and `ElementApi` (static methods). We also export `Element` type like `slate` but we don't recommend it as it's conflicting with the DOM type. + + - Signature change: + + - `editor.tf.toggle.block({ type, ...options })` -> `editor.tf.toggleBlock(type, options)` + - `editor.tf.toggle.mark({ key, clear })` -> `editor.tf.toggleMark(key, { remove: clear })` + + - Moved editor functions: + + - `addMark` -> `editor.tf.addMark` + - `addRangeMarks` -> `editor.tf.setNodes(props, { at, marks: true })` + - `blurEditor` -> `editor.tf.blur` + - `collapseSelection` -> `editor.tf.collapse` + - `createDocumentNode` -> `editor.api.create.value` (core) + - `createNode` -> `editor.api.create.block` + - `createPathRef` -> `editor.api.pathRef` + - `createPointRef` -> `editor.api.pointRef` + - `createRangeRef` -> `editor.api.rangeRef` + - `deleteBackward({ unit })` -> `editor.tf.deleteBackward(unit)` + - `deleteForward({ unit })` -> `editor.tf.deleteForward(unit)` + - `deleteFragment` -> `editor.tf.deleteFragment` + - `deleteText` -> `editor.tf.delete` + - `deselect` -> `editor.tf.deselect` + - `deselectEditor` -> `editor.tf.deselectDOM` + - `duplicateBlocks` -> `editor.tf.duplicateNodes({ nodes })` + - `findDescendant` -> `editor.api.descendant` + - `findEditorDocumentOrShadowRoot` -> `editor.api.findDocumentOrShadowRoot` + - `findEventRange` -> `editor.api.findEventRange` + - `findNode(options)` -> `editor.api.node(options)` + - `findNodeKey` -> `editor.api.findKey` + - `findNodePath` -> `editor.api.findPath` + - `findPath` -> `editor.api.findPath` + - `focusEditor` -> `editor.tf.focus({ at })` + - `focusEditorEdge` -> `editor.tf.focus({ at, edge: 'startEditor' | 'endEditor' })` + - `getAboveNode` -> `editor.api.above` + - `getAncestorNode` -> `editor.api.block({ highest: true })` + - `getBlockAbove` -> `editor.api.block({ at, above: true })` or `editor.api.block()` if `at` is not a path + - `getBlocks` -> `editor.api.blocks` + - `getEdgeBlocksAbove` -> `editor.api.edgeBlocks` + - `getEdgePoints` -> `editor.api.edges` + - `getEditorString` -> `editor.api.string` + - `getEditorWindow` -> `editor.api.getWindow` + - `getEndPoint` -> `editor.api.end` + - `getFirstNode` -> `editor.api.first` + - `getFragment` -> `editor.api.fragment` + - `getFragmentProp(fragment, options)` -> `editor.api.prop({ nodes, ...options})` + - `getLastNode` -> `editor.api.last` + - `getLastNodeByLevel(level)` -> `editor.api.last([], { level })` + - `getLeafNode` -> `editor.api.leaf` + - `getLevels` -> `editor.api.levels` + - `getMark` -> `editor.api.mark` + - `getMarks` -> `editor.api.marks` + - `getNextNode` -> `editor.api.next` + - `getNextNodeStartPoint` -> `editor.api.start(at, { next: true })` + - `getNodeEntries` -> `editor.api.nodes` + - `getNodeEntry` -> `editor.api.node(at, options)` + - `getNodesRange` -> `editor.api.nodesRange` + - `getParentNode` -> `editor.api.parent` + - `getPath` -> `editor.api.path` + - `getPathRefs` -> `editor.api.pathRefs` + - `getPoint` -> `editor.api.point` + - `getPointAfter` -> `editor.api.after` + - `getPointBefore` -> `editor.api.before` + - `getPointBeforeLocation` -> `editor.api.before` + - `getPointRefs` -> `editor.api.pointRefs` + - `getPositions` -> `editor.api.positions` + - `getPreviousBlockById` -> `editor.api.previous({ id, block: true })` + - `getPreviousNode` -> `editor.api.previous` + - `getPreviousNodeEndPoint` -> `editor.api.end({ previous: true })` + - `getPreviousSiblingNode` -> `editor.api.previous({ at, sibling: true })` + - `getRange` -> `editor.api.range` + - `getRangeBefore` -> `editor.api.range('before', to, { before })` + - `getRangeFromBlockStart` -> `editor.api.range('start', to)` + - `getRangeRefs` -> `editor.api.rangeRefs` + - `getSelectionFragment` -> `editor.api.fragment(editor.selection, { structuralTypes })` + - `getSelectionText` -> `editor.api.string()` + - `getStartPoint` -> `editor.api.start` + - `getVoidNode` -> `editor.api.void` + - `hasBlocks` -> `editor.api.hasBlocks` + - `hasEditorDOMNode` -> `editor.api.hasDOMNode` + - `hasEditorEditableTarget` -> `editor.api.hasEditableTarget` + - `hasEditorSelectableTarget` -> `editor.api.hasSelectableTarget` + - `hasEditorTarget` -> `editor.api.hasTarget` + - `hasInlines` -> `editor.api.hasInlines` + - `hasTexts` -> `editor.api.hasTexts` + - `insertBreak` -> `editor.tf.insertBreak` + - `insertData` -> `editor.tf.insertData` + - `insertElements` -> `editor.tf.insertNodes` + - `insertEmptyElement` -> `editor.tf.insertNodes(editor.api.create.block({ type }))` + - `insertFragment` -> `editor.tf.insertFragment` + - `insertNode` -> `editor.tf.insertNode` + - `insertNodes` -> `editor.tf.insertNodes` + - `insertText` -> `editor.tf.insertText` + - `isAncestorEmpty` -> `editor.api.isEmpty` + - `isBlock` -> `editor.api.isBlock` + - `isBlockAboveEmpty` -> `editor.api.isEmpty(editor.selection, { block: true })` + - `isBlockTextEmptyAfterSelection` -> `editor.api.isEmpty(editor.selection, { after: true })` + - `isCollapsed(editor.selection)` -> `editor.api.isCollapsed()` + - `isComposing` -> `editor.api.isComposing` + - `isDocumentEnd` -> `editor.api.isEditorEnd` + - `isEdgePoint` -> `editor.api.isEdge` + - `isEditor` -> `editor.api.isEditor` + - `isEditorEmpty` -> `editor.api.isEmpty()` + - `isEditorFocused` -> `editor.api.isFocused` + - `isEditorNormalizing` -> `editor.api.isNormalizing` + - `isEditorReadOnly` -> `editor.api.isReadOnly` + - `isElementEmpty` -> `editor.api.isEmpty` + - `isElementReadOnly` -> `editor.api.elementReadOnly` + - `isEndPoint` -> `editor.api.isEnd` + - `isExpanded(editor.selection)` -> `editor.api.isCollapsed()` + - `isInline` -> `editor.api.isInline` + - `isMarkableVoid` -> `editor.api.markableVoid` + - `isMarkActive` -> `editor.api.hasMark(key)` + - `isPointAtWordEnd` -> `editor.api.isAt({ at, word: true, end: true })` + - `isRangeAcrossBlocks` -> `editor.api.isAt({ at, blocks: true })` + - `isRangeInSameBlock` -> `editor.api.isAt({ at, block: true })` + - `isRangeInSingleText` -> `editor.api.isAt({ at, text: true })` + - `isSelectionAtBlockEnd` -> `editor.api.isAt({ end: true })` + - `isSelectionAtBlockStart` -> `editor.api.isAt({ start: true })` + - `isSelectionCoverBlock` -> `editor.api.isAt({ block: true, start: true, end: true })` + - `isSelectionExpanded` -> `editor.api.isExpanded()` + - `isStartPoint` -> `editor.api.isStart` + - `isTargetinsideNonReadonlyVoidEditor` -> `editor.api.isTargetInsideNonReadonlyVoid` + - `isTextByPath` -> `editor.api.isText(at)` + - `isVoid` -> `editor.api.isVoid` + - `liftNodes` -> `editor.tf.liftNodes` + - `mergeNodes` -> `editor.tf.mergeNodes` + - `moveChildren` -> `editor.tf.moveNodes({ at, to, children: true, fromIndex, match: (node, path) => boolean })` + - `moveNodes` -> `editor.tf.moveNodes` + - `moveSelection` -> `editor.tf.move` + - `normalizeEditor` -> `editor.tf.normalize` + - `removeEditorMark` -> `editor.tf.removeMark` + - `removeEditorText` -> `editor.tf.removeNodes({ text: true, empty: false })` + - `removeEmptyPreviousBlock` -> `editor.tf.removeNodes({ previousEmptyBlock: true })` + - `removeMark(options)` -> `editor.tf.removeMarks(keys, options)` + - `removeNodeChildren` -> `editor.tf.removeNodes({ at, children: true })` + - `removeNodes` -> `editor.tf.removeNodes` + - `removeSelectionMark` -> `editor.tf.removeMarks()` + - `replaceNode(editor, { nodes, insertOptions, removeOptions })` -> `editor.tf.replaceNodes(nodes, { removeNodes, ...insertOptions })` + - `select` -> `editor.tf.select` + - `selectEndOfBlockAboveSelection` -> `editor.tf.select(editor.selection, { edge: 'end' })` + - `selectNodes` -> `editor.tf.select(editor.api.nodesRange(nodes))` + - `setFragmentData` -> `editor.tf.setFragmentData` + - `setMarks(marks, clear)` -> `editor.tf.addMarks(marks, { remove: string | string[] })` + - `setNodes` -> `editor.tf.setNodes` + - `setPoint` -> `editor.tf.setPoint` + - `setSelection` -> `editor.tf.setSelection` + - `someNode` -> `editor.api.some(options)` + - `splitNodes` -> `editor.tf.splitNodes` + - `toDOMNode` -> `editor.api.toDOMNode` + - `toDOMPoint` -> `editor.api.toDOMPoint` + - `toDOMRange` -> `editor.api.toDOMRange` + - `toggleWrapNodes` -> `editor.tf.toggleBlock(type, { wrap: true })` + - `toSlateNode` -> `editor.api.toSlateNode` + - `toSlatePoint` -> `editor.api.toSlatePoint` + - `toSlateRange` -> `editor.api.toSlateRange` + - `unhangCharacterRange` -> `editor.api.unhangRange(range, { character: true })` + - `unhangRange` -> `editor.api.unhangRange` + - `unsetNodes` -> `editor.tf.unsetNodes` + - `unwrapNodes` -> `editor.tf.unwrapNodes` + - `withoutNormalizing` -> `editor.tf.withoutNormalizing` + - `wrapNodeChildren` -> `editor.tf.wrapNodes(element, { children: true })` + - `wrapNodes` -> `editor.tf.wrapNodes` + - `replaceNodeChildren` -> `editor.tf.replaceNodes({ at, children: true })` + - `resetEditor` -> `editor.tf.reset` + - `resetEditorChildren` -> `editor.tf.reset({ children: true })` + - `selectEditor` -> `editor.tf.select([], { focus, edge })` + - `selectSiblingNodePoint` -> `editor.tf.select(at, { next, previous })` + + - Moved to `NodeApi.`: + + - `getNextSiblingNodes(parentEntry, path)` -> `NodeApi.children(editor, path, { from: path.at(-1) + 1 })` + - `getFirstNodeText` -> `NodeApi.firstText` + - `getFirstChild([node, path])` -> `NodeApi.firstChild(editor, path)` + - `getLastChild([node, path])` -> `NodeApi.lastChild(editor, path)` + - `getLastChildPath([node, path])` -> `NodeApi.lastChild(editor, path)` + - `isLastChild([node, path], childPath)` -> `NodeApi.isLastChild(editor, childPath)` + - `getChildren([node, path])` -> `Array.from(NodeApi.children(editor, path))` + - `getCommonNode` -> `NodeApi.common` + - `getNode` -> `NodeApi.get` + - `getNodeAncestor` -> `NodeApi.ancestor` + - `getNodeAncestors` -> `NodeApi.ancestors` + - `getNodeChild` -> `NodeApi.child` + - `getNodeChildren` -> `NodeApi.children` + - `getNodeDescendant` -> `NodeApi.descendant` + - `getNodeDescendants` -> `NodeApi.descendants` + - `getNodeElements` -> `NodeApi.elements` + - `getNodeFirstNode` -> `NodeApi.first` + - `getNodeFragment` -> `NodeApi.fragment` + - `getNodeLastNode` -> `NodeApi.last` + - `getNodeLeaf` -> `NodeApi.leaf` + - `getNodeLevels` -> `NodeApi.levels` + - `getNodeParent` -> `NodeApi.parent` + - `getNodeProps` -> `NodeApi.extractProps` + - `getNodes` -> `NodeApi.nodes` + - `getNodeString` -> `NodeApi.string` + - `getNodeTexts` -> `NodeApi.texts` + - `hasNode` -> `NodeApi.has` + - `hasSingleChild` -> `NodeApi.hasSingleChild` + - `isAncestor` -> `NodeApi.isAncestor` + - `isDescendant` -> `NodeApi.isDescendant` + - `isNode` -> `NodeApi.isNode` + - `isNodeList` -> `NodeApi.isNodeList` + - `nodeMatches` -> `NodeApi.matches` + + - Moved to `ElementApi.`: + + - `elementMatches` -> `ElementApi.matches` + - `isElement` -> `ElementApi.isElement` + - `isElementList` -> `ElementApi.isElementList` + + - Moved to `TextApi.`: + + - `isText` -> `TextApi.isText(at)` + + - Moved to `RangeApi.`: + + - `isCollapsed` -> `RangeApi.isCollapsed` + - `isExpanded` -> `RangeApi.isExpanded` + + - Moved to `PathApi.`: + + - `isFirstChild` -> `!PathApi.hasPrevious` + - `getPreviousPath` -> `PathApi.previous` + + - Moved to `PointApi.`: + + - `getPointFromLocation({ at, focus })` -> `PointApi.get(at, { focus })` + + - Moved from `@udecode/plate/react` to `@udecode/plate`: + + - `Hotkeys` + + - Upgraded to `zustand@5` and `zustand-x@5`: + - Replace `createZustandStore('name')(initialState)` with `createZustandStore(initialState, { mutative: true, name: 'name' })` + - All plugin stores now use [zustand-mutative](https://github.com/mutativejs/zustand-mutative) for immutable state updates, which is faster than `immer`. + + Types: + + - Rename the following types: + - `TEditor` -> `Editor` + - `TOperation` -> `Operation` + - `TPath` -> `Path` + - `TNodeProps` -> `NodeProps` + - `TNodeChildEntry` -> `NodeChildEntry` + - `TNodeEntry` -> `NodeEntry` + - `TDescendant` -> `Descendant` + - `TDescendantEntry` -> `DescendantEntry` + - `TAncestor` -> `Ancestor` + - `TAncestorEntry` -> `AncestorEntry` + - `TElementEntry` -> `ElementEntry` + - `TTextEntry` -> `TextEntry` + - Query/transform options now use generic `V extends Value` instead of `E extends Editor`. + - `getEndPoint`, `getEdgePoints`, `getFirstNode`, `getFragment`, `getLastNode`, `getLeafNode`, `getPath`, `getPoint`, `getStartPoint` can return `undefined` if not found (suppressing error throws). + - `NodeApi.ancestor`, `NodeApi.child`, `NodeApi.common`, `NodeApi.descendant`, `NodeApi.first`, `NodeApi.get`, `NodeApi.last`, `NodeApi.leaf`, `NodeApi.parent`, `NodeApi.getIf`, `PathApi.previous` return `undefined` if not found instead of throwing + - Replace `NodeOf` type with `DescendantOf` in `editor.tf.setNodes` `editor.tf.unsetNodes`, `editor.api.previous`, `editor.api.node`, `editor.api.nodes`, `editor.api.last` + - Enhanced `editor.tf.setNodes`: + - Added `marks` option to handle mark-specific operations + - When `marks: true`: + - Only applies to text nodes in non-void nodes or markable void nodes + - Automatically sets `split: true` and `voids: true` + - Handles both expanded ranges and collapsed selections in markable voids + - Replaces `addRangeMarks` functionality + +## @udecode/slate-utils@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – This package is now deprecated. Use `@udecode/slate` or `@udecode/plate` instead. + +## @udecode/slate-react@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – This package is now deprecated. Use `@udecode/slate` or `@udecode/plate` instead. + +## @udecode/plate-table@42.0.0 + +### Major Changes + +- [#3920](https://github.com/udecode/plate/pull/3920) by [@zbeyens](https://github.com/zbeyens) – **Major performance improvement**: all table cells were re-rendering when a single cell changed. This is now fixed. + + - `TablePlugin` now depends on `NodeIdPlugin`. + - Table merging is now enabled by default: + - Renamed `enableMerging` to `disableMerge`. + - **Migration**: + - `enableMerging: true` → remove the option. + - otherwise → `TablePlugin.configure({ options: { disableMerge: true } })` + - Renamed `unmergeTableCells` to `splitTableCell`. + - Renamed `editor.api.create.cell` to `editor.api.create.tableCell`. + - In `useTableMergeState`, renamed `canUnmerge` to `canSplit`. + - `insertTableRow` and `insertTableColumn`: removed `disableSelect` in favor of `select`. **Migration**: replace it with the opposite boolean. + - `getTableCellBorders`: params `(element, options)` → `(editor, options)`; removed `isFirstCell` and `isFirstRow`. + - Merged `useTableCellElementState` into `useTableCellElement`: + - Removed its parameter. + - Removed `hovered` and `hoveredLeft` returns (use CSS instead). + - Renamed `rowSize` to `minHeight`. + - Computes column sizes and returns `width`. + - Merged `useTableCellElementResizableState` into `useTableCellElementResizable`: + - Removed `onHover` and `onHoverEnd` props (use CSS instead). + - Merged `useTableElementState` into `useTableElement`: + - Removed its parameter. + - No longer computes and returns `colSizes`, `minColumnWidth`, and `colGroupProps`. + # 41.0.2 ## @udecode/slate-react@41.0.0 diff --git a/apps/www/content/docs/cn/ai.mdx b/apps/www/content/docs/cn/ai.mdx index d506636a6f..64528e868d 100644 --- a/apps/www/content/docs/cn/ai.mdx +++ b/apps/www/content/docs/cn/ai.mdx @@ -49,7 +49,7 @@ import { BaseCodeLinePlugin, BaseCodeSyntaxPlugin, } from '@udecode/plate-code-block'; -import { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate-common'; +import { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate'; import { BaseHeadingPlugin, HEADING_LEVELS } from '@udecode/plate-heading'; import { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule'; import { BaseIndentListPlugin } from '@udecode/plate-indent-list'; @@ -393,7 +393,7 @@ AI 聊天是否打开。 插入带有 AI 标记的 AI 生成节点。 - + 要插入带有 AI 标记的节点。 diff --git a/apps/www/content/docs/cn/alignment.mdx b/apps/www/content/docs/cn/alignment.mdx index 1cceb2a4b4..929a2027f5 100644 --- a/apps/www/content/docs/cn/alignment.mdx +++ b/apps/www/content/docs/cn/alignment.mdx @@ -25,9 +25,9 @@ npm install @udecode/plate-alignment ```tsx // ... -import { createPlateEditor } from '@udecode/plate-common/react'; +import { createPlateEditor } from '@udecode/plate/react'; import { AlignPlugin } from '@udecode/plate-alignment/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { HeadingPlugin } from '@udecode/plate-heading/react'; const editor = createPlateEditor({ diff --git a/apps/www/content/docs/cn/api/common.mdx b/apps/www/content/docs/cn/api/common.mdx deleted file mode 100644 index d271b792e0..0000000000 --- a/apps/www/content/docs/cn/api/common.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Plate Common -description: udecode/plate-common的 API 参考。 ---- - -`@udecode/plate-common` 包含 Plate 的常用类型和函数: - -- [Core](/docs/api/core) -- [Plate Utils](/docs/api/utils) -- [Slate](/docs/api/slate) -- [Slate React](/docs/api/slate-react) diff --git a/apps/www/content/docs/cn/api/core.mdx b/apps/www/content/docs/cn/api/core.mdx index 1c497be31e..a6c2ab2a75 100644 --- a/apps/www/content/docs/cn/api/core.mdx +++ b/apps/www/content/docs/cn/api/core.mdx @@ -455,7 +455,7 @@ description: udecode/plate-core的 API 参考。 有关更多详细信息,请参阅[调试](/docs/debugging)。 -### SlateNextPlugin +### SlateExtensionPlugin & SlateReactExtensionPlugin 扩展核心 API 并改进默认功能。 ### DOMPlugin & ReactPlugin @@ -485,5 +485,23 @@ description: udecode/plate-core的 API 参考。 ### EventEditorPlugin 管理编辑器事件,如焦点和模糊。 -### PlateApiPlugin -提供 Plate 编辑器功能的核心 API。 +## Utils + +### isType + +检查节点是否匹配提供的类型。 + + + + 节点所在的编辑器。 + + + 要检查的节点。 + + + 用于匹配节点的类型。可以是字符串或字符串数组。 + + + + 一个布尔值,指示节点的类型是否匹配提供的类型。 + diff --git a/apps/www/content/docs/cn/api/core/plate.mdx b/apps/www/content/docs/cn/api/core/plate-components.mdx similarity index 92% rename from apps/www/content/docs/cn/api/core/plate.mdx rename to apps/www/content/docs/cn/api/core/plate-components.mdx index 28516f8809..80d7002181 100644 --- a/apps/www/content/docs/cn/api/core/plate.mdx +++ b/apps/www/content/docs/cn/api/core/plate-components.mdx @@ -1,5 +1,5 @@ --- -title: Plate +title: Plate Components description: Plate 组件的 API 参考。 --- @@ -36,10 +36,10 @@ description: Plate 组件的 API 参考。 如果为 true,编辑器处于只读模式。 - + 元素的自定义渲染函数。 - + 叶子节点的自定义渲染函数。 @@ -65,8 +65,8 @@ description: Plate 组件的 API 参考。 - - + + diff --git a/apps/www/content/docs/cn/api/core/plate-controller.mdx b/apps/www/content/docs/cn/api/core/plate-controller.mdx index f4f7bca908..3c8c2a1dd7 100644 --- a/apps/www/content/docs/cn/api/core/plate-controller.mdx +++ b/apps/www/content/docs/cn/api/core/plate-controller.mdx @@ -1,5 +1,5 @@ --- -title: PlateController +title: Plate Controller description: PlateController 组件的 API 参考。 --- @@ -119,7 +119,7 @@ const App = withHoc(PlateController, () => { const toggleBold = () => { if (activeEditor.isFallback) return; - toggleMark(activeEditor, { key: BoldPlugin.key }); + activeEditor.tf.toggleMark(BoldPlugin.key); }; return ( @@ -146,7 +146,7 @@ const App = withHoc(PlateController, () => { const isFallback = !useEditorMounted(); const toggleBold = () => { - toggleMark(activeEditor, { key: BoldPlugin.key }); + activeEditor.tf.toggleMark(BoldPlugin.key); }; return ( diff --git a/apps/www/content/docs/cn/api/core/plate-editor.mdx b/apps/www/content/docs/cn/api/core/plate-editor.mdx index 8da411f401..760e593fbd 100644 --- a/apps/www/content/docs/cn/api/core/plate-editor.mdx +++ b/apps/www/content/docs/cn/api/core/plate-editor.mdx @@ -3,7 +3,7 @@ title: Plate Editor description: Plate 编辑器的 API 参考。 --- -一个自定义的编辑器接口,扩展了基础的 **`TEditor`** 接口,并包含 Plate 库特有的属性和方法。 +一个自定义的编辑器接口,扩展了基础的 **`Editor`** 接口,并包含 Plate 库特有的属性和方法。 ## Core Properties @@ -36,16 +36,16 @@ description: Plate 编辑器的 API 参考。 ## API Methods - + 获取插件的类型化 API。 - + 获取插件的类型化变换。 - + 通过键或基础插件获取编辑器插件实例。 - + 获取插件的节点类型。 @@ -53,19 +53,19 @@ description: Plate 编辑器的 API 参考。 ## Option Methods - + 获取插件的特定选项值。 - + 获取插件的所有选项。 - + 设置插件的特定选项值。 - + 设置插件的多个选项。 - + 获取插件的 zustand-x 选项存储。 @@ -73,10 +73,10 @@ description: Plate 编辑器的 API 参考。 ## React Hooks - + 在 React 组件中订阅特定选项值。 - + 在 React 组件中订阅插件选项或派生自选项的值。 @@ -84,7 +84,7 @@ description: Plate 编辑器的 API 参考。 ## Plate Store Methods - + 更新全局 Plate 状态。 @@ -108,21 +108,10 @@ description: Plate 编辑器的 API 参考。 -### SlateNextPlugin - - - - 切换一个块元素。 - - - 切换选中文本上的标记。 - - - ### HtmlPlugin - + 将 HTML 内容反序列化为 Slate 节点。 @@ -135,7 +124,7 @@ description: Plate 编辑器的 API 参考。 -### PlateApiPlugin +### SlateReactExtensionPlugin diff --git a/apps/www/content/docs/cn/api/core/plate-plugin.mdx b/apps/www/content/docs/cn/api/core/plate-plugin.mdx index 7aa97ac609..e74d751ea6 100644 --- a/apps/www/content/docs/cn/api/core/plate-plugin.mdx +++ b/apps/www/content/docs/cn/api/core/plate-plugin.mdx @@ -1,9 +1,9 @@ --- -title: PlatePlugin +title: Plate Plugin description: Plate 插件的 API 参考。 --- -Plate 插件是传递给 `Plate` [plugins](/docs/api/core/plate#plugins) 属性的对象。 +Plate 插件是传递给 `Plate` [plugins](/docs/api/core/plate-components#plugins) 属性的对象。 ## 泛型类型 @@ -39,27 +39,27 @@ const MyPlugin = createPlatePlugin({ Plate 用于存储插件的唯一标识符,通过 `editor.plugins` 键。 - + 插件提供的 API 函数对象。这些函数通过 `editor.api[key]` 访问。 - + 插件提供的变换函数,用于修改编辑器状态。这些函数通过 `editor.tf[key]` 访问。 - + 插件作为选项使用的扩展属性。 - + 各种编辑器事件的事件处理程序,包括 `onChange`。 - + 定义插件如何将功能注入其他插件或编辑器。 - + Plate 用于将属性注入任何节点组件的属性。 @@ -84,7 +84,7 @@ Plate 用于将属性注入任何节点组件的属性。 节点属性注入的最大嵌套级别。深度大于此级别的节点将不会接收注入的属性。 - + 插件可以使用的属性,用于允许其他插件注入代码。 @@ -98,7 +98,7 @@ Plate 用于将属性注入任何节点组件的属性。 - + 定义插件的节点特定配置。 @@ -164,14 +164,14 @@ HTML React 序列化器配置。 - -定义编辑器各个部分的渲染函数。 + +定义插件如何渲染组件。 - + 在 `Editable` 组件上方但在 `Slate` 包装器内渲染组件。 - + 在所有其他插件的 `node` 组件上方渲染组件。 @@ -222,15 +222,25 @@ HTML React 序列化器配置。 Plate 用来装饰编辑器范围的属性。 - -Hook called when the editor is initialized. + +用于扩展编辑器实例的函数。主要用于集成需要直接编辑器变更的传统 Slate 插件。每个插件只允许一个 `extendEditor`。 + +```ts +extendEditor: ({ editor }) => { + // 示例:集成传统 Slate 插件 + return withYjs(editor); +}} + + + +当编辑器初始化时调用的钩子。 ## Plugin Methods - + 创建一个具有更新选项的新插件实例。 ```ts @@ -238,14 +248,14 @@ Hook called when the editor is initialized. ``` - + 创建一个具有附加配置的新插件实例。可以接受一个对象或一个函数。 ```ts (extendConfig: Partial | ((ctx: PlatePluginContext) => Partial)) => PlatePlugin ``` - + 扩展一个现有的嵌套插件或添加一个新的插件,如果未找到。支持深度嵌套。 ```ts @@ -261,7 +271,7 @@ Hook called when the editor is initialized. ``` - + 扩展插件的 API。 ```ts @@ -269,7 +279,7 @@ Hook called when the editor is initialized. ``` - + 使用插件特定的方法扩展编辑器的 API。 ```ts @@ -277,15 +287,15 @@ Hook called when the editor is initialized. ``` - -使用插件特定的方法扩展插件的变换。 + +扩展插件的变换。 ```ts (transforms: (ctx: PlatePluginContext) => any) => PlatePlugin ``` - + 使用插件特定的方法扩展编辑器的变换。 ```ts @@ -293,13 +303,39 @@ Hook called when the editor is initialized. ``` - + 使用选择器扩展插件选项。 ```ts (options: (ctx: PlatePluginContext) => any) => PlatePlugin ``` + + +创建一个具有覆盖编辑器方法的新插件实例。通过 `tf` 和 `api` 参数提供对原始方法的访问。可以多次调用以层叠不同的覆盖。 + +```ts +overrideEditor(({ editor, tf: { deleteForward }, api: { isInline } }) => ({ + transforms: { + // 覆盖 transforms + deleteForward(options) { + deleteForward(options); + }, + }, + api: { + // 覆盖 API 方法 + isInline(element) { + return isInline(element); + }, + }, +})) => PlatePlugin +``` + +- 修改编辑器行为的首选方法 +- 对原始方法的类型安全访问 +- 在 transforms 和 API 之间清晰分离 +- 可以多次链式调用 + ## Plugin Context diff --git a/apps/www/content/docs/cn/api/core/store.mdx b/apps/www/content/docs/cn/api/core/plate-store.mdx similarity index 98% rename from apps/www/content/docs/cn/api/core/store.mdx rename to apps/www/content/docs/cn/api/core/plate-store.mdx index 4391dd495f..a056fced15 100644 --- a/apps/www/content/docs/cn/api/core/store.mdx +++ b/apps/www/content/docs/cn/api/core/plate-store.mdx @@ -36,7 +36,7 @@ Slate 编辑器引用。 用于装饰编辑器中范围的函数。 ```ts -(options: { editor: PlateEditor; entry: TNodeEntry }) => Range[] +(options: { editor: PlateEditor; entry: NodeEntry }) => Range[] ``` diff --git a/apps/www/content/docs/cn/api/floating.mdx b/apps/www/content/docs/cn/api/floating.mdx index f26f2a2b5c..4e76e0380d 100644 --- a/apps/www/content/docs/cn/api/floating.mdx +++ b/apps/www/content/docs/cn/api/floating.mdx @@ -104,7 +104,7 @@ npm install @udecode/plate-floating 获取编辑器中位置或位置数组的边界客户端矩形。 - + 编辑器实例。 @@ -133,7 +133,7 @@ npm install @udecode/plate-floating 获取特定 Slate 范围的边界客户端矩形。 - + 编辑器实例。 diff --git a/apps/www/content/docs/cn/api/plate.mdx b/apps/www/content/docs/cn/api/plate.mdx new file mode 100644 index 0000000000..a31b1b617e --- /dev/null +++ b/apps/www/content/docs/cn/api/plate.mdx @@ -0,0 +1,10 @@ +--- +title: Plate +description: udecode/plate的 API 参考。 +--- + +`@udecode/plate` 包含 Plate 的常用类型和函数: + +- [Slate](/docs/api/slate) +- [Plate Core](/docs/api/core) +- [Plate Utils](/docs/api/utils) diff --git a/apps/www/content/docs/cn/api/slate-react.mdx b/apps/www/content/docs/cn/api/slate-react.mdx deleted file mode 100644 index 3cc11abbaf..0000000000 --- a/apps/www/content/docs/cn/api/slate-react.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Slate React -description: udecode/slate-react的 API 参考。 ---- - -`@udecode/slate-react` 使用泛型类型扩展了 Slate React API。 - -## React Editor - -在 [Slate React 文档](https://docs.slatejs.org/libraries/slate-react/react-editor) 中查找相应的文档。 - -### `SlateProps` - -### `blurEditor` - -### `deselectEditor` - -### `findEditorDocumentOrShadowRoot` - -### `findEventRange` - -### `findNodeKey` - -### `findPath` - -### `focusEditor` - -### `getEditorWindow` - -### `hasEditorDOMNode` - -### `hasEditorEditableTarget` - -### `hasEditorSelectableTarget` - -### `hasEditorTarget` - -### `insertData` - -### `isComposing` - -### `isEditorFocused` - -### `isEditorReadOnly` - -### `isTargetInsideNonReadonlyVoidEditor` - -### `setFragmentData` - -### `toDOMNode` - -### `toDOMPoint` - -### `toDOMRange` - -### `toSlateNode` - -### `toSlatePoint` - -### `toSlateRange` - -## Transforms - -### focusEditorEdge - -在指定的边缘(开始或结束)聚焦编辑器。 - - - - 编辑器实例。 - - - - - 要聚焦的边缘。 - - 'start': 在编辑器开始处聚焦。 - - 'end': 在编辑器结束处聚焦。 - 默认值为 'start'。 - - - - - -### setNode - -在编辑器中设置特定节点的属性。 - - - - 编辑器实例。 - - - 要更新的节点。 - - - 要在节点上设置的属性。 - - - 设置节点的选项,不包括 'at' 属性。 - - \ No newline at end of file diff --git a/apps/www/content/docs/cn/api/slate-utils.mdx b/apps/www/content/docs/cn/api/slate-utils.mdx deleted file mode 100644 index 0fc4bd41e9..0000000000 --- a/apps/www/content/docs/cn/api/slate-utils.mdx +++ /dev/null @@ -1,1018 +0,0 @@ ---- -title: Slate Utils -description: udecode/slate-utils的 API 参考。 ---- - -`@udecode/slate-utils` 包含用于 Slate 的实用函数。 - -## 查询 - -### findDescendant - -遍历编辑器中的所有节点并返回第一个匹配项。如果没有找到匹配项,则返回 undefined。 - - - - 要搜索后代节点的编辑器。 - - - 查找节点的选项。它可以包含匹配条件、起始位置、是否反向遍历以及是否包含空节点。 - - - - 返回第一个匹配条件的节点entry,如果没有找到匹配项则返回 `undefined`。 - - -### getBlockAbove - -返回指定位置上方的块 - -- **默认值:** 选区。 - - - - 要搜索块的编辑器。 - - - 查找位置上方块的选项。 - - - - -返回指定位置上方的块。 - - - -### getBlocks - -从编辑器中检索块级节点entry。 - - - - 要搜索块级节点的编辑器。 - - - 获取节点entry的选项。 - - - - - 块级节点entry的数组。 - - -### getChildren - -返回节点entry的子节点entry。 - - - - 要获取其子节点的节点entry。 - - - - -返回子节点entry的数组。 - - - -### getEdgeBlocksAbove - -返回指定位置上方的边缘块。 - -- **默认值:** 选区。 - - - - 要搜索边缘块的编辑器。 - - - 查找位置上方边缘块的选项。 - - - - 返回包含指定位置上方的起始块和结束块的数组,如果未找到则返回 `null`。 - - -### getFragmentProp - -从节点片段中检索一个一致的属性值。 - - - - 要搜索属性的节点片段。 - - - - - 从每个节点提取的属性键。 - - - 如果未找到有效属性时返回的默认值。 - - - 从节点提取属性值的自定义函数。 - - - 确定如何遍历片段: - - 'all':检查块节点和文本节点 - - 'block':仅检查块节点 - - 'text':仅检查文本节点 - 默认值为 'block'。 - - - - - - - 在片段中找到的一致属性值,如果没有找到一致的值则返回 undefined。 - - -### getFirstNodeText - -从节点获取第一个文本节点。 - - - - 要搜索文本节点的根节点。 - - - 获取节点文本的选项。 - - - - 返回第一个文本节点entry,如果未找到文本节点则返回 `undefined`。 - - -### getLastChild - -返回节点的最后一个子节点,如果没有子节点则返回 `null`。 - - - - 要获取其最后一个子节点的节点entry。 - - - - 返回节点的最后一个子节点,如果没有子节点则返回 `null`。 - - -### getLastNodeByLevel - -检索编辑器中指定层级的最后一个节点。 - - - - 要搜索最后一个节点的编辑器。 - - - 要查找最后一个节点的层级。 - - - - 返回指定层级的最后一个节点entry,如果未找到节点则返回 `undefined`。 - - -### getMark - -在编辑器中通过键检索选区标记的值。 - - - - 选区标记所在的编辑器。 - - - 要检索的选区标记的键。 - - - - 返回选区标记的值,如果未找到编辑器或标记则返回 `undefined`。 - - -### getNextNodeStartPoint - -检索编辑器中指定路径的下一个节点的起始点。 - - - - 要搜索下一个节点的编辑器。 - - - 要查找下一个节点的路径。 - - - - 返回下一个节点的起始点,如果未找到下一个节点则返回 `undefined`。 - - -### getNextSiblingNodes - -检索祖先节点中指定路径之后的兄弟节点。 - - - - 兄弟节点的祖先节点。 - - - 参考节点的路径。 - - - - 返回路径之后的兄弟节点数组,如果未找到兄弟节点则返回空数组。 - - -### getOperations - -检索编辑器的操作。 - - - - 要获取其操作的编辑器。 - - - - 返回编辑器的操作作为 `TOperation` 数组。 - - -### getPointBeforeLocation - -返回位置之前的点,并提供额外选项来自定义行为。如果未提供选项或者既未定义 **`match`** 也未定义 **`matchString`**,它将默认使用 **`getPointBefore`**。 - - - - 要在位置之前查找点的编辑器。 - - - 开始的位置。 - - - 定义如何执行搜索的选项。 - - - - 返回位置之前的点。如果未找到,则返回 `undefined`。 - - -### getPointFromLocation - -从位置返回点(**默认值:** 选区)。如果位置是范围,则获取锚点。如果位置是路径,则获取该路径上偏移量为 0 的点。 - - - -要查找点的编辑器。 - - - - - - -要获取点的位置。 - -- **默认值:** 选区。 - - - -如果为 true,返回焦点。否则,返回锚点。 - - - - - - - - - -返回位置的点。 - - - -### getPointNextToVoid - -如果起始点在内联空节点内,则返回其前面或后面的点。 - - - -要查找空节点旁边的点的编辑器。 - - - - - - -开始的点。 - - - -如果为 true,获取空节点后面的点。否则,获取前面的点。 - - - - - - - -返回空节点旁边的点。 - - - -### getPreviousBlockById - -通过 ID 查找块之前的块。如果未找到,则通过 ID 查找第一个块并返回 **`[null, 其前面的路径]`**。 - - - - 要查找前一个块的编辑器。 - - - 块的 ID。 - - - 节点查询的选项。 - - - - 如果找到,则返回前一个块的节点entry,否则返回 undefined。 - - -### getPreviousNodeEndPoint - -获取前一个节点的结束点。 - - - - 要查找前一个节点结束点的编辑器。 - - - 开始搜索的路径。 - - - - 如果找到,则返回前一个节点的结束点,否则返回 `undefined`。 - - -### getPreviousPath - -基于给定路径生成前一个路径。 - - - - 当前路径。 - - - - 前一个路径,如果没有前一个路径则返回 `undefined`。 - - -### getPreviousSiblingNode - -从给定路径获取前一个兄弟节点。 - - - - 编辑器实例。 - - - 当前路径。 - - - - 包含前一个兄弟节点及其路径的数组,如果没有前一个兄弟节点则返回 `undefined`。 - - -### getRangeBefore - -获取给定位置之前的点到位置结束点的范围。 - - - - 编辑器实例。 - - - 要考虑的位置。 - - - 获取位置之前点的选项。 - - - - 从位置之前的点到位置结束点的范围,如果不存在这样的点则返回 `undefined`。 - - -### getRangeFromBlockStart - -获取从位置上方块的开始到位置的范围。 - - - - 编辑器实例。 - - - 获取位置上方块的选项。 - - - - 从位置上方块的开始到位置的范围,如果不存在这样的块则返回 `undefined`。 - - -### getSelectionFragment - -检索当前选区的片段,可选择解包结构节点。 - - - - 要获取选区片段的编辑器。 - - - - - 要从片段中解包的结构类型数组。 - - - - - - - 表示当前选区片段的 `TElement` 数组。如果选区未展开或未找到片段,则返回空数组。 - - -### getSelectionText - -从编辑器获取选中的文本。 - - - - 编辑器实例。 - - - - 选中的文本,如果未选中文本则返回空字符串。 - - -### isAncestorEmpty - -检查祖先节点是否为空(具有空文本且没有内联子节点)。 - - - - 编辑器实例。 - - - 要检查的祖先节点。 - - - - -如果祖先节点为空则返回 true,否则返回 false。 - - - -### isBlockAboveEmpty - -检查选区上方的块是否为空。 - - - - 编辑器实例。 - - - - -如果选区上方的块为空则返回 true,否则返回 false。 - - - -### isBlockTextEmptyAfterSelection - -检查选区后块中的文本是否为空。 - - - - 编辑器实例。 - - - - -如果选区后块中的文本为空则返回 true,否则返回 false。 - - - -### isDocumentEnd - -检查选区是否在文档末尾。 - - - - 编辑器实例。 - - - - -如果选区在文档末尾则返回 true,否则返回 false。 - - - -### isFirstChild - -检查节点是否是其父节点的第一个子节点。 - - - - 要检查的节点的路径。 - - - - -如果节点是其父节点的第一个子节点则返回 true,否则返回 false。 - - - -### isMarkActive - -检查选区中是否激活了标记。 - - - - 编辑器实例。 - - - 标记键。 - - - - -如果选区中激活了标记则返回 true。 - - - -### isPointAtWordEnd - -检查点是否在单词末尾。 - - - - 编辑器实例。 - - - 要检查的点。 - - - - 如果点在单词末尾则返回 true,否则返回 false。 - - -### isRangeAcrossBlocks - -确定范围(**默认值:** 选区)是否跨越多个块。 - - - - 编辑器实例。 - - - 要检查的范围。如果未提供,则使用选区范围。 - - - - 如果范围跨越多个块则返回 true,如果在单个块内则返回 false,如果未找到块则返回 undefined。 - - -### isRangeInSameBlock - -确定范围是否在同一个块内。 - - - - 编辑器实例。 - - - 要检查的范围。如果未提供,则使用选区范围。 - - - - 如果范围在同一个块内则返回 true,否则返回 false。 - - -### isRangeInSingleText - -检查范围是否在单个文本路径内。 - - - - 要检查的范围。 - - - - 如果范围在单个文本路径内则返回 true,否则返回 false。 - - -### isSelectionAtBlockEnd - -检查选区焦点是否在其父块的末尾。 - - - - 编辑器实例。 - - - 选项对象。 - - - - 如果选区焦点在其父块的末尾则返回 true,否则返回 false。 - - -### isSelectionAtBlockStart - -检查选区锚点或焦点是否在其父块的开始。 - - - - 编辑器实例。 - - - 选项对象。 - - - - 如果选区锚点或焦点在其父块的开始则返回 true,否则返回 false。 - - -### isSelectionExpanded - -检查选区是否展开。 - - - - 编辑器实例。 - - - - -如果选区展开则返回 true,否则返回 false。 - - - -### isTextByPath - -检查给定路径的节点是否是文本节点。 - - - - 编辑器实例。 - - - 要检查的节点的路径。 - - - - -如果节点是文本节点则返回 true,否则返回 false。 - - - -### isWordAfterTrigger - -检查给定点的单词是否在触发器(标点符号)之后。 - - - - 编辑器实例。 - - - 要检查的点。 - - - 要检查的触发字符。 - - - - 一个对象,包含从前一个单词开始之前的点到给定点的范围,如果该范围的文本以触发器开始并以单词字符结束,则包含匹配项。 - - -### queryEditor - -查询编辑器状态。 - - - - 编辑器实例。 - - - 选项对象,可以包含过滤函数、selectionAtBlockStart、selectionAtBlockEnd、allow、exclude 和 at 属性。 - - - - 如果编辑器状态匹配查询则返回 true,否则返回 false。 - - -## 转换 - -### duplicateBlocks - -复制给定的块并将它们插入到选区中最后一个块之后。 - - - - 编辑器实例。 - - - 表示要复制的块的节点entry数组。 - - - -### insertElements - -在文档中的位置插入节点。 - - - - 编辑器实例。 - - - 要插入的节点。 - - - 选项对象。 - - - -### insertEmptyElement - -在文档中的位置插入空元素。 - - - - 编辑器实例。 - - - 要插入的元素的类型。 - - - 选项对象。 - - - -### moveChildren - -将节点的子节点移动到路径。 - - - - 编辑器实例。 - - - 选项对象,包括 `at`、`to`、`match` 和 `fromStartIndex` 属性。 - - - - -移动的子节点数量。 - - - -### removeEditorText - -从编辑器中删除所有非空文本节点。 - - - - 编辑器实例。 - - - 删除节点的选项。选项中的 `match` 函数将与文本长度检查组合。 - - - -### removeMark - -删除标记,如果选区折叠则触发 `onChange`。 - - - - 编辑器实例。 - - - 选项对象,包括 `key`、`at` 和 `shouldChange` 属性。 - - - -### removeNodeChildren - -删除节点的所有子节点。 - - - - 编辑器实例。 - - - 要删除子节点的节点的路径。 - - - 选项对象。 - - - -### removeSelectionMark - -从选区中删除所有标记。 - - - - 编辑器实例。 - - - -### replaceNodeChildren - -替换节点的子节点:先删除后插入。 - - - - 编辑器实例。 - - - 选项对象,包括 `at`、`nodes`、`insertOptions` 和 `removeOptions` 属性。 - - - -### selectEndOfBlockAboveSelection - -选择选区上方块的结束点。 - - - - 编辑器实例。 - - - -### selectNodes - -选择包含给定节点的范围。 - - - - 编辑器实例。 - - - 要选择的节点entry数组。 - - - -### setBlockAboveNode - -在当前选区上方的块上设置属性。 - - - - 编辑器实例。 - - - 要在块上设置的属性。 - - - 设置节点的选项,不包括 'at' 属性。 - - - -### setBlockAboveTexts - -在当前选区上方块内的最低级节点上设置属性。 - - - - 编辑器实例。 - - - 要在文本节点上设置的属性。 - - - 设置节点的选项,不包括 'at' 属性。 - - - -### setBlockNodes - -在所有匹配给定选项的块节点上设置属性。 - - - - 编辑器实例。 - - - 要在匹配的块节点上设置的属性。 - - - 获取要更新的节点entry的选项。 - - - -### setMarks - -在选中的文本上设置标记。 - - - - 编辑器实例。 - - - 要设置的标记。 - - - 要清除的标记。 - - - -### toggleMark - -在选区中添加或删除标记。 - - - - 编辑器实例。 - - - 选项对象,包含 `key` 和 `clear` 属性。 - - - -### toggleWrapNodes - -如果选区中存在该节点类型则解除包装,否则进行包装。 - - - - 编辑器实例。 - - - 节点的类型。 - - - -### wrapNodeChildren - -将节点的子节点包装到单个元素中。 - - - - 编辑器实例。 - - - 新的父元素。 - - - 选项对象,包含 `at` 属性。 - - - -## Utils - -### createDocumentNode - -创建一个新的文档节点。 - - - -节点的类型。 - -- **默认值:** `'p'` - - - -节点的文本。 - -- **默认值:** 空字符串。 - - - -剩余的节点。 - -- **默认值:** 空数组。 - - - - -一个 `TDescendant` 节点数组,以新创建的节点开始。 - - -### createNode - -创建一个新节点。 - - - -节点的类型。 - -- **默认值:** `'p'` - - - -节点的文本。 - -- **默认值:** 空字符串。 - - - - - -一个新的 `TElement` 节点。 - - diff --git a/apps/www/content/docs/cn/api/slate.mdx b/apps/www/content/docs/cn/api/slate.mdx index c9167ffd44..630b6f56f0 100644 --- a/apps/www/content/docs/cn/api/slate.mdx +++ b/apps/www/content/docs/cn/api/slate.mdx @@ -111,7 +111,7 @@ description: udecode/slate的 API 参考。 ### `removeEditorMark` -### `TEditor` +### `Editor` ### `unhangRange` @@ -149,7 +149,7 @@ description: udecode/slate的 API 参考。 在 [Slate 文档](https://docs.slatejs.org/api/nodes/node) 中查找相应的文档。 -### `TDescendant` +### `Descendant` ### `getNodeDescendants` @@ -173,7 +173,7 @@ description: udecode/slate的 API 参考。 ### `getNodeProps` -### `TAncestor` +### `Ancestor` ### `getNode` @@ -185,7 +185,7 @@ description: udecode/slate的 API 参考。 ### `getNodeAncestor` -### `TNodeEntry` +### `NodeEntry` ### `TNode` @@ -280,7 +280,7 @@ description: udecode/slate的 API 参考。 @@ -312,3 +312,1055 @@ description: udecode/slate的 API 参考。 + +# DOM Editor + +在 [Slate React 文档](https://docs.slatejs.org/libraries/slate-react/react-editor) 中查找相应的文档。 + +### `blurEditor` + +### `deselectEditor` + +### `findEditorDocumentOrShadowRoot` + +### `findEventRange` + +### `findNodeKey` + +### `findPath` + +### `focusEditor` + +### `getEditorWindow` + +### `hasEditorDOMNode` + +### `hasEditorEditableTarget` + +### `hasEditorSelectableTarget` + +### `hasEditorTarget` + +### `insertData` + +### `isComposing` + +### `isEditorFocused` + +### `isEditorReadOnly` + +### `isTargetInsideNonReadonlyVoidEditor` + +### `setFragmentData` + +### `toDOMNode` + +### `toDOMPoint` + +### `toDOMRange` + +### `toSlateNode` + +### `toSlatePoint` + +### `toSlateRange` + +## Queries + +### findDescendant + +遍历编辑器中的所有节点并返回第一个匹配项。如果没有找到匹配项,则返回 undefined。 + + + + 要搜索后代节点的编辑器。 + + + 查找节点的选项。它可以包含匹配条件、起始位置、是否反向遍历以及是否包含空节点。 + + + + 返回第一个匹配条件的节点entry,如果没有找到匹配项则返回 `undefined`。 + + +### getBlockAbove + +返回指定位置上方的块 + +- **默认值:** 选区。 + + + + 要搜索块的编辑器。 + + + 查找位置上方块的选项。 + + + + +返回指定位置上方的块。 + + + +### getBlocks + +从编辑器中检索块级节点entry。 + + + + 要搜索块级节点的编辑器。 + + + 获取节点entry的选项。 + + + + + 块级节点entry的数组。 + + +### getChildren + +返回节点entry的子节点entry。 + + + + 要获取其子节点的节点entry。 + + + + +返回子节点entry的数组。 + + + +### getEdgeBlocksAbove + +返回指定位置上方的边缘块。 + +- **默认值:** 选区。 + + + + 要搜索边缘块的编辑器。 + + + 查找位置上方边缘块的选项。 + + + + 返回包含指定位置上方的起始块和结束块的数组,如果未找到则返回 `null`。 + + +### getFragmentProp + +从节点片段中检索一个一致的属性值。 + + + + 要搜索属性的节点片段。 + + + + + 从每个节点提取的属性键。 + + + 如果未找到有效属性时返回的默认值。 + + + 从节点提取属性值的自定义函数。 + + + 确定如何遍历片段: + - 'all':检查块节点和文本节点 + - 'block':仅检查块节点 + - 'text':仅检查文本节点 + 默认值为 'block'。 + + + + + + + 在片段中找到的一致属性值,如果没有找到一致的值则返回 undefined。 + + +### getFirstNodeText + +从节点获取第一个文本节点。 + + + + 要搜索文本节点的根节点。 + + + 获取节点文本的选项。 + + + + 返回第一个文本节点entry,如果未找到文本节点则返回 `undefined`。 + + +### getLastChild + +返回节点的最后一个子节点,如果没有子节点则返回 `null`。 + + + + 要获取其最后一个子节点的节点entry。 + + + + 返回节点的最后一个子节点,如果没有子节点则返回 `null`。 + + +### getLastNodeByLevel + +检索编辑器中指定层级的最后一个节点。 + + + + 要搜索最后一个节点的编辑器。 + + + 要查找最后一个节点的层级。 + + + + 返回指定层级的最后一个节点entry,如果未找到节点则返回 `undefined`。 + + +### getMark + +在编辑器中通过键检索选区标记的值。 + + + + 选区标记所在的编辑器。 + + + 要检索的选区标记的键。 + + + + 返回选区标记的值,如果未找到编辑器或标记则返回 `undefined`。 + + +### getNextNodeStartPoint + +检索编辑器中指定路径的下一个节点的起始点。 + + + + 要搜索下一个节点的编辑器。 + + + 要查找下一个节点的路径。 + + + + 返回下一个节点的起始点,如果未找到下一个节点则返回 `undefined`。 + + +### getNextSiblingNodes + +检索祖先节点中指定路径之后的兄弟节点。 + + + + 兄弟节点的祖先节点。 + + + 参考节点的路径。 + + + + 返回路径之后的兄弟节点数组,如果未找到兄弟节点则返回空数组。 + + +### getOperations + +检索编辑器的操作。 + + + + 要获取其操作的编辑器。 + + + + 返回编辑器的操作作为 `Operation` 数组。 + + +### getPointBeforeLocation + +返回位置之前的点,并提供额外选项来自定义行为。如果未提供选项或者既未定义 **`match`** 也未定义 **`matchString`**,它将默认使用 **`getPointBefore`**。 + + + + 要在位置之前查找点的编辑器。 + + + 开始的位置。 + + + 定义如何执行搜索的选项。 + + + + 返回位置之前的点。如果未找到,则返回 `undefined`。 + + +### getPointFromLocation + +从位置返回点(**默认值:** 选区)。如果位置是范围,则获取锚点。如果位置是路径,则获取该路径上偏移量为 0 的点。 + + + +要查找点的编辑器。 + + + + + + +要获取点的位置。 + +- **默认值:** 选区。 + + + +如果为 true,返回焦点。否则,返回锚点。 + + + + + + + + + +返回位置的点。 + + + +### getPointNextToVoid + +如果起始点在内联空节点内,则返回其前面或后面的点。 + + + +要查找空节点旁边的点的编辑器。 + + + + + + +开始的点。 + + + +如果为 true,获取空节点后面的点。否则,获取前面的点。 + + + + + + + +返回空节点旁边的点。 + + + +### getPreviousBlockById + +通过 ID 查找块之前的块。如果未找到,则通过 ID 查找第一个块并返回 **`[null, 其前面的路径]`**。 + + + + 要查找前一个块的编辑器。 + + + 块的 ID。 + + + 节点查询的选项。 + + + + 如果找到,则返回前一个块的节点entry,否则返回 undefined。 + + +### getPreviousNodeEndPoint + +获取前一个节点的结束点。 + + + + 要查找前一个节点结束点的编辑器。 + + + 开始搜索的路径。 + + + + 如果找到,则返回前一个节点的结束点,否则返回 `undefined`。 + + +### getPreviousPath + +基于给定路径生成前一个路径。 + + + + 当前路径。 + + + + 前一个路径,如果没有前一个路径则返回 `undefined`。 + + +### getPreviousSiblingNode + +从给定路径获取前一个兄弟节点。 + + + + 编辑器实例。 + + + 当前路径。 + + + + 包含前一个兄弟节点及其路径的数组,如果没有前一个兄弟节点则返回 `undefined`。 + + +### getRangeBefore + +获取给定位置之前的点到位置结束点的范围。 + + + + 编辑器实例。 + + + 要考虑的位置。 + + + 获取位置之前点的选项。 + + + + 从位置之前的点到位置结束点的范围,如果不存在这样的点则返回 `undefined`。 + + +### getRangeFromBlockStart + +获取从位置上方块的开始到位置的范围。 + + + + 编辑器实例。 + + + 获取位置上方块的选项。 + + + + 从位置上方块的开始到位置的范围,如果不存在这样的块则返回 `undefined`。 + + +### getSelectionFragment + +检索当前选区的片段,可选择解包结构节点。 + + + + 要获取选区片段的编辑器。 + + + + + 要从片段中解包的结构类型数组。 + + + + + + + 表示当前选区片段的 `TElement` 数组。如果选区未展开或未找到片段,则返回空数组。 + + +### getSelectionText + +从编辑器获取选中的文本。 + + + + 编辑器实例。 + + + + 选中的文本,如果未选中文本则返回空字符串。 + + +### isAncestorEmpty + +检查祖先节点是否为空(具有空文本且没有内联子节点)。 + + + + 编辑器实例。 + + + 要检查的祖先节点。 + + + + +如果祖先节点为空则返回 true,否则返回 false。 + + + +### isBlockAboveEmpty + +检查选区上方的块是否为空。 + + + + 编辑器实例。 + + + + +如果选区上方的块为空则返回 true,否则返回 false。 + + + +### isBlockTextEmptyAfterSelection + +检查选区后块中的文本是否为空。 + + + + 编辑器实例。 + + + + +如果选区后块中的文本为空则返回 true,否则返回 false。 + + + +### isDocumentEnd + +检查选区是否在文档末尾。 + + + + 编辑器实例。 + + + + +如果选区在文档末尾则返回 true,否则返回 false。 + + + +### isFirstChild + +检查节点是否是其父节点的第一个子节点。 + + + + 要检查的节点的路径。 + + + + +如果节点是其父节点的第一个子节点则返回 true,否则返回 false。 + + + +### isMarkActive + +检查选区中是否激活了标记。 + + + + 编辑器实例。 + + + 标记键。 + + + + +如果选区中激活了标记则返回 true。 + + + +### isPointAtWordEnd + +检查点是否在单词末尾。 + + + + 编辑器实例。 + + + 要检查的点。 + + + + 如果点在单词末尾则返回 true,否则返回 false。 + + +### isRangeAcrossBlocks + +确定范围(**默认值:** 选区)是否跨越多个块。 + + + + 编辑器实例。 + + + 要检查的范围。如果未提供,则使用选区范围。 + + + + 如果范围跨越多个块则返回 true,如果在单个块内则返回 false,如果未找到块则返回 undefined。 + + +### isRangeInSameBlock + +确定范围是否在同一个块内。 + + + + 编辑器实例。 + + + 要检查的范围。如果未提供,则使用选区范围。 + + + + 如果范围在同一个块内则返回 true,否则返回 false。 + + +### isRangeInSingleText + +检查范围是否在单个文本路径内。 + + + + 要检查的范围。 + + + + 如果范围在单个文本路径内则返回 true,否则返回 false。 + + +### isSelectionAtBlockEnd + +检查选区焦点是否在其父块的末尾。 + + + + 编辑器实例。 + + + 选项对象。 + + + + 如果选区焦点在其父块的末尾则返回 true,否则返回 false。 + + +### isSelectionAtBlockStart + +检查选区锚点或焦点是否在其父块的开始。 + + + + 编辑器实例。 + + + 选项对象。 + + + + 如果选区锚点或焦点在其父块的开始则返回 true,否则返回 false。 + + +### isSelectionExpanded + +检查选区是否展开。 + + + + 编辑器实例。 + + + + +如果选区展开则返回 true,否则返回 false。 + + + +### isTextByPath + +检查给定路径的节点是否是文本节点。 + + + + 编辑器实例。 + + + 要检查的节点的路径。 + + + + +如果节点是文本节点则返回 true,否则返回 false。 + + + +### isWordAfterTrigger + +检查给定点的单词是否在触发器(标点符号)之后。 + + + + 编辑器实例。 + + + 要检查的点。 + + + 要检查的触发字符。 + + + + 一个对象,包含从前一个单词开始之前的点到给定点的范围,如果该范围的文本以触发器开始并以单词字符结束,则包含匹配项。 + + +### queryEditor + +查询编辑器状态。 + + + + 编辑器实例。 + + + 选项对象,可以包含过滤函数、selectionAtBlockStart、selectionAtBlockEnd、allow、exclude 和 at 属性。 + + + + 如果编辑器状态匹配查询则返回 true,否则返回 false。 + + +## Transforms + +### focusEditorEdge + +在指定的边缘(开始或结束)聚焦编辑器。 + + + + 编辑器实例。 + + + + + 要聚焦的边缘。 + - 'start': 在编辑器开始处聚焦。 + - 'end': 在编辑器结束处聚焦。 + 默认值为 'start'。 + + + + + +### duplicateBlocks + +复制给定的块并将它们插入到选区中最后一个块之后。 + + + + 编辑器实例。 + + + 表示要复制的块的节点entry数组。 + + + +### moveChildren + +将节点的子节点移动到路径。 + + + + 编辑器实例。 + + + 选项对象,包括 `at`、`to`、`match` 和 `fromStartIndex` 属性。 + + + + +移动的子节点数量。 + + + +### removeEditorText + +从编辑器中删除所有非空文本节点。 + + + + 编辑器实例。 + + + 删除节点的选项。选项中的 `match` 函数将与文本长度检查组合。 + + + +### removeMark + +删除标记,如果选区折叠则触发 `onChange`。 + + + + 编辑器实例。 + + + 选项对象,包括 `key`、`at` 和 `shouldChange` 属性。 + + + +### removeNodeChildren + +删除节点的所有子节点。 + + + + 编辑器实例。 + + + 要删除子节点的节点的路径。 + + + 选项对象。 + + + +### removeSelectionMark + +从选区中删除所有标记。 + + + + 编辑器实例。 + + + +### replaceNodeChildren + +替换节点的子节点:先删除后插入。 + + + + 编辑器实例。 + + + 选项对象,包括 `at`、`nodes`、`insertOptions` 和 `removeOptions` 属性。 + + + +### selectEndOfBlockAboveSelection + +选择选区上方块的结束点。 + + + + 编辑器实例。 + + + +### selectNodes + +选择包含给定节点的范围。 + + + + 编辑器实例。 + + + 要选择的节点entry数组。 + + + +### setBlockAboveNode + +在当前选区上方的块上设置属性。 + + + + 编辑器实例。 + + + 要在块上设置的属性。 + + + 设置节点的选项,不包括 'at' 属性。 + + + +### setBlockAboveTexts + +在当前选区上方块内的最低级节点上设置属性。 + + + + 编辑器实例。 + + + 要在文本节点上设置的属性。 + + + 设置节点的选项,不包括 'at' 属性。 + + + +### setBlockNodes + +在所有匹配给定选项的块节点上设置属性。 + + + + 编辑器实例。 + + + 要在匹配的块节点上设置的属性。 + + + 获取要更新的节点entry的选项。 + + + +### setMarks + +在选中的文本上设置标记。 + + + + 编辑器实例。 + + + 要设置的标记。 + + + 要清除的标记。 + + + +### toggleMark + +在选区中添加或删除标记。 + + + + 编辑器实例。 + + + 选项对象,包含 `key` 和 `clear` 属性。 + + + +### toggleWrapNodes + +如果选区中存在该节点类型则解除包装,否则进行包装。 + + + + 编辑器实例。 + + + 节点的类型。 + + + +### wrapNodeChildren + +将节点的子节点包装到单个元素中。 + + + + 编辑器实例。 + + + 新的父元素。 + + + 选项对象,包含 `at` 属性。 + + + +## Utils + +### createDocumentNode + +创建一个新的文档节点。 + + + +节点的类型。 + +- **默认值:** `'p'` + + + +节点的文本。 + +- **默认值:** 空字符串。 + + + +剩余的节点。 + +- **默认值:** 空数组。 + + + + +一个 `Descendant` 节点数组,以新创建的节点开始。 + + +### createNode + +创建一个新节点。 + + + +节点的类型。 + +- **默认值:** `'p'` + + + +节点的文本。 + +- **默认值:** 空字符串。 + + + + + +一个新的 `TElement` 节点。 + + diff --git a/apps/www/content/docs/cn/api/utils.mdx b/apps/www/content/docs/cn/api/utils.mdx index 453f7f5f9f..615bc7b407 100644 --- a/apps/www/content/docs/cn/api/utils.mdx +++ b/apps/www/content/docs/cn/api/utils.mdx @@ -226,137 +226,3 @@ PlateLeafProps。 - -## Queries - -### isType - -检查节点是否匹配提供的类型。 - - - - 节点所在的编辑器。 - - - 要检查的节点。 - - - 用于匹配节点的类型。可以是字符串或字符串数组。 - - - - 一个布尔值,指示节点的类型是否匹配提供的类型。 - - -## Transforms - -### resetEditorChildren - -用默认块替换编辑器的子节点。 - - - - 要替换其子节点的编辑器。 - - - 替换节点子节点的选项。不包括 `at` 和 `nodes` 选项。 - - - -### selectEditor - -在目标位置或边缘(开始、结束)选择编辑器。 - - - - 要选择的编辑器。 - - - 要选择的具体位置。 - - 如果未定义 `edge`,则考虑此选项。 - - - 选择编辑器的开始或结束。 - - 如果定义了此选项,则覆盖 `at` 选项。 - - - 如果为 true,则在选择 markdown Copy code 之前聚焦 React 编辑器。 - - - **默认值:** `false` - - - - - 没有显式返回,但会选择并可能聚焦编辑器。 - - -### moveSelectionByOffset - -根据键盘方向键按偏移量移动选择。 - - - - 编辑器实例。 - - - 按偏移量移动选择的选项。这是一个可选参数。 - - - 启用行为的查询函数。 - - - 触发移动的键盘事件。 - - - - - -### selectSiblingNodePoint - -从指定节点的前一个或后一个兄弟节点选择一个点。 - - - - 编辑器实例。 - - - 选择兄弟节点点的选项。 - - - 参考节点的路径。如果未提供,则必须指定 `node`。 - - - 是否选择前一个兄弟节点而不是后一个。 - - `false`: 选择下一个兄弟节点的起始点。 - - `true`: 选择前一个兄弟节点的结束点。 - - **Default:** `false` - - - 选择后是否聚焦编辑器。 - - **Default:** `true` - - - 参考节点。如果未提供 `at`,则用于查找路径。 - - - - - -## Utils - -### defaultsDeepToNodes - -使用查询递归地将源对象合并到子节点中。 - - - - 函数的选项,不包括 'apply' 选项。 - - - - 没有显式返回,但会根据提供的选项修改子节点。 - diff --git a/apps/www/content/docs/cn/basic-elements.mdx b/apps/www/content/docs/cn/basic-elements.mdx index e423fcd225..63250d64ef 100644 --- a/apps/www/content/docs/cn/basic-elements.mdx +++ b/apps/www/content/docs/cn/basic-elements.mdx @@ -138,7 +138,7 @@ const plugins = [ - + 要缩进的代码行。 - + 要减少缩进的代码行。 - + 包含要减少缩进的代码行的代码块。 diff --git a/apps/www/content/docs/cn/block-selection.mdx b/apps/www/content/docs/cn/block-selection.mdx index ce86779ecf..0e40000773 100644 --- a/apps/www/content/docs/cn/block-selection.mdx +++ b/apps/www/content/docs/cn/block-selection.mdx @@ -251,7 +251,7 @@ Options for the selection area. Example: 获取编辑器中选中的块。 - + 选中块entry的数组。 @@ -291,12 +291,6 @@ Options for the selection area. Example: 复制选中的块。 - - - 要复制的节点entry数组。 - - - ### editor.tf.blockSelection.removeNodes 从编辑器中移除选中的节点。 @@ -310,7 +304,7 @@ Options for the selection area. Example: 设置选中节点的属性。 - + 要设置到选中节点的属性。 @@ -323,7 +317,7 @@ Options for the selection area. Example: 设置选中节点的文本属性。 - + 要设置到选中节点的文本属性。 diff --git a/apps/www/content/docs/cn/callout.mdx b/apps/www/content/docs/cn/callout.mdx index 14240cadd9..9875b06674 100644 --- a/apps/www/content/docs/cn/callout.mdx +++ b/apps/www/content/docs/cn/callout.mdx @@ -75,7 +75,7 @@ Work in progress. 要插入的标注变体。 - + 来自 `InsertNodesOptions` 的其他选项。 diff --git a/apps/www/content/docs/cn/caption.mdx b/apps/www/content/docs/cn/caption.mdx index a64ed37e38..e2e277c78f 100644 --- a/apps/www/content/docs/cn/caption.mdx +++ b/apps/www/content/docs/cn/caption.mdx @@ -85,7 +85,7 @@ const plugins = [ 扩展 `TElement`. - + 标题值。 diff --git a/apps/www/content/docs/cn/combobox.mdx b/apps/www/content/docs/cn/combobox.mdx index ac41df506a..3e178a8076 100644 --- a/apps/www/content/docs/cn/combobox.mdx +++ b/apps/www/content/docs/cn/combobox.mdx @@ -41,7 +41,6 @@ const ComboboxInputPlugin = createPlatePlugin({ ```ts const MyPlugin = createPlatePlugin({ key: 'my_plugin', - extendEditor: withTriggerCombobox, // Plugin node options node: { isElement: true, @@ -60,7 +59,7 @@ const MyPlugin = createPlatePlugin({ }, // Include the input plugin plugins: [ComboboxInputPlugin], -}); +}).overrideEditor(withTriggerCombobox); ``` diff --git a/apps/www/content/docs/cn/comments.mdx b/apps/www/content/docs/cn/comments.mdx index 72b75bba8c..72cfdb2f41 100644 --- a/apps/www/content/docs/cn/comments.mdx +++ b/apps/www/content/docs/cn/comments.mdx @@ -124,7 +124,7 @@ const editor = createPlateEditor({ 编辑器实例。 - + 查找节点的附加选项。 diff --git a/apps/www/content/docs/cn/components/changelog.mdx b/apps/www/content/docs/cn/components/changelog.mdx index 01642f21f2..62c58f5f13 100644 --- a/apps/www/content/docs/cn/components/changelog.mdx +++ b/apps/www/content/docs/cn/components/changelog.mdx @@ -480,7 +480,7 @@ export const TableElement = withHOC( - 从依赖中移除 `clsx`:`class-variance-utility` 已经将其导出为 `cx` - 新依赖:`@udecode/cn` - 移除 `@/lib/utils.ts` 并使用 `@udecode/cn` 代替。将所有从 `@/lib/utils` 导入的代码替换为 `@udecode/cn` -- 从 `@udecode/cn` 导入 `withProps` 而不是 `@udecode/plate-common` +- 从 `@udecode/cn` 导入 `withProps` 而不是 `@udecode/plate` ` - 所有使用 `forwardRef` 的组件现在使用 `withRef`。`withProps`、`withCn` 和 `withVariants` 也被使用以减少样板代码。 diff --git a/apps/www/content/docs/cn/components/installation/manual.mdx b/apps/www/content/docs/cn/components/installation/manual.mdx index a7e93f59c2..069c703643 100644 --- a/apps/www/content/docs/cn/components/installation/manual.mdx +++ b/apps/www/content/docs/cn/components/installation/manual.mdx @@ -16,7 +16,7 @@ description: 手动将依赖项添加到您的项目中。 Add the following dependencies to your project: ```bash -npm install slate slate-dom slate-react slate-history slate-hyperscript @udecode/plate-common @udecode/cn class-variance-authority tailwindcss-animate tailwind-scrollbar-hide lucide-react +npm install @udecode/plate @udecode/cn class-variance-authority tailwindcss-animate tailwind-scrollbar-hide lucide-react ``` ### Configure path aliases diff --git a/apps/www/content/docs/cn/csv.mdx b/apps/www/content/docs/cn/csv.mdx index 675fa26d0d..7e02787f77 100644 --- a/apps/www/content/docs/cn/csv.mdx +++ b/apps/www/content/docs/cn/csv.mdx @@ -90,8 +90,8 @@ CSV 数据中错误的容忍度,以小数形式表示的百分比。该值是 - - 返回一个 `TDescendant` 对象数组,表示 CSV 数据在 Slate 兼容格式下的结构。 + + 返回一个 `Descendant` 对象数组,表示 CSV 数据在 Slate 兼容格式下的结构。 如果 CSV 数据解析失败或数据无效,此函数返回 `undefined`。 diff --git a/apps/www/content/docs/cn/debugging.mdx b/apps/www/content/docs/cn/debugging.mdx index 107dd1636b..55dc2bcd1e 100644 --- a/apps/www/content/docs/cn/debugging.mdx +++ b/apps/www/content/docs/cn/debugging.mdx @@ -109,17 +109,14 @@ You can use the `extendEditor` option to override editor methods and add logging ```ts const LoggingPlugin = createPlatePlugin({ key: 'logging', - extendEditor: (editor) => { - const { apply } = editor; - - editor.apply = (operation) => { +}).overrideEditor(({ editor, tf: { apply } }) => ({ + transforms: { + apply(operation) { console.log('Operation:', operation); apply(operation); - }; - - return editor; + }, }, -}); +})); const editor = createPlateEditor({ plugins: [LoggingPlugin], diff --git a/apps/www/content/docs/cn/dnd.mdx b/apps/www/content/docs/cn/dnd.mdx index 195ce13344..5cab0609d0 100644 --- a/apps/www/content/docs/cn/dnd.mdx +++ b/apps/www/content/docs/cn/dnd.mdx @@ -81,7 +81,7 @@ const plugins = [ 编辑器实例。 - + 获取节点entry的选项。 @@ -202,7 +202,7 @@ const plugins = [ 拖放的方向。默认为 `'vertical'`。 - + 确定节点是否可以在当前位置放置的回调。 diff --git a/apps/www/content/docs/cn/editor-methods.mdx b/apps/www/content/docs/cn/editor-methods.mdx index f4f140a8e3..a26b23f480 100644 --- a/apps/www/content/docs/cn/editor-methods.mdx +++ b/apps/www/content/docs/cn/editor-methods.mdx @@ -18,7 +18,7 @@ description: 探索用于与 Plate 编辑器交互和自定义的各种方法。 - `useEditorState`: 每次更改时重新渲染。 ```ts -import { useEditorRef, useEditorSelector, useEditorState } from '@udecode/plate-common/react'; +import { useEditorRef, useEditorSelector, useEditorState } from '@udecode/plate/react'; const MyComponent = () => { const editor = useEditorRef(); @@ -56,7 +56,7 @@ const MyComponent = () => { 要在 `Plate` 组件外部访问编辑器或处理多个编辑器,请使用 `PlateController` 组件: ```ts -import { PlateController } from '@udecode/plate-common/react'; +import { PlateController } from '@udecode/plate/react'; const App = () => ( diff --git a/apps/www/content/docs/cn/editor.mdx b/apps/www/content/docs/cn/editor.mdx index 8aa49a4a12..99e267dbc1 100644 --- a/apps/www/content/docs/cn/editor.mdx +++ b/apps/www/content/docs/cn/editor.mdx @@ -10,7 +10,7 @@ description: 学习如何配置和自定义 Plate 编辑器。 要创建一个基本的 Plate 编辑器,你可以使用 `createPlateEditor` 函数,或在 React 组件中使用 `usePlateEditor`: ```ts -import { createPlateEditor } from '@udecode/plate-common/react'; +import { createPlateEditor } from '@udecode/plate/react'; const editor = createPlateEditor({ plugins: [ParagraphPlugin, HeadingPlugin], @@ -207,8 +207,8 @@ editor.tf.insert.tableRow() 对于更复杂的编辑器,你可以在单独的文件中定义你的类型(例如 `plate-types.ts`): ```ts -import type { TElement, TText } from '@udecode/plate-common'; -import type { TPlateEditor } from '@udecode/plate-common/react'; +import type { TElement, TText } from '@udecode/plate'; +import type { TPlateEditor } from '@udecode/plate/react'; // 定义自定义元素类型 interface ParagraphElement extends TElement { diff --git a/apps/www/content/docs/cn/excalidraw.mdx b/apps/www/content/docs/cn/excalidraw.mdx index 1bc5ce1be2..bffa6aee73 100644 --- a/apps/www/content/docs/cn/excalidraw.mdx +++ b/apps/www/content/docs/cn/excalidraw.mdx @@ -54,7 +54,7 @@ const plugins = [ Excalidraw 元素的属性。 diff --git a/apps/www/content/docs/cn/forced-layout.mdx b/apps/www/content/docs/cn/forced-layout.mdx index 3f8b8abb8b..6e3980935d 100644 --- a/apps/www/content/docs/cn/forced-layout.mdx +++ b/apps/www/content/docs/cn/forced-layout.mdx @@ -23,7 +23,7 @@ npm install @udecode/plate-normalizers @udecode/plate-trailing-block ```tsx import { NormalizersPlugin } from '@udecode/plate-normalizers/react'; import { TrailingBlockPlugin } from '@udecode/plate-trailing-block/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { HEADING_KEYS } from '@udecode/plate-heading/react'; const plugins = [ diff --git a/apps/www/content/docs/cn/getting-started.mdx b/apps/www/content/docs/cn/getting-started.mdx index 5b21b9b0ad..7ae74c5caa 100644 --- a/apps/www/content/docs/cn/getting-started.mdx +++ b/apps/www/content/docs/cn/getting-started.mdx @@ -22,7 +22,7 @@ description: 一个快速教程,帮助你快速上手 Plate。 首先,安装核心依赖: ```bash -npm install @udecode/plate-common slate slate-dom slate-react slate-history +npm install @udecode/plate slate-react ``` 对于本指南中的示例,我们还将使用这些插件: @@ -45,7 +45,7 @@ import { usePlateEditor, Plate, PlateContent, -} from '@udecode/plate-common/react'; +} from '@udecode/plate/react'; export default function BasicEditor() { const editor = usePlateEditor(); @@ -212,7 +212,7 @@ import { PlateElement, PlateLeaf, usePlateEditor, -} from '@udecode/plate-common/react'; +} from '@udecode/plate/react'; export default function BasicEditor() { const editor = usePlateEditor({ diff --git a/apps/www/content/docs/cn/horizontal-rule.mdx b/apps/www/content/docs/cn/horizontal-rule.mdx index 4270214d44..c884fde2c5 100644 --- a/apps/www/content/docs/cn/horizontal-rule.mdx +++ b/apps/www/content/docs/cn/horizontal-rule.mdx @@ -25,9 +25,9 @@ npm install @udecode/plate-horizontal-rule ## 使用 ```tsx -import { insertNodes, setNodes } from '@udecode/plate-common'; +import { insertNodes, setNodes } from '@udecode/plate'; import { AutoformatPlugin } from '@udecode/plate-autoformat/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react'; import { SelectOnBackspacePlugin } from '@udecode/plate-select/react'; diff --git a/apps/www/content/docs/cn/html.mdx b/apps/www/content/docs/cn/html.mdx index 986e31375f..b12dc385ef 100644 --- a/apps/www/content/docs/cn/html.mdx +++ b/apps/www/content/docs/cn/html.mdx @@ -16,7 +16,7 @@ title: Serializing HTML ```tsx // ... -import { createSlateEditor, serializeHtml } from '@udecode/plate-common'; +import { createSlateEditor, serializeHtml } from '@udecode/plate'; import { EditorStatic } from '@/components/plate-ui/editor-static'; // 创建一个编辑器并配置所有需要的插件 @@ -88,7 +88,7 @@ const fullHtml = ` // 使用静态组件,这些组件不依赖于 'use client', // 它们只是返回纯 HTML。 -import { createSlateEditor, serializeHtml } from '@udecode/plate-common'; +import { createSlateEditor, serializeHtml } from '@udecode/plate'; // 导入静态版本的组件 import { ParagraphElementStatic } from '@/components/plate-ui/paragraph-element-static'; @@ -194,7 +194,7 @@ const html = await serializeHtml(editor, { components }); `editor.api.html.deserialize` 函数允许你将 HTML 内容转换为 Slate 值: ```typescript -import { createPlateEditor } from '@udecode/plate-common/react'; +import { createPlateEditor } from '@udecode/plate/react'; const editor = createPlateEditor({ plugins: [ @@ -379,7 +379,7 @@ export const IndentListPlugin = createTSlatePlugin({ - + 反序列化后的 Slate 值。 diff --git a/apps/www/content/docs/cn/indent-list.mdx b/apps/www/content/docs/cn/indent-list.mdx index e26f4ce366..2ca3fbc1ac 100644 --- a/apps/www/content/docs/cn/indent-list.mdx +++ b/apps/www/content/docs/cn/indent-list.mdx @@ -69,7 +69,7 @@ import { IndentPlugin } from '@udecode/plate-indent/react'; import { IndentListPlugin } from '@udecode/plate-indent-list/react'; import { HEADING_KEYS } from '@udecode/plate-heading'; import { HeadingPlugin } from '@udecode/plate-heading/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; const plugins = [ // ...otherPlugins, @@ -136,7 +136,7 @@ const plugins = [ - + 具有缩进列表的下一个兄弟entry,如果未找到则返回 `undefined`。 @@ -162,7 +162,7 @@ const plugins = [ - + 具有缩进列表的前一个兄弟entry,如果未找到则返回 `undefined`。 diff --git a/apps/www/content/docs/cn/indent.mdx b/apps/www/content/docs/cn/indent.mdx index a78f30aed1..a2741c43ca 100644 --- a/apps/www/content/docs/cn/indent.mdx +++ b/apps/www/content/docs/cn/indent.mdx @@ -41,7 +41,7 @@ npm install @udecode/plate-indent import { IndentPlugin } from '@udecode/plate-indent/react'; import { HEADING_KEYS } from '@udecode/plate-heading'; import { HeadingPlugin } from '@udecode/plate-heading/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; const plugins = [ // ...otherPlugins, @@ -123,7 +123,7 @@ const plugins = [ 获取要缩进的节点的选项。 @@ -162,7 +162,7 @@ const plugins = [ 额外的 `getNodes` 选项。 diff --git a/apps/www/content/docs/cn/list.mdx b/apps/www/content/docs/cn/list.mdx index 04258ac022..31610b1f9e 100644 --- a/apps/www/content/docs/cn/list.mdx +++ b/apps/www/content/docs/cn/list.mdx @@ -199,7 +199,7 @@ const plugins = [ - + 最近的 `li` 和 `ul`/`ol` 包装节点entry。 @@ -221,7 +221,7 @@ const plugins = [ - + 根列表元素entry。 @@ -248,7 +248,7 @@ const plugins = [ 编辑器实例。 - + 要检查的节点。 @@ -394,10 +394,10 @@ const plugins = [ - + 列表节点的entry。 - + 要移动的列表项节点的entry。 @@ -424,10 +424,10 @@ const plugins = [ optional > - + 包含要移动的子列表项的列表项entry。 - + 子列表项将被移动到的列表项entry。 @@ -455,10 +455,10 @@ const plugins = [ - + 包含要移动的列表项的列表entry。 - + 要移动的列表项entry。 @@ -533,7 +533,7 @@ const plugins = [ 其列表项将被移动的列表。 @@ -541,7 +541,7 @@ const plugins = [ 其子列表项将被移动的列表项。 @@ -560,7 +560,7 @@ const plugins = [ 列表项将被移动到的列表。 @@ -635,10 +635,10 @@ const plugins = [ - + 包含列表项的列表entry。 - + 要删除的列表项entry。 @@ -661,10 +661,10 @@ const plugins = [ - + 包含列表项的列表entry。 - + 要删除的列表项entry。 diff --git a/apps/www/content/docs/cn/markdown.mdx b/apps/www/content/docs/cn/markdown.mdx index f7f65b5306..e6a5ff4a8a 100644 --- a/apps/www/content/docs/cn/markdown.mdx +++ b/apps/www/content/docs/cn/markdown.mdx @@ -117,7 +117,7 @@ const content = editor.api.markdown.serialize(); - + 一个 Slate 节点数组,表示反序列化的 Markdown 内容。 @@ -129,7 +129,7 @@ const content = editor.api.markdown.serialize(); - + 要序列化的 Slate 节点。如果未提供,则使用整个编辑器值。 diff --git a/apps/www/content/docs/cn/migration/slate-to-plate.mdx b/apps/www/content/docs/cn/migration/slate-to-plate.mdx index dd721c155a..af5ad622e3 100644 --- a/apps/www/content/docs/cn/migration/slate-to-plate.mdx +++ b/apps/www/content/docs/cn/migration/slate-to-plate.mdx @@ -121,17 +121,26 @@ const withMyPlugin = (editor) => { }; // After +// 用于覆盖现有方法: const MyPlugin = createPlatePlugin({ key: 'myPlugin', - extendEditor: ({ editor }) => { - const { insertText } = editor; - editor.insertText = (text) => { +}).overrideEditor(({ editor, tf: { insertText } }) => ({ + transforms: { + insertText(text) { // Custom logic insertText(text); - }; - return editor; - }, -}); + }, + } +})); + +// 用于添加新方法: +const MyOtherPlugin = createPlatePlugin({ + key: 'myOtherPlugin', +}).extendEditorTransforms(({ editor }) => ({ + newMethod(text) { + // 添加新功能 + } +})); ``` 有关使用插件上下文的工作原理,请查看 [Plugin Context guide](/docs/plugin-context). diff --git a/apps/www/content/docs/cn/node-id.mdx b/apps/www/content/docs/cn/node-id.mdx index 1d7cd39e68..f1732f0929 100644 --- a/apps/www/content/docs/cn/node-id.mdx +++ b/apps/www/content/docs/cn/node-id.mdx @@ -97,7 +97,7 @@ const plugins = [ 不应该接收 ID 的节点类型列表。 - + 用于确定节点是否应该接收 ID 的自定义过滤函数。 - **默认值:** `() => true` @@ -114,7 +114,7 @@ const plugins = [ // 插入节点(例如复制/粘贴) -editor.insertNode(inserted); +editor.tf.insertNode(inserted); // 结果: test @@ -122,7 +122,7 @@ editor.insertNode(inserted); // 插入多个节点 -editor.insertNodes([ +editor.tf.insertNodes([ inserted, test, ]); @@ -158,13 +158,13 @@ editor.insertNodes([ 4. **撤销/重做**: ```tsx // 当 reuseId=true -editor.insertNode(text); +editor.tf.insertNode(text); editor.undo(); editor.redo(); // 如果 ID 未被使用,节点保持 id="1" // 当 reuseId=false -editor.insertNode(text); +editor.tf.insertNode(text); editor.undo(); editor.redo(); // 节点获得新的 id="2" diff --git a/apps/www/content/docs/cn/playwright.mdx b/apps/www/content/docs/cn/playwright.mdx index 563015138b..5e680bb506 100644 --- a/apps/www/content/docs/cn/playwright.mdx +++ b/apps/www/content/docs/cn/playwright.mdx @@ -152,7 +152,7 @@ await page.keyboard.type('Hello world!'); ```ts await editorHandle.evaluate((editor) => { - editor.insertNodes(/* ... */); + editor.tf.insertNodes(/* ... */); }); ``` diff --git a/apps/www/content/docs/cn/plugin-components.mdx b/apps/www/content/docs/cn/plugin-components.mdx index 2628e794b4..89c424b332 100644 --- a/apps/www/content/docs/cn/plugin-components.mdx +++ b/apps/www/content/docs/cn/plugin-components.mdx @@ -20,7 +20,7 @@ description: 学习如何为 Plate 插件创建和样式化自定义组件。 ### Element ```tsx -import { PlateElement, PlateElementProps } from '@udecode/plate-common/react'; +import { PlateElement, PlateElementProps } from '@udecode/plate/react'; export function BlockquoteElement({ className, @@ -38,7 +38,7 @@ export function BlockquoteElement({ ### Leaf ```tsx -import { PlateLeaf, PlateLeafProps } from '@udecode/plate-common/react'; +import { PlateLeaf, PlateLeafProps } from '@udecode/plate/react'; export function CodeLeaf({ className, children, ...props }: PlateLeafProps) { return ( diff --git a/apps/www/content/docs/cn/plugin-methods.mdx b/apps/www/content/docs/cn/plugin-methods.mdx index 512effd4bd..3896398f24 100644 --- a/apps/www/content/docs/cn/plugin-methods.mdx +++ b/apps/www/content/docs/cn/plugin-methods.mdx @@ -299,11 +299,53 @@ editor.tf.editorTransform(); ```ts const CodeBlockPlugin = toPlatePlugin(createSlatePlugin({ key: 'code_block' }), { - extendEditor: ({ api, editor }) => { - api.plugin.getSyntaxState(); - return editor; - }, handlers: {}, options: { hotkey: ['mod+opt+8', 'mod+shift+8'] }, }); ``` + +### .overrideEditor + +`overrideEditor` 方法专门用于覆盖现有的编辑器方法,同时保持对原始实现的访问: + +```ts +const MyPlugin = createPlatePlugin({ + key: 'myPlugin', +}).overrideEditor(({ editor, tf: { insertText }, api: { isInline } }) => ({ + transforms: { + insertText(text) { + // 自定义逻辑 + console.log('Inserting:', text); + + // 调用原始方法 + insertText(text); + + // 后续逻辑 + console.log('Inserted:', text); + }, + }, + api: { + isInline(element) { + // 自定义内联元素检查 + if (element.type === 'custom-inline') { + return true; + } + + // 回退到原始行为 + return isInline(element); + }, + }, +})); +``` + +- 修改编辑器行为的首选方法 +- 对原始方法的类型安全访问(通过 `tf` 和 `api` 参数) +- 在 transforms 和 API 之间清晰分离 +- 可以多次链式调用以层叠不同的覆盖 +- 不能添加新方法(请改用 `extendEditorTransforms` 或 `extendEditorApi`) + + +`extendEditor` 和 `overrideEditor` 的区别: +- 使用 `extendEditor` 来集成需要直接编辑器变更的传统 Slate 插件,如 `withYjs`。每个插件只能有一个 `extendEditor`。 +- 优先使用 `overrideEditor` 来修改编辑器行为,因为它具有单一职责和更好的类型安全性。它可以多次调用以层叠不同的覆盖。 + diff --git a/apps/www/content/docs/cn/plugin-shortcuts.mdx b/apps/www/content/docs/cn/plugin-shortcuts.mdx index 5dfeada536..1dd1eff3b8 100644 --- a/apps/www/content/docs/cn/plugin-shortcuts.mdx +++ b/apps/www/content/docs/cn/plugin-shortcuts.mdx @@ -110,13 +110,13 @@ const FormattingPlugin = createPlatePlugin({ shortcuts: { toggleBold: { handler: ({ editor }) => { - editor.toggleMark('bold'); + editor.tf.toggleMark('bold'); }, keys: 'mod+b', }, toggleItalic: { handler: ({ editor }) => { - editor.toggleMark('italic'); + editor.tf.toggleMark('italic'); }, keys: 'mod+i', }, diff --git a/apps/www/content/docs/cn/plugin.mdx b/apps/www/content/docs/cn/plugin.mdx index bf8d75e01a..6c283215d2 100644 --- a/apps/www/content/docs/cn/plugin.mdx +++ b/apps/www/content/docs/cn/plugin.mdx @@ -167,22 +167,12 @@ const AlignPlugin = createPlatePlugin({ 偶尔,你需要覆盖 Slate 提供的内置编辑器方法,以解决 bug 或添加复杂功能。为此,你可以使用 `extendEditor` 插件选项,在创建后直接修改 `editor` 对象的属性。 -一个常见的应用是创建自定义 [normalizers](https://docs.slatejs.org/concepts/11-normalizing)。 - ```ts showLineNumbers {20} const CustomNormalizerPlugin = createPlatePlugin({ key: 'customNormalizer', extendEditor: ({ editor }) => { - const { normalizeNode } = editor; - - editor.normalizeNode = ([node, path]) => { - // 自定义规范化逻辑 - // ... - - // 调用其他规范化器 - normalizeNode([node, path]); - }; - + editor.customState = true; + return editor; }, }); @@ -352,7 +342,7 @@ const CodeBlockPlugin = createTPlatePlugin({ })).extendEditorTransforms(() => ({ insert: { codeBlock: ({ editor, getOptions }) => { - editor.insertBlock({ type: 'code_block', language: getOptions().language }); + editor.tf.insertBlock({ type: 'code_block', language: getOptions().language }); }, }, })); diff --git a/apps/www/content/docs/cn/reset-node.mdx b/apps/www/content/docs/cn/reset-node.mdx index 4c04ea552b..2b89562c16 100644 --- a/apps/www/content/docs/cn/reset-node.mdx +++ b/apps/www/content/docs/cn/reset-node.mdx @@ -26,7 +26,7 @@ npm install @udecode/plate-reset-node import { isBlockAboveEmpty, isSelectionAtBlockStart, -} from '@udecode/plate-common'; +} from '@udecode/plate'; import { ResetNodePlugin } from '@udecode/plate-reset-node/react'; const resetBlockTypesCommonRule = { diff --git a/apps/www/content/docs/cn/tabbable.mdx b/apps/www/content/docs/cn/tabbable.mdx index 70968265af..bfd59c7759 100644 --- a/apps/www/content/docs/cn/tabbable.mdx +++ b/apps/www/content/docs/cn/tabbable.mdx @@ -136,7 +136,7 @@ insertTabbableEntries: (editor) => { 可 tab 切换entry对应的 Slate 节点。 - + Slate 文档中 Slate 节点的路径。 \ No newline at end of file diff --git a/apps/www/content/docs/cn/table.mdx b/apps/www/content/docs/cn/table.mdx index 677f5b8917..55b2d7981c 100644 --- a/apps/www/content/docs/cn/table.mdx +++ b/apps/www/content/docs/cn/table.mdx @@ -108,7 +108,7 @@ const plugins = [ 新单元格节点的子元素。 @@ -137,7 +137,7 @@ const plugins = [ - + 表格单元格的子元素。 @@ -235,7 +235,7 @@ const plugins = [ 获取下一行中的单元格。 - + 编辑器实例。 @@ -245,7 +245,7 @@ const plugins = [ - + 下一行中单元格的节点entry,如果当前行是最后一行则返回 `undefined`。 @@ -256,7 +256,7 @@ const plugins = [ 获取上一行中单元格的节点entry,给定当前行的路径。 - + 编辑器实例。 @@ -266,7 +266,7 @@ const plugins = [ - + 上一行中单元格的节点entry,如果当前行是第一行则返回 `undefined`。 @@ -310,7 +310,7 @@ const plugins = [ 新单元格节点的子元素。 @@ -416,7 +416,7 @@ const plugins = [ - + 当前单元格左侧单元格的节点entry,如果当前单元格是行中的第一个单元格则返回 `undefined`。 @@ -426,22 +426,22 @@ const plugins = [ 获取表格中的下一个单元格。 - + 编辑器实例。 - + 当前单元格的entry。 当前单元格的路径。 - + 当前行的entry。 - + 下一行中单元格的节点entry,如果当前行是最后一行则返回 `undefined`。 @@ -451,22 +451,22 @@ const plugins = [ 获取表格中的上一个单元格。 - + 编辑器实例。 - + 当前单元格的entry。 当前单元格的路径。 - + 当前行的entry。 - + 上一行中单元格的节点entry,如果当前行是第一行则返回 `undefined`。 @@ -479,11 +479,11 @@ const plugins = [ 编辑器实例。 - + - + 当前选择上方的表格节点entry,如果不存在则返回 `undefined`。 @@ -511,7 +511,7 @@ const plugins = [ 获取表格中单元格节点的列索引。 - + 编辑器实例。 @@ -554,13 +554,13 @@ const plugins = [ - + 表格节点entry。 - + 行节点entry。 - + 单元格节点entry。 @@ -587,7 +587,7 @@ const plugins = [ - 子表格entry。 + 子表格entry。 ### getTableGridByRange @@ -620,7 +620,7 @@ const plugins = [ - 子表格entry。 + 子表格entry。 ### getTableOverriddenColSizes @@ -647,7 +647,7 @@ const plugins = [ 获取表格中单元格节点的行索引。 - + 编辑器实例。 @@ -677,7 +677,7 @@ const plugins = [ - + 单元格节点entry。 @@ -883,7 +883,7 @@ const plugins = [ 设置表格中特定列的宽度。 - + 编辑器实例。 @@ -896,7 +896,7 @@ const plugins = [ - + 用于查找表格节点的其他选项。 @@ -906,7 +906,7 @@ const plugins = [ 设置表格的左边距。 - + 编辑器实例。 @@ -916,7 +916,7 @@ const plugins = [ - + 用于查找表格节点的其他选项。 @@ -926,7 +926,7 @@ const plugins = [ 设置表格行的大小(高度)。 - + 编辑器实例。 @@ -939,7 +939,7 @@ const plugins = [ - + 用于查找表格节点的其他选项。 diff --git a/apps/www/content/docs/cn/toggle.mdx b/apps/www/content/docs/cn/toggle.mdx index 980426df3d..6ef4fbe6fa 100644 --- a/apps/www/content/docs/cn/toggle.mdx +++ b/apps/www/content/docs/cn/toggle.mdx @@ -34,7 +34,7 @@ npm install @udecode/plate-indent @udecode/plate-node-id @udecode/plate-toggle ```tsx // ... -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { NodeIdPlugin } from '@udecode/plate-node-id'; import { IndentPlugin } from '@udecode/plate-indent/react'; import { TogglePlugin } from '@udecode/plate-toggle/react'; @@ -89,7 +89,7 @@ const plugins = [ 在插入块之前使用此函数,以便在插入时折叠处于展开状态。 - + 编辑器实例。 diff --git a/apps/www/content/docs/cn/unit-testing.mdx b/apps/www/content/docs/cn/unit-testing.mdx index 6713ffae9b..bc4c108d4f 100644 --- a/apps/www/content/docs/cn/unit-testing.mdx +++ b/apps/www/content/docs/cn/unit-testing.mdx @@ -8,7 +8,7 @@ description: 学习如何对 Plate 编辑器和插件进行单元测试。 ## Installation ```bash -npm install @udecode/plate-test-utils slate-hyperscript +npm install @udecode/plate-test-utils ``` ## 设置测试 @@ -76,7 +76,8 @@ it('should use custom hotkey for bold', async () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, plugins: [ BoldPlugin.configure({ handlers: { @@ -118,10 +119,11 @@ it('should collapse selection on backspace', async () => { ) as any as PlateEditor; const [editor] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, }); - editor.deleteBackward('character'); + editor.tf.deleteBackward(); expect(editor.children).toEqual(output.children); expect(editor.selection).toEqual(output.selection); @@ -151,7 +153,8 @@ it('should extend selection on shift+ArrowRight', async () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, }); await triggerKeyboardEvent('shift+ArrowRight'); @@ -200,7 +203,8 @@ describe('Table plugin', () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, plugins: [TablePlugin], }); @@ -237,7 +241,8 @@ it('should use custom hotkey for bold', async () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, plugins: [ BoldPlugin.configure({ shortcuts: { diff --git a/apps/www/content/docs/en/ai.mdx b/apps/www/content/docs/en/ai.mdx index 21ce43f1e3..e54e64d20e 100644 --- a/apps/www/content/docs/en/ai.mdx +++ b/apps/www/content/docs/en/ai.mdx @@ -49,7 +49,7 @@ import { BaseCodeLinePlugin, BaseCodeSyntaxPlugin, } from '@udecode/plate-code-block'; -import { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate-common'; +import { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate'; import { BaseHeadingPlugin, HEADING_LEVELS } from '@udecode/plate-heading'; import { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule'; import { BaseIndentListPlugin } from '@udecode/plate-indent-list'; @@ -250,6 +250,8 @@ Extends the editor with AI transforms. ### AIChatPlugin +This plugin is experimental. + Enables chat operations and streaming text generation in the editor. @@ -394,7 +396,7 @@ In insert mode, undoes previous AI changes before submitting. Inserts AI-generated nodes with the AI mark. - + Nodes to insert with AI mark. diff --git a/apps/www/content/docs/en/alignment.mdx b/apps/www/content/docs/en/alignment.mdx index ec03790708..14302a727f 100644 --- a/apps/www/content/docs/en/alignment.mdx +++ b/apps/www/content/docs/en/alignment.mdx @@ -25,9 +25,9 @@ npm install @udecode/plate-alignment ```tsx // ... -import { createPlateEditor } from '@udecode/plate-common/react'; +import { createPlateEditor } from '@udecode/plate/react'; import { AlignPlugin } from '@udecode/plate-alignment/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { HeadingPlugin } from '@udecode/plate-heading/react'; const editor = createPlateEditor({ diff --git a/apps/www/content/docs/en/api/common.mdx b/apps/www/content/docs/en/api/common.mdx deleted file mode 100644 index bdee950267..0000000000 --- a/apps/www/content/docs/en/api/common.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Plate Common -description: API reference for @udecode/plate-common. ---- - -`@udecode/plate-common` contains common types and functions for Plate: - -- [Core](/docs/api/core) -- [Plate Utils](/docs/api/utils) -- [Slate](/docs/api/slate) -- [Slate React](/docs/api/slate-react) diff --git a/apps/www/content/docs/en/api/core.mdx b/apps/www/content/docs/en/api/core.mdx index 9202b20a15..33d3bc6e27 100644 --- a/apps/www/content/docs/en/api/core.mdx +++ b/apps/www/content/docs/en/api/core.mdx @@ -3,6 +3,8 @@ title: Plate Core description: API reference for @udecode/plate-core. --- +v42 documentation is in progress. + ## API ### createPlateEditor @@ -455,7 +457,7 @@ Provides debugging capabilities with configurable log levels and error handling. See [Debugging](/docs/debugging) for more details. -### SlateNextPlugin +### SlateExtensionPlugin & SlateReactExtensionPlugin Extend core apis and improve default functionality. ### DOMPlugin & ReactPlugin @@ -485,5 +487,25 @@ Provides paragraph formatting functionality. ### EventEditorPlugin Manages editor events such as focus and blur. -### PlateApiPlugin -Provides the core API for Plate editor functionality. +## Utils + +### isType + +Checks whether a node matches the provided type. + + + + The editor in which the node is present. + + + The node to be checked. + + + The type or types to match the node against. Can be a string or an array of + strings. + + + + A boolean indicating whether the node's type matches the provided type or + types. + diff --git a/apps/www/content/docs/en/api/core/plate.mdx b/apps/www/content/docs/en/api/core/plate-components.mdx similarity index 92% rename from apps/www/content/docs/en/api/core/plate.mdx rename to apps/www/content/docs/en/api/core/plate-components.mdx index 8bd88de24a..1fcfcb878e 100644 --- a/apps/www/content/docs/en/api/core/plate.mdx +++ b/apps/www/content/docs/en/api/core/plate-components.mdx @@ -1,5 +1,5 @@ --- -title: Plate +title: Plate Components description: API reference for Plate component. --- @@ -36,10 +36,10 @@ Controls whether the editor is considered active by default when used with a Pla If true, the editor is in read-only mode. - + Custom render function for elements. - + Custom render function for leaf nodes. @@ -65,8 +65,8 @@ Custom `Editable` node. - - + + diff --git a/apps/www/content/docs/en/api/core/plate-controller.mdx b/apps/www/content/docs/en/api/core/plate-controller.mdx index 729bd51a73..74b35ecfd4 100644 --- a/apps/www/content/docs/en/api/core/plate-controller.mdx +++ b/apps/www/content/docs/en/api/core/plate-controller.mdx @@ -1,5 +1,5 @@ --- -title: PlateController +title: Plate Controller description: API reference for PlateController component. --- @@ -119,7 +119,7 @@ const App = withHoc(PlateController, () => { const toggleBold = () => { if (activeEditor.isFallback) return; - toggleMark(activeEditor, { key: BoldPlugin.key }); + activeEditor.tf.toggleMark(BoldPlugin.key); }; return ( @@ -146,7 +146,7 @@ const App = withHoc(PlateController, () => { const isFallback = !useEditorMounted(); const toggleBold = () => { - toggleMark(activeEditor, { key: BoldPlugin.key }); + activeEditor.tf.toggleMark(BoldPlugin.key); }; return ( diff --git a/apps/www/content/docs/en/api/core/plate-editor.mdx b/apps/www/content/docs/en/api/core/plate-editor.mdx index 5b78b18273..004d14024c 100644 --- a/apps/www/content/docs/en/api/core/plate-editor.mdx +++ b/apps/www/content/docs/en/api/core/plate-editor.mdx @@ -3,7 +3,7 @@ title: Plate Editor description: API reference for Plate editor. --- -A custom editor interface that extends the base **`TEditor`** interface and includes additional properties and methods specific to the Plate library. +A custom editor interface that extends the base **`Editor`** interface and includes additional properties and methods specific to the Plate library. ## Core Properties @@ -36,16 +36,16 @@ A custom editor interface that extends the base **`TEditor`** interface and incl ## API Methods - + Retrieve the typed API for a plugin. - + Get the typed transforms for a plugin. - + Retrieve the editor plugin instance by its key or base plugin. - + Get the node type associated with a plugin. @@ -53,19 +53,19 @@ A custom editor interface that extends the base **`TEditor`** interface and incl ## Option Methods - + Get a specific option value for a plugin. - + Get all options for a plugin. - + Set a specific option value for a plugin. - + Set multiple options for a plugin. - + Get the zustand-x options store for a plugin. @@ -73,10 +73,10 @@ A custom editor interface that extends the base **`TEditor`** interface and incl ## React Hooks - + Subscribe to a specific option value in a React component. - + Subscribe to plugin options or a derived value from options in a React component. @@ -84,7 +84,7 @@ A custom editor interface that extends the base **`TEditor`** interface and incl ## Plate Store Methods - + Update the global Plate state. @@ -108,21 +108,10 @@ A custom editor interface that extends the base **`TEditor`** interface and incl -### SlateNextPlugin - - - - Toggle a block element. - - - Toggle a mark on the selected text. - - - ### HtmlPlugin - + Deserialize HTML content into Slate nodes. @@ -135,7 +124,7 @@ A custom editor interface that extends the base **`TEditor`** interface and incl -### PlateApiPlugin +### SlateReactExtensionPlugin diff --git a/apps/www/content/docs/en/api/core/plate-plugin.mdx b/apps/www/content/docs/en/api/core/plate-plugin.mdx index b97aec51b4..a5c6d41b04 100644 --- a/apps/www/content/docs/en/api/core/plate-plugin.mdx +++ b/apps/www/content/docs/en/api/core/plate-plugin.mdx @@ -1,9 +1,9 @@ --- -title: PlatePlugin +title: Plate Plugin description: API reference for Plate plugins. --- -Plate plugins are objects passed to `Plate` [plugins](/docs/api/core/plate#plugins) prop. +Plate plugins are objects passed to `Plate` [plugins](/docs/api/core/plate-components#plugins) prop. ## Generic Types @@ -33,34 +33,32 @@ const MyPlugin = createPlatePlugin({ ## Plugin Properties -## Plugin Properties - Unique identifier used by Plate to store the plugins by key in `editor.plugins`. - + An object of API functions provided by the plugin. These functions are accessible via `editor.api[key]`. - + Transform functions provided by the plugin that modify the editor state. These are accessible via `editor.tf[key]`. - + Extended properties used by the plugin as options. - + Event handlers for various editor events, including `onChange`. - + Defines how the plugin injects functionality into other plugins or the editor. - + Properties used by Plate to inject props into any node component. @@ -85,7 +83,7 @@ If true, only matches leaf nodes. Used to restrict prop injection to leaf nodes. Maximum nesting level for node prop injection. Nodes deeper than this level will not receive injected props. - + Property that can be used by a plugin to allow other plugins to inject code. @@ -99,7 +97,7 @@ Plugin keys used by `InjectNodeProps` and the `targetPluginToInject` function. - + Defines the node-specific configuration for the plugin. @@ -112,12 +110,17 @@ Indicates if this plugin's elements should be treated as inline. Indicates if this plugin's nodes should be rendered as leaves. - -Indicates if this plugin's elements should be treated as void. - Indicates if this plugin's void elements should be markable. + +Indicates if this plugin's nodes should be selectable. + +- **Default:** `true` + + +Indicates if this plugin's elements should be treated as void. + Specifies the type identifier for this plugin's nodes. @@ -165,27 +168,27 @@ HTML React serializer configuration. - -Defines rendering functions for various parts of the editor. + +Defines how the plugin renders components. - -Renders a component above the `Editable` component but within the `Slate` wrapper. + +Component rendered above the Editable component but inside the Slate wrapper. - -Renders a component above all other plugins' `node` components. + +Component rendered above all other plugins' node components. - -Renders a component above the `Slate` wrapper. + +Component rendered above the Slate wrapper. -Renders a component after the `Editable` component. +Renders a component after the Editable component. -Renders a component before the `Editable` component. +Renders a component before the Editable component. -Renders a component below all other plugins' `node` components, but above their `children`. +Renders a component below all other plugins' node components, but above their children. Renders the node component. @@ -223,7 +226,18 @@ Defines the order in which plugins are registered and executed. Property used by Plate to decorate editor ranges. - + +Function to extend the editor instance. Used primarily for integrating legacy Slate plugins that need direct editor mutation. Only one `extendEditor` is allowed per plugin. + +```ts +extendEditor: ({ editor }) => { + // Example: Integrating a legacy Slate plugin + return withYjs(editor); +} +``` + + + Hook called when the editor is initialized. @@ -231,7 +245,7 @@ Hook called when the editor is initialized. ## Plugin Methods - + Creates a new plugin instance with updated options. ```ts @@ -239,15 +253,15 @@ Creates a new plugin instance with updated options. ``` - -Creates a new plugin instance with additional configuration. Can accept either an object or a function. + +Creates a new plugin instance with additional configuration. ```ts (extendConfig: Partial | ((ctx: PlatePluginContext) => Partial)) => PlatePlugin ``` - + Extends an existing nested plugin or adds a new one if not found. Supports deep nesting. ```ts @@ -263,43 +277,69 @@ Sets or replaces the component associated with a plugin. ``` - + +Creates a new plugin instance with overridden editor methods. Provides access to original methods via `tf` and `api` parameters. Can be called multiple times to layer different overrides. + +```ts +overrideEditor(({ editor, tf: { deleteForward }, api: { isInline } }) => ({ + transforms: { + // Override transforms + deleteForward(options) { + deleteForward(options); + }, + }, + api: { + // Override API methods + isInline(element) { + return isInline(element); + }, + }, +})) => PlatePlugin +``` + +- Preferred method for modifying editor behavior +- Type-safe access to original methods +- Clean separation between transforms and API +- Can be chained multiple times + + + Extends the plugin's API. ```ts -(api: (ctx: PlatePluginContext) => any) => PlatePlugin +(api: (ctx: PlatePluginContext) => Record) => PlatePlugin ``` - + Extends the editor's API with plugin-specific methods. ```ts -(api: (ctx: PlatePluginContext) => any) => PlatePlugin +(api: (ctx: PlatePluginContext) => Record) => PlatePlugin ``` - + Extends the plugin's transforms. ```ts -(transforms: (ctx: PlatePluginContext) => any) => PlatePlugin +(transforms: (ctx: PlatePluginContext) => Record) => PlatePlugin ``` - + Extends the editor's transforms with plugin-specific methods. ```ts -(transforms: (ctx: PlatePluginContext) => any) => PlatePlugin +(transforms: (ctx: PlatePluginContext) => Record) => PlatePlugin ``` - + Extends the plugin options with selectors. ```ts -(options: (ctx: PlatePluginContext) => any) => PlatePlugin +(options: (ctx: PlatePluginContext) => Record) => PlatePlugin ``` diff --git a/apps/www/content/docs/en/api/core/store.mdx b/apps/www/content/docs/en/api/core/plate-store.mdx similarity index 98% rename from apps/www/content/docs/en/api/core/store.mdx rename to apps/www/content/docs/en/api/core/plate-store.mdx index 1e00ae52e1..6db3cde8e3 100644 --- a/apps/www/content/docs/en/api/core/store.mdx +++ b/apps/www/content/docs/en/api/core/plate-store.mdx @@ -37,7 +37,7 @@ A reference to the editor container element. Function used to decorate ranges in the editor. ```ts -(options: { editor: PlateEditor; entry: TNodeEntry }) => Range[] +(options: { editor: PlateEditor; entry: NodeEntry }) => Range[] ``` diff --git a/apps/www/content/docs/en/api/floating.mdx b/apps/www/content/docs/en/api/floating.mdx index c0c1c63706..93c3fc257c 100644 --- a/apps/www/content/docs/en/api/floating.mdx +++ b/apps/www/content/docs/en/api/floating.mdx @@ -104,7 +104,7 @@ Creates a floating toolbar that appears when text is selected in the editor. Gets the bounding client rectangle for a location or array of locations in the editor. - + The editor instance. @@ -133,7 +133,7 @@ Gets the bounding client rectangle of the current DOM selection. Gets the bounding client rectangle for a specific Slate range. - + The editor instance. diff --git a/apps/www/content/docs/en/api/plate.mdx b/apps/www/content/docs/en/api/plate.mdx new file mode 100644 index 0000000000..217515445e --- /dev/null +++ b/apps/www/content/docs/en/api/plate.mdx @@ -0,0 +1,11 @@ +--- +title: Plate +description: API reference for @udecode/plate. +--- + +`@udecode/plate` contains common types and functions for Plate: + +- [Slate](/docs/api/slate) +- [Plate Core](/docs/api/core) +- [Plate Utils](/docs/api/utils) +- [React Utils](/docs/api/react-utils) diff --git a/apps/www/content/docs/en/api/slate-react.mdx b/apps/www/content/docs/en/api/slate-react.mdx deleted file mode 100644 index e194f9b0f3..0000000000 --- a/apps/www/content/docs/en/api/slate-react.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Slate React -description: API reference for @udecode/slate-react. ---- - -`@udecode/slate-react` extends Slate React API with generic types. - -## React Editor - -Find the corresponding documentation in the [Slate React docs](https://docs.slatejs.org/libraries/slate-react/react-editor). - -### `SlateProps` - -### `blurEditor` - -### `deselectEditor` - -### `findEditorDocumentOrShadowRoot` - -### `findEventRange` - -### `findNodeKey` - -### `findPath` - -### `focusEditor` - -### `getEditorWindow` - -### `hasEditorDOMNode` - -### `hasEditorEditableTarget` - -### `hasEditorSelectableTarget` - -### `hasEditorTarget` - -### `insertData` - -### `isComposing` - -### `isEditorFocused` - -### `isEditorReadOnly` - -### `isTargetInsideNonReadonlyVoidEditor` - -### `setFragmentData` - -### `toDOMNode` - -### `toDOMPoint` - -### `toDOMRange` - -### `toSlateNode` - -### `toSlatePoint` - -### `toSlateRange` - -## Transforms - -### focusEditorEdge - -Focuses the editor at a specified edge (start or end). - - - - The editor instance. - - - - - The edge to focus on. - - 'start': Focus at the beginning of the editor. - - 'end': Focus at the end of the editor. - Default is 'start'. - - - - - -### setNode - -Sets properties on a specific node in the editor. - - - - The editor instance. - - - The node to update. - - - The properties to set on the node. - - - Options for setting nodes, excluding the 'at' property. - - \ No newline at end of file diff --git a/apps/www/content/docs/en/api/slate.mdx b/apps/www/content/docs/en/api/slate.mdx index 2b40cdf487..9db7f82ca1 100644 --- a/apps/www/content/docs/en/api/slate.mdx +++ b/apps/www/content/docs/en/api/slate.mdx @@ -1,314 +1,6 @@ --- title: Slate -description: API reference for @udecode/slate. +description: API reference for @udecode/slate --- -`@udecode/slate` extends Slate API with generic types. - -## Editor - -Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/transforms). - -### `addMark` - -### `createPathRef` - -### `createPointRef` - -### `createRangeRef` - -### `deleteBackward` - -### `deleteForward` - -### `deleteFragment` - -### `deleteMerge` - -### `getAboveNode` - -### `getEdgePoints` - -### `getEditorString` - -### `getEndPoint` - -### `getFirstNode` - -### `getFragment` - -### `getLastNode` - -### `getLeafNode` - -### `getLevels` - -### `getMarks` - -### `getNextNode` - -### `getNodeEntries` - -### `getNodeEntry` - -### `getParentNode` - -### `getPath` - -### `getPathRefs` - -### `getPoint` - -### `getPointAfter` - -### `getPointBefore` - -### `getPointRefs` - -### `getPositions` - -### `getPreviousNode` - -### `getRange` - -### `getRangeRefs` - -### `getStartPoint` - -### `getVoidNode` - -### `hasBlocks` - -### `hasInlines` - -### `hasTexts` - -### `index` - -### `insertBreak` - -### `insertNode` - -### `isBlock` - -### `isEdgePoint` - -### `isEditor` - -### `isEditorNormalizing` - -### `isElementEmpty` - -### `isEndPoint` - -### `isInline` - -### `isStartPoint` - -### `isVoid` - -### `normalizeEditor` - -### `removeEditorMark` - -### `TEditor` - -### `unhangRange` - -### `withoutNormalizing` - -## Element - -Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/element). - -### `elementMatches` - -### `index` - -### `isElement` - -### `isElementList` - -### `TElement` - -## History - -Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/libraries/slate-history). - -### `isHistoryEditor` - -### `isHistoryMerging` - -### `isHistorySaving` - -### `withoutMergingHistory` - -### `withoutSavingHistory` - -## Node - -Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/node). - -### `TDescendant` - -### `getNodeDescendants` - -### `getNodeLastNode` - -### `getNodeString` - -### `getNodeFirstNode` - -### `hasNode` - -### `isNode` - -### `getNodeFragment` - -### `getNodeLeaf` - -### `getNodeLevels` - -### `isNodeList` - -### `getNodeProps` - -### `TAncestor` - -### `getNode` - -### `getNodeTexts` - -### `getNodes` - -### `getNodeChildren` - -### `getNodeAncestor` - -### `TNodeEntry` - -### `TNode` - -### `nodeMatches` - -### `getNodeChild` - -### `getNodeElements` - -### `getNodeAncestors` - -### `getNodeDescendant` - -### `getCommonNode` - -### `isAncestor` - -### `hasSingleChild` - -### `getNodeParent` - -## Range - -Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/locations/range). - -### `isCollapsed` - -### `isExpanded` - -## Text - -Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/text). - -### `isText` - -### `isTextList` - -### `textEquals` - -### `textMatches` - -### `TText` - -## Transforms - -Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/transforms). - -### `moveNodes` - -### `moveSelection` - -### `removeNodes` - -### `select` - -### `insertText` - -### `insertNodes` - -### `deleteText` - -### `setPoint` - -### `setNodes` - -### `unwrapNodes` - -### `deselect` - -### `mergeNodes` - -### `collapseSelection` - -### `unsetNodes` - -### `setSelection` - -### `splitNodes` - -### `insertFragment` - -### `wrapNodes` - -### `liftNodes` - -## Types - -### QueryNodeOptions - -An interface used to query node entries. - - - - -A function to filter node entries. - -- The function should take a node entry as a parameter and return a boolean. - - - - -List of types that are valid. - -- If empty or undefined, all types are allowed. - - - - -List of types that are invalid. - - - - -Valid path levels. - - - - -Paths above this level are invalid. - - - +v42 documentation is in progress. \ No newline at end of file diff --git a/apps/www/content/docs/en/api/slate-utils.mdx b/apps/www/content/docs/en/api/slate/_slate.mdx similarity index 71% rename from apps/www/content/docs/en/api/slate-utils.mdx rename to apps/www/content/docs/en/api/slate/_slate.mdx index 608175c536..4f57af1df3 100644 --- a/apps/www/content/docs/en/api/slate-utils.mdx +++ b/apps/www/content/docs/en/api/slate/_slate.mdx @@ -1,9 +1,371 @@ --- -title: Slate Utils -description: API reference for @udecode/slate-utils. +title: Slate +description: API reference for @udecode/slate. --- -`@udecode/slate-utils` contains utility functions for Slate. +v42 documentation is in progress. + +`@udecode/slate` extends Slate API with generic types. + +## Editor + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/transforms). + +### `addMark` + +### `createPathRef` + +### `createPointRef` + +### `createRangeRef` + +### `deleteBackward` + +### `deleteForward` + +### `deleteFragment` + +### `deleteMerge` + +### `getAboveNode` + +### `getEdgePoints` + +### `getEditorString` + +### `getEndPoint` + +### `getFirstNode` + +### `getFragment` + +### `getLastNode` + +### `getLeafNode` + +### `getLevels` + +### `getMarks` + +### `getNextNode` + +### `getNodeEntries` + +### `getNodeEntry` + +### `getParentNode` + +### `getPath` + +### `getPathRefs` + +### `getPoint` + +### `getPointAfter` + +### `getPointBefore` + +### `getPointRefs` + +### `getPositions` + +### `getPreviousNode` + +### `getRange` + +### `getRangeRefs` + +### `getStartPoint` + +### `getVoidNode` + +### `hasBlocks` + +### `hasInlines` + +### `hasTexts` + +### `index` + +### `insertBreak` + +### `insertNode` + +### `isBlock` + +### `isEdgePoint` + +### `isEditor` + +### `isEditorNormalizing` + +### `isElementEmpty` + +### `isEndPoint` + +### `isInline` + +### `isStartPoint` + +### `isVoid` + +### `normalizeEditor` + +### `removeEditorMark` + +### `Editor` + +### `unhangRange` + +### `withoutNormalizing` + +## DOM Editor + +Find the corresponding documentation in the [Slate React docs](https://docs.slatejs.org/libraries/slate-react/react-editor). + +### `blurEditor` + +### `deselectEditor` + +### `findEditorDocumentOrShadowRoot` + +### `findEventRange` + +### `findNodeKey` + +### `findPath` + +### `focusEditor` + +### `getEditorWindow` + +### `hasEditorDOMNode` + +### `hasEditorEditableTarget` + +### `hasEditorSelectableTarget` + +### `hasEditorTarget` + +### `insertData` + +### `isComposing` + +### `isEditorFocused` + +### `isEditorReadOnly` + +### `isTargetInsideNonReadonlyVoidEditor` + +### `setFragmentData` + +### `toDOMNode` + +### `toDOMPoint` + +### `toDOMRange` + +### `toSlateNode` + +### `toSlatePoint` + +### `toSlateRange` + +## Element + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/element). + +### `elementMatches` + +### `index` + +### `isElement` + +### `isElementList` + +### `TElement` + +## History + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/libraries/slate-history). + +### `isHistoryEditor` + +### `isHistoryMerging` + +### `isHistorySaving` + +### `withoutMergingHistory` + +### `withoutSavingHistory` + +## Node + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/node). + +### `Descendant` + +### `getNodeDescendants` + +### `getNodeLastNode` + +### `getNodeString` + +### `getNodeFirstNode` + +### `hasNode` + +### `isNode` + +### `getNodeFragment` + +### `getNodeLeaf` + +### `getNodeLevels` + +### `isNodeList` + +### `getNodeProps` + +### `Ancestor` + +### `getNode` + +### `getNodeTexts` + +### `getNodes` + +### `getNodeChildren` + +### `getNodeAncestor` + +### `NodeEntry` + +### `TNode` + +### `nodeMatches` + +### `getNodeChild` + +### `getNodeElements` + +### `getNodeAncestors` + +### `getNodeDescendant` + +### `getCommonNode` + +### `isAncestor` + +### `hasSingleChild` + +### `getNodeParent` + +## Range + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/locations/range). + +### `isCollapsed` + +### `isExpanded` + +## Text + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/text). + +### `isText` + +### `isTextList` + +### `textEquals` + +### `textMatches` + +### `TText` + +## Editor Transforms + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/transforms). + +### `moveNodes` + +### `moveSelection` + +### `removeNodes` + +### `select` + +### `insertText` + +### `insertNodes` + +### `deleteText` + +### `setPoint` + +### `setNodes` + +### `unwrapNodes` + +### `deselect` + +### `mergeNodes` + +### `collapseSelection` + +### `unsetNodes` + +### `setSelection` + +### `splitNodes` + +### `insertFragment` + +### `wrapNodes` + +### `liftNodes` + +## Types + +### QueryNodeOptions + +An interface used to query node entries. + + + + +A function to filter node entries. + +- The function should take a node entry as a parameter and return a boolean. + + + + +List of types that are valid. + +- If empty or undefined, all types are allowed. + + + + +List of types that are invalid. + + + + +Valid path levels. + + + + +Paths above this level are invalid. + + + ## Queries @@ -12,7 +374,7 @@ description: API reference for @udecode/slate-utils. Iterates through all nodes in the editor and returns the first match. If no match is found, returns undefined. - + The editor to search for the descendant node. @@ -32,10 +394,10 @@ Returns the block above a specified location - **Default:** Selection. - + The editor to search for the block. - + The options to find the block above a location. @@ -50,10 +412,10 @@ Returns the block above the specified location. Retrieves block-level node entries from the editor. - + The editor to search for block-level nodes. - + Options for getting node entries. @@ -67,7 +429,7 @@ Retrieves block-level node entries from the editor. Returns the children node entries of a node entry. - + The node entry to get its children. @@ -84,10 +446,10 @@ Returns the edge blocks above a specified location. - **Default:** Selection. - + The editor to search for the edge blocks. - + The options to find the edge blocks above a location. @@ -151,7 +513,7 @@ Gets the first text node from a node. Returns the last child of a node or `null` if no children. - + The node entry to get its last child. @@ -164,7 +526,7 @@ Returns the last child of a node or `null` if no children. Retrieves the last node at a specified level in the editor. - + The editor to search for the last node. @@ -181,7 +543,7 @@ Retrieves the last node at a specified level in the editor. Retrieves the value of the selection mark by key in the editor. - + The editor where the selection mark is located. @@ -198,7 +560,7 @@ Retrieves the value of the selection mark by key in the editor. Retrieves the start point of the next node at a specified path in the editor. - + The editor to search for the next node. @@ -215,7 +577,7 @@ Retrieves the start point of the next node at a specified path in the editor. Retrieves the sibling nodes following a specified path in the ancestor node. - + The ancestor node of the sibling nodes. @@ -232,12 +594,12 @@ Retrieves the sibling nodes following a specified path in the ancestor node. Retrieves the operations of the editor. - + The editor to get its operations. - Returns the operations of the editor as `TOperation` array. + Returns the operations of the editor as `Operation` array. ### getPointBeforeLocation @@ -245,7 +607,7 @@ Retrieves the operations of the editor. Returns the point before a location, with additional options to customize the behavior. If no options are provided or neither **`match`** nor **`matchString`** are defined, it will default to using **`getPointBefore`**. - + The editor where to find the point before a location. @@ -264,7 +626,7 @@ Returns the point before a location, with additional options to customize the be Returns the point from a location (**Default:** selection). If the location is a range, it gets the anchor point. If the location is a path, it gets the point at this path with offset 0. - + The editor where to find the point. @@ -297,7 +659,7 @@ Returns the point from the location. If the start point is inside an inline void, returns the point before or after it. - + The editor where to find the point next to the void. @@ -326,7 +688,7 @@ Returns the point next to the void. Finds the block before a block by ID. If not found, it finds the first block by ID and returns **`[null, its previous path]`**. - + The editor where to find the previous block. @@ -345,7 +707,7 @@ Finds the block before a block by ID. If not found, it finds the first block by Gets the end point of the previous node. - + The editor where to find the previous node's end point. @@ -374,7 +736,7 @@ Generates the previous path based on the given path. Gets the previous sibling node from the given path. - + The editor instance. @@ -391,7 +753,7 @@ Gets the previous sibling node from the given path. Gets the range from the point before a given location to the end point of the location. - + The editor instance. @@ -411,10 +773,10 @@ Gets the range from the point before a given location to the end point of the lo Gets the range from the start of the block above a location to the location. - + The editor instance. - + Options for getting the block above the location. @@ -428,7 +790,7 @@ Gets the range from the start of the block above a location to the location. Retrieves the fragment of the current selection, optionally unwrapping structural nodes. - + The editor to get the selection fragment from. @@ -449,7 +811,7 @@ Retrieves the fragment of the current selection, optionally unwrapping structura Gets the selected text from the editor. - + The editor instance. @@ -462,10 +824,10 @@ Gets the selected text from the editor. Checks whether an ancestor node is empty (has empty text and no inline children). - + The editor instance. - + The ancestor node to check. @@ -480,7 +842,7 @@ True if the ancestor node is empty, false otherwise. Checks whether the block above the selection is empty. - + The editor instance. @@ -495,7 +857,7 @@ True if the block above the selection is empty, false otherwise. Checks whether the text in the block after the selection is empty. - + The editor instance. @@ -510,7 +872,7 @@ True if the text in the block after the selection is empty, false otherwise. Checks whether the selection is at the end of the document. - + The editor instance. @@ -540,7 +902,7 @@ True if the node is the first child of its parent, false otherwise. Checks whether a mark is active in the selection. - + The editor instance. @@ -558,7 +920,7 @@ True if the mark is active in the selection. Checks whether a point is at the end of a word. - + The editor instance. @@ -574,7 +936,7 @@ Checks whether a point is at the end of a word. Determines whether the range (**Default:** selection) is across blocks. - + The editor instance. @@ -591,7 +953,7 @@ Determines whether the range (**Default:** selection) is across blocks. Determines whether the range is within the same block. - + The editor instance. @@ -620,10 +982,10 @@ Checks whether a range is within a single text path. Checks whether the selection focus is at the end of its parent block. - + The editor instance. - + The options object. @@ -637,10 +999,10 @@ Checks whether the selection focus is at the end of its parent block. Checks whether the selection anchor or focus is at the start of its parent block. - + The editor instance. - + The options object. @@ -654,7 +1016,7 @@ Checks whether the selection anchor or focus is at the start of its parent block Checks whether the selection is expanded. - + The editor instance. @@ -669,7 +1031,7 @@ True if the selection is expanded, false otherwise. Checks whether the node at a given path is a text node. - + The editor instance. @@ -687,7 +1049,7 @@ True if the node is a text node, false otherwise. Checks whether the word at a given point is after a trigger (punctuation character). - + The editor instance. @@ -708,7 +1070,7 @@ Checks whether the word at a given point is after a trigger (punctuation charact Queries the editor state. - + The editor instance. @@ -728,52 +1090,20 @@ Queries the editor state. Duplicates the given blocks and inserts them after the last block in the selection. - + The editor instance. - + An array of node entries representing the blocks to duplicate. -### insertElements - -Inserts nodes at a location in the document. - - - - The editor instance. - - - The nodes to insert. - - - The options object. - - - -### insertEmptyElement - -Inserts an empty element at a location in the document. - - - - The editor instance. - - - The type of the element to insert. - - - The options object. - - - ### moveChildren Moves the children of a node to a path. - + The editor instance. @@ -792,10 +1122,10 @@ The number of children moved. Removes all non-empty text nodes from the editor. - + The editor instance. - + Options for removing nodes. The `match` function in options will be combined with the text length check. @@ -805,7 +1135,7 @@ Removes all non-empty text nodes from the editor. Removes a mark and triggers `onChange` if the selection is collapsed. - + The editor instance. @@ -819,7 +1149,7 @@ Removes a mark and triggers `onChange` if the selection is collapsed. Removes all children of a node. - + The editor instance. @@ -835,7 +1165,7 @@ Removes all children of a node. Removes all marks from the selection. - + The editor instance. @@ -845,7 +1175,7 @@ Removes all marks from the selection. Replaces the children of a node: removes then inserts them. - + The editor instance. @@ -859,7 +1189,7 @@ Replaces the children of a node: removes then inserts them. Selects the end point of the block above the selection. - + The editor instance. @@ -869,10 +1199,10 @@ Selects the end point of the block above the selection. Selects the range encompassing the given nodes. - + The editor instance. - + An array of node entries to select. @@ -882,13 +1212,13 @@ Selects the range encompassing the given nodes. Sets properties on the block above the current selection. - + The editor instance. - + The properties to set on the block. - + Options for setting nodes, excluding the 'at' property. @@ -898,13 +1228,13 @@ Sets properties on the block above the current selection. Sets properties on the lowest-level nodes within the block above the current selection. - + The editor instance. - + The properties to set on the text nodes. - + Options for setting nodes, excluding the 'at' property. @@ -914,13 +1244,13 @@ Sets properties on the lowest-level nodes within the block above the current sel Sets properties on all block nodes that match the given options. - + The editor instance. - + The properties to set on the matching block nodes. - + Options for getting node entries to update. @@ -930,7 +1260,7 @@ Sets properties on all block nodes that match the given options. Sets marks to selected text. - + The editor instance. @@ -946,7 +1276,7 @@ Sets marks to selected text. Adds or removes marks in the selection. - + The editor instance. @@ -959,7 +1289,7 @@ Adds or removes marks in the selection. Unwraps a node if the node type is in selection, otherwise wraps it. - + The editor instance. @@ -972,7 +1302,7 @@ Unwraps a node if the node type is in selection, otherwise wraps it. Wraps the children of a node into a single element. - + The editor instance. @@ -1002,7 +1332,7 @@ The text for the node. - **Default:** an empty string. - + The remaining nodes. - **Default:** an empty array. @@ -1010,7 +1340,7 @@ The remaining nodes. -An array of `TDescendant` nodes, starting with the newly created node. +An array of `Descendant` nodes, starting with the newly created node. ### createNode @@ -1036,3 +1366,23 @@ The text for the node. A new `TElement` node. + +### focusEditorEdge + +Focuses the editor at a specified edge (start or end). + + + + The editor instance. + + + + + The edge to focus on. + - 'start': Focus at the beginning of the editor. + - 'end': Focus at the end of the editor. + Default is 'start'. + + + + diff --git a/apps/www/content/docs/en/api/slate/editor-api.mdx b/apps/www/content/docs/en/api/slate/editor-api.mdx new file mode 100644 index 0000000000..91e4b24da2 --- /dev/null +++ b/apps/www/content/docs/en/api/slate/editor-api.mdx @@ -0,0 +1,1413 @@ +--- +title: Editor API +description: API reference for the Editor API. +--- + +The Editor API provides a set of helper functions for querying and manipulating the editor state. + +## `editor.api` + +### `above` + +Get the matching ancestor above a location in the document. + + + + + + Common query options. + + + Query mode options. + + + Whether to include void nodes in the search + + + + + + + Returns a `NodeEntry>` tuple containing the matching ancestor node and its path, or `undefined` if no match is found. + + +### `block` + +Get the block at a location or find the first block that matches options. + +```ts +editor.api.block() // Get block above selection +editor.api.block({ above: true }) // Get block above selection +editor.api.block({ at: [0, 0] }) // Get block at [0, 0] +editor.api.block({ at: [0, 0], above: true }) // Get block at [0] +editor.api.block({ highest: true }) // Get highest block at selection +``` + + + + + + Common query options. + + + The location to query at. Defaults to current selection. + + + Whether to ignore non-selectable nodes during traversal. + + + Whether to traverse in reverse order. + + + Whether to ensure the operation works universally across all nodes. + + + If true, get the block above the location. + + + If true, get the highest block at the location. + + + + + + + Returns the matching block node entry or `undefined` if no match is found. + + +### `blocks` + +Returns all matching blocks. + + + + + + Common query options. + + + The location to query at. Defaults to current selection. + + + Whether to ignore non-selectable nodes during traversal. + + + Whether to traverse in reverse order. + + + Whether to ensure the operation works universally across all nodes. + + + Query mode options. + + + Whether to include void nodes in the search. + + + + + + + Returns an array of `NodeEntry>` tuples containing the matching block nodes and their paths. + + +### `descendant` + +Returns the first matching descendant. + + + + + + Common query options. + + + The location to query at. Defaults to current selection. + + + Whether to ignore non-selectable nodes during traversal. + + + Whether to traverse in reverse order. + + + Whether to ensure the operation works universally across all nodes. + + + Query mode options. + + + Whether to include void nodes in the search. + + + + + + + Returns a `NodeEntry>` tuple containing the first matching descendant node and its path, or `undefined` if no match is found. + + +### `edgeBlocks` + +Returns the edge blocks above a location (default: selection). + + + + + + Common query options. + + + The location to query at. Defaults to current selection. + + + Whether to ignore non-selectable nodes during traversal. + + + Whether to traverse in reverse order. + + + Whether to ensure the operation works universally across all nodes. + + + Query mode options. + + + Whether to include void nodes in the search. + + + + + + + Returns a tuple of `[NodeEntry>, NodeEntry>]` containing the start and end block nodes and their paths, or `null` if not found. + + +### `fragment` + +Get the fragment at a location or selection. + + + + The location to get the fragment from. Defaults to current selection. + + + + + Types of structural nodes to unwrap. + + + + + + + Returns an array of `ElementOrTextIn` nodes representing the fragment. + + +### `isEmpty` + +Check if an element is empty, accounting for void nodes. + +```ts +editor.api.isEmpty() // Check if editor is empty +editor.api.isEmpty(at) // Check if nodes at location are empty +editor.api.isEmpty(at, { after: true }) // Check if text after location is empty +editor.api.isEmpty(at, { block: true }) // Check if block above location is empty +``` + + + + + + Common query options. + + + The location to check. Defaults to current selection. + + + Check if text after selection is empty. + + + Check if block above location is empty. + + + + + + + Returns `true` if empty, `false` otherwise. + + +### `isAt` + +Check if a location (point/range) is at a specific position. + +```ts +// For ranges: +editor.api.isAt({ text: true }) // Check if range is in single text node +editor.api.isAt({ block: true }) // Check if range is in single block +editor.api.isAt({ blocks: true }) // Check if range is across multiple blocks +editor.api.isAt({ start: true }) // Check if range starts at block start +editor.api.isAt({ end: true }) // Check if range ends at block end + +// For points: +editor.api.isAt({ word: true }) // Check relative to word boundaries +editor.api.isAt({ start: true }) // Check if at start +editor.api.isAt({ end: true }) // Check if at end +``` + + + + + + The location to check. Defaults to current selection. + + + Check if range is in single text node. + + + Check if range is in single block. + + + Check if range is across multiple blocks. + + + Check if at start position. + + + Check if at end position. + + + Check relative to word boundaries. + + + + + + + Returns `true` if the location matches the specified position criteria. + + +### `mark` + +Returns the selection mark value by key. + + + + The mark key to get the value for. + + + + + Returns `MarksIn[K] | null | undefined` - The mark value if it exists, `null` if the mark is not set, or `undefined` if there are multiple different values. + + +### `nodes` + +Iterate through all nodes in the editor that match the given options. + + + + + + Common query options. + + + Where to start iterating. Defaults to editor selection. + + + Whether to ignore non-selectable nodes during traversal. + + + Whether to traverse in reverse order. + + + Whether to ensure the operation works universally across all nodes. + + + Query mode options. + + + Whether to include void nodes in the search. + + + + + + + Returns a generator of `NodeEntry>` tuples containing the matching nodes and their paths. + + +### `prop` + +Get a property value from a list of nodes. Returns undefined if the property value is not consistent across all nodes. + + + + + + Nodes to get the property value from. + + + Property key to get. + + + Default value if property not found. + + + Custom function to extract property value. + + + - 'all': Get the property value from all nodes. + - 'block': Get the property value from the first block node. + - 'text': Get the property value from the first text node. + + + + + + + Returns `string | undefined` - The consistent property value if found, or `undefined` if the property is not consistent across nodes. + + +## DOM + +### `findPath` + +Find the path of a Slate node. + + + + The node to find the path for. + + + + + Common query options. + + + Whether to ignore non-selectable nodes during traversal. + + + Whether to traverse in reverse order. + + + Whether to ensure the operation works universally across all nodes. + + + Query mode options. + + + Whether to include void nodes in the search. + + + + + + + Returns `Path | undefined` - The path of the node if found, or `undefined` if not found. + + +### `toDOMNode` + +Find the native DOM element from a Slate node. + + + + The Slate node to find the corresponding DOM element for. + + + + + Returns `HTMLElement` - The corresponding DOM element for the Slate node. + + +### `toSlateNode` + +Find a Slate node from a native DOM element. + + + + The DOM node to find the corresponding Slate node for. + + + + + Returns `TNode | undefined` - The corresponding Slate node if found, or `undefined` if not found. + + +## Utils + +### `createPathRef` + +Create a mutable ref for a Path object. + + + + The path to create a reference for. + + + + + The direction to resolve the ref when ambiguous: + - 'forward': Resolve to the next valid position + - 'backward': Resolve to the previous valid position + - null: Do not resolve to any position + + + + + + + Returns `PathRef` - A mutable reference that updates its path as operations are applied to the editor. + + +### `createPointRef` + +Create a mutable ref for a Point object. + + + + The point to create a reference for. + + + + + The direction to resolve the ref when ambiguous: + - 'forward': Resolve to the next valid position + - 'backward': Resolve to the previous valid position + - null: Do not resolve to any position + + + + + + + Returns `PointRef` - A mutable reference that updates its point as operations are applied to the editor. + + +### `createRangeRef` + +Create a mutable ref for a Range object. + + + + The range to create a reference for. + + + + + The direction to resolve the ref when ambiguous: + - 'forward': Resolve both points forward + - 'backward': Resolve both points backward + - 'outward': Resolve start backward and end forward + - 'inward': Resolve start forward and end backward + - null: Do not resolve to any position + + + + + + + Returns `RangeRef` - A mutable reference that updates its range as operations are applied to the editor. + + +### `unhangRange` + +Convert a range into a non-hanging one. + +```ts +// A "hanging" range is one created by the browser's "triple-click" selection behavior. +// When triple-clicking a block, the browser selects from the start of that block to +// the start of the next block. The range thus "hangs over" into the next block. +``` + + + + The range to unhang. + + + + + Allow placing the end of the selection in a void node. + + + + + + + Returns `Range` - A new range with the end point moved backwards if it was hanging. + + +## Editor State + +### `shouldMergeNodesRemovePrevNode` + +Determines whether to remove the previous node when merging nodes. + + + + A tuple containing the previous node and its path. + + + A tuple containing the current node and its path. + + + + + Returns `boolean` - `true` if the previous node should be removed during merge, `false` otherwise. + + +### `shouldNormalize` + +Controls whether the editor should normalize after an operation. + + + + + + The paths that need to be normalized. + + + The initial number of dirty paths before normalization started. + + + The current normalization iteration count. + + + The operation that triggered the normalization. + + + + + + + Returns `boolean` - `true` if the editor should normalize, `false` otherwise. + + +### `getDirtyPaths` + +Get the paths that need to be normalized after an operation. + + + + The operation that triggered the normalization. + + + + + Returns `Path[]` - An array of paths that need to be normalized after applying the operation. + + +### `setNormalizing` + +Manually control the editor's normalizing state. + + + + Whether the editor should normalize after each operation. + + + + + Returns `void` + + +```ts +// Note: Using this incorrectly can leave the editor in an invalid state. +``` + +### `onChange` + +Called when there is a change in the editor. + + + + + + The operation that triggered the change. + + + + + + + Returns `void` + + +## Node Operations + +### `last` + +Get the last node at a location. + + + + The location to get the last node from. + + + + + Get last node at this level (0-based). + + + + + + + Returns `NodeEntry>` tuple containing the last node and its path, or `undefined` if not found. + + +### `leaf` + +Get the leaf text node at a location. + + + + The location to get the leaf from. + + + + + The depth to search to. + + + Which edge to get the leaf from ('start' | 'end'). + + + + + + + Returns `NodeEntry>` tuple containing the leaf text node and its path, or `undefined` if not found. + + +### `levels` + +Iterate through all levels at a location. + + + + + + Common query options. + + + Whether to traverse in reverse order. + + + Whether to include void nodes in the search. + + + + + + + Returns a generator of `NodeEntry>` tuples containing each ancestor node and its path. + + +## Element Operations + +### `isElementReadOnly` + +Check if an element is read-only. + + + + The element to check for read-only status. + + + + + Returns `boolean` - `true` if the element is read-only, `false` otherwise. + + +### `isVoid` + +Check if an element is void. + + + + The element to check. + + + + + Returns `boolean` - `true` if the element is void, `false` otherwise. + + +### `markableVoid` + +Check if an element is a markable void element. + + + + The element to check for markable void status. + + + + + Returns `boolean` - `true` if the element is a markable void, `false` otherwise. + + +## Position Operations + +### `positions` + +Iterate through all possible point positions in the document. + + + + + + The location to start iterating from. Defaults to editor selection. + + + The unit to move by ('offset' | 'character' | 'word' | 'line' | 'block'). + + + Whether to iterate in reverse order. + + + Whether to include void nodes in the search. + + + Whether to skip non-selectable nodes. + + + + + + + Returns a generator of `Point` objects representing each possible position in the document. + + +## Range Operations + +### `range` + +Create a range between two locations. + + + + + + The location to create the range at. Defaults to current selection. + + + The focus point of the range. + + + The anchor point of the range. + + + + + + + Returns `Range` - A new range between the specified points. + + +### `start` + +Get the start point of a location. + + + + The location to get the start point from. Defaults to current selection. + + + + + Get the start point of the next node. + + + + + + + Returns `Point` - The start point of the location. + + +### `string` + +Get the text string content of a location. + + + + The location to get text from. Defaults to current selection. + + + + + Whether to include void nodes in the search. + + + + + + + Returns `string` - The text content at the specified location. + + +### `next` + +Get the matching node in the branch of the document after a location. + + + + + + Common query options. + + + The location to start searching from. Defaults to current selection. + + + Query mode options. + + + Whether to include void nodes in the search. + + + + + + + Returns `NodeEntry>` tuple containing the next matching node and its path, or `undefined` if not found. + + +### `node` + +Get the node at a location or find the first node that matches options. + + + + The location to get the node from. Defaults to current selection. + + + + + The depth of the node to return. + + + Which edge to get the node from. + + + + + + + Returns `NodeEntry>` tuple containing the node and its path, or `undefined` if not found. + + +### `parent` + +Get the parent node of a location. + + + + The location to get the parent from. Defaults to current selection. + + + + + The number of levels to traverse up. + + + Which edge to get the parent from. + + + + + + + Returns `NodeEntry>` tuple containing the parent node and its path, or `undefined` if not found. + + +### `path` + +Get the path of a location. + + + + The location to get the path from. Defaults to current selection. + + + + + The depth of the path to return. + + + Which edge to get the path from. + + + + + + + Returns `Path` - The path at the specified location. + + +### `point` + +Get the start or end point of a location. + + + + The location to get the point from. Defaults to current selection. + + + + + Which edge to get the point from. + + + + + + + Returns `Point` - The point at the specified edge of the location. + + +### `previous` + +Get the matching node in the branch of the document before a location. + + + + + + Common query options. + + + The location to start searching from. Defaults to current selection. + + + Query mode options. + + + Whether to include void nodes in the search. + + + Whether to get the previous sibling node. + + + + + + + Returns `NodeEntry>` tuple containing the previous matching node and its path, or `undefined` if not found. + + +## Reference Operations + +### `createPathRef` + +Create a mutable ref for a Path object. + + + + The path to create a reference for. + + + + + The direction to resolve the ref when ambiguous: + - 'forward': Resolve to the next valid position + - 'backward': Resolve to the previous valid position + - null: Do not resolve to any position + + + + + + + Returns `PathRef` - A mutable reference that updates its path as operations are applied to the editor. + + +### `createPointRef` + +Create a mutable ref for a Point object. + + + + The point to create a reference for. + + + + + The direction to resolve the ref when ambiguous: + - 'forward': Resolve to the next valid position + - 'backward': Resolve to the previous valid position + - null: Do not resolve to any position + + + + + + + Returns `PointRef` - A mutable reference that updates its point as operations are applied to the editor. + + +### `createRangeRef` + +Create a mutable ref for a Range object. + + + + The range to create a reference for. + + + + + The direction to resolve the ref when ambiguous: + - 'forward': Resolve both points forward + - 'backward': Resolve both points backward + - 'outward': Resolve start backward and end forward + - 'inward': Resolve start forward and end backward + - null: Do not resolve to any position + + + + + + + Returns `RangeRef` - A mutable reference that updates its range as operations are applied to the editor. + + +## DOM Operations + +### `findPath` + +Find the path of a DOM node. + + + + The DOM node to find the path for. + + + + + mode: Query mode ('highest' | 'lowest' | 'all') + + + voids: Whether to include void nodes + + + + + +### `toDOMNode` + +Find the DOM node from a Slate node. + + + + The Slate node to find the corresponding DOM element for. + + + + + Returns `HTMLElement` - The corresponding DOM element for the Slate node. + + +### `toDOMPoint` + +Find a Slate point from a DOM point. + + + + The DOM point to convert to a Slate point. + + + + + Returns `Point | undefined` - The corresponding Slate point if found, or `undefined` if not found. + + +### `toDOMRange` + +Find a DOM range from a Slate range. + + + + The Slate range to convert to a DOM range. + + + + + Returns `DOMRange` - The corresponding DOM range for the Slate range. + + +### `toSlateNode` + +Find a Slate node from a native DOM element. + + + + The DOM node to find the corresponding Slate node for. + + + + + Returns `TNode | undefined` - The corresponding Slate node if found, or `undefined` if not found. + + +### `toSlatePoint` + +Find a Slate point from a DOM point. + + + + The DOM point to convert to a Slate point. + + + + + Returns `Point | undefined` - The corresponding Slate point if found, or `undefined` if not found. + + +### `toSlateRange` + +Find a Slate range from a DOM range. + + + + The DOM range to convert to a Slate range. + + + + + Returns `Range | undefined` - The corresponding Slate range if found, or `undefined` if not found. + + +## Query Operations + +### `hasBlocks` + +Check if a node has block children. + + + + The node to check for block children. + + + + + Returns `boolean` - `true` if the node has block children, `false` otherwise. + + +### `hasInlines` + +Check if a node has inline children. + + + + The node to check for inline children. + + + + + Returns `boolean` - `true` if the node has inline children, `false` otherwise. + + +### `hasTexts` + +Check if a node has text children. + + + + The node to check for text children. + + + + + Returns `boolean` - `true` if the node has text children, `false` otherwise. + + +### `isBlock` + +Check if a value is a block element. + + + + The value to check for block element type. + + + + + Returns `boolean` - `true` if the value is a block element, `false` otherwise. + + +### `isEdgePoint` + +Check if a point is an edge of a location. + + + + The point to check for edge position. + + + The location to check the edge of. + + + + + Returns `boolean` - `true` if the point is at the start or end edge of the location, `false` otherwise. + + +### `isEmpty` + +Check if a location is empty. + + + + The location to check for emptiness. Defaults to current selection. + + + + + Whether to check if text after the location is empty. + + + Whether to check if the block above the location is empty. + + + + + + + Returns `boolean` - `true` if the location is empty, `false` otherwise. + + +### `isEnd` + +Check if a point is the end of a location. + + + + The point to check for end position. + + + The location to check the end of. + + + + + Whether to get the end point of the previous node. + + + + + + + Returns `boolean` - `true` if the point is at the end of the location, `false` otherwise. + + +### `isStart` + +Check if a point is the start of a location. + + + + The point to check for start position. + + + The location to check the start of. + + + + + Whether to get the start point of the next node. + + + + + + + Returns `boolean` - `true` if the point is at the start of the location, `false` otherwise. + + +### `isElementReadOnly` + +Check if an element is read-only. + + + + The element to check for read-only status. + + + + + Returns `boolean` - `true` if the element is read-only, `false` otherwise. + + +### `isVoid` + +Check if an element is void. + + + + The element to check. + + + + + Returns `boolean` - `true` if the element is void, `false` otherwise. + + +### `markableVoid` + +Check if an element is a markable void element. + + + + The element to check for markable void status. + + + + + Returns `boolean` - `true` if the element is a markable void, `false` otherwise. + + +```ts +// Note: Using this incorrectly can leave the editor in an invalid state. +``` + +## Options + +### `QueryOptions` + +Common options used across multiple query methods: + + + + Location to start searching from. Defaults to current selection. + + + Match the node by id. `true` will match all nodes with an id. + + + Match block nodes. + + + When true, match only empty nodes. When false, match only non-empty nodes. + + + Match the node. + + + When true, match only text nodes. + + + +### `QueryMode` + + + + - 'all' (default): Return all matching nodes + - 'highest': In a hierarchy of nodes, only return the highest level matching nodes + - 'lowest': In a hierarchy of nodes, only return the lowest level matching nodes + + \ No newline at end of file diff --git a/apps/www/content/docs/en/api/slate/editor-transforms.mdx b/apps/www/content/docs/en/api/slate/editor-transforms.mdx new file mode 100644 index 0000000000..cf72dfbf5f --- /dev/null +++ b/apps/www/content/docs/en/api/slate/editor-transforms.mdx @@ -0,0 +1,700 @@ +--- +title: Editor Transforms +description: API reference for editor transformation operations in Slate. +--- + +Editor transforms are methods that modify the editor state. They are grouped into several categories: node operations, text operations, selection operations, DOM operations, and history operations. + +## `editor.tf` + +### `insertFragment` + +Insert a fragment of nodes at the specified location or current selection. + + + + The nodes to insert. + + + Options for the insertion: + + + batchDirty: Whether to batch dirty operations + + + hanging: Whether the insertion is hanging + + + at: Location where to perform insertion + + + voids: Whether to allow insertion in void nodes + + + + +### `insertNode` + +Atomically insert a node at the specified location or current selection. + + + + The node to insert. + + + Options for the insertion: + + batchDirty: Whether to batch dirty operations + + + hanging: Whether insertion is hanging + + + nextBlock: Insert after current block + + + removeEmpty: Remove current block if empty + + + select: Select inserted nodes + + + + +### `insertNodes` + +Atomically inserts multiple nodes at the specified location or current selection. + + + + A single node or array of nodes to insert. + + + Options for insertion: + + + at: Location where to insert nodes + + + hanging: Whether insertion is hanging + + + nextBlock: Insert after current block + + + removeEmpty: Remove current block if empty + + + select: Select inserted nodes + + + + + +### `replaceNodes` + +Replace nodes at a location with new nodes. + + + + The replacement nodes. + + + Options for the replacement: + + + children: When true, replace all children of the node at the specified location + + + removeNodes: Options for removing nodes before replacement + + + at: Location where to perform the replacement + + + select: When true, select the replaced nodes + + + hanging: Whether the operation is hanging + + + + + +### `setNodes` + +Set properties of nodes at the specified location. + + + + The properties to set. + + + Options for setting properties: + + + compare: Function to compare properties between nodes + + + hanging: Whether the operation is hanging + + + marks: When true, only apply to text nodes in non-void nodes or markable void nodes + + + merge: Function to merge properties between nodes + + + split: Whether to allow splitting nodes + + + at: Location where to set properties + + + match: Predicate to filter nodes + + + mode: The matching mode to use ('highest' | 'lowest') + + + + + +### `unsetNodes` + +Unset properties of nodes at the specified location. + + + + The properties to unset. + + + Options for unsetting properties: + + + hanging: Whether the operation is hanging + + + split: Whether to allow splitting nodes + + + + + +### `wrapNodes` + +Wrap nodes at the specified location in an element container. + + + + The wrapping element. + + + Options for wrapping: + + + children: When true, wrap node children into a single element + + + hanging: Whether the operation is hanging + + + split: Whether to allow splitting nodes during wrapping + + + + + +### `unwrapNodes` + +Unwrap nodes at the specified location. + + + + Options for unwrapping: + + + hanging: Whether the operation is hanging + + + split: Whether to allow splitting nodes + + + + + +### `mergeNodes` + +Merge a node with the previous node at the same depth. + + + + Options for merging: + + + hanging: Whether the operation is hanging + + + mergeNode: Custom function to handle node merging + + + removeEmptyAncestor: Custom function to handle empty ancestor removal + + + + + +### `moveNodes` + +Move nodes from one location to another. + + + + Options for moving: + + + to: The destination path + + + children: Move only children of the node at location + + + fromIndex: Start index of the children to move (Default: 0) + + + + + +### `liftNodes` + +Lift nodes upwards in the document tree. + + + + Options for lifting nodes. + + + +## Text Operations + +### `insertText` + +Insert text at the specified location or current selection. + + + + The text to insert. + + + Options for text insertion: + + + at: Location where to insert text + + + voids: Whether to allow insertion in void nodes + + + + + +### `deleteText` + +Delete text in the document. + + + + Options for deletion: + + + distance: Number of units to delete + + + hanging: Whether deletion is hanging + + + reverse: Whether to delete backwards + + + unit: Unit of text to delete + + + + + +## Selection Operations + +### `select` + +Set the selection to a new value. + + + + The target location. + + + Options for selection: + + + edge: Select edge of the block above location ('start' | 'end') + + + + + +### `setSelection` + +Set new properties on an active selection. + + + + The selection properties to set. + + + +## DOM Operations + +### `focus` + +Focus the editor. + + + + Options for focusing: + + + at: Target location to select before focusing + + + edge: Focus at location or editor edge ('start' | 'end' | 'startEditor' | 'endEditor') + + + retries: Number of times to retry focusing + + + + + +## History Operations + +### `withoutNormalizing` + +Call a function, deferring normalization until after it completes. + + + + The function to execute. + + + +### `withMerging` + +Apply changes that will be merged into the previous history. + + + + The function containing the changes. + + + +### `withNewBatch` + +Apply changes starting a new batch in the history. + + + + The function containing the changes. + + + +### `addMark` + +Add a custom property to the leaf text nodes in the current selection. + + + + The mark key to add. + + + The value to set for the mark. + + + +### `addMarks` + +Add multiple marks to the leaf text nodes in the current selection. + + + + The marks to add. + + + Options for adding marks: + + + remove: Marks to remove before adding new ones (string[] | string) + + + + + +### `removeMark` + +Remove a custom property from leaf text nodes in the current selection. + + + + The mark key to remove. + + + +### `removeMarks` + +Remove marks from text nodes. + + + + The mark keys to remove. + + + Options for removing marks: + + + at: Range where the mark(s) will be removed (Default: selection) + + + shouldChange: When true, trigger onChange if collapsed selection + + + + + +### `toggleMark` + +Toggle a mark on the leaf text nodes in the current selection. + + + + The mark key to toggle. + + + The value to set when adding the mark. + + + Options for toggling: + + + remove: Mark keys to remove when adding the mark + + + + + +### `deleteBackward` + +Delete content backward from the current selection. + + + + Options for deletion: + + + unit: Unit of text to delete ('character' | 'word' | 'line' | 'block') + + + distance: Number of units to delete + + + reverse: Whether to delete backwards + + + + + +### `deleteForward` + +Delete content forward from the current selection. + + + + Options for deletion: + + + unit: Unit of text to delete ('character' | 'word' | 'line' | 'block') + + + distance: Number of units to delete + + + + + +### `deleteFragment` + +Delete the content of the current selection. + + + + Options for deletion: + + + direction: Direction of deletion ('forward' | 'backward') + + + + + +### `duplicateNodes` + +Duplicate nodes at a location. + + + + Options for duplication: + + + at: Location to get nodes from and insert after (Default: selection) + + + block: If true, duplicate blocks above location + + + nodes: Specific nodes to duplicate (ignores block option if provided) + + + + + +### `insertBreak` + +Insert a block break at the current selection. + +### `insertSoftBreak` + +Insert a soft break at the current selection. + +### `normalize` + +Normalize any dirty objects in the editor. + + + + Options for normalization: + + + force: Whether to force normalization on all nodes + + + + + +### `redo` + +Redo to the next saved state. + +### `undo` + +Undo to the previous saved state. + +### `collapseSelection` + +Collapse the selection to a single point. + + + + Options for collapsing: + + + edge: Which edge to collapse to ('start' | 'end') + + + + + +### `moveSelection` + +Move the selection in a direction. + + + + Options for moving: + + + distance: Number of units to move + + + unit: Unit to move by ('offset' | 'character' | 'word' | 'line') + + + reverse: Whether to move backwards + + + edge: Which edge to move ('anchor' | 'focus' | 'start' | 'end') + + + + + +### `setPoint` + +Set new properties on one of the selection's points. + + + + The point properties to set. + + + Options for setting point: + + + edge: Which edge to set ('anchor' | 'focus' | 'start' | 'end') + + + + + +### `blur` + +Blur the editor. + +### `deselect` + +Unset the selection. + +### `withoutSaving` + +Apply changes without saving to history. + + + + The function containing the changes. + + + +### `withoutMerging` + +Apply changes without merging into previous history. + + + + The function containing the changes. + + + +## History Operations + +### `HistoryEditor` + +The `HistoryEditor` interface extends the base `Editor` interface to handle history operations. + + + + The history of operations. + + + Undo the last operation. + + + Redo the last undone operation. + + diff --git a/apps/www/content/docs/en/api/slate/element.mdx b/apps/www/content/docs/en/api/slate/element.mdx new file mode 100644 index 0000000000..ff420dd614 --- /dev/null +++ b/apps/www/content/docs/en/api/slate/element.mdx @@ -0,0 +1,156 @@ +--- +title: Element +description: API reference for elements in Slate. +--- + +`Element` objects are a type of node in a Slate document that contain other element nodes or text nodes. They can be either "blocks" or "inlines" depending on the Slate editor's configuration. + +## Element + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/element). + +### `isElementType` + +Checks if a value implements the `TElement` interface and has elementKey with selected value. + + + + The value to check. + + + The value to match against. + + + The key to check. Defaults to 'type'. + + + + Returns `true` if the value is an element with matching type. + + +### `isAncestor` + +Checks if a value implements the 'Ancestor' interface. + + + + The value to check. + + + + Returns `true` if the value is an ancestor node. + + +### `isElement` + +Checks if a value implements the `TElement` interface. + + + + The value to check. + + + + Returns `true` if the value is an element. + + +### `isElementList` + +Checks if a value is an array of `TElement` objects. + + + + The value to check. + + + + Returns `true` if the value is an array of elements. + + +### `isElementProps` + +Checks if a set of props is a partial of TElement. + + + + The props to check. + + + + Returns `true` if the props match element properties. + + +### `matches` + +Checks if an element matches set of properties. + + + + The element to check. + + + The properties to match against. + + + + Returns `true` if the element matches all properties (excluding children). + + +## Types + +### TElement + +The base element type. + + + + Properties: + - `children: Descendant[]` - Array of child nodes + - `type: string` - Element type identifier + - `[key: string]: unknown` - Additional custom properties + + + +### Element + +The concrete element type (same as TElement). + +### ElementOrTextOf + +A union type representing either an element or text node of an editor. + + + + Generic type for elements or text nodes from a specific editor type. + + + +### ElementOrTextIn + +A union type representing either an element or text node in a value. + + + + Generic type for elements or text nodes from a specific value type. + + + +### ElementOf + +A utility type to get all the element nodes type from a root node. + + + + Generic type that extracts element types from a node type. + + + +### ElementIn + +A utility type to get element types from a value type. + + + + Generic type that extracts element types from a value type. + + diff --git a/apps/www/content/docs/en/api/slate/location-ref.mdx b/apps/www/content/docs/en/api/slate/location-ref.mdx new file mode 100644 index 0000000000..b4373456c6 --- /dev/null +++ b/apps/www/content/docs/en/api/slate/location-ref.mdx @@ -0,0 +1,108 @@ +--- +title: Location References +description: API reference for location references in Slate. +--- + +Location references are objects that keep specific locations (paths, points, or ranges) in a document synced over time as new operations are applied to the editor. + +## PathRef + +`PathRef` objects keep a specific path in a document synced over time. You can access their `current` property at any time for the up-to-date path value. + +### `transform` + +Transforms the path ref's current value by an operation. + + + + The path reference to transform. + + + The operation to apply. + + + + + + Properties: + + + current: The current path value (Path | null) + + + affinity: The direction to prefer when transforming ('backward' | 'forward' | null) + + + unref(): Unreference and get the final path value (Path | null) + + + + + +## PointRef + +`PointRef` objects keep a specific point in a document synced over time. You can access their `current` property at any time for the up-to-date point value. + +### `transform` + +Transforms the point ref's current value by an operation. + + + + The point reference to transform. + + + The operation to apply. + + + + + + Properties: + + + current: The current point value (Point | null) + + + affinity: The direction to prefer when transforming (TextDirection | null) + + + unref(): Unreference and get the final point value (Point | null) + + + + + +## RangeRef + +`RangeRef` objects keep a specific range in a document synced over time. You can access their `current` property at any time for the up-to-date range value. + +### `transform` + +Transforms the range ref's current value by an operation. + + + + The range reference to transform. + + + The operation to apply. + + + + + + Properties: + + + current: The current range value (TRange | null) + + + affinity: The direction to prefer when transforming ('backward' | 'forward' | 'inward' | 'outward' | null) + + + unref(): Unreference and get the final range value (TRange | null) + + + + diff --git a/apps/www/content/docs/en/api/slate/location.mdx b/apps/www/content/docs/en/api/slate/location.mdx new file mode 100644 index 0000000000..9b08283e98 --- /dev/null +++ b/apps/www/content/docs/en/api/slate/location.mdx @@ -0,0 +1,115 @@ +--- +title: Location +description: API reference for locations in Slate. +--- + +The `Location` interface is a union of the ways to refer to a specific location in a Slate document: paths, points, or ranges. Methods often accept a `Location` instead of requiring only a `Path`, `Point`, or `Range`. This eliminates the need for developers to manage converting between the different interfaces in their own code base. + +## Location + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/locations). + +### `isAt` + +Checks if a value implements the `At` interface. + + + + The value to check. + + + + Returns `true` if the value is either a Location or a Node. + + +### `isLocation` + +Checks if a value implements the `Location` interface. + + + + The value to check. + + + + Returns `true` if the value is a Path, Point, or Range. + + +## Span + +The `Span` interface is a low-level way to refer to locations in nodes without using `Point` which requires leaf text nodes to be present. It is represented as a tuple of two paths. + +### `isSpan` + +Checks if a value implements the `Span` interface. + + + + The value to check. + + + + Returns `true` if the value is a valid Span (tuple of two paths). + + +## Types + +### TLocation + +The base location type that can be either a Path, Point, or Range. + + + + A union type that can be: + + + Path: An array of numbers representing a node's position + + + Point: An object with `path` and `offset` properties + + + TRange: An object with `anchor` and `focus` points + + + + + +### Location + +The concrete location type (same as TLocation but using concrete types). + + + + A union type that can be: + + + Path: An array of numbers representing a node's position + + + Point: An object with `path` and `offset` properties + + + Range: An object with `anchor` and `focus` points + + + + + +### Span + +A low-level location representation. + + + + A tuple containing: + + + First element: Starting path + + + Second element: Ending path + + + + diff --git a/apps/www/content/docs/en/api/slate/node-entry.mdx b/apps/www/content/docs/en/api/slate/node-entry.mdx new file mode 100644 index 0000000000..6752599d4b --- /dev/null +++ b/apps/www/content/docs/en/api/slate/node-entry.mdx @@ -0,0 +1,151 @@ +--- +title: NodeEntry +description: API reference for node entries in Slate. +--- + +`NodeEntry` objects are returned when iterating over the nodes in a Slate document tree. They consist of the node and its `Path` relative to the root node in the document. Node entries are represented as tuples of `[Node, Path]`. + +## Types + +### NodeEntry + +The base node entry type representing any node and its path in the document. + + + + A tuple containing: + + + First element: The node itself + + + Second element: The path to the node + + + + + +### ElementEntry + +Refers to an `Element` node and its path in the document. + + + + A tuple containing: + + + First element: An Element node + + + Second element: The path to the element + + + + + +### TextEntry + +Refers to a `Text` node and its path in the document. + + + + A tuple containing: + + + First element: A Text node + + + Second element: The path to the text node + + + + + +### AncestorEntry + +Represents an ancestor node (Editor or Element) and its path. + + + + A tuple containing: + + + First element: An Editor or Element node + + + Second element: The path to the ancestor + + + + + +### DescendantEntry + +Represents a descendant node (Element or Text) and its path. + + + + A tuple containing: + + + First element: An Element or Text node + + + Second element: The path to the descendant + + + + + +### NodeChildEntry + +Represents a child node and its path relative to its parent. + + + + A tuple containing: + + + First element: A child node + + + Second element: The path to the child + + + + + +## Generic Types + +These types provide type safety when working with specific node types: + + + + + + `NodeEntryOf`: Node entry from a specific editor type + + + `NodeEntryIn`: Node entry from a specific value type + + + `ElementEntryOf`: Element entry from a specific editor type + + + `TextEntryOf`: Text entry from a specific editor type + + + `TextEntryIn`: Text entry from a specific value type + + + `AncestorEntryOf`: Ancestor entry from a specific editor type + + + `DescendantEntryOf`: Descendant entry from a specific editor type + + + `DescendantEntryIn`: Descendant entry from a specific value type + + + + diff --git a/apps/www/content/docs/en/api/slate/node.mdx b/apps/www/content/docs/en/api/slate/node.mdx new file mode 100644 index 0000000000..b85be3e7bd --- /dev/null +++ b/apps/www/content/docs/en/api/slate/node.mdx @@ -0,0 +1,260 @@ +--- +title: Node +description: API reference for nodes in Slate. +--- + +The `Node` union type represents all of the different types of nodes that occur in a Slate document tree. This includes Editors, Elements, and Text nodes. + +## Node + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/node). + +### `ancestor` + +Gets the node at a specific path, asserting that it's an ancestor node. + + + + The root node to start from. + + + The path to the ancestor node. + + + + Returns the ancestor node if found, `undefined` otherwise. + + +### `ancestors` + +Returns a generator of all the ancestor nodes above a specific path. + + + + The root node to start from. + + + The path to get ancestors for. + + + + + If true, returns ancestors top-down instead of bottom-up. + + + + + + Returns a generator of `[Node, Path]` tuples. + + +### `child` + +Gets the child of a node at a specific index. + + + + The parent node. + + + The index of the child. + + + + Returns the child node if found, `undefined` otherwise. + + +### `children` + +Iterates over the children of a node at a specific path. + + + + The root node. + + + The path to the parent node. + + + + + If true, iterates in reverse order. + + + Start index (inclusive). + + + End index (exclusive). + + + + + + Returns a generator of `[Node, Path]` tuples. + + +### `common` + +Gets an entry for the common ancestor node of two paths. + + + + The root node. + + + First path. + + + Second path. + + + + Returns the common ancestor entry if found, `undefined` otherwise. + + +### `descendant` + +Gets the node at a specific path, asserting that it's a descendant node. + + + + The root node. + + + The path to the descendant. + + + + Returns the descendant node if found, `undefined` otherwise. + + +### `descendants` + +Returns a generator of all the descendant node entries inside a root node. + + + + The root node. + + + + + Starting path. + + + Ending path. + + + If true, iterates in reverse order. + + + Filter function for descendants. + + + + + + Returns a generator of `[Node, Path]` tuples. + + +### `elements` + +Returns a generator of all the element nodes inside a root node. + + + + The root node. + + + Similar options to `descendants`. + + + + Returns a generator of element entries. + + +### `texts` + +Returns a generator of all leaf text nodes in a root node. + + + + The root node. + + + Similar options to `descendants`. + + + + Returns a generator of text node entries. + + +### `matches` + +Checks if a node matches a set of props. + + + + The node to check. + + + The properties to match against. + + + + Returns `true` if the node matches all properties. + + +### `string` + +Gets the concatenated text string of a node's content. + + + + The node to get text from. + + + + Returns the concatenated text content. + + +## Types + +### Node + +The base node type that can be either an Editor, Element, or Text node. + +### Descendant + +Represents nodes that can be descendants in the tree (Element or Text nodes). + +### Ancestor + +Represents nodes that can be ancestors in the tree (Editor or Element nodes). + +### NodeProps + +Convenience type for returning the props of a node, omitting the `children` or `text` property. + +### NodeEntry + +A tuple type of `[Node, Path]` representing a node and its location in the tree. + +### Options Interfaces + + + + - `reverse?: boolean` - Reverse traversal order + + + - `reverse?: boolean` - Reverse traversal order + - `from?: number` - Start index (inclusive) + - `to?: number` - End index (exclusive) + + + - `reverse?: boolean` - Reverse traversal order + - `from?: Path` - Starting path + - `to?: Path` - Ending path + - `pass?: function` - Filter function + + \ No newline at end of file diff --git a/apps/www/content/docs/en/api/slate/operation.mdx b/apps/www/content/docs/en/api/slate/operation.mdx new file mode 100644 index 0000000000..0f70b39078 --- /dev/null +++ b/apps/www/content/docs/en/api/slate/operation.mdx @@ -0,0 +1,163 @@ +--- +title: Operation +description: API reference for operations in Slate. +--- + +`Operation` objects define the low-level instructions that Slate editors use to apply changes to their internal state. Representing all changes as operations is what allows Slate editors to easily implement history, collaboration, and other features. + +## Operation + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/concepts/05-operations). + +### `isNodeOperation` + +Checks if a value is a `NodeOperation` object. + + + + The value to check. + + + + Returns `true` if the value is a node operation. + + +### `inverse` + +Inverts an operation, returning a new operation that will exactly undo the original when applied. + + + + The operation to invert. + + + + Returns a new operation that undoes the original operation. + + +### `isOperation` + +Checks if a value is an `Operation` object. + + + + The value to check. + + + + Returns `true` if the value is an operation. + + +### `isOperationList` + +Checks if a value is a list of `Operation` objects. + + + + The value to check. + + + + Returns `true` if the value is an array of operations. + + +### `isSelectionOperation` + +Checks if a value is a `SelectionOperation` object. + + + + The value to check. + + + + Returns `true` if the value is a selection operation. + + +### `isTextOperation` + +Checks if a value is a `TextOperation` object. + + + + The value to check. + + + + Returns `true` if the value is a text operation. + + +## Types + +### Operation + +The base operation type that represents any change to the editor state. Operations can be one of three types: + +- **NodeOperation**: Operations that modify nodes (insert, merge, move, remove, set, split) +- **SelectionOperation**: Operations that modify the selection state +- **TextOperation**: Operations that modify text content (insert, remove) + +### NodeOperation + + + + - `type: 'insert_node'` + - `path: Path` - Where to insert the node + - `node: Descendant` - The node to insert + + + - `type: 'merge_node'` + - `path: Path` - The node to merge + - `position: number` - The position to merge at + - `properties: Partial` - Properties of the merged node + + + - `type: 'move_node'` + - `path: Path` - The node to move + - `newPath: Path` - Where to move the node + + + - `type: 'remove_node'` + - `path: Path` - The node to remove + - `node: Descendant` - The node being removed + + + - `type: 'set_node'` + - `path: Path` - The node to update + - `properties: Partial` - The old properties + - `newProperties: Partial` - The new properties + + + - `type: 'split_node'` + - `path: Path` - The node to split + - `position: number` - Where to split the node + - `properties: Partial` - Properties of the new node + + + +### TextOperation + + + + - `type: 'insert_text'` + - `path: Path` - The text node to modify + - `offset: number` - Where to insert the text + - `text: string` - The text to insert + + + - `type: 'remove_text'` + - `path: Path` - The text node to modify + - `offset: number` - Where to remove the text + - `text: string` - The text being removed + + + +### SelectionOperation + + + + - `type: 'set_selection'` + - `properties: Partial | null` - The old selection + - `newProperties: Partial | null` - The new selection + + diff --git a/apps/www/content/docs/en/api/slate/path.mdx b/apps/www/content/docs/en/api/slate/path.mdx new file mode 100644 index 0000000000..1176d4793b --- /dev/null +++ b/apps/www/content/docs/en/api/slate/path.mdx @@ -0,0 +1,474 @@ +--- +title: Path +description: API reference for paths in Slate. +--- + +`Path` arrays are a list of indexes that describe a node's exact position in a Slate node tree. Although they are usually relative to the root `Editor` object, they can be relative to any `Node` object. + +## Path + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/locations/path). + +### `operationCanTransformPath` + +Returns whether an operation can affect paths or not. Used as an optimization when updating dirty paths during normalization. + + + + The operation to check. + + + + Returns `true` if the operation can transform paths (insert, merge, move, remove, or split operations). + + +### `transform` + +Transforms a path by an operation. + + + + The path to transform. + + + The operation to apply. + + + + + The affinity of the transform. + + + + + + Returns the transformed path, or `null` if the path was deleted. + + +### `ancestors` + +Gets a list of ancestor paths for a given path. + + + + The path to get ancestors for. + + + + + If true, the paths are returned in reverse order (deepest to shallowest). + + + + + + Returns an array of paths sorted from shallowest to deepest ancestor (unless reversed). + + +### `child` + +Gets a path to a child at the given index. + + + + The parent path. + + + The child index. + + + + Returns the path to the child node. + + +### `common` + +Gets the common ancestor path of two paths. + + + + The first path. + + + The second path. + + + + Returns the common ancestor path. + + +### `compare` + +Compares a path to another, returning an integer indicating whether the path was before, at, or after the other. + + + + The first path to compare. + + + The second path to compare. + + + + Returns: + - `-1` if the first path is before the second + - `0` if the paths are at the same location + - `1` if the first path is after the second + +Note: Two paths of unequal length can still receive a `0` result if one is directly above or below the other. For exact matching, use `equals` instead. + + +### `endsAfter` + +Checks if a path ends after one of the indexes in another. + + + + The path to check. + + + The path to compare against. + + + + Returns `true` if the path ends after the other path. + + +### `endsAt` + +Checks if a path ends at one of the indexes in another. + + + + The path to check. + + + The path to compare against. + + + + Returns `true` if the path ends at the same index as the other path. + + +### `endsBefore` + +Checks if a path ends before one of the indexes in another. + + + + The path to check. + + + The path to compare against. + + + + Returns `true` if the path ends before the other path. + + +### `equals` + +Checks if a path is exactly equal to another. + + + + The first path. + + + The second path. + + + + Returns `true` if the paths are exactly equal. + + +### `firstChild` + +Gets a path to the first child of a path. + + + + The parent path. + + + + Returns the path to the first child node. + + +### `hasPrevious` + +Checks if the path of previous sibling node exists. + + + + The path to check. + + + + Returns `true` if a previous sibling exists. + + +### `isAfter` + +Checks if a path is after another. + + + + The path to check. + + + The path to compare against. + + + + Returns `true` if the first path is after the second. + + +### `isAncestor` + +Checks if a path is an ancestor of another. + + + + The potential ancestor path. + + + The potential descendant path. + + + + Returns `true` if the path is an ancestor of the other path. + + +### `isBefore` + +Checks if a path is before another. + + + + The path to check. + + + The path to compare against. + + + + Returns `true` if the first path is before the second. + + +### `isChild` + +Checks if a path is a child of another. + + + + The potential child path. + + + The potential parent path. + + + + Returns `true` if the path is a child of the other path. + + +### `isCommon` + +Checks if a path is equal to or an ancestor of another. + + + + The path to check. + + + The path to compare against. + + + + Returns `true` if the path is equal to or an ancestor of the other path. + + +### `isDescendant` + +Checks if a path is a descendant of another. + + + + The potential descendant path. + + + The potential ancestor path. + + + + Returns `true` if the path is a descendant of the other path. + + +### `isParent` + +Checks if a path is the parent of another. + + + + The potential parent path. + + + The potential child path. + + + + Returns `true` if the path is the parent of the other path. + + +### `isPath` + +Checks if a value implements the `Path` interface. + + + + The value to check. + + + + Returns `true` if the value is a path. + + +### `isSibling` + +Checks if a path is a sibling of another. + + + + The path to check. + + + The path to compare against. + + + + Returns `true` if the paths are siblings. + + +### `lastIndex` + +Gets the last index of a path. + + + + The path to check. + + + + Returns the last index, or -1 if the path is empty. + + +### `levels` + +Gets a list of paths at every level down to a path. + + + + The path to get levels for. + + + + + If true, the paths are returned in reverse order (deepest to shallowest). + + + + + + Returns an array of paths including the path itself and all its ancestors. + + +### `next` + +Gets the path to the next sibling node. + + + + The current path. + + + + Returns the path to the next sibling. + + +### `parent` + +Gets the path to the parent node. + + + + The current path. + + + + Returns the path to the parent node. + + +### `previous` + +Gets the path to the previous sibling node. + + + + The current path. + + + + Returns the path to the previous sibling, or `undefined` if there is none. + + +### `relative` + +Gets a path relative to an ancestor. + + + + The path to make relative. + + + The ancestor path. + + + + Returns the relative path. + + +## Types + +### Path + +An array of numbers representing the indexes to traverse to reach a specific node in the document tree. + +### PathAncestorsOptions + +Options for getting ancestor paths. + + + + If true, the paths are returned in reverse order. + + + +### PathLevelsOptions + +Options for getting path levels. + + + + If true, the paths are returned in reverse order. + + + +### PathTransformOptions + +Options for transforming paths. + + + + The affinity of the transform. + + diff --git a/apps/www/content/docs/en/api/slate/point.mdx b/apps/www/content/docs/en/api/slate/point.mdx new file mode 100644 index 0000000000..b029e741ad --- /dev/null +++ b/apps/www/content/docs/en/api/slate/point.mdx @@ -0,0 +1,171 @@ +--- +title: Point +description: API reference for points in Slate. +--- + +A `Point` represents a specific location in a Slate document. It consists of a path to a text node and an offset within that text node's content. + +## Point + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/locations/point). + +### `get` + +Gets the point from a location. If the location is a range, gets the anchor point (or focus point if specified). If the location is a path, gets the point at this path with offset 0. + + + + The location to get the point from. Can be a Range, Point, or Path. + + + + + If true and the location is a range, returns the focus point instead of the anchor point. + + + + + + Returns the point at the specified location, or `undefined` if not found. + + +### `transform` + +Transforms a point by an operation. + + + + The point to transform. + + + The operation to apply to the point. + + + + + The direction to prefer when transforming the point. + + + + + + Returns the transformed point, or `null` if the point was deleted. + + +### `compare` + +Compares a point to another, returning an integer indicating whether the point was before, at, or after the other. + + + + The first point to compare. + + + The second point to compare. + + + + Returns: + - `-1` if the first point is before the second + - `0` if the points are at the same location + - `1` if the first point is after the second + + +### `equals` + +Checks if a point is exactly equal to another. + + + + The first point to compare. + + + The second point to compare. + + + + Returns `true` if the points are equal, `false` otherwise. + + +### `isAfter` + +Checks if a point is after another. + + + + The point to check. + + + The point to compare against. + + + + Returns `true` if the first point is after the second, `false` otherwise. + + +### `isBefore` + +Checks if a point is before another. + + + + The point to check. + + + The point to compare against. + + + + Returns `true` if the first point is before the second, `false` otherwise. + + +### `isPoint` + +Checks if a value implements the `Point` interface. + + + + The value to check. + + + + Returns `true` if the value is a point, `false` otherwise. + + +## Types + +### Point + +The base point type that represents a specific location in a Slate document. + + + + The index of the character in the text node. + + + The path to the text node. + + + +### PointTransformOptions + +Options for transforming a point. + + + + The direction to prefer when transforming the point. + + + +### PointEntry + +A tuple type returned when iterating over points in a range. + + + + The point location. + + + Indicates whether this point is the anchor or focus of a range. + + diff --git a/apps/www/content/docs/en/api/slate/range.mdx b/apps/www/content/docs/en/api/slate/range.mdx new file mode 100644 index 0000000000..d6201c63f4 --- /dev/null +++ b/apps/www/content/docs/en/api/slate/range.mdx @@ -0,0 +1,256 @@ +--- +title: Range +description: API reference for ranges in Slate. +--- + +`Range` objects are a set of points that refer to a specific span of a Slate document. They can define a span inside a single node or span across multiple nodes. A range consists of two points: an anchor (start) and a focus (end). + +## Range + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/locations/range). + +### `transform` + +Transforms a range by an operation. + + + + The range to transform. + + + The operation to apply to the range. + + + + + The direction to prefer when transforming the range. + + + + + + Returns the transformed range, or `null` if the range was deleted. + + +### `edges` + +Gets the start and end points of a range, in the order in which they appear in the document. + + + + The range to get edges from. + + + + + If true, returns the points in reverse order. + + + + + + Returns a tuple of `[Point, Point]` representing the start and end points. + + +### `end` + +Gets the end point of a range. + + + + The range to get the end point from. + + + + Returns the end point of the range. + + +### `equals` + +Checks if a range is exactly equal to another. + + + + The first range to compare. + + + The second range to compare. + + + + Returns `true` if the ranges are equal, `false` otherwise. + + +### `includes` + +Checks if a range includes a path, a point or part of another range. + + + + The range to check. + + + The target to check for inclusion. + + + + Returns `true` if the range includes the target, `false` otherwise. + + +### `intersection` + +Gets the intersection of a range with another. + + + + The first range. + + + The second range. + + + + Returns the intersecting range, or `null` if there is no intersection. + + +### `isBackward` + +Checks if a range is backward, meaning that its anchor point appears in the document _after_ its focus point. + + + + The range to check. + + + + Returns `true` if the range is backward, `false` otherwise. + + +### `isCollapsed` + +Checks if a range is collapsed, meaning that both its anchor and focus points refer to the exact same position in the document. + + + + The range to check. + + + + Returns `true` if the range exists and is collapsed, `false` otherwise. + + +### `isExpanded` + +Checks if a range is expanded. This is the opposite of `isCollapsed` and is provided for legibility. + + + + The range to check. + + + + Returns `true` if the range exists and is expanded, `false` otherwise. + + +### `isForward` + +Checks if a range is forward. This is the opposite of `isBackward` and is provided for legibility. + + + + The range to check. + + + + Returns `true` if the range is forward, `false` otherwise. + + +### `isRange` + +Checks if a value implements the `TRange` interface. + + + + The value to check. + + + + Returns `true` if the value is a range, `false` otherwise. + + +### `points` + +Iterates through all of the point entries in a range. + + + + The range to iterate through. + + + + Returns a generator that yields point entries. + + +### `start` + +Gets the start point of a range. + + + + The range to get the start point from. + + + + Returns the start point of the range. + + +### `surrounds` + +Checks if a range completely includes another range. + + + + The range that might surround the target. + + + The target range that might be surrounded. + + + + Returns `true` if the range surrounds the target, `false` otherwise. + + +## Types + +### TRange + +The base range type that represents a span in a Slate document. + + + + The start point of the range. + + + The end point of the range. + + + +### RangeEdgesOptions + +Options for getting the edges of a range. + + + + If true, returns the points in reverse order. + + + +### RangeTransformOptions + +Options for transforming a range. + + + + The direction to prefer when transforming the range. + + diff --git a/apps/www/content/docs/en/api/slate/text.mdx b/apps/www/content/docs/en/api/slate/text.mdx new file mode 100644 index 0000000000..faa4c57f42 --- /dev/null +++ b/apps/www/content/docs/en/api/slate/text.mdx @@ -0,0 +1,143 @@ +--- +title: Text +description: API reference for text nodes in Slate. +--- + +`Text` objects represent the nodes that contain the actual text content of a Slate document along with any formatting properties. They are always leaf nodes in the document tree as they cannot contain any children. + +## Text + +Find the corresponding documentation in the [Slate docs](https://docs.slatejs.org/api/nodes/text). + +### `decorations` + +Gets the leaves for a text node given decorations. + + + + The text node to get leaves from. + + + Array of decorated ranges to apply. + + + + Returns an array of text nodes with the decorations applied. + + +### `equals` + +Checks if two text nodes are equal. + + + + First text node to compare. + + + Second text node to compare. + + + + + If true, the text content is not compared. This is used to check whether sibling text nodes can be merged. + + + + + + Returns `true` if the text nodes are equal, `false` otherwise. + + +### `isText` + +Checks if a value implements the `Text` interface. + + + + The value to check. + + + + Returns `true` if the value is a text node, `false` otherwise. + + +### `isTextList` + +Checks if a value is a list of `Text` objects. + + + + The value to check. + + + + Returns `true` if the value is an array of text nodes, `false` otherwise. + + +### `isTextProps` + +Checks if some props are a partial of Text. + + + + The props to check. + + + + Returns `true` if the props match a partial text node structure, `false` otherwise. + + +### `matches` + +Checks if a text matches set of properties. + +Note: this is for matching custom properties, and it does not ensure that the `text` property of two nodes are equal. + + + + The text node to check. + + + The properties to match against. + + + + Returns `true` if the text node matches the properties, `false` otherwise. + + +## Types + +### TText + +The base text node type that contains the actual text content and any formatting properties. + + + + The text content of the node. + + + Additional formatting properties. + + + +### DecoratedRange + +Represents a range with decorations applied. + +### TextEqualsOptions + +Options for comparing text nodes. + + + + If true, the text content is not compared. Used to check if sibling text nodes can be merged. + + + +### `TextOf` + +A utility type to get all the text node types from a root node type. + +### `MarksOf` + +A utility type to get all the mark types from a root node type. diff --git a/apps/www/content/docs/en/api/utils.mdx b/apps/www/content/docs/en/api/utils.mdx index 76df95c484..b9809445a1 100644 --- a/apps/www/content/docs/en/api/utils.mdx +++ b/apps/www/content/docs/en/api/utils.mdx @@ -3,6 +3,8 @@ title: Plate Utils description: API reference for @udecode/plate-utils. --- +v42 documentation is in progress. + `@udecode/plate-utils` contains utility functions for Plate. ## Components @@ -234,141 +236,3 @@ Generates the props for a button that, when clicked, removes a node from the edi - -## Queries - -### isType - -Checks whether a node matches the provided type. - - - - The editor in which the node is present. - - - The node to be checked. - - - The type or types to match the node against. Can be a string or an array of - strings. - - - - A boolean indicating whether the node's type matches the provided type or - types. - - -## Transforms - -### resetEditorChildren - -Replaces the children of an editor with default blocks. - - - - The editor whose children are to be replaced. - - - Options for replacing the children of the node. Excludes `at` and `nodes` - options. - - - -### selectEditor - -Selects an editor at a target location or an edge (start, end). - - - - The editor to be selected. - - - Specific location to select. - - If `edge` is not defined, this option is considered. - - - Select the start or end of the editor. - - Overrides `at` option if defined. - - - If true, focuses the React editor before selecting markdown Copy code. - - - **Default:** `false` - - - - - No explicit return, but selects and potentially focuses the editor. - - -### moveSelectionByOffset - -Moves the selection by offset based on the keyboard arrow keys. - - - - The editor instance. - - - Options for moving the selection by offset. This is an optional parameter. - - - A query function to enable the behavior. - - - The keyboard event that triggered the move. - - - - - -### selectSiblingNodePoint - -Selects a point from the previous or next sibling node of the specified node. - - - - The editor instance. - - - Options for selecting a sibling node's point. - - - The path of the reference node. If not provided, `node` must be specified. - - - Whether to select the previous sibling instead of the next. - - `false`: Select the start point of the next sibling node. - - `true`: Select the end point of the previous sibling node. - - **Default:** `false` - - - Whether to focus the editor after selection. - - **Default:** `true` - - - The reference node. Used to find the path if `at` is not provided. - - - - - -## Utils - -### defaultsDeepToNodes - -Recursively merges a source object into children nodes using a query. - - - - Options for the function, excluding the 'apply' option. - - - - No explicit return, but it modifies the children nodes based on the provided - options. - diff --git a/apps/www/content/docs/en/basic-elements.mdx b/apps/www/content/docs/en/basic-elements.mdx index 512f46359b..d582e8433f 100644 --- a/apps/www/content/docs/en/basic-elements.mdx +++ b/apps/www/content/docs/en/basic-elements.mdx @@ -142,7 +142,7 @@ The editor instance. - + The code line to be indented. - + The code line to be outdented. - + The code block containing the code line to be outdented. diff --git a/apps/www/content/docs/en/block-selection.mdx b/apps/www/content/docs/en/block-selection.mdx index d737855c04..e1d92245c7 100644 --- a/apps/www/content/docs/en/block-selection.mdx +++ b/apps/www/content/docs/en/block-selection.mdx @@ -254,7 +254,7 @@ Adds a selected row to the block selection. Gets the selected blocks in the editor. - + An array of selected block entries. @@ -294,12 +294,6 @@ Unselects all blocks and sets the `isSelecting` flag to false. Duplicates the selected blocks. - - - An array of node entries to duplicate. - - - ### editor.tf.blockSelection.removeNodes Removes the selected nodes from the editor. @@ -313,7 +307,7 @@ Selects the nodes returned by `getNodes()` and resets the selected IDs. Sets properties on the selected nodes. - + The properties to set on the selected nodes. @@ -326,7 +320,7 @@ Sets properties on the selected nodes. Sets text properties on the selected nodes. - + The text properties to set on the selected nodes. diff --git a/apps/www/content/docs/en/callout.mdx b/apps/www/content/docs/en/callout.mdx index 6320c23ef8..27a3ede056 100644 --- a/apps/www/content/docs/en/callout.mdx +++ b/apps/www/content/docs/en/callout.mdx @@ -76,7 +76,7 @@ Inserts a callout element into the editor. The variant of the callout to insert. - + Other options from `InsertNodesOptions`. diff --git a/apps/www/content/docs/en/caption.mdx b/apps/www/content/docs/en/caption.mdx index 382585b112..d351fdf479 100644 --- a/apps/www/content/docs/en/caption.mdx +++ b/apps/www/content/docs/en/caption.mdx @@ -85,7 +85,7 @@ const plugins = [ Extends `TElement`. - + Caption value. diff --git a/apps/www/content/docs/en/combobox.mdx b/apps/www/content/docs/en/combobox.mdx index 9d8001d03f..947081f17a 100644 --- a/apps/www/content/docs/en/combobox.mdx +++ b/apps/www/content/docs/en/combobox.mdx @@ -41,7 +41,6 @@ Create your main plugin with `withTriggerCombobox`: ```ts const MyPlugin = createPlatePlugin({ key: 'my_plugin', - extendEditor: withTriggerCombobox, // Plugin node options node: { isElement: true, @@ -60,7 +59,7 @@ const MyPlugin = createPlatePlugin({ }, // Include the input plugin plugins: [ComboboxInputPlugin], -}); +}).overrideEditor(withTriggerCombobox); ``` diff --git a/apps/www/content/docs/en/comments.mdx b/apps/www/content/docs/en/comments.mdx index 652b59fda2..572959a881 100644 --- a/apps/www/content/docs/en/comments.mdx +++ b/apps/www/content/docs/en/comments.mdx @@ -126,7 +126,7 @@ Finds the comment node in the editor. The editor instance. - + Additional options for finding the node. diff --git a/apps/www/content/docs/en/components/changelog.mdx b/apps/www/content/docs/en/components/changelog.mdx index b10dd447e9..77d32fdb6f 100644 --- a/apps/www/content/docs/en/components/changelog.mdx +++ b/apps/www/content/docs/en/components/changelog.mdx @@ -25,8 +25,24 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver ### December 25 #17.6 +v42 + +- `table-element`, `table-element-static` + - Move icons to `table-icons` + - Remove `colgroup`, col width is now set in `table-cell-element` +- `table-row-element`: remove `hideBorder` prop +- `table-cell-element`, `table-cell-element-static`: + - column hover/resizing state is now using Tailwind instead of JS + - **Major performance improvement**: all table cells were re-rendering on a single cell change. This is now fixed. + - React.memo +- `table-dropdown-menu`: + - dynamic table insert + - merge/split cells + - insert row/col before +- `tooltip`: add `TooltipButton` - `indent-list-toolbar-button`: Remove `IndentListToolbarButton` use `NumberedIndentListToolbarButton` and `BulletedIndentListToolbarButton` instead. - `table-dropdown-menu`: new insert table interface. +- `column-group-element`: fix `ColumnFloatingToolbar` onColumnChange ### December 23 #17.5 @@ -482,7 +498,7 @@ export const TableElement = withHOC( - remove `clsx` from dependency: `class-variance-utility` already exports it as `cx` - new dependency: `@udecode/cn` - remove `@/lib/utils.ts` in favor of `cn` from `@udecode/cn`. Replace all imports from `@/lib/utils` with `@udecode/cn` -- import `withProps` from `@udecode/cn` instead of `@udecode/plate-common +- import `withProps` from `@udecode/cn` instead of `@udecode/plate ` - all components using `forwardRef` are now using `withRef`. `withProps`, `withCn` and `withVariants` are also used to reduce boilerplate. diff --git a/apps/www/content/docs/en/components/installation/manual.mdx b/apps/www/content/docs/en/components/installation/manual.mdx index 70c3b4fc87..9fe16832d5 100644 --- a/apps/www/content/docs/en/components/installation/manual.mdx +++ b/apps/www/content/docs/en/components/installation/manual.mdx @@ -16,7 +16,7 @@ Components are styled using Tailwind CSS. You need to install Tailwind CSS in yo Add the following dependencies to your project: ```bash -npm install slate slate-dom slate-react slate-history slate-hyperscript @udecode/plate-common @udecode/cn class-variance-authority tailwindcss-animate tailwind-scrollbar-hide lucide-react +npm install @udecode/plate @udecode/cn class-variance-authority tailwindcss-animate tailwind-scrollbar-hide lucide-react ``` ### Configure path aliases diff --git a/apps/www/content/docs/en/csv.mdx b/apps/www/content/docs/en/csv.mdx index f9840589c4..3145590788 100644 --- a/apps/www/content/docs/en/csv.mdx +++ b/apps/www/content/docs/en/csv.mdx @@ -90,8 +90,8 @@ Refer to [PapaParse documentation](https://www.papaparse.com/docs#config) for mo - - Returns an array of `TDescendant` objects that represent the structure of + + Returns an array of `Descendant` objects that represent the structure of the CSV data in a Slate compatible format. If parsing of the CSV data fails or the data is not valid, this function returns `undefined`. diff --git a/apps/www/content/docs/en/debugging.mdx b/apps/www/content/docs/en/debugging.mdx index 353b2a1baf..f0ccb59b10 100644 --- a/apps/www/content/docs/en/debugging.mdx +++ b/apps/www/content/docs/en/debugging.mdx @@ -109,17 +109,14 @@ You can use the `extendEditor` option to override editor methods and add logging ```ts const LoggingPlugin = createPlatePlugin({ key: 'logging', - extendEditor: (editor) => { - const { apply } = editor; - - editor.apply = (operation) => { +}).overrideEditor(({ editor, tf: { apply } }) => ({ + transforms: { + apply(operation) { console.log('Operation:', operation); apply(operation); - }; - - return editor; + }, }, -}); +})); const editor = createPlateEditor({ plugins: [LoggingPlugin], diff --git a/apps/www/content/docs/en/dnd.mdx b/apps/www/content/docs/en/dnd.mdx index 6d0b7a2d62..96a6cec881 100644 --- a/apps/www/content/docs/en/dnd.mdx +++ b/apps/www/content/docs/en/dnd.mdx @@ -81,7 +81,7 @@ Returns an array of blocks that have an ID. The editor instance. - + The options for getting node entries. @@ -206,7 +206,7 @@ A custom hook that combines the `useDragNode` and `useDropNode` hooks to enable The orientation of drag and drop. Defaults to `'vertical'`. - + Callback to determine if a node can be dropped at the current location. diff --git a/apps/www/content/docs/en/editor-methods.mdx b/apps/www/content/docs/en/editor-methods.mdx index c052812a38..d73f3ffc0e 100644 --- a/apps/www/content/docs/en/editor-methods.mdx +++ b/apps/www/content/docs/en/editor-methods.mdx @@ -18,7 +18,7 @@ Use one of these hooks: - `useEditorState`: Re-render on every change. ```ts -import { useEditorRef, useEditorSelector, useEditorState } from '@udecode/plate-common/react'; +import { useEditorRef, useEditorSelector, useEditorState } from '@udecode/plate/react'; const MyComponent = () => { const editor = useEditorRef(); @@ -56,7 +56,7 @@ const MyComponent = () => { To access the editor outside the `Plate` component or work with multiple editors, use the `PlateController` component: ```ts -import { PlateController } from '@udecode/plate-common/react'; +import { PlateController } from '@udecode/plate/react'; const App = () => ( @@ -106,13 +106,21 @@ You can also use `editor.isFallback` to check if the editor is a fallback instan ## API Methods +### findPath + +Find the path of a node. Default is `findNodePath` (traversal). Overridden by `withPlate` to use `ReactEditor.findPath` (memo). + +```ts +const path = editor.findPath(node); +``` + ### getApi Retrieve the typed API for the editor: ```ts const api = editor.getApi(TablePlugin); -api.api.create.cell(); // Type-safe API method +api.api.create.tableCell(); // Type-safe API method ``` ### getTransforms diff --git a/apps/www/content/docs/en/editor.mdx b/apps/www/content/docs/en/editor.mdx index e66eccff7d..7f65f4ea32 100644 --- a/apps/www/content/docs/en/editor.mdx +++ b/apps/www/content/docs/en/editor.mdx @@ -10,7 +10,7 @@ This guide covers the configuration options for the Plate editor, including basi To create a basic Plate editor, you can use the `createPlateEditor` function, or `usePlateEditor` in a React component: ```ts -import { createPlateEditor } from '@udecode/plate-common/react'; +import { createPlateEditor } from '@udecode/plate/react'; const editor = createPlateEditor({ plugins: [ParagraphPlugin, HeadingPlugin], @@ -207,8 +207,8 @@ editor.tf.insert.tableRow() For more complex editors, you can define your types in a separate file (e.g., `plate-types.ts`): ```ts -import type { TElement, TText } from '@udecode/plate-common'; -import type { TPlateEditor } from '@udecode/plate-common/react'; +import type { TElement, TText } from '@udecode/plate'; +import type { TPlateEditor } from '@udecode/plate/react'; // Define custom element types interface ParagraphElement extends TElement { diff --git a/apps/www/content/docs/en/excalidraw.mdx b/apps/www/content/docs/en/excalidraw.mdx index 35f41e0465..25f91942fc 100644 --- a/apps/www/content/docs/en/excalidraw.mdx +++ b/apps/www/content/docs/en/excalidraw.mdx @@ -54,7 +54,7 @@ Inserts an Excalidraw element into the editor. The props for the Excalidraw element. diff --git a/apps/www/content/docs/en/forced-layout.mdx b/apps/www/content/docs/en/forced-layout.mdx index 84cb0fb0fc..34004ff360 100644 --- a/apps/www/content/docs/en/forced-layout.mdx +++ b/apps/www/content/docs/en/forced-layout.mdx @@ -23,7 +23,7 @@ npm install @udecode/plate-normalizers @udecode/plate-trailing-block ```tsx import { NormalizersPlugin } from '@udecode/plate-normalizers/react'; import { TrailingBlockPlugin } from '@udecode/plate-trailing-block/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { HEADING_KEYS } from '@udecode/plate-heading/react'; const plugins = [ diff --git a/apps/www/content/docs/en/getting-started.mdx b/apps/www/content/docs/en/getting-started.mdx index d74045bc19..6a2b5101a7 100644 --- a/apps/www/content/docs/en/getting-started.mdx +++ b/apps/www/content/docs/en/getting-started.mdx @@ -22,7 +22,7 @@ For an existing React project, jump to the next step. First, install the core dependencies: ```bash -npm install @udecode/plate-common slate slate-dom slate-react slate-history +npm install @udecode/plate slate-react slate-history ``` For the examples in this guide, we'll also use these plugins: @@ -45,7 +45,7 @@ import { usePlateEditor, Plate, PlateContent, -} from '@udecode/plate-common/react'; +} from '@udecode/plate/react'; export default function BasicEditor() { const editor = usePlateEditor(); @@ -219,7 +219,7 @@ import { PlateElement, PlateLeaf, usePlateEditor, -} from '@udecode/plate-common/react'; +} from '@udecode/plate/react'; export default function BasicEditor() { const editor = usePlateEditor({ diff --git a/apps/www/content/docs/en/horizontal-rule.mdx b/apps/www/content/docs/en/horizontal-rule.mdx index f48bdd1757..65f45fed78 100644 --- a/apps/www/content/docs/en/horizontal-rule.mdx +++ b/apps/www/content/docs/en/horizontal-rule.mdx @@ -25,9 +25,9 @@ npm install @udecode/plate-horizontal-rule ## Usage ```tsx -import { insertNodes, setNodes } from '@udecode/plate-common'; +import { insertNodes, setNodes } from '@udecode/plate'; import { AutoformatPlugin } from '@udecode/plate-autoformat/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react'; import { SelectOnBackspacePlugin } from '@udecode/plate-select/react'; diff --git a/apps/www/content/docs/en/html.mdx b/apps/www/content/docs/en/html.mdx index 88693009e6..6f65cf9267 100644 --- a/apps/www/content/docs/en/html.mdx +++ b/apps/www/content/docs/en/html.mdx @@ -18,7 +18,7 @@ title: Serializing HTML ```tsx // ... -import { createSlateEditor, serializeHtml } from '@udecode/plate-common'; +import { createSlateEditor, serializeHtml } from '@udecode/plate'; import { EditorStatic } from '@/components/plate-ui/editor-static'; // Create an editor and configure all the plugins you need @@ -90,7 +90,7 @@ For each plugin key, provide its corresponding static component in the `componen // Instead of using interactive components that rely on 'use client', // use statically defined components that simply return plain HTML. -import { createSlateEditor, serializeHtml } from '@udecode/plate-common'; +import { createSlateEditor, serializeHtml } from '@udecode/plate'; // Import static versions of your components import { ParagraphElementStatic } from '@/components/plate-ui/paragraph-element-static'; @@ -196,7 +196,7 @@ A HTML string representing the Slate content. The `editor.api.html.deserialize` function allows you to convert HTML content into Slate value: ```typescript -import { createPlateEditor } from '@udecode/plate-common/react'; +import { createPlateEditor } from '@udecode/plate/react'; const editor = createPlateEditor({ plugins: [ @@ -381,7 +381,7 @@ Flag to enable or disable the removal of whitespace from the serialized HTML. - + The deserialized Slate value. diff --git a/apps/www/content/docs/en/indent-list.mdx b/apps/www/content/docs/en/indent-list.mdx index 701af26392..6d78d1d40b 100644 --- a/apps/www/content/docs/en/indent-list.mdx +++ b/apps/www/content/docs/en/indent-list.mdx @@ -69,7 +69,7 @@ import { IndentPlugin } from '@udecode/plate-indent/react'; import { IndentListPlugin } from '@udecode/plate-indent-list/react'; import { HEADING_KEYS } from '@udecode/plate-heading'; import { HeadingPlugin } from '@udecode/plate-heading/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; const plugins = [ // ...otherPlugins, @@ -134,7 +134,7 @@ const plugins = [ - + The entry of the next sibling with an indent list, or `undefined` if not found. @@ -159,7 +159,7 @@ Gets the previous sibling entry with an indent list. - + The entry of the previous sibling with an indent list, or `undefined` if not found. diff --git a/apps/www/content/docs/en/indent.mdx b/apps/www/content/docs/en/indent.mdx index da0419383a..ad98349155 100644 --- a/apps/www/content/docs/en/indent.mdx +++ b/apps/www/content/docs/en/indent.mdx @@ -40,7 +40,7 @@ npm install @udecode/plate-indent import { IndentPlugin } from '@udecode/plate-indent/react'; import { HEADING_KEYS } from '@udecode/plate-heading'; import { HeadingPlugin } from '@udecode/plate-heading/react'; -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; const plugins = [ // ...otherPlugins, @@ -118,7 +118,7 @@ The indentation offset used in `(offset * element.indent) + unit`. Options to get the nodes to indent. @@ -159,7 +159,7 @@ Used to provide options for setting the indentation of a block of text. Additional `getNodes` options. diff --git a/apps/www/content/docs/en/list.mdx b/apps/www/content/docs/en/list.mdx index 07ed62d8f3..01c186e211 100644 --- a/apps/www/content/docs/en/list.mdx +++ b/apps/www/content/docs/en/list.mdx @@ -202,7 +202,7 @@ the current selection. - + The nearest `li` and `ul`/`ol` wrapping node entries. @@ -225,7 +225,7 @@ Searches upward for the root list element. - + The root list element entry. @@ -252,7 +252,7 @@ Checks if a node has a list child. The editor instance. - + The node to check. @@ -400,10 +400,10 @@ Moves a list item down to the next list item. - + The entry of the list node. - + The entry of the list item node to move. @@ -430,10 +430,10 @@ The editor instance. optional > - + The entry of the list item containing the sublist items to move. - + The entry of the list item where the sublist items will be moved. @@ -461,10 +461,10 @@ Moves a list item up. - + The entry of the list containing the list item to move. - + The entry of the list item to move. @@ -541,7 +541,7 @@ The editor instance. The list whose list items will be moved. @@ -549,7 +549,7 @@ The list whose list items will be moved. The list item whose sublist items will be moved. @@ -569,7 +569,7 @@ it overrides the `toList` and `toListIndex` options. The list where the list items will be moved to. @@ -648,10 +648,10 @@ Removes the first list item if the list is not nested and the list item is not t - + The list entry containing the list item. - + The list item entry to be removed. @@ -674,10 +674,10 @@ The editor instance. - + The list entry containing the list item. - + The list item entry to be removed. diff --git a/apps/www/content/docs/en/markdown.mdx b/apps/www/content/docs/en/markdown.mdx index 86eb96de4c..1351cc7320 100644 --- a/apps/www/content/docs/en/markdown.mdx +++ b/apps/www/content/docs/en/markdown.mdx @@ -117,7 +117,7 @@ The Markdown string to be deserialized. - + An array of Slate nodes representing the deserialized Markdown content. @@ -129,7 +129,7 @@ Converts the current Slate value to a Markdown string. - + The Slate nodes to serialize. If not provided, the entire editor value will be used. diff --git a/apps/www/content/docs/en/migration/slate-to-plate.mdx b/apps/www/content/docs/en/migration/slate-to-plate.mdx index d7d26dafa7..8d00cba934 100644 --- a/apps/www/content/docs/en/migration/slate-to-plate.mdx +++ b/apps/www/content/docs/en/migration/slate-to-plate.mdx @@ -123,15 +123,23 @@ const withMyPlugin = (editor) => { // After const MyPlugin = createPlatePlugin({ key: 'myPlugin', - extendEditor: ({ editor }) => { - const { insertText } = editor; - editor.insertText = (text) => { +}).overrideEditor(({ editor, tf: { insertText } }) => ({ + transforms: { + insertText(text) { // Custom logic insertText(text); - }; - return editor; - }, -}); + }, + } +})); + +// For adding new methods: +const MyOtherPlugin = createPlatePlugin({ + key: 'myOtherPlugin', +}).extendEditorTransforms(({ editor }) => ({ + newMethod(text) { + // Add new functionality + } +})); ``` For more information on working with the plugin context, see the [Plugin Context guide](/docs/plugin-context). diff --git a/apps/www/content/docs/en/node-id.mdx b/apps/www/content/docs/en/node-id.mdx index 04738d3dfd..2410f14f2b 100644 --- a/apps/www/content/docs/en/node-id.mdx +++ b/apps/www/content/docs/en/node-id.mdx @@ -97,7 +97,7 @@ Plugin that automatically assigns and manages unique IDs for nodes in the editor List of node types that should not receive IDs. - + Custom filter function for nodes that should receive IDs. - **Default:** `() => true` @@ -114,7 +114,7 @@ The plugin handles several scenarios: // Insert node with existing ID (e.g. copy/paste) -editor.insertNode(inserted); +editor.tf.insertNode(inserted); // Results in: test @@ -122,7 +122,7 @@ editor.insertNode(inserted); // Insert multiple nodes -editor.insertNodes([ +editor.tf.insertNodes([ inserted, test, ]); @@ -158,13 +158,13 @@ editor.insertNodes([ 4. **Undo/Redo**: ```tsx // With reuseId=true -editor.insertNode(text); +editor.tf.insertNode(text); editor.undo(); editor.redo(); // Node keeps id="1" if not in use // With reuseId=false -editor.insertNode(text); +editor.tf.insertNode(text); editor.undo(); editor.redo(); // Node gets new id="2" diff --git a/apps/www/content/docs/en/playwright.mdx b/apps/www/content/docs/en/playwright.mdx index 756043b52a..8ae2fe4dea 100644 --- a/apps/www/content/docs/en/playwright.mdx +++ b/apps/www/content/docs/en/playwright.mdx @@ -152,7 +152,7 @@ See [Playwright's docs](https://playwright.dev/docs/evaluating) for more informa ```ts await editorHandle.evaluate((editor) => { - editor.insertNodes(/* ... */); + editor.tf.insertNodes(/* ... */); }); ``` diff --git a/apps/www/content/docs/en/plugin-components.mdx b/apps/www/content/docs/en/plugin-components.mdx index 587002fd98..87a792c2b0 100644 --- a/apps/www/content/docs/en/plugin-components.mdx +++ b/apps/www/content/docs/en/plugin-components.mdx @@ -20,7 +20,7 @@ Note that the `children` prop must be rendered unconditionally in order for the ### Element ```tsx -import { PlateElement, PlateElementProps } from '@udecode/plate-common/react'; +import { PlateElement, PlateElementProps } from '@udecode/plate/react'; export function BlockquoteElement({ className, @@ -38,7 +38,7 @@ export function BlockquoteElement({ ### Leaf ```tsx -import { PlateLeaf, PlateLeafProps } from '@udecode/plate-common/react'; +import { PlateLeaf, PlateLeafProps } from '@udecode/plate/react'; export function CodeLeaf({ className, children, ...props }: PlateLeafProps) { return ( diff --git a/apps/www/content/docs/en/plugin-methods.mdx b/apps/www/content/docs/en/plugin-methods.mdx index 25f1e16023..073442fbbe 100644 --- a/apps/www/content/docs/en/plugin-methods.mdx +++ b/apps/www/content/docs/en/plugin-methods.mdx @@ -246,6 +246,34 @@ const MyPlugin = createPlatePlugin({ editor.tf.editorTransform(); ``` +### .overrideEditor + +The `overrideEditor` method is used specifically for overriding existing editor methods without altering the plugin's type: + +```ts +const MyPlugin = createPlatePlugin({ + key: 'myPlugin', +}).overrideEditor(({ editor, tf: { insertText }, api: { isInline } }) => ({ + transforms: { + insertText(text) { + // Override insertText behavior + insertText(text); + }, + }, + api: { + isInline(element) { + // Override isInline behavior + return isInline(element); + }, + }, +})); +``` + +- Used specifically for overriding existing editor methods +- Returns the overridden methods wrapped in `transforms` or `api` objects +- Cannot add new methods (use `extendEditorTransforms` or `extendEditorApi` instead) +- Provides access to original methods through the context + ### Difference between API and Transforms While there is currently no core difference between API and Transforms in Plate, they serve distinct purposes and are designed with future extensibility in mind: @@ -299,10 +327,6 @@ To convert a typed Slate plugin to a Plate plugin, you can use `toPlatePlugin`: ```ts const CodeBlockPlugin = toPlatePlugin(createSlatePlugin({ key: 'code_block' }), { - extendEditor: ({ api, editor }) => { - api.plugin.getSyntaxState(); - return editor; - }, handlers: {}, options: { hotkey: ['mod+opt+8', 'mod+shift+8'] }, }); diff --git a/apps/www/content/docs/en/plugin-shortcuts.mdx b/apps/www/content/docs/en/plugin-shortcuts.mdx index 02ecda15c0..6a8daca660 100644 --- a/apps/www/content/docs/en/plugin-shortcuts.mdx +++ b/apps/www/content/docs/en/plugin-shortcuts.mdx @@ -111,13 +111,13 @@ const FormattingPlugin = createPlatePlugin({ shortcuts: { toggleBold: { handler: ({ editor }) => { - editor.toggleMark('bold'); + editor.tf.toggleMark('bold'); }, keys: 'mod+b', }, toggleItalic: { handler: ({ editor }) => { - editor.toggleMark('italic'); + editor.tf.toggleMark('italic'); }, keys: 'mod+i', }, diff --git a/apps/www/content/docs/en/plugin.mdx b/apps/www/content/docs/en/plugin.mdx index 3fdf98b555..515a6bdc51 100644 --- a/apps/www/content/docs/en/plugin.mdx +++ b/apps/www/content/docs/en/plugin.mdx @@ -164,31 +164,93 @@ A paragraph node affected by the above plugin would look like this: } ``` -### Extend Editor (Advanced) +### Override Editor Methods + +The `overrideEditor` method provides a way to override existing editor methods while maintaining access to the original implementations. This is particularly useful when you want to modify the behavior of core editor functionality. + +```ts +const CustomPlugin = createPlatePlugin({ + key: 'custom', +}).overrideEditor(({ editor, tf: { deleteForward }, api: { isInline } }) => ({ + // Override transforms + transforms: { + deleteForward(options) { + // Custom logic before deletion + console.log('Deleting forward...'); + + // Call original transform + deleteForward(options); + + // Custom logic after deletion + console.log('Deleted forward'); + }, + }, + // Override API methods + api: { + isInline(element) { + // Custom inline element check + if (element.type === 'custom-inline') { + return true; + } + + // Fall back to original behavior + return isInline(element); + }, + }, +})); +``` + +- Access to original methods via destructured `tf` (transforms) and `api` parameters +- Type-safe overrides of existing methods +- Clean separation between transforms and API methods +- Plugin context and options access + +Example with typed options: + +```ts +type CustomConfig = PluginConfig< + 'custom', + { allowDelete: boolean } +>; + +const CustomPlugin = createTPlatePlugin({ + key: 'custom', + options: { allowDelete: true }, +}).overrideEditor(({ editor, tf: { deleteForward }, getOptions }) => ({ + transforms: { + deleteForward(options) { + // Use typed options to control behavior + if (!getOptions().allowDelete) { + return; + } + + deleteForward(options); + }, + }, +})); +``` -Occasionally, you'll need to override the built-in editor methods provided by Slate to work around bugs or add complex functionality. To do this, you can use the `extendEditor` plugin option to directly mutate properties of the `editor` object after its creation. +### Extend Editor (Advanced) -One common application of this technique is to create custom [normalizers](https://docs.slatejs.org/concepts/11-normalizing). +You can extend the editor for complex functionality. To do this, you can use the `extendEditor` plugin option to directly mutate properties of the `editor` object after its creation. ```ts showLineNumbers {20} const CustomNormalizerPlugin = createPlatePlugin({ key: 'customNormalizer', extendEditor: ({ editor }) => { - const { normalizeNode } = editor; - - editor.normalizeNode = ([node, path]) => { - // Custom normalization logic here - // ... - - // Call other normalizers - normalizeNode([node, path]); - }; - + editor.customState = true; + return editor; }, }); ``` + +The difference between `extendEditor` and `overrideEditor`: +- Use `extendEditor` when integrating legacy Slate plugins like `withYjs` that need direct editor mutation. There is only one `extendEditor` per plugin. +- Prefer using `overrideEditor` for modifying editor behavior as it has single purpose responsibility and better type safety. It can be called multiple times to layer different overrides. + + ## Advanced Plugin Configuration ### Plugin Store @@ -353,7 +415,7 @@ const CodeBlockPlugin = createTPlatePlugin({ })).extendEditorTransforms(() => ({ insert: { codeBlock: ({ editor, getOptions }) => { - editor.insertBlock({ type: 'code_block', language: getOptions().language }); + editor.tf.insertBlock({ type: 'code_block', language: getOptions().language }); }, }, })); @@ -386,4 +448,4 @@ editor.tf.insert.codeBlock({ language: 'typescript' }); ## See also -See the [PlatePlugin API](/docs/api/core/plate-plugin) for more plugin options. \ No newline at end of file +See the [PlatePlugin API](/docs/api/core/plate-plugin) for more plugin options. diff --git a/apps/www/content/docs/en/reset-node.mdx b/apps/www/content/docs/en/reset-node.mdx index b109f7ce86..d02c54daea 100644 --- a/apps/www/content/docs/en/reset-node.mdx +++ b/apps/www/content/docs/en/reset-node.mdx @@ -26,7 +26,7 @@ npm install @udecode/plate-reset-node import { isBlockAboveEmpty, isSelectionAtBlockStart, -} from '@udecode/plate-common'; +} from '@udecode/plate'; import { ResetNodePlugin } from '@udecode/plate-reset-node/react'; const resetBlockTypesCommonRule = { diff --git a/apps/www/content/docs/en/tabbable.mdx b/apps/www/content/docs/en/tabbable.mdx index 01a740cfaf..2e22ee3d6d 100644 --- a/apps/www/content/docs/en/tabbable.mdx +++ b/apps/www/content/docs/en/tabbable.mdx @@ -137,7 +137,7 @@ Defines the properties of a tabbable entry. The corresponding Slate node of the tabbable entry. - + The path to the Slate node in the Slate document. \ No newline at end of file diff --git a/apps/www/content/docs/en/table.mdx b/apps/www/content/docs/en/table.mdx index 6892d0b83d..5dd0bb6523 100644 --- a/apps/www/content/docs/en/table.mdx +++ b/apps/www/content/docs/en/table.mdx @@ -47,7 +47,7 @@ const plugins = [ ]; ``` -### Without merging +### Disable merging @@ -57,6 +57,9 @@ const plugins = [ + +Disables the merging behavior of cells. + Disables the expansion of the table when inserting cells. @@ -91,27 +94,26 @@ Plugin for table header cells. ## API -### editor.api.create.cell - -Creates an empty cell node for a table. +### editor.api.create.table - -Options for creating the cell. + +The editor instance. + + +Extends `GetEmptyRowNodeOptions`. -Specify `true` if the cell is a header cell. +Specify `true` if the table has a header row. - -The row element. If `header` is not specified, it will determine if the cell is a header cell based on the row's children. + +The number of rows in the table. + +- **Default:** `0` + - -The children of the new cell node. + +The number of columns in the table. @@ -121,187 +123,16 @@ The children of the new cell node. -The cell node. - - - - -### editor.api.table.getCellChildren - -Gets the children of a table cell. - - - -The table cell element. - - - - - - -The children of the table cell. - - - - -### editor.tf.insert.tableColumn - -Inserts a column into the table at the current selection or a specified cell path. - - - - - - If true, the inserted column will be treated as a header column. - - - The path of the cell to insert the column from. - - - The exact path of the cell to insert the column at. This overrules the - `fromCell` option. - - - If true, selection will be disabled after insertion. - - - - - -### editor.tf.insert.tableRow - -Inserts a row into the table at the current selection or a specified row path. - - - - - - If true, the inserted row will be treated as a header row. - - - The path of the row to insert the new row from. - - - The exact path of the row to insert the new row at. This overrules the - `fromRow` option. - - - If true, selection will be disabled after insertion. - - - - - -### deleteColumn - -Deletes the column containing the selected cell in a table. - - - - The editor instance. - - - -### deleteRow - -Deletes the row containing the selected cell in a table. - - - - The editor instance. - - - -### deleteTable - -Deletes the entire table. - - - - The editor instance. - - - -### getCellInNextTableRow - -Gets the cell in the next row. - - - - The editor instance. - - - The path of the current row. - - - - - - - The node entry of the cell in the next row, or `undefined` if the current row - is the last row. - - - - -### getCellInPreviousTableRow - -Gets the node entry of the cell in the previous row, given the current row's path. - - - - The editor instance. - - - The path of the current row. - - - - - - - The node entry of the cell in the previous row, or `undefined` if the current - row is the first row. - - - - -### getCellType - -Get the plugin cell types. - - - - The editor instance. - - - - +The table node. - - An array of element types for table cells (td and th) in the editor. - -### getEmptyCellNode +### editor.api.create.tableCell -Returns an empty cell node for a table. +Creates an empty cell node for a table. - -The editor instance. - Options for creating the cell. @@ -314,7 +145,7 @@ The row element. If `header` is not specified, it will determine if the cell is The children of the new cell node. @@ -335,7 +166,7 @@ The cell node. -### getEmptyRowNode +### editor.api.create.tableRow Creates an empty row node with the specified number of columns. @@ -368,62 +199,157 @@ The row node. -### getEmptyTableNode +### editor.api.table.getCellBorders + +Gets the border styles for a table cell, handling special cases for first row and first column cells. - -The editor instance. - - -Extends `GetEmptyRowNodeOptions`. - - -Specify `true` if the table has a header row. - - -The number of rows in the table. + + The editor instance. + + + + + The table cell element to get the border styles for. + + + The default border style to use when cell borders are not defined. + + + The border color. + - **Default:** `'rgb(209 213 219)'` + + + The border size. + - **Default:** `1` + + + The border style. + - **Default:** `'solid'` + + + + + + -- **Default:** `0` + + + An object containing: + + + The bottom border style. + + + The right border style. + + + The left border style. Only present for cells in the first column. + + + The top border style. Only present for cells in the first row. + + + + - - -The number of columns in the table. - - +### editor.api.table.getCellChildren + +Gets the children of a table cell. + + +The table cell element. - + -The table node. +The children of the table cell. -### getLeftTableCell +### editor.api.table.getCellSize -Gets the cell to the left of the current cell in a table. +Gets the width and minimum height of a table cell, taking into account column spans and column sizes. The editor instance. - + - - The path of the current cell. + + The table cell element to get the size for. + + + Optional array of column sizes. If not provided, will use the table's overridden column sizes. - - The node entry of the cell to the left of the current cell, or `undefined` - if the current cell is the first cell in the row. + + The total width of the cell, calculated by summing the widths of all columns it spans. + + + The minimum height of the cell, derived from the row's size property. + + + +### editor.api.table.getColSpan + +Gets the column span of a table cell. + + + + The table cell element to get the column span for. + + + + + + The number of columns this cell spans. + - **Default:** `1` + + + +### editor.api.table.getRowSpan + +Gets the row span of a table cell. + + + + The table cell element to get the row span for. + + + + + + The number of rows this cell spans. + - **Default:** `1` + + + +### getCellType + +Get the plugin cell types. + + + + The editor instance. + + + + + + An array of element types for table cells (td and th) in the editor. + + ### getNextTableCell @@ -431,22 +357,22 @@ Gets the cell to the left of the current cell in a table. Gets the next cell in the table. - + The editor instance. - + The entry of the current cell. The path of the current cell. - + The entry of the current row. - + The node entry of the cell in the next row, or `undefined` if the current row is the last row. @@ -457,45 +383,27 @@ Gets the next cell in the table. Gets the previous cell in the table. - + The editor instance. - + The entry of the current cell. The path of the current cell. - + The entry of the current row. - + The node entry of the cell in the previous row, or `undefined` if the current row is the first row. -### getTableAbove - -Gets the table node above the current selection. - - - - The editor instance. - - - - - - - The table node entry above the current selection, or `undefined` if there is - none. - - - ### getTableColumnCount Gets the number of columns in a table. @@ -519,7 +427,7 @@ The number of columns in the table. Gets the column index of a cell node within a table. - + The editor instance. @@ -562,13 +470,13 @@ The location where the table cell is located. - + The table node entry. - + The row node entry. - + The cell node entry. @@ -595,7 +503,7 @@ The format of the sub table to retrieve. - The sub table entries. + The sub table entries. ### getTableGridByRange @@ -628,28 +536,7 @@ The format of the output. - The sub table entries. - - -### getTableOverriddenColSizes - -Gets the column sizes of a table node, with overrides applied if provided. - - - - The table node from which to retrieve the column sizes. - - - Optional overrides for the column sizes. It should be a map-like object - where the keys are column indices and the values are the overridden sizes. - - - - - - An array of column sizes, with overrides applied if provided. If no column - sizes are defined in the table node, it returns a 0-filled array. - + The sub table entries. ### getTableRowIndex @@ -657,7 +544,7 @@ Gets the column sizes of a table node, with overrides applied if provided. Gets the row index of a cell node within a table. - + The editor instance. @@ -688,21 +575,41 @@ Gets the cell above the current cell in the table. - + + +The cell node entry. + + + + +### isTableBorderHidden + +Checks if the border of a table cell or the table itself is hidden based on the specified border direction. + + + + The editor instance. + + + The border direction to check. + + + + + -The cell node entry. +`true` if the border is hidden, `false` otherwise. -### insertTable +## API Transforms + +### editor.tf.insert.table Inserts a table at the current selection if there is no existing table in the editor. Selects the start of the inserted table. - -The editor instance. - Extends `GetEmptyRowNodeOptions`. @@ -730,90 +637,91 @@ The options for inserting the table nodes. -### insertTableColumn +### editor.tf.insert.tableColumn Inserts a column into the table at the current selection or a specified cell path. - - The editor instance. - - - If true, the inserted column will be treated as a header column. + + The exact path of the cell to insert the column at. This overrules the + `fromCell` option. + + + If true, insert the column before the current column instead of after. The path of the cell to insert the column from. - - The exact path of the cell to insert the column at. This overrules the - `fromCell` option. + + If true, the inserted column will be treated as a header column. - - If true, selection will be disabled after insertion. + + If true, the inserted column will be selected after insertion. -### insertTableRow +### editor.tf.insert.tableRow Inserts a row into the table at the current selection or a specified row path. - - The editor instance. - - - If true, the inserted row will be treated as a header row. + + Exact path of the row to insert the column at. Pass the table path to + insert at the end of the table. Will overrule `fromRow`. + + + If true, insert the row before the current row instead of after. The path of the row to insert the new row from. - - The exact path of the row to insert the new row at. This overrules the - `fromRow` option. + + If true, the inserted row will be treated as a header row. - - If true, selection will be disabled after insertion. + + If true, the inserted row will be selected after insertion. -### isTableBorderHidden +### editor.tf.remove.tableColumn -Checks if the border of a table cell or the table itself is hidden based on the specified border direction. +Deletes the column containing the selected cell in a table. - - - The editor instance. - - - The border direction to check. - - +### editor.tf.remove.tableRow - - +Deletes the row containing the selected cell in a table. -`true` if the border is hidden, `false` otherwise. +### editor.tf.remove.table - - +Deletes the entire table. + +### editor.tf.table.merge + +Merges multiple selected cells into one. + +The merged cell will: +- Have a colSpan equal to the number of columns spanned by the selected cells +- Have a rowSpan equal to the number of rows spanned by the selected cells +- Contain the combined content of all merged cells (non-empty cells only) +- Inherit the header status from the first selected cell + +### editor.tf.table.split + +Splits a merged cell back into individual cells. + +The split operation will: +- Create new cells for each column and row that was spanned +- Copy the header status from the original merged cell +- Place the original cell's content in the first cell +- Create empty cells for the remaining spaces ### moveSelectionFromCell @@ -852,19 +760,6 @@ Moves the selection by cell unit within a table. -### overrideSelectionFromCell - -Overrides the new selection if the previous selection and the new one are in different cells. - - - - The editor instance. - - - The new selection to be checked and overridden. - - - ### setBorderSize Sets the size of the specified border in a table cell. @@ -897,7 +792,7 @@ The border direction to set the size. Sets the width of a specific column in a table. - + The editor instance. @@ -910,7 +805,7 @@ Sets the width of a specific column in a table. - + Additional options for finding the table node. @@ -920,7 +815,7 @@ Sets the width of a specific column in a table. Sets the margin left of a table. - + The editor instance. @@ -930,7 +825,7 @@ Sets the margin left of a table. - + Additional options for finding the table node. @@ -940,7 +835,7 @@ Sets the margin left of a table. Sets the size (height) of a table row. - + The editor instance. @@ -953,7 +848,7 @@ Sets the size (height) of a table row. - + Additional options for finding the table node. @@ -1094,176 +989,54 @@ Enhance the editor instance with table-related functionality by applying the fol -## API Components - -### useTableCellElementResizableState - -A state for the table resize handles. - - - - The index of the column of the cell. - - - The index of the row of the cell. - - - The step size for resizing the table cell element. - - - The step size for resizing the table cell element horizontally. - - - **Default:** `step` - - - - The step size for resizing the table cell element vertically. - - - **Default:** `step` - - - - - - - Whether to disable the margin left. - - - The index of the column of the cell. - - - The index of the row of the cell. - - - The step size for resizing the table cell element horizontally. - - - The step size for resizing the table cell element vertically. - - +## API Hooks ### useTableCellElementResizable -A behavior hook for the table resize handles. - - - -The state returned by [useTableCellElementResizableState](#usetablecellelementresizablestate). - - - - - -The props for the right resize handle. - - -The props for the bottom resize handle. - - -The props for the left resize handle. - - -Whether the left resize handle is hidden. - - - -### getOnSelectTableBorderFactory - -Gets the `onSelectTableBorder` handler for a table cell element. +A hook that provides resizing functionality for table cell elements. - - The editor instance. - - - The selected cells. + + + + The index of the column. + + + The number of columns this cell spans. + + + The index of the row. + + + Resize by step instead of by pixel. + + + Step size for horizontal resizing. + - **Default:** `step` + + + Step size for vertical resizing. + - **Default:** `step` + + -### getTableCellBorders - -Gets the border styles for a table cell. - - - -The table cell element. - - - - -Whether the cell is the first cell in the row. - - -Whether the cell is in the first row. - - -The default border style. - - - -The border size. - -- **Default:** `size : 1` - - - -The border style. - -- **Default:** `style : 'solid'` - - - -The border color. - -- **Default:** `color : 'rgb(209 213 219)'` - - - - - - - - - - - The border style for the bottom side of the cell. + + Props for the bottom resize handle, including resize direction and handler. - - The border style for the right side of the cell. + + Whether the left resize handle should be hidden. True if not the first column or margin left is disabled. - - The border style for the left side of the cell. Only present if `isFirstCell` is `true`. - - - Only present if `isFirstCell` is `true`. - + + Props for the left resize handle, including resize direction and handler. - - The border style for the top side of the cell. Only present if `isFirstRow` is `true`. - - - Only present if `isFirstRow` is `true`. - + + Props for the right resize handle, including resize direction, initial size, and handler. -### roundCellSizeToStep - -Rounds a cell size to the nearest step, or returns the size if the step is not set. - - - - The cell size to be rounded. - - - The step value used for rounding. If not provided, the size is returned as - is. - - - ### useTableStore The table store stores the state of the table plugin. @@ -1278,12 +1051,12 @@ The table store stores the state of the table plugin. The margin left override. - - The hovered column index. - The selected cells. + + The selected tables. + ### useIsCellSelected @@ -1345,9 +1118,6 @@ specific border type. Custom hook that returns the column sizes of a table with overrides applied. If the `colCount` of the table updates to 1 and the `enableUnsetSingleColSize` option is enabled, it unsets the `colSizes` node. - -The table node. - Additional options. @@ -1370,143 +1140,105 @@ If `true`, disables applying overrides to the column sizes. ### useTableElement -A behavior hook for a table element. +A hook for a table element that handles cell selection and margin left calculations. + + Whether cells are currently being selected. + + + The margin left of the table, considering overrides and plugin options. + - The props of the table element. + Props for the table element: - A function that is called when the table is clicked. - - - - - The props of the table element. - - - A function that is called when the table is clicked. - - - A function that is called when the table is clicked. + Handler that collapses selection when clicking on the table while cells are selected. -### useTableElementState - -A state hook for a table element. +### useTableCellElement - - - - - A function that transforms the column sizes. - - - - +A hook for a table cell element that provides state and functionality for table cells. - - The column sizes of the table. + + The border styles of the table cell. + + + The ending column index (considering colSpan). + + + The number of columns this cell spans. - Indicates whether the user is currently selecting cells. + Whether cells are currently being selected. - - The minimum column width. + + The minimum height of the cell. - - The margin left of the table. + + The ending row index (considering rowSpan). + + + Whether this cell is currently selected. + + + The width of the cell. -### useTableCellElement +### useTableCellBorders -A behavior hook for a table cell element. +A hook that returns the border styles for a table cell. - - - - A function that transforms the column sizes. - - - + None - - The props of the table cell element. + + An object containing the border styles for the cell: - - The column span of the table cell. + + The bottom border style. + + + The right border style. + + + The left border style. Only present for cells in the first column. + + + The top border style. Only present for cells in the first row. -### useTableCellElementState +### useTableCellSize -A state hook for a table cell element. +A hook that returns the size (width and minimum height) of a table cell. - - - - Ignores editable readOnly mode. - - - + None - - The column index of the table cell. - - - The row index of the table cell. - - - Indicates whether the table cell is read only. - - - Indicates whether the table cell is selected. - - - Indicates whether the table cell is hovered. - - - Indicates whether the table cell is hovered left. - - - The row size of the table cell. - - - The border styles of the table cell. - - - Indicates whether the user is currently selecting cells. + + An object containing: + + + The total width of the cell, calculated by summing the widths of all columns it spans. + + + The minimum height of the cell, derived from the row's size property. + + + + + diff --git a/apps/www/content/docs/en/toggle.mdx b/apps/www/content/docs/en/toggle.mdx index 101f6be7ee..f28913310e 100644 --- a/apps/www/content/docs/en/toggle.mdx +++ b/apps/www/content/docs/en/toggle.mdx @@ -34,7 +34,7 @@ npm install @udecode/plate-indent @udecode/plate-node-id @udecode/plate-toggle ```tsx // ... -import { ParagraphPlugin } from '@udecode/plate-common/react'; +import { ParagraphPlugin } from '@udecode/plate/react'; import { NodeIdPlugin } from '@udecode/plate-node-id'; import { IndentPlugin } from '@udecode/plate-indent/react'; import { TogglePlugin } from '@udecode/plate-toggle/react'; @@ -91,7 +91,7 @@ Marks the block at the current selection as an open toggle. Use this function right before inserting a block so that the toggle is expanded upon insertion. - + The editor instance. diff --git a/apps/www/content/docs/en/unit-testing.mdx b/apps/www/content/docs/en/unit-testing.mdx index 12e7602244..02183dda30 100644 --- a/apps/www/content/docs/en/unit-testing.mdx +++ b/apps/www/content/docs/en/unit-testing.mdx @@ -8,7 +8,7 @@ This guide outlines best practices for unit testing Plate plugins and components ## Installation ```bash -npm install @udecode/plate-test-utils slate-hyperscript +npm install @udecode/plate-test-utils ``` ## Setting Up Tests @@ -76,7 +76,8 @@ it('should use custom hotkey for bold', async () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, plugins: [ BoldPlugin.configure({ handlers: { @@ -119,10 +120,11 @@ it('should collapse selection on backspace', async () => { ) as any as PlateEditor; const [editor] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, }); - editor.deleteBackward('character'); + editor.tf.deleteBackward(); expect(editor.children).toEqual(output.children); expect(editor.selection).toEqual(output.selection); @@ -152,7 +154,8 @@ it('should extend selection on shift+ArrowRight', async () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, }); await triggerKeyboardEvent('shift+ArrowRight'); @@ -201,7 +204,8 @@ describe('Table plugin', () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, plugins: [TablePlugin], }); @@ -238,7 +242,8 @@ it('should use custom hotkey for bold', async () => { ) as any as PlateEditor; const [editor, { triggerKeyboardEvent }] = await createPlateTestEditor({ - editor: input, + value: input.children, + selection: input.selection, plugins: [ BoldPlugin.configure({ shortcuts: { diff --git a/apps/www/package.json b/apps/www/package.json index 85462e2c85..5e3f60511a 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -87,7 +87,6 @@ "@udecode/plate-code-block": "workspace:^", "@udecode/plate-combobox": "workspace:^", "@udecode/plate-comments": "workspace:^", - "@udecode/plate-common": "workspace:^", "@udecode/plate-core": "workspace:^", "@udecode/plate-csv": "workspace:^", "@udecode/plate-date": "workspace:^", @@ -132,8 +131,6 @@ "@udecode/react-hotkeys": "workspace:^", "@udecode/react-utils": "workspace:^", "@udecode/slate": "workspace:^", - "@udecode/slate-react": "workspace:^", - "@udecode/slate-utils": "workspace:^", "@udecode/utils": "workspace:^", "@uploadthing/react": "7.1.0", "@vercel/og": "^0.6.2", @@ -152,7 +149,7 @@ "next": "15.0.3", "next-contentlayer2": "^0.4.6", "next-themes": "^0.4.3", - "nuqs": "^2.0.3", + "nuqs": "^2.3.0", "pdf-lib": "^1.17.1", "prismjs": "^1.29.0", "react": "^18.3.1", @@ -171,11 +168,6 @@ "react-wrap-balancer": "^1.1.1", "remark-emoji": "5.0.1", "sass": "^1.78.0", - "slate": "0.112.0", - "slate-dom": "0.111.0", - "slate-history": "0.110.3", - "slate-hyperscript": "0.100.0", - "slate-react": "0.111.0", "slate-test-utils": "1.3.2", "sonner": "^1.5.0", "swr": "2.2.6-beta.3", diff --git a/apps/www/public/r/index.json b/apps/www/public/r/index.json index 253d10f507..a69602dd6d 100644 --- a/apps/www/public/r/index.json +++ b/apps/www/public/r/index.json @@ -1194,6 +1194,10 @@ "path": "plate-ui/table-element.tsx", "type": "registry:ui" }, + { + "path": "plate-ui/table-icons.tsx", + "type": "registry:ui" + }, { "path": "plate-ui/table-element-static.tsx", "type": "registry:ui" @@ -3174,6 +3178,10 @@ { "path": "plate-ui/table-dropdown-menu.tsx", "type": "registry:ui" + }, + { + "path": "plate-ui/table-icons.tsx", + "type": "registry:ui" } ], "name": "table-dropdown-menu", diff --git a/apps/www/public/r/styles/default/ai-demo.json b/apps/www/public/r/styles/default/ai-demo.json index 4e9cd3faba..ed61067ec9 100644 --- a/apps/www/public/r/styles/default/ai-demo.json +++ b/apps/www/public/r/styles/default/ai-demo.json @@ -11,13 +11,13 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate } from '@udecode/plate-common/react';\n\nimport { editorPlugins } from '@/components/editor/plugins/editor-plugins';\nimport { useCreateEditor } from '@/components/editor/use-create-editor';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nimport { DEMO_VALUES } from './values/demo-values';\n\nexport default function Demo({ id }: { id: string }) {\n const editor = useCreateEditor({\n plugins: [...editorPlugins],\n value: DEMO_VALUES[id],\n });\n\n return (\n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate } from '@udecode/plate/react';\n\nimport { editorPlugins } from '@/components/editor/plugins/editor-plugins';\nimport { useCreateEditor } from '@/components/editor/use-create-editor';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nimport { DEMO_VALUES } from './values/demo-values';\n\nexport default function Demo({ id }: { id: string }) {\n const editor = useCreateEditor({\n plugins: [...editorPlugins],\n value: DEMO_VALUES[id],\n });\n\n return (\n \n \n \n \n \n );\n}\n", "path": "example/demo.tsx", "target": "components/demo.tsx", "type": "registry:example" }, { - "content": "'use client';\n\nimport React from 'react';\n\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n} from '@udecode/plate-basic-marks';\nimport { BaseBlockquotePlugin } from '@udecode/plate-block-quote';\nimport {\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodeSyntaxPlugin,\n} from '@udecode/plate-code-block';\nimport { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate-common';\nimport { BaseHeadingPlugin, HEADING_LEVELS } from '@udecode/plate-heading';\nimport { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { BaseIndentListPlugin } from '@udecode/plate-indent-list';\nimport { BaseLinkPlugin } from '@udecode/plate-link';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\n\nimport { AIMenu } from '@/components/plate-ui/ai-menu';\nimport {\n TodoLiStatic,\n TodoMarkerStatic,\n} from '@/components/plate-ui/indent-todo-marker-static';\n\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nconst createAIEditor = () => {\n const editor = createSlateEditor({\n id: 'ai',\n plugins: [\n BaseBlockquotePlugin,\n BaseBoldPlugin,\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodePlugin,\n BaseCodeSyntaxPlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n BaseHeadingPlugin,\n BaseHorizontalRulePlugin,\n BaseLinkPlugin,\n BaseParagraphPlugin,\n BaseIndentListPlugin.extend({\n inject: {\n targetPlugins: [\n BaseParagraphPlugin.key,\n ...HEADING_LEVELS,\n BaseBlockquotePlugin.key,\n BaseCodeBlockPlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n todo: {\n liComponent: TodoLiStatic,\n markerComponent: TodoMarkerStatic,\n type: 'todo',\n },\n },\n },\n }),\n MarkdownPlugin.configure({ options: { indentList: true } }),\n ],\n });\n\n return editor;\n};\n\nconst systemCommon = `\\\nYou are an advanced AI-powered note-taking assistant, designed to enhance productivity and creativity in note management.\nRespond directly to user prompts with clear, concise, and relevant content. Maintain a neutral, helpful tone.\n\nRules:\n- is the entire note the user is working on.\n- is a reminder of how you should reply to INSTRUCTIONS. It does not apply to questions.\n- Anything else is the user prompt.\n- Your response should be tailored to the user's prompt, providing precise assistance to optimize note management.\n- For INSTRUCTIONS: Follow the exactly. Provide ONLY the content to be inserted or replaced. No explanations or comments.\n- For QUESTIONS: Provide a helpful and concise answer. You may include brief explanations if necessary.\n- CRITICAL: Distinguish between INSTRUCTIONS and QUESTIONS. Instructions typically ask you to modify or add content. Questions ask for information or clarification.\n`;\n\nconst systemDefault = `\\\n${systemCommon}\n- is the current block of text the user is working on.\n- Ensure your output can seamlessly fit into the existing structure.\n- CRITICAL: Provide only a single block of text. DO NOT create multiple paragraphs or separate blocks.\n\n{block}\n\n`;\n\nconst systemSelecting = `\\\n${systemCommon}\n- is the block of text containing the user's selection, providing context.\n- Ensure your output can seamlessly fit into the existing structure.\n- is the specific text the user has selected in the block and wants to modify or ask about.\n- Consider the context provided by , but only modify . Your response should be a direct replacement for .\n\n{block}\n\n\n{selection}\n\n`;\n\nconst systemBlockSelecting = `\\\n${systemCommon}\n- represents the full blocks of text the user has selected and wants to modify or ask about.\n- Your response should be a direct replacement for the entire .\n- Maintain the overall structure and formatting of the selected blocks, unless explicitly instructed otherwise.\n- CRITICAL: Provide only the content to replace . Do not add additional blocks or change the block structure unless specifically requested.\n\n{block}\n\n`;\n\nconst userDefault = `\nCRITICAL: DO NOT use block formatting. You can only use inline formatting.\nCRITICAL: DO NOT start new lines or paragraphs.\nNEVER write .\n\n{prompt}`;\n\nconst userSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the text to replace . No explanations.\nEnsure it fits seamlessly within . If is empty, write ONE random sentence.\nNEVER write or .\n\n{prompt} about `;\n\nconst userBlockSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the content to replace the entire . No explanations.\nMaintain the overall structure unless instructed otherwise.\nNEVER write or .\n\n{prompt} about `;\n\nexport const PROMPT_TEMPLATES = {\n systemBlockSelecting,\n systemDefault,\n systemSelecting,\n userBlockSelecting,\n userDefault,\n userSelecting,\n};\n\nexport const aiPlugins = [\n cursorOverlayPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n AIPlugin,\n AIChatPlugin.configure({\n options: {\n createAIEditor,\n promptTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.userBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.userSelecting\n : PROMPT_TEMPLATES.userDefault;\n },\n systemTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.systemBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.systemSelecting\n : PROMPT_TEMPLATES.systemDefault;\n },\n },\n render: { afterEditable: () => },\n }),\n] as const;\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate';\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n} from '@udecode/plate-basic-marks';\nimport { BaseBlockquotePlugin } from '@udecode/plate-block-quote';\nimport {\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodeSyntaxPlugin,\n} from '@udecode/plate-code-block';\nimport { BaseHeadingPlugin, HEADING_LEVELS } from '@udecode/plate-heading';\nimport { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { BaseIndentListPlugin } from '@udecode/plate-indent-list';\nimport { BaseLinkPlugin } from '@udecode/plate-link';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\n\nimport { AIMenu } from '@/components/plate-ui/ai-menu';\nimport {\n TodoLiStatic,\n TodoMarkerStatic,\n} from '@/components/plate-ui/indent-todo-marker-static';\n\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nconst createAIEditor = () => {\n const editor = createSlateEditor({\n id: 'ai',\n plugins: [\n BaseBlockquotePlugin,\n BaseBoldPlugin,\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodePlugin,\n BaseCodeSyntaxPlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n BaseHeadingPlugin,\n BaseHorizontalRulePlugin,\n BaseLinkPlugin,\n BaseParagraphPlugin,\n BaseIndentListPlugin.extend({\n inject: {\n targetPlugins: [\n BaseParagraphPlugin.key,\n ...HEADING_LEVELS,\n BaseBlockquotePlugin.key,\n BaseCodeBlockPlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n todo: {\n liComponent: TodoLiStatic,\n markerComponent: TodoMarkerStatic,\n type: 'todo',\n },\n },\n },\n }),\n MarkdownPlugin.configure({ options: { indentList: true } }),\n ],\n });\n\n return editor;\n};\n\nconst systemCommon = `\\\nYou are an advanced AI-powered note-taking assistant, designed to enhance productivity and creativity in note management.\nRespond directly to user prompts with clear, concise, and relevant content. Maintain a neutral, helpful tone.\n\nRules:\n- is the entire note the user is working on.\n- is a reminder of how you should reply to INSTRUCTIONS. It does not apply to questions.\n- Anything else is the user prompt.\n- Your response should be tailored to the user's prompt, providing precise assistance to optimize note management.\n- For INSTRUCTIONS: Follow the exactly. Provide ONLY the content to be inserted or replaced. No explanations or comments.\n- For QUESTIONS: Provide a helpful and concise answer. You may include brief explanations if necessary.\n- CRITICAL: Distinguish between INSTRUCTIONS and QUESTIONS. Instructions typically ask you to modify or add content. Questions ask for information or clarification.\n`;\n\nconst systemDefault = `\\\n${systemCommon}\n- is the current block of text the user is working on.\n- Ensure your output can seamlessly fit into the existing structure.\n- CRITICAL: Provide only a single block of text. DO NOT create multiple paragraphs or separate blocks.\n\n{block}\n\n`;\n\nconst systemSelecting = `\\\n${systemCommon}\n- is the block of text containing the user's selection, providing context.\n- Ensure your output can seamlessly fit into the existing structure.\n- is the specific text the user has selected in the block and wants to modify or ask about.\n- Consider the context provided by , but only modify . Your response should be a direct replacement for .\n\n{block}\n\n\n{selection}\n\n`;\n\nconst systemBlockSelecting = `\\\n${systemCommon}\n- represents the full blocks of text the user has selected and wants to modify or ask about.\n- Your response should be a direct replacement for the entire .\n- Maintain the overall structure and formatting of the selected blocks, unless explicitly instructed otherwise.\n- CRITICAL: Provide only the content to replace . Do not add additional blocks or change the block structure unless specifically requested.\n\n{block}\n\n`;\n\nconst userDefault = `\nCRITICAL: DO NOT use block formatting. You can only use inline formatting.\nCRITICAL: DO NOT start new lines or paragraphs.\nNEVER write .\n\n{prompt}`;\n\nconst userSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the text to replace . No explanations.\nEnsure it fits seamlessly within . If is empty, write ONE random sentence.\nNEVER write or .\n\n{prompt} about `;\n\nconst userBlockSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the content to replace the entire . No explanations.\nMaintain the overall structure unless instructed otherwise.\nNEVER write or .\n\n{prompt} about `;\n\nexport const PROMPT_TEMPLATES = {\n systemBlockSelecting,\n systemDefault,\n systemSelecting,\n userBlockSelecting,\n userDefault,\n userSelecting,\n};\n\nexport const aiPlugins = [\n cursorOverlayPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n AIPlugin,\n AIChatPlugin.configure({\n options: {\n createAIEditor,\n promptTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.userBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.userSelecting\n : PROMPT_TEMPLATES.userDefault;\n },\n systemTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.systemBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.systemSelecting\n : PROMPT_TEMPLATES.systemDefault;\n },\n },\n render: { afterEditable: () => },\n }),\n] as const;\n", "path": "components/editor/plugins/ai-plugins.tsx", "target": "components/ai-plugins.tsx", "type": "registry:example" @@ -29,13 +29,13 @@ "type": "registry:example" }, { - "content": "'use client';\n\nimport type { Value } from '@udecode/plate-common';\n\nimport { withProps } from '@udecode/cn';\nimport { AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n CodeSyntaxPlugin,\n} from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n type CreatePlateEditorOptions,\n ParagraphPlugin,\n PlateLeaf,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { EmojiInputPlugin } from '@udecode/plate-emoji/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport {\n EquationPlugin,\n InlineEquationPlugin,\n} from '@udecode/plate-math/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n MentionInputPlugin,\n MentionPlugin,\n} from '@udecode/plate-mention/react';\nimport { SlashInputPlugin } from '@udecode/plate-slash-command/react';\nimport {\n TableCellHeaderPlugin,\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\n\nimport { AILeaf } from '@/components/plate-ui/ai-leaf';\nimport { BlockquoteElement } from '@/components/plate-ui/blockquote-element';\nimport { CodeBlockElement } from '@/components/plate-ui/code-block-element';\nimport { CodeLeaf } from '@/components/plate-ui/code-leaf';\nimport { CodeLineElement } from '@/components/plate-ui/code-line-element';\nimport { CodeSyntaxLeaf } from '@/components/plate-ui/code-syntax-leaf';\nimport { ColumnElement } from '@/components/plate-ui/column-element';\nimport { ColumnGroupElement } from '@/components/plate-ui/column-group-element';\nimport { CommentLeaf } from '@/components/plate-ui/comment-leaf';\nimport { DateElement } from '@/components/plate-ui/date-element';\nimport { EmojiInputElement } from '@/components/plate-ui/emoji-input-element';\nimport { EquationElement } from '@/components/plate-ui/equation-element';\nimport { HeadingElement } from '@/components/plate-ui/heading-element';\nimport { HighlightLeaf } from '@/components/plate-ui/highlight-leaf';\nimport { HrElement } from '@/components/plate-ui/hr-element';\nimport { ImageElement } from '@/components/plate-ui/image-element';\nimport { InlineEquationElement } from '@/components/plate-ui/inline-equation-element';\nimport { KbdLeaf } from '@/components/plate-ui/kbd-leaf';\nimport { LinkElement } from '@/components/plate-ui/link-element';\nimport { MediaAudioElement } from '@/components/plate-ui/media-audio-element';\nimport { MediaEmbedElement } from '@/components/plate-ui/media-embed-element';\nimport { MediaFileElement } from '@/components/plate-ui/media-file-element';\nimport { MediaPlaceholderElement } from '@/components/plate-ui/media-placeholder-element';\nimport { MediaVideoElement } from '@/components/plate-ui/media-video-element';\nimport { MentionElement } from '@/components/plate-ui/mention-element';\nimport { MentionInputElement } from '@/components/plate-ui/mention-input-element';\nimport { ParagraphElement } from '@/components/plate-ui/paragraph-element';\nimport { withPlaceholders } from '@/components/plate-ui/placeholder';\nimport { SlashInputElement } from '@/components/plate-ui/slash-input-element';\nimport {\n TableCellElement,\n TableCellHeaderElement,\n} from '@/components/plate-ui/table-cell-element';\nimport { TableElement } from '@/components/plate-ui/table-element';\nimport { TableRowElement } from '@/components/plate-ui/table-row-element';\nimport { TocElement } from '@/components/plate-ui/toc-element';\nimport { ToggleElement } from '@/components/plate-ui/toggle-element';\n\nimport { editorPlugins, viewPlugins } from './plugins/editor-plugins';\n\nexport const viewComponents = {\n [AudioPlugin.key]: MediaAudioElement,\n [BlockquotePlugin.key]: BlockquoteElement,\n [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),\n [CodeBlockPlugin.key]: CodeBlockElement,\n [CodeLinePlugin.key]: CodeLineElement,\n [CodePlugin.key]: CodeLeaf,\n [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,\n [ColumnItemPlugin.key]: ColumnElement,\n [ColumnPlugin.key]: ColumnGroupElement,\n [CommentsPlugin.key]: CommentLeaf,\n [DatePlugin.key]: DateElement,\n [EquationPlugin.key]: EquationElement,\n [FilePlugin.key]: MediaFileElement,\n [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }),\n [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }),\n [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }),\n [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }),\n [HighlightPlugin.key]: HighlightLeaf,\n [HorizontalRulePlugin.key]: HrElement,\n [ImagePlugin.key]: ImageElement,\n [InlineEquationPlugin.key]: InlineEquationElement,\n [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }),\n [KbdPlugin.key]: KbdLeaf,\n [LinkPlugin.key]: LinkElement,\n [MediaEmbedPlugin.key]: MediaEmbedElement,\n [MentionPlugin.key]: MentionElement,\n [ParagraphPlugin.key]: ParagraphElement,\n [PlaceholderPlugin.key]: MediaPlaceholderElement,\n [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }),\n [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }),\n [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }),\n [TableCellHeaderPlugin.key]: TableCellHeaderElement,\n [TableCellPlugin.key]: TableCellElement,\n [TablePlugin.key]: TableElement,\n [TableRowPlugin.key]: TableRowElement,\n [TocPlugin.key]: TocElement,\n [TogglePlugin.key]: ToggleElement,\n [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),\n [VideoPlugin.key]: MediaVideoElement,\n};\n\nexport const editorComponents = {\n ...viewComponents,\n [AIPlugin.key]: AILeaf,\n [EmojiInputPlugin.key]: EmojiInputElement,\n [MentionInputPlugin.key]: MentionInputElement,\n [SlashInputPlugin.key]: SlashInputElement,\n};\n\nexport const useCreateEditor = (\n {\n components,\n override,\n readOnly,\n ...options\n }: {\n components?: Record;\n plugins?: any[];\n readOnly?: boolean;\n } & Omit = {},\n deps: any[] = []\n) => {\n return usePlateEditor(\n {\n override: {\n components: {\n ...(readOnly ? viewComponents : withPlaceholders(editorComponents)),\n ...components,\n },\n ...override,\n },\n plugins: (readOnly ? viewPlugins : editorPlugins) as any,\n ...options,\n },\n deps\n );\n};\n", + "content": "'use client';\n\nimport type { Value } from '@udecode/plate';\n\nimport { withProps } from '@udecode/cn';\nimport {\n type CreatePlateEditorOptions,\n ParagraphPlugin,\n PlateLeaf,\n usePlateEditor,\n} from '@udecode/plate/react';\nimport { AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n CodeSyntaxPlugin,\n} from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { EmojiInputPlugin } from '@udecode/plate-emoji/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport {\n EquationPlugin,\n InlineEquationPlugin,\n} from '@udecode/plate-math/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n MentionInputPlugin,\n MentionPlugin,\n} from '@udecode/plate-mention/react';\nimport { SlashInputPlugin } from '@udecode/plate-slash-command/react';\nimport {\n TableCellHeaderPlugin,\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\n\nimport { AILeaf } from '@/components/plate-ui/ai-leaf';\nimport { BlockquoteElement } from '@/components/plate-ui/blockquote-element';\nimport { CodeBlockElement } from '@/components/plate-ui/code-block-element';\nimport { CodeLeaf } from '@/components/plate-ui/code-leaf';\nimport { CodeLineElement } from '@/components/plate-ui/code-line-element';\nimport { CodeSyntaxLeaf } from '@/components/plate-ui/code-syntax-leaf';\nimport { ColumnElement } from '@/components/plate-ui/column-element';\nimport { ColumnGroupElement } from '@/components/plate-ui/column-group-element';\nimport { CommentLeaf } from '@/components/plate-ui/comment-leaf';\nimport { DateElement } from '@/components/plate-ui/date-element';\nimport { EmojiInputElement } from '@/components/plate-ui/emoji-input-element';\nimport { EquationElement } from '@/components/plate-ui/equation-element';\nimport { HeadingElement } from '@/components/plate-ui/heading-element';\nimport { HighlightLeaf } from '@/components/plate-ui/highlight-leaf';\nimport { HrElement } from '@/components/plate-ui/hr-element';\nimport { ImageElement } from '@/components/plate-ui/image-element';\nimport { InlineEquationElement } from '@/components/plate-ui/inline-equation-element';\nimport { KbdLeaf } from '@/components/plate-ui/kbd-leaf';\nimport { LinkElement } from '@/components/plate-ui/link-element';\nimport { MediaAudioElement } from '@/components/plate-ui/media-audio-element';\nimport { MediaEmbedElement } from '@/components/plate-ui/media-embed-element';\nimport { MediaFileElement } from '@/components/plate-ui/media-file-element';\nimport { MediaPlaceholderElement } from '@/components/plate-ui/media-placeholder-element';\nimport { MediaVideoElement } from '@/components/plate-ui/media-video-element';\nimport { MentionElement } from '@/components/plate-ui/mention-element';\nimport { MentionInputElement } from '@/components/plate-ui/mention-input-element';\nimport { ParagraphElement } from '@/components/plate-ui/paragraph-element';\nimport { withPlaceholders } from '@/components/plate-ui/placeholder';\nimport { SlashInputElement } from '@/components/plate-ui/slash-input-element';\nimport {\n TableCellElement,\n TableCellHeaderElement,\n} from '@/components/plate-ui/table-cell-element';\nimport { TableElement } from '@/components/plate-ui/table-element';\nimport { TableRowElement } from '@/components/plate-ui/table-row-element';\nimport { TocElement } from '@/components/plate-ui/toc-element';\nimport { ToggleElement } from '@/components/plate-ui/toggle-element';\n\nimport { editorPlugins, viewPlugins } from './plugins/editor-plugins';\n\nexport const viewComponents = {\n [AudioPlugin.key]: MediaAudioElement,\n [BlockquotePlugin.key]: BlockquoteElement,\n [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),\n [CodeBlockPlugin.key]: CodeBlockElement,\n [CodeLinePlugin.key]: CodeLineElement,\n [CodePlugin.key]: CodeLeaf,\n [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,\n [ColumnItemPlugin.key]: ColumnElement,\n [ColumnPlugin.key]: ColumnGroupElement,\n [CommentsPlugin.key]: CommentLeaf,\n [DatePlugin.key]: DateElement,\n [EquationPlugin.key]: EquationElement,\n [FilePlugin.key]: MediaFileElement,\n [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }),\n [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }),\n [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }),\n [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }),\n [HighlightPlugin.key]: HighlightLeaf,\n [HorizontalRulePlugin.key]: HrElement,\n [ImagePlugin.key]: ImageElement,\n [InlineEquationPlugin.key]: InlineEquationElement,\n [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }),\n [KbdPlugin.key]: KbdLeaf,\n [LinkPlugin.key]: LinkElement,\n [MediaEmbedPlugin.key]: MediaEmbedElement,\n [MentionPlugin.key]: MentionElement,\n [ParagraphPlugin.key]: ParagraphElement,\n [PlaceholderPlugin.key]: MediaPlaceholderElement,\n [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }),\n [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }),\n [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }),\n [TableCellHeaderPlugin.key]: TableCellHeaderElement,\n [TableCellPlugin.key]: TableCellElement,\n [TablePlugin.key]: TableElement,\n [TableRowPlugin.key]: TableRowElement,\n [TocPlugin.key]: TocElement,\n [TogglePlugin.key]: ToggleElement,\n [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),\n [VideoPlugin.key]: MediaVideoElement,\n};\n\nexport const editorComponents = {\n ...viewComponents,\n [AIPlugin.key]: AILeaf,\n [EmojiInputPlugin.key]: EmojiInputElement,\n [MentionInputPlugin.key]: MentionInputElement,\n [SlashInputPlugin.key]: SlashInputElement,\n};\n\nexport const useCreateEditor = (\n {\n components,\n override,\n readOnly,\n ...options\n }: {\n components?: Record;\n plugins?: any[];\n readOnly?: boolean;\n } & Omit = {},\n deps: any[] = []\n) => {\n return usePlateEditor(\n {\n override: {\n components: {\n ...(readOnly ? viewComponents : withPlaceholders(editorComponents)),\n ...components,\n },\n ...override,\n },\n plugins: (readOnly ? viewPlugins : editorPlugins) as any,\n ...options,\n },\n deps\n );\n};\n", "path": "components/editor/use-create-editor.ts", "target": "components/use-create-editor.ts", "type": "registry:example" }, { - "content": "'use client';\n\nimport { CalloutPlugin } from '@udecode/plate-callout/react';\nimport { ParagraphPlugin } from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\n\nimport { FixedToolbarPlugin } from '@/components/editor/plugins/fixed-toolbar-plugin';\nimport { FloatingToolbarPlugin } from '@/components/editor/plugins/floating-toolbar-plugin';\n\nimport { aiPlugins } from './ai-plugins';\nimport { alignPlugin } from './align-plugin';\nimport { autoformatPlugin } from './autoformat-plugin';\nimport { basicNodesPlugins } from './basic-nodes-plugins';\nimport { blockMenuPlugins } from './block-menu-plugins';\nimport { commentsPlugin } from './comments-plugin';\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nimport { deletePlugins } from './delete-plugins';\nimport { dndPlugins } from './dnd-plugins';\nimport { equationPlugins } from './equation-plugins';\nimport { exitBreakPlugin } from './exit-break-plugin';\nimport { indentListPlugins } from './indent-list-plugins';\nimport { lineHeightPlugin } from './line-height-plugin';\nimport { linkPlugin } from './link-plugin';\nimport { mediaPlugins } from './media-plugins';\nimport { mentionPlugin } from './mention-plugin';\nimport { resetBlockTypePlugin } from './reset-block-type-plugin';\nimport { softBreakPlugin } from './soft-break-plugin';\nimport { tablePlugin } from './table-plugin';\nimport { tocPlugin } from './toc-plugin';\n\nexport const viewPlugins = [\n ...basicNodesPlugins,\n HorizontalRulePlugin,\n linkPlugin,\n DatePlugin,\n mentionPlugin,\n tablePlugin,\n TogglePlugin,\n tocPlugin,\n ...mediaPlugins,\n ...equationPlugins,\n CalloutPlugin,\n ColumnPlugin,\n\n // Marks\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n alignPlugin,\n ...indentListPlugins,\n lineHeightPlugin,\n\n // Collaboration\n commentsPlugin,\n] as const;\n\nexport const editorPlugins = [\n // AI\n ...aiPlugins,\n\n // Nodes\n ...viewPlugins,\n\n // Functionality\n SlashPlugin,\n autoformatPlugin,\n cursorOverlayPlugin,\n ...blockMenuPlugins,\n ...dndPlugins,\n EmojiPlugin,\n exitBreakPlugin,\n resetBlockTypePlugin,\n ...deletePlugins,\n softBreakPlugin,\n TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key } }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // UI\n FixedToolbarPlugin,\n FloatingToolbarPlugin,\n];\n", + "content": "'use client';\n\nimport { ParagraphPlugin } from '@udecode/plate/react';\nimport { CalloutPlugin } from '@udecode/plate-callout/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\n\nimport { FixedToolbarPlugin } from '@/components/editor/plugins/fixed-toolbar-plugin';\nimport { FloatingToolbarPlugin } from '@/components/editor/plugins/floating-toolbar-plugin';\n\nimport { aiPlugins } from './ai-plugins';\nimport { alignPlugin } from './align-plugin';\nimport { autoformatPlugin } from './autoformat-plugin';\nimport { basicNodesPlugins } from './basic-nodes-plugins';\nimport { blockMenuPlugins } from './block-menu-plugins';\nimport { commentsPlugin } from './comments-plugin';\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nimport { deletePlugins } from './delete-plugins';\nimport { dndPlugins } from './dnd-plugins';\nimport { equationPlugins } from './equation-plugins';\nimport { exitBreakPlugin } from './exit-break-plugin';\nimport { indentListPlugins } from './indent-list-plugins';\nimport { lineHeightPlugin } from './line-height-plugin';\nimport { linkPlugin } from './link-plugin';\nimport { mediaPlugins } from './media-plugins';\nimport { mentionPlugin } from './mention-plugin';\nimport { resetBlockTypePlugin } from './reset-block-type-plugin';\nimport { softBreakPlugin } from './soft-break-plugin';\nimport { tablePlugin } from './table-plugin';\nimport { tocPlugin } from './toc-plugin';\n\nexport const viewPlugins = [\n ...basicNodesPlugins,\n HorizontalRulePlugin,\n linkPlugin,\n DatePlugin,\n mentionPlugin,\n tablePlugin,\n TogglePlugin,\n tocPlugin,\n ...mediaPlugins,\n ...equationPlugins,\n CalloutPlugin,\n ColumnPlugin,\n\n // Marks\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n alignPlugin,\n ...indentListPlugins,\n lineHeightPlugin,\n\n // Collaboration\n commentsPlugin,\n] as const;\n\nexport const editorPlugins = [\n // AI\n ...aiPlugins,\n\n // Nodes\n ...viewPlugins,\n\n // Functionality\n SlashPlugin,\n autoformatPlugin,\n cursorOverlayPlugin,\n ...blockMenuPlugins,\n ...dndPlugins,\n EmojiPlugin,\n exitBreakPlugin,\n resetBlockTypePlugin,\n ...deletePlugins,\n softBreakPlugin,\n TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key } }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // UI\n FixedToolbarPlugin,\n FloatingToolbarPlugin,\n];\n", "path": "components/editor/plugins/editor-plugins.tsx", "target": "components/editor-plugins.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/ai-leaf.json b/apps/www/public/r/styles/default/ai-leaf.json index 546d486207..5568584ebe 100644 --- a/apps/www/public/r/styles/default/ai-leaf.json +++ b/apps/www/public/r/styles/default/ai-leaf.json @@ -21,7 +21,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { PlateLeaf } from '@udecode/plate-common/react';\n\nexport const AILeaf = withRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n {children}\n \n );\n }\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { cn, withRef } from '@udecode/cn';\nimport { PlateLeaf } from '@udecode/plate/react';\n\nexport const AILeaf = withRef(\n ({ children, className, ...props }, ref) => {\n return (\n \n {children}\n \n );\n }\n);\n", "path": "plate-ui/ai-leaf.tsx", "target": "components/plate-ui/ai-leaf.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/ai-menu.json b/apps/www/public/r/styles/default/ai-menu.json index aaacf94647..afc7afe4fc 100644 --- a/apps/www/public/r/styles/default/ai-menu.json +++ b/apps/www/public/r/styles/default/ai-menu.json @@ -27,19 +27,19 @@ }, "files": [ { - "content": "'use client';\n\nimport * as React from 'react';\n\nimport { AIChatPlugin, useEditorChat } from '@udecode/plate-ai/react';\nimport {\n type SlateEditor,\n type TElement,\n type TNodeEntry,\n getAncestorNode,\n getBlocks,\n isElementEmpty,\n isHotkey,\n isSelectionAtBlockEnd,\n} from '@udecode/plate-common';\nimport {\n toDOMNode,\n useEditorPlugin,\n useHotkeys,\n} from '@udecode/plate-common/react';\nimport {\n BlockSelectionPlugin,\n useIsSelecting,\n} from '@udecode/plate-selection/react';\nimport { Loader2Icon } from 'lucide-react';\n\nimport { useChat } from '@/components/editor/use-chat';\n\nimport { AIChatEditor } from './ai-chat-editor';\nimport { AIMenuItems } from './ai-menu-items';\nimport { Command, CommandList, InputCommand } from './command';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\n\nexport function AIMenu() {\n const { api, editor, useOption } = useEditorPlugin(AIChatPlugin);\n const open = useOption('open');\n const mode = useOption('mode');\n const isSelecting = useIsSelecting();\n\n const aiEditorRef = React.useRef(null);\n const [value, setValue] = React.useState('');\n\n const chat = useChat();\n\n const { input, isLoading, messages, setInput } = chat;\n const [anchorElement, setAnchorElement] = React.useState(\n null\n );\n\n const setOpen = (open: boolean) => {\n if (open) {\n api.aiChat.show();\n } else {\n api.aiChat.hide();\n }\n };\n\n const show = (anchorElement: HTMLElement) => {\n setAnchorElement(anchorElement);\n setOpen(true);\n };\n\n useEditorChat({\n chat,\n onOpenBlockSelection: (blocks: TNodeEntry[]) => {\n show(toDOMNode(editor, blocks.at(-1)![0])!);\n },\n onOpenChange: (open) => {\n if (!open) {\n setAnchorElement(null);\n setInput('');\n }\n },\n onOpenCursor: () => {\n const ancestor = getAncestorNode(editor)?.[0] as TElement;\n\n if (!isSelectionAtBlockEnd(editor) && !isElementEmpty(editor, ancestor)) {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.addSelectedRow(ancestor.id as string);\n }\n\n show(toDOMNode(editor, ancestor)!);\n },\n onOpenSelection: () => {\n show(toDOMNode(editor, getBlocks(editor).at(-1)![0])!);\n },\n });\n\n useHotkeys(\n 'meta+j',\n () => {\n api.aiChat.show();\n },\n { enableOnContentEditable: true, enableOnFormTags: true }\n );\n\n return (\n \n \n\n {\n e.preventDefault();\n\n if (isLoading) {\n api.aiChat.stop();\n } else {\n api.aiChat.hide();\n }\n }}\n align=\"center\"\n avoidCollisions={false}\n side=\"bottom\"\n >\n \n {mode === 'chat' && isSelecting && messages.length > 0 && (\n \n )}\n\n {isLoading ? (\n
\n \n {messages.length > 1 ? 'Editing...' : 'Thinking...'}\n
\n ) : (\n {\n if (isHotkey('backspace')(e) && input.length === 0) {\n e.preventDefault();\n api.aiChat.hide();\n }\n if (isHotkey('enter')(e) && !e.shiftKey && !value) {\n e.preventDefault();\n void api.aiChat.submit();\n }\n }}\n onValueChange={setInput}\n placeholder=\"Ask AI anything...\"\n data-plate-focus\n autoFocus\n />\n )}\n\n {!isLoading && (\n \n \n \n )}\n \n \n
\n );\n}\n", + "content": "'use client';\n\nimport * as React from 'react';\n\nimport { type NodeEntry, type SlateEditor, isHotkey } from '@udecode/plate';\nimport { useEditorPlugin, useHotkeys } from '@udecode/plate/react';\nimport { AIChatPlugin, useEditorChat } from '@udecode/plate-ai/react';\nimport {\n BlockSelectionPlugin,\n useIsSelecting,\n} from '@udecode/plate-selection/react';\nimport { Loader2Icon } from 'lucide-react';\n\nimport { useChat } from '@/components/editor/use-chat';\n\nimport { AIChatEditor } from './ai-chat-editor';\nimport { AIMenuItems } from './ai-menu-items';\nimport { Command, CommandList, InputCommand } from './command';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\n\nexport function AIMenu() {\n const { api, editor, useOption } = useEditorPlugin(AIChatPlugin);\n const open = useOption('open');\n const mode = useOption('mode');\n const isSelecting = useIsSelecting();\n\n const aiEditorRef = React.useRef(null);\n const [value, setValue] = React.useState('');\n\n const chat = useChat();\n\n const { input, isLoading, messages, setInput } = chat;\n const [anchorElement, setAnchorElement] = React.useState(\n null\n );\n\n const setOpen = (open: boolean) => {\n if (open) {\n api.aiChat.show();\n } else {\n api.aiChat.hide();\n }\n };\n\n const show = (anchorElement: HTMLElement) => {\n setAnchorElement(anchorElement);\n setOpen(true);\n };\n\n useEditorChat({\n chat,\n onOpenBlockSelection: (blocks: NodeEntry[]) => {\n show(editor.api.toDOMNode(blocks.at(-1)![0])!);\n },\n onOpenChange: (open) => {\n if (!open) {\n setAnchorElement(null);\n setInput('');\n }\n },\n onOpenCursor: () => {\n const [ancestor] = editor.api.block({ highest: true })!;\n\n if (!editor.api.isAt({ end: true }) && !editor.api.isEmpty(ancestor)) {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.addSelectedRow(ancestor.id as string);\n }\n\n show(editor.api.toDOMNode(ancestor)!);\n },\n onOpenSelection: () => {\n show(editor.api.toDOMNode(editor.api.blocks().at(-1)![0])!);\n },\n });\n\n useHotkeys(\n 'meta+j',\n () => {\n api.aiChat.show();\n },\n { enableOnContentEditable: true, enableOnFormTags: true }\n );\n\n return (\n \n \n\n {\n e.preventDefault();\n\n if (isLoading) {\n api.aiChat.stop();\n } else {\n api.aiChat.hide();\n }\n }}\n align=\"center\"\n avoidCollisions={false}\n side=\"bottom\"\n >\n \n {mode === 'chat' && isSelecting && messages.length > 0 && (\n \n )}\n\n {isLoading ? (\n
\n \n {messages.length > 1 ? 'Editing...' : 'Thinking...'}\n
\n ) : (\n {\n if (isHotkey('backspace')(e) && input.length === 0) {\n e.preventDefault();\n api.aiChat.hide();\n }\n if (isHotkey('enter')(e) && !e.shiftKey && !value) {\n e.preventDefault();\n void api.aiChat.submit();\n }\n }}\n onValueChange={setInput}\n placeholder=\"Ask AI anything...\"\n data-plate-focus\n autoFocus\n />\n )}\n\n {!isLoading && (\n \n \n \n )}\n \n \n
\n );\n}\n", "path": "plate-ui/ai-menu.tsx", "target": "components/plate-ui/ai-menu.tsx", "type": "registry:ui" }, { - "content": "'use client';\n\nimport { useEffect, useMemo } from 'react';\n\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport {\n type SlateEditor,\n getAncestorNode,\n getEndPoint,\n getNodeString,\n} from '@udecode/plate-common';\nimport {\n type PlateEditor,\n focusEditor,\n useEditorPlugin,\n} from '@udecode/plate-common/react';\nimport { useIsSelecting } from '@udecode/plate-selection/react';\nimport {\n Album,\n BadgeHelp,\n Check,\n CornerUpLeft,\n FeatherIcon,\n ListEnd,\n ListMinus,\n ListPlus,\n PenLine,\n Wand,\n X,\n} from 'lucide-react';\n\nimport { CommandGroup, CommandItem } from './command';\n\nexport type EditorChatState =\n | 'cursorCommand'\n | 'cursorSuggestion'\n | 'selectionCommand'\n | 'selectionSuggestion';\n\nexport const aiChatItems = {\n accept: {\n icon: ,\n label: 'Accept',\n value: 'accept',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIChatPlugin).aiChat.accept();\n focusEditor(editor, getEndPoint(editor, editor.selection!));\n },\n },\n continueWrite: {\n icon: ,\n label: 'Continue writing',\n value: 'continueWrite',\n onSelect: ({ editor }) => {\n const ancestorNode = getAncestorNode(editor);\n\n if (!ancestorNode) return;\n\n const isEmpty = getNodeString(ancestorNode[0]).trim().length === 0;\n\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: isEmpty\n ? `\n{editor}\n\nStart writing a new paragraph AFTER ONLY ONE SENTENCE`\n : 'Continue writing AFTER ONLY ONE SENTENCE. DONT REPEAT THE TEXT.',\n });\n },\n },\n discard: {\n icon: ,\n label: 'Discard',\n shortcut: 'Escape',\n value: 'discard',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIPlugin).ai.undo();\n editor.getApi(AIChatPlugin).aiChat.hide();\n },\n },\n explain: {\n icon: ,\n label: 'Explain',\n value: 'explain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: {\n default: 'Explain {editor}',\n selecting: 'Explain',\n },\n });\n },\n },\n fixSpelling: {\n icon: ,\n label: 'Fix spelling & grammar',\n value: 'fixSpelling',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Fix spelling and grammar',\n });\n },\n },\n improveWriting: {\n icon: ,\n label: 'Improve writing',\n value: 'improveWriting',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Improve the writing',\n });\n },\n },\n insertBelow: {\n icon: ,\n label: 'Insert below',\n value: 'insertBelow',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.insertBelow(aiEditor);\n },\n },\n makeLonger: {\n icon: ,\n label: 'Make longer',\n value: 'makeLonger',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make longer',\n });\n },\n },\n makeShorter: {\n icon: ,\n label: 'Make shorter',\n value: 'makeShorter',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make shorter',\n });\n },\n },\n replace: {\n icon: ,\n label: 'Replace selection',\n value: 'replace',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.replaceSelection(aiEditor);\n },\n },\n simplifyLanguage: {\n icon: ,\n label: 'Simplify language',\n value: 'simplifyLanguage',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Simplify the language',\n });\n },\n },\n summarize: {\n icon: ,\n label: 'Add a summary',\n value: 'summarize',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: {\n default: 'Summarize {editor}',\n selecting: 'Summarize',\n },\n });\n },\n },\n tryAgain: {\n icon: ,\n label: 'Try again',\n value: 'tryAgain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.reload();\n },\n },\n} satisfies Record<\n string,\n {\n icon: React.ReactNode;\n label: string;\n value: string;\n component?: React.ComponentType<{ menuState: EditorChatState }>;\n filterItems?: boolean;\n items?: { label: string; value: string }[];\n shortcut?: string;\n onSelect?: ({\n aiEditor,\n editor,\n }: {\n aiEditor: SlateEditor;\n editor: PlateEditor;\n }) => void;\n }\n>;\n\nconst menuStateItems: Record<\n EditorChatState,\n {\n items: (typeof aiChatItems)[keyof typeof aiChatItems][];\n heading?: string;\n }[]\n> = {\n cursorCommand: [\n {\n items: [\n aiChatItems.continueWrite,\n aiChatItems.summarize,\n aiChatItems.explain,\n ],\n },\n ],\n cursorSuggestion: [\n {\n items: [aiChatItems.accept, aiChatItems.discard, aiChatItems.tryAgain],\n },\n ],\n selectionCommand: [\n {\n items: [\n aiChatItems.improveWriting,\n aiChatItems.makeLonger,\n aiChatItems.makeShorter,\n aiChatItems.fixSpelling,\n aiChatItems.simplifyLanguage,\n ],\n },\n ],\n selectionSuggestion: [\n {\n items: [\n aiChatItems.replace,\n aiChatItems.insertBelow,\n aiChatItems.discard,\n aiChatItems.tryAgain,\n ],\n },\n ],\n};\n\nexport const AIMenuItems = ({\n aiEditorRef,\n setValue,\n}: {\n aiEditorRef: React.MutableRefObject;\n setValue: (value: string) => void;\n}) => {\n const { editor, useOption } = useEditorPlugin(AIChatPlugin);\n const { messages } = useOption('chat');\n const isSelecting = useIsSelecting();\n\n const menuState = useMemo(() => {\n if (messages && messages.length > 0) {\n return isSelecting ? 'selectionSuggestion' : 'cursorSuggestion';\n }\n\n return isSelecting ? 'selectionCommand' : 'cursorCommand';\n }, [isSelecting, messages]);\n\n const menuGroups = useMemo(() => {\n const items = menuStateItems[menuState];\n\n return items;\n }, [menuState]);\n\n useEffect(() => {\n if (menuGroups.length > 0 && menuGroups[0].items.length > 0) {\n setValue(menuGroups[0].items[0].value);\n }\n }, [menuGroups, setValue]);\n\n return (\n <>\n {menuGroups.map((group, index) => (\n \n {group.items.map((menuItem) => (\n {\n menuItem.onSelect?.({\n aiEditor: aiEditorRef.current!,\n editor: editor,\n });\n }}\n >\n {menuItem.icon}\n {menuItem.label}\n \n ))}\n \n ))}\n \n );\n};\n", + "content": "'use client';\n\nimport { useEffect, useMemo } from 'react';\n\nimport { type SlateEditor, NodeApi } from '@udecode/plate';\nimport { type PlateEditor, useEditorPlugin } from '@udecode/plate/react';\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport { useIsSelecting } from '@udecode/plate-selection/react';\nimport {\n Album,\n BadgeHelp,\n Check,\n CornerUpLeft,\n FeatherIcon,\n ListEnd,\n ListMinus,\n ListPlus,\n PenLine,\n Wand,\n X,\n} from 'lucide-react';\n\nimport { CommandGroup, CommandItem } from './command';\n\nexport type EditorChatState =\n | 'cursorCommand'\n | 'cursorSuggestion'\n | 'selectionCommand'\n | 'selectionSuggestion';\n\nexport const aiChatItems = {\n accept: {\n icon: ,\n label: 'Accept',\n value: 'accept',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIChatPlugin).aiChat.accept();\n editor.tf.focus({ edge: 'end' });\n },\n },\n continueWrite: {\n icon: ,\n label: 'Continue writing',\n value: 'continueWrite',\n onSelect: ({ editor }) => {\n const ancestorNode = editor.api.block({ highest: true });\n\n if (!ancestorNode) return;\n\n const isEmpty = NodeApi.string(ancestorNode[0]).trim().length === 0;\n\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: isEmpty\n ? `\n{editor}\n\nStart writing a new paragraph AFTER ONLY ONE SENTENCE`\n : 'Continue writing AFTER ONLY ONE SENTENCE. DONT REPEAT THE TEXT.',\n });\n },\n },\n discard: {\n icon: ,\n label: 'Discard',\n shortcut: 'Escape',\n value: 'discard',\n onSelect: ({ editor }) => {\n editor.getTransforms(AIPlugin).ai.undo();\n editor.getApi(AIChatPlugin).aiChat.hide();\n },\n },\n explain: {\n icon: ,\n label: 'Explain',\n value: 'explain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: {\n default: 'Explain {editor}',\n selecting: 'Explain',\n },\n });\n },\n },\n fixSpelling: {\n icon: ,\n label: 'Fix spelling & grammar',\n value: 'fixSpelling',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Fix spelling and grammar',\n });\n },\n },\n improveWriting: {\n icon: ,\n label: 'Improve writing',\n value: 'improveWriting',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Improve the writing',\n });\n },\n },\n insertBelow: {\n icon: ,\n label: 'Insert below',\n value: 'insertBelow',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.insertBelow(aiEditor);\n },\n },\n makeLonger: {\n icon: ,\n label: 'Make longer',\n value: 'makeLonger',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make longer',\n });\n },\n },\n makeShorter: {\n icon: ,\n label: 'Make shorter',\n value: 'makeShorter',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Make shorter',\n });\n },\n },\n replace: {\n icon: ,\n label: 'Replace selection',\n value: 'replace',\n onSelect: ({ aiEditor, editor }) => {\n void editor.getTransforms(AIChatPlugin).aiChat.replaceSelection(aiEditor);\n },\n },\n simplifyLanguage: {\n icon: ,\n label: 'Simplify language',\n value: 'simplifyLanguage',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n prompt: 'Simplify the language',\n });\n },\n },\n summarize: {\n icon: ,\n label: 'Add a summary',\n value: 'summarize',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit({\n mode: 'insert',\n prompt: {\n default: 'Summarize {editor}',\n selecting: 'Summarize',\n },\n });\n },\n },\n tryAgain: {\n icon: ,\n label: 'Try again',\n value: 'tryAgain',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.reload();\n },\n },\n} satisfies Record<\n string,\n {\n icon: React.ReactNode;\n label: string;\n value: string;\n component?: React.ComponentType<{ menuState: EditorChatState }>;\n filterItems?: boolean;\n items?: { label: string; value: string }[];\n shortcut?: string;\n onSelect?: ({\n aiEditor,\n editor,\n }: {\n aiEditor: SlateEditor;\n editor: PlateEditor;\n }) => void;\n }\n>;\n\nconst menuStateItems: Record<\n EditorChatState,\n {\n items: (typeof aiChatItems)[keyof typeof aiChatItems][];\n heading?: string;\n }[]\n> = {\n cursorCommand: [\n {\n items: [\n aiChatItems.continueWrite,\n aiChatItems.summarize,\n aiChatItems.explain,\n ],\n },\n ],\n cursorSuggestion: [\n {\n items: [aiChatItems.accept, aiChatItems.discard, aiChatItems.tryAgain],\n },\n ],\n selectionCommand: [\n {\n items: [\n aiChatItems.improveWriting,\n aiChatItems.makeLonger,\n aiChatItems.makeShorter,\n aiChatItems.fixSpelling,\n aiChatItems.simplifyLanguage,\n ],\n },\n ],\n selectionSuggestion: [\n {\n items: [\n aiChatItems.replace,\n aiChatItems.insertBelow,\n aiChatItems.discard,\n aiChatItems.tryAgain,\n ],\n },\n ],\n};\n\nexport const AIMenuItems = ({\n aiEditorRef,\n setValue,\n}: {\n aiEditorRef: React.MutableRefObject;\n setValue: (value: string) => void;\n}) => {\n const { editor, useOption } = useEditorPlugin(AIChatPlugin);\n const { messages } = useOption('chat');\n const isSelecting = useIsSelecting();\n\n const menuState = useMemo(() => {\n if (messages && messages.length > 0) {\n return isSelecting ? 'selectionSuggestion' : 'cursorSuggestion';\n }\n\n return isSelecting ? 'selectionCommand' : 'cursorCommand';\n }, [isSelecting, messages]);\n\n const menuGroups = useMemo(() => {\n const items = menuStateItems[menuState];\n\n return items;\n }, [menuState]);\n\n useEffect(() => {\n if (menuGroups.length > 0 && menuGroups[0].items.length > 0) {\n setValue(menuGroups[0].items[0].value);\n }\n }, [menuGroups, setValue]);\n\n return (\n <>\n {menuGroups.map((group, index) => (\n \n {group.items.map((menuItem) => (\n {\n menuItem.onSelect?.({\n aiEditor: aiEditorRef.current!,\n editor: editor,\n });\n }}\n >\n {menuItem.icon}\n {menuItem.label}\n \n ))}\n \n ))}\n \n );\n};\n", "path": "plate-ui/ai-menu-items.tsx", "target": "components/plate-ui/ai-menu-items.tsx", "type": "registry:ui" }, { - "content": "'use client';\n\nimport React, { memo } from 'react';\n\nimport { withProps } from '@udecode/cn';\nimport { AIChatPlugin, useLastAssistantMessage } from '@udecode/plate-ai/react';\nimport {\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n} from '@udecode/plate-basic-marks';\nimport { BaseBlockquotePlugin } from '@udecode/plate-block-quote';\nimport {\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodeSyntaxPlugin,\n} from '@udecode/plate-code-block';\nimport { useEditorPlugin } from '@udecode/plate-common/react';\nimport {\n type SlateEditor,\n BaseParagraphPlugin,\n SlateLeaf,\n} from '@udecode/plate-common';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { BaseLinkPlugin } from '@udecode/plate-link';\nimport { deserializeMd } from '@udecode/plate-markdown';\n\nimport { BlockquoteElementStatic } from './blockquote-element-static';\nimport { CodeBlockElementStatic } from './code-block-element-static';\nimport { CodeLeafStatic } from './code-leaf-static';\nimport { CodeLineElementStatic } from './code-line-element-static';\nimport { CodeSyntaxLeafStatic } from './code-syntax-leaf-static';\nimport { EditorStatic } from './editor-static';\nimport { HeadingElementStatic } from './heading-element-static';\nimport { HrElementStatic } from './hr-element-static';\nimport { LinkElementStatic } from './link-element-static';\nimport { ParagraphElementStatic } from './paragraph-element-static';\n\nconst staticComponents = {\n [BaseBlockquotePlugin.key]: BlockquoteElementStatic,\n [BaseBoldPlugin.key]: withProps(SlateLeaf, { as: 'strong' }),\n [BaseCodeBlockPlugin.key]: CodeBlockElementStatic,\n [BaseCodeLinePlugin.key]: CodeLineElementStatic,\n [BaseCodePlugin.key]: CodeLeafStatic,\n [BaseCodeSyntaxPlugin.key]: CodeSyntaxLeafStatic,\n [BaseHorizontalRulePlugin.key]: HrElementStatic,\n [BaseItalicPlugin.key]: withProps(SlateLeaf, { as: 'em' }),\n [BaseLinkPlugin.key]: LinkElementStatic,\n [BaseParagraphPlugin.key]: ParagraphElementStatic,\n [BaseStrikethroughPlugin.key]: withProps(SlateLeaf, { as: 's' }),\n [BaseUnderlinePlugin.key]: withProps(SlateLeaf, { as: 'u' }),\n [HEADING_KEYS.h1]: withProps(HeadingElementStatic, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElementStatic, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElementStatic, { variant: 'h3' }),\n};\n\nexport const AIChatEditor = memo(\n ({\n aiEditorRef,\n }: {\n aiEditorRef: React.MutableRefObject;\n }) => {\n const { getOptions } = useEditorPlugin(AIChatPlugin);\n const lastAssistantMessage = useLastAssistantMessage();\n const content = lastAssistantMessage?.content ?? '';\n\n const aiEditor = React.useMemo(() => {\n const editor = getOptions().createAIEditor();\n\n const fragment = deserializeMd(editor, content);\n editor.children =\n fragment.length > 0 ? fragment : editor.api.create.value();\n\n return editor;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n React.useEffect(() => {\n if (aiEditor && content) {\n aiEditorRef.current = aiEditor;\n\n setTimeout(() => {\n aiEditor.tf.setValue(deserializeMd(aiEditor, content));\n }, 0);\n }\n }, [aiEditor, aiEditorRef, content]);\n\n if (!content) return null;\n\n return (\n \n );\n }\n);\n", + "content": "'use client';\n\nimport React, { memo } from 'react';\n\nimport { withProps } from '@udecode/cn';\nimport {\n type SlateEditor,\n BaseParagraphPlugin,\n SlateLeaf,\n} from '@udecode/plate';\nimport { useEditorPlugin } from '@udecode/plate/react';\nimport { AIChatPlugin, useLastAssistantMessage } from '@udecode/plate-ai/react';\nimport {\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n} from '@udecode/plate-basic-marks';\nimport { BaseBlockquotePlugin } from '@udecode/plate-block-quote';\nimport {\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodeSyntaxPlugin,\n} from '@udecode/plate-code-block';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { BaseLinkPlugin } from '@udecode/plate-link';\nimport { deserializeMd } from '@udecode/plate-markdown';\n\nimport { BlockquoteElementStatic } from './blockquote-element-static';\nimport { CodeBlockElementStatic } from './code-block-element-static';\nimport { CodeLeafStatic } from './code-leaf-static';\nimport { CodeLineElementStatic } from './code-line-element-static';\nimport { CodeSyntaxLeafStatic } from './code-syntax-leaf-static';\nimport { EditorStatic } from './editor-static';\nimport { HeadingElementStatic } from './heading-element-static';\nimport { HrElementStatic } from './hr-element-static';\nimport { LinkElementStatic } from './link-element-static';\nimport { ParagraphElementStatic } from './paragraph-element-static';\n\nconst staticComponents = {\n [BaseBlockquotePlugin.key]: BlockquoteElementStatic,\n [BaseBoldPlugin.key]: withProps(SlateLeaf, { as: 'strong' }),\n [BaseCodeBlockPlugin.key]: CodeBlockElementStatic,\n [BaseCodeLinePlugin.key]: CodeLineElementStatic,\n [BaseCodePlugin.key]: CodeLeafStatic,\n [BaseCodeSyntaxPlugin.key]: CodeSyntaxLeafStatic,\n [BaseHorizontalRulePlugin.key]: HrElementStatic,\n [BaseItalicPlugin.key]: withProps(SlateLeaf, { as: 'em' }),\n [BaseLinkPlugin.key]: LinkElementStatic,\n [BaseParagraphPlugin.key]: ParagraphElementStatic,\n [BaseStrikethroughPlugin.key]: withProps(SlateLeaf, { as: 's' }),\n [BaseUnderlinePlugin.key]: withProps(SlateLeaf, { as: 'u' }),\n [HEADING_KEYS.h1]: withProps(HeadingElementStatic, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElementStatic, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElementStatic, { variant: 'h3' }),\n};\n\nexport const AIChatEditor = memo(\n ({\n aiEditorRef,\n }: {\n aiEditorRef: React.MutableRefObject;\n }) => {\n const { getOptions } = useEditorPlugin(AIChatPlugin);\n const lastAssistantMessage = useLastAssistantMessage();\n const content = lastAssistantMessage?.content ?? '';\n\n const aiEditor = React.useMemo(() => {\n const editor = getOptions().createAIEditor();\n\n const fragment = deserializeMd(editor, content);\n editor.children =\n fragment.length > 0 ? fragment : editor.api.create.value();\n\n return editor;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n React.useEffect(() => {\n if (aiEditor && content) {\n aiEditorRef.current = aiEditor;\n\n setTimeout(() => {\n aiEditor.tf.setValue(deserializeMd(aiEditor, content));\n }, 0);\n }\n }, [aiEditor, aiEditorRef, content]);\n\n if (!content) return null;\n\n return (\n \n );\n }\n);\n", "path": "plate-ui/ai-chat-editor.tsx", "target": "components/plate-ui/ai-chat-editor.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/ai-plugins.json b/apps/www/public/r/styles/default/ai-plugins.json index 42ad1006a9..96caa86179 100644 --- a/apps/www/public/r/styles/default/ai-plugins.json +++ b/apps/www/public/r/styles/default/ai-plugins.json @@ -11,7 +11,7 @@ ], "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n} from '@udecode/plate-basic-marks';\nimport { BaseBlockquotePlugin } from '@udecode/plate-block-quote';\nimport {\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodeSyntaxPlugin,\n} from '@udecode/plate-code-block';\nimport { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate-common';\nimport { BaseHeadingPlugin, HEADING_LEVELS } from '@udecode/plate-heading';\nimport { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { BaseIndentListPlugin } from '@udecode/plate-indent-list';\nimport { BaseLinkPlugin } from '@udecode/plate-link';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\n\nimport { AIMenu } from '@/components/plate-ui/ai-menu';\nimport {\n TodoLiStatic,\n TodoMarkerStatic,\n} from '@/components/plate-ui/indent-todo-marker-static';\n\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nconst createAIEditor = () => {\n const editor = createSlateEditor({\n id: 'ai',\n plugins: [\n BaseBlockquotePlugin,\n BaseBoldPlugin,\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodePlugin,\n BaseCodeSyntaxPlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n BaseHeadingPlugin,\n BaseHorizontalRulePlugin,\n BaseLinkPlugin,\n BaseParagraphPlugin,\n BaseIndentListPlugin.extend({\n inject: {\n targetPlugins: [\n BaseParagraphPlugin.key,\n ...HEADING_LEVELS,\n BaseBlockquotePlugin.key,\n BaseCodeBlockPlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n todo: {\n liComponent: TodoLiStatic,\n markerComponent: TodoMarkerStatic,\n type: 'todo',\n },\n },\n },\n }),\n MarkdownPlugin.configure({ options: { indentList: true } }),\n ],\n });\n\n return editor;\n};\n\nconst systemCommon = `\\\nYou are an advanced AI-powered note-taking assistant, designed to enhance productivity and creativity in note management.\nRespond directly to user prompts with clear, concise, and relevant content. Maintain a neutral, helpful tone.\n\nRules:\n- is the entire note the user is working on.\n- is a reminder of how you should reply to INSTRUCTIONS. It does not apply to questions.\n- Anything else is the user prompt.\n- Your response should be tailored to the user's prompt, providing precise assistance to optimize note management.\n- For INSTRUCTIONS: Follow the exactly. Provide ONLY the content to be inserted or replaced. No explanations or comments.\n- For QUESTIONS: Provide a helpful and concise answer. You may include brief explanations if necessary.\n- CRITICAL: Distinguish between INSTRUCTIONS and QUESTIONS. Instructions typically ask you to modify or add content. Questions ask for information or clarification.\n`;\n\nconst systemDefault = `\\\n${systemCommon}\n- is the current block of text the user is working on.\n- Ensure your output can seamlessly fit into the existing structure.\n- CRITICAL: Provide only a single block of text. DO NOT create multiple paragraphs or separate blocks.\n\n{block}\n\n`;\n\nconst systemSelecting = `\\\n${systemCommon}\n- is the block of text containing the user's selection, providing context.\n- Ensure your output can seamlessly fit into the existing structure.\n- is the specific text the user has selected in the block and wants to modify or ask about.\n- Consider the context provided by , but only modify . Your response should be a direct replacement for .\n\n{block}\n\n\n{selection}\n\n`;\n\nconst systemBlockSelecting = `\\\n${systemCommon}\n- represents the full blocks of text the user has selected and wants to modify or ask about.\n- Your response should be a direct replacement for the entire .\n- Maintain the overall structure and formatting of the selected blocks, unless explicitly instructed otherwise.\n- CRITICAL: Provide only the content to replace . Do not add additional blocks or change the block structure unless specifically requested.\n\n{block}\n\n`;\n\nconst userDefault = `\nCRITICAL: DO NOT use block formatting. You can only use inline formatting.\nCRITICAL: DO NOT start new lines or paragraphs.\nNEVER write .\n\n{prompt}`;\n\nconst userSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the text to replace . No explanations.\nEnsure it fits seamlessly within . If is empty, write ONE random sentence.\nNEVER write or .\n\n{prompt} about `;\n\nconst userBlockSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the content to replace the entire . No explanations.\nMaintain the overall structure unless instructed otherwise.\nNEVER write or .\n\n{prompt} about `;\n\nexport const PROMPT_TEMPLATES = {\n systemBlockSelecting,\n systemDefault,\n systemSelecting,\n userBlockSelecting,\n userDefault,\n userSelecting,\n};\n\nexport const aiPlugins = [\n cursorOverlayPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n AIPlugin,\n AIChatPlugin.configure({\n options: {\n createAIEditor,\n promptTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.userBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.userSelecting\n : PROMPT_TEMPLATES.userDefault;\n },\n systemTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.systemBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.systemSelecting\n : PROMPT_TEMPLATES.systemDefault;\n },\n },\n render: { afterEditable: () => },\n }),\n] as const;\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { BaseParagraphPlugin, createSlateEditor } from '@udecode/plate';\nimport { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BaseBoldPlugin,\n BaseCodePlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n} from '@udecode/plate-basic-marks';\nimport { BaseBlockquotePlugin } from '@udecode/plate-block-quote';\nimport {\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodeSyntaxPlugin,\n} from '@udecode/plate-code-block';\nimport { BaseHeadingPlugin, HEADING_LEVELS } from '@udecode/plate-heading';\nimport { BaseHorizontalRulePlugin } from '@udecode/plate-horizontal-rule';\nimport { BaseIndentListPlugin } from '@udecode/plate-indent-list';\nimport { BaseLinkPlugin } from '@udecode/plate-link';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\n\nimport { AIMenu } from '@/components/plate-ui/ai-menu';\nimport {\n TodoLiStatic,\n TodoMarkerStatic,\n} from '@/components/plate-ui/indent-todo-marker-static';\n\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nconst createAIEditor = () => {\n const editor = createSlateEditor({\n id: 'ai',\n plugins: [\n BaseBlockquotePlugin,\n BaseBoldPlugin,\n BaseCodeBlockPlugin,\n BaseCodeLinePlugin,\n BaseCodePlugin,\n BaseCodeSyntaxPlugin,\n BaseItalicPlugin,\n BaseStrikethroughPlugin,\n BaseUnderlinePlugin,\n BaseHeadingPlugin,\n BaseHorizontalRulePlugin,\n BaseLinkPlugin,\n BaseParagraphPlugin,\n BaseIndentListPlugin.extend({\n inject: {\n targetPlugins: [\n BaseParagraphPlugin.key,\n ...HEADING_LEVELS,\n BaseBlockquotePlugin.key,\n BaseCodeBlockPlugin.key,\n ],\n },\n options: {\n listStyleTypes: {\n todo: {\n liComponent: TodoLiStatic,\n markerComponent: TodoMarkerStatic,\n type: 'todo',\n },\n },\n },\n }),\n MarkdownPlugin.configure({ options: { indentList: true } }),\n ],\n });\n\n return editor;\n};\n\nconst systemCommon = `\\\nYou are an advanced AI-powered note-taking assistant, designed to enhance productivity and creativity in note management.\nRespond directly to user prompts with clear, concise, and relevant content. Maintain a neutral, helpful tone.\n\nRules:\n- is the entire note the user is working on.\n- is a reminder of how you should reply to INSTRUCTIONS. It does not apply to questions.\n- Anything else is the user prompt.\n- Your response should be tailored to the user's prompt, providing precise assistance to optimize note management.\n- For INSTRUCTIONS: Follow the exactly. Provide ONLY the content to be inserted or replaced. No explanations or comments.\n- For QUESTIONS: Provide a helpful and concise answer. You may include brief explanations if necessary.\n- CRITICAL: Distinguish between INSTRUCTIONS and QUESTIONS. Instructions typically ask you to modify or add content. Questions ask for information or clarification.\n`;\n\nconst systemDefault = `\\\n${systemCommon}\n- is the current block of text the user is working on.\n- Ensure your output can seamlessly fit into the existing structure.\n- CRITICAL: Provide only a single block of text. DO NOT create multiple paragraphs or separate blocks.\n\n{block}\n\n`;\n\nconst systemSelecting = `\\\n${systemCommon}\n- is the block of text containing the user's selection, providing context.\n- Ensure your output can seamlessly fit into the existing structure.\n- is the specific text the user has selected in the block and wants to modify or ask about.\n- Consider the context provided by , but only modify . Your response should be a direct replacement for .\n\n{block}\n\n\n{selection}\n\n`;\n\nconst systemBlockSelecting = `\\\n${systemCommon}\n- represents the full blocks of text the user has selected and wants to modify or ask about.\n- Your response should be a direct replacement for the entire .\n- Maintain the overall structure and formatting of the selected blocks, unless explicitly instructed otherwise.\n- CRITICAL: Provide only the content to replace . Do not add additional blocks or change the block structure unless specifically requested.\n\n{block}\n\n`;\n\nconst userDefault = `\nCRITICAL: DO NOT use block formatting. You can only use inline formatting.\nCRITICAL: DO NOT start new lines or paragraphs.\nNEVER write .\n\n{prompt}`;\n\nconst userSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the text to replace . No explanations.\nEnsure it fits seamlessly within . If is empty, write ONE random sentence.\nNEVER write or .\n\n{prompt} about `;\n\nconst userBlockSelecting = `\nIf this is a question, provide a helpful and concise answer about .\nIf this is an instruction, provide ONLY the content to replace the entire . No explanations.\nMaintain the overall structure unless instructed otherwise.\nNEVER write or .\n\n{prompt} about `;\n\nexport const PROMPT_TEMPLATES = {\n systemBlockSelecting,\n systemDefault,\n systemSelecting,\n userBlockSelecting,\n userDefault,\n userSelecting,\n};\n\nexport const aiPlugins = [\n cursorOverlayPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n AIPlugin,\n AIChatPlugin.configure({\n options: {\n createAIEditor,\n promptTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.userBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.userSelecting\n : PROMPT_TEMPLATES.userDefault;\n },\n systemTemplate: ({ isBlockSelecting, isSelecting }) => {\n return isBlockSelecting\n ? PROMPT_TEMPLATES.systemBlockSelecting\n : isSelecting\n ? PROMPT_TEMPLATES.systemSelecting\n : PROMPT_TEMPLATES.systemDefault;\n },\n },\n render: { afterEditable: () => },\n }),\n] as const;\n", "path": "components/editor/plugins/ai-plugins.tsx", "target": "components/editor/plugins/ai-plugins.tsx", "type": "registry:component" diff --git a/apps/www/public/r/styles/default/ai-toolbar-button.json b/apps/www/public/r/styles/default/ai-toolbar-button.json index 25beec8982..d12fd6f349 100644 --- a/apps/www/public/r/styles/default/ai-toolbar-button.json +++ b/apps/www/public/r/styles/default/ai-toolbar-button.json @@ -21,7 +21,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport { AIChatPlugin } from '@udecode/plate-ai/react';\nimport { useEditorPlugin } from '@udecode/plate-common/react';\n\nimport { ToolbarButton } from './toolbar';\n\nexport const AIToolbarButton = withRef(\n ({ children, ...rest }, ref) => {\n const { api } = useEditorPlugin(AIChatPlugin);\n\n return (\n {\n api.aiChat.show();\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n }}\n >\n {children}\n \n );\n }\n);\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { withRef } from '@udecode/cn';\nimport { useEditorPlugin } from '@udecode/plate/react';\nimport { AIChatPlugin } from '@udecode/plate-ai/react';\n\nimport { ToolbarButton } from './toolbar';\n\nexport const AIToolbarButton = withRef(\n ({ children, ...rest }, ref) => {\n const { api } = useEditorPlugin(AIChatPlugin);\n\n return (\n {\n api.aiChat.show();\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n }}\n >\n {children}\n \n );\n }\n);\n", "path": "plate-ui/ai-toolbar-button.tsx", "target": "components/plate-ui/ai-toolbar-button.tsx", "type": "registry:ui" diff --git a/apps/www/public/r/styles/default/align-demo.json b/apps/www/public/r/styles/default/align-demo.json index a586021964..9215b17e37 100644 --- a/apps/www/public/r/styles/default/align-demo.json +++ b/apps/www/public/r/styles/default/align-demo.json @@ -4,7 +4,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate } from '@udecode/plate-common/react';\n\nimport { editorPlugins } from '@/components/editor/plugins/editor-plugins';\nimport { useCreateEditor } from '@/components/editor/use-create-editor';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nimport { DEMO_VALUES } from './values/demo-values';\n\nexport default function Demo({ id }: { id: string }) {\n const editor = useCreateEditor({\n plugins: [...editorPlugins],\n value: DEMO_VALUES[id],\n });\n\n return (\n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate } from '@udecode/plate/react';\n\nimport { editorPlugins } from '@/components/editor/plugins/editor-plugins';\nimport { useCreateEditor } from '@/components/editor/use-create-editor';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nimport { DEMO_VALUES } from './values/demo-values';\n\nexport default function Demo({ id }: { id: string }) {\n const editor = useCreateEditor({\n plugins: [...editorPlugins],\n value: DEMO_VALUES[id],\n });\n\n return (\n \n \n \n \n \n );\n}\n", "path": "example/demo.tsx", "target": "components/demo.tsx", "type": "registry:example" @@ -16,13 +16,13 @@ "type": "registry:example" }, { - "content": "'use client';\n\nimport type { Value } from '@udecode/plate-common';\n\nimport { withProps } from '@udecode/cn';\nimport { AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n CodeSyntaxPlugin,\n} from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n type CreatePlateEditorOptions,\n ParagraphPlugin,\n PlateLeaf,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { EmojiInputPlugin } from '@udecode/plate-emoji/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport {\n EquationPlugin,\n InlineEquationPlugin,\n} from '@udecode/plate-math/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n MentionInputPlugin,\n MentionPlugin,\n} from '@udecode/plate-mention/react';\nimport { SlashInputPlugin } from '@udecode/plate-slash-command/react';\nimport {\n TableCellHeaderPlugin,\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\n\nimport { AILeaf } from '@/components/plate-ui/ai-leaf';\nimport { BlockquoteElement } from '@/components/plate-ui/blockquote-element';\nimport { CodeBlockElement } from '@/components/plate-ui/code-block-element';\nimport { CodeLeaf } from '@/components/plate-ui/code-leaf';\nimport { CodeLineElement } from '@/components/plate-ui/code-line-element';\nimport { CodeSyntaxLeaf } from '@/components/plate-ui/code-syntax-leaf';\nimport { ColumnElement } from '@/components/plate-ui/column-element';\nimport { ColumnGroupElement } from '@/components/plate-ui/column-group-element';\nimport { CommentLeaf } from '@/components/plate-ui/comment-leaf';\nimport { DateElement } from '@/components/plate-ui/date-element';\nimport { EmojiInputElement } from '@/components/plate-ui/emoji-input-element';\nimport { EquationElement } from '@/components/plate-ui/equation-element';\nimport { HeadingElement } from '@/components/plate-ui/heading-element';\nimport { HighlightLeaf } from '@/components/plate-ui/highlight-leaf';\nimport { HrElement } from '@/components/plate-ui/hr-element';\nimport { ImageElement } from '@/components/plate-ui/image-element';\nimport { InlineEquationElement } from '@/components/plate-ui/inline-equation-element';\nimport { KbdLeaf } from '@/components/plate-ui/kbd-leaf';\nimport { LinkElement } from '@/components/plate-ui/link-element';\nimport { MediaAudioElement } from '@/components/plate-ui/media-audio-element';\nimport { MediaEmbedElement } from '@/components/plate-ui/media-embed-element';\nimport { MediaFileElement } from '@/components/plate-ui/media-file-element';\nimport { MediaPlaceholderElement } from '@/components/plate-ui/media-placeholder-element';\nimport { MediaVideoElement } from '@/components/plate-ui/media-video-element';\nimport { MentionElement } from '@/components/plate-ui/mention-element';\nimport { MentionInputElement } from '@/components/plate-ui/mention-input-element';\nimport { ParagraphElement } from '@/components/plate-ui/paragraph-element';\nimport { withPlaceholders } from '@/components/plate-ui/placeholder';\nimport { SlashInputElement } from '@/components/plate-ui/slash-input-element';\nimport {\n TableCellElement,\n TableCellHeaderElement,\n} from '@/components/plate-ui/table-cell-element';\nimport { TableElement } from '@/components/plate-ui/table-element';\nimport { TableRowElement } from '@/components/plate-ui/table-row-element';\nimport { TocElement } from '@/components/plate-ui/toc-element';\nimport { ToggleElement } from '@/components/plate-ui/toggle-element';\n\nimport { editorPlugins, viewPlugins } from './plugins/editor-plugins';\n\nexport const viewComponents = {\n [AudioPlugin.key]: MediaAudioElement,\n [BlockquotePlugin.key]: BlockquoteElement,\n [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),\n [CodeBlockPlugin.key]: CodeBlockElement,\n [CodeLinePlugin.key]: CodeLineElement,\n [CodePlugin.key]: CodeLeaf,\n [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,\n [ColumnItemPlugin.key]: ColumnElement,\n [ColumnPlugin.key]: ColumnGroupElement,\n [CommentsPlugin.key]: CommentLeaf,\n [DatePlugin.key]: DateElement,\n [EquationPlugin.key]: EquationElement,\n [FilePlugin.key]: MediaFileElement,\n [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }),\n [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }),\n [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }),\n [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }),\n [HighlightPlugin.key]: HighlightLeaf,\n [HorizontalRulePlugin.key]: HrElement,\n [ImagePlugin.key]: ImageElement,\n [InlineEquationPlugin.key]: InlineEquationElement,\n [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }),\n [KbdPlugin.key]: KbdLeaf,\n [LinkPlugin.key]: LinkElement,\n [MediaEmbedPlugin.key]: MediaEmbedElement,\n [MentionPlugin.key]: MentionElement,\n [ParagraphPlugin.key]: ParagraphElement,\n [PlaceholderPlugin.key]: MediaPlaceholderElement,\n [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }),\n [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }),\n [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }),\n [TableCellHeaderPlugin.key]: TableCellHeaderElement,\n [TableCellPlugin.key]: TableCellElement,\n [TablePlugin.key]: TableElement,\n [TableRowPlugin.key]: TableRowElement,\n [TocPlugin.key]: TocElement,\n [TogglePlugin.key]: ToggleElement,\n [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),\n [VideoPlugin.key]: MediaVideoElement,\n};\n\nexport const editorComponents = {\n ...viewComponents,\n [AIPlugin.key]: AILeaf,\n [EmojiInputPlugin.key]: EmojiInputElement,\n [MentionInputPlugin.key]: MentionInputElement,\n [SlashInputPlugin.key]: SlashInputElement,\n};\n\nexport const useCreateEditor = (\n {\n components,\n override,\n readOnly,\n ...options\n }: {\n components?: Record;\n plugins?: any[];\n readOnly?: boolean;\n } & Omit = {},\n deps: any[] = []\n) => {\n return usePlateEditor(\n {\n override: {\n components: {\n ...(readOnly ? viewComponents : withPlaceholders(editorComponents)),\n ...components,\n },\n ...override,\n },\n plugins: (readOnly ? viewPlugins : editorPlugins) as any,\n ...options,\n },\n deps\n );\n};\n", + "content": "'use client';\n\nimport type { Value } from '@udecode/plate';\n\nimport { withProps } from '@udecode/cn';\nimport {\n type CreatePlateEditorOptions,\n ParagraphPlugin,\n PlateLeaf,\n usePlateEditor,\n} from '@udecode/plate/react';\nimport { AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n CodeSyntaxPlugin,\n} from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { EmojiInputPlugin } from '@udecode/plate-emoji/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport {\n EquationPlugin,\n InlineEquationPlugin,\n} from '@udecode/plate-math/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n MentionInputPlugin,\n MentionPlugin,\n} from '@udecode/plate-mention/react';\nimport { SlashInputPlugin } from '@udecode/plate-slash-command/react';\nimport {\n TableCellHeaderPlugin,\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\n\nimport { AILeaf } from '@/components/plate-ui/ai-leaf';\nimport { BlockquoteElement } from '@/components/plate-ui/blockquote-element';\nimport { CodeBlockElement } from '@/components/plate-ui/code-block-element';\nimport { CodeLeaf } from '@/components/plate-ui/code-leaf';\nimport { CodeLineElement } from '@/components/plate-ui/code-line-element';\nimport { CodeSyntaxLeaf } from '@/components/plate-ui/code-syntax-leaf';\nimport { ColumnElement } from '@/components/plate-ui/column-element';\nimport { ColumnGroupElement } from '@/components/plate-ui/column-group-element';\nimport { CommentLeaf } from '@/components/plate-ui/comment-leaf';\nimport { DateElement } from '@/components/plate-ui/date-element';\nimport { EmojiInputElement } from '@/components/plate-ui/emoji-input-element';\nimport { EquationElement } from '@/components/plate-ui/equation-element';\nimport { HeadingElement } from '@/components/plate-ui/heading-element';\nimport { HighlightLeaf } from '@/components/plate-ui/highlight-leaf';\nimport { HrElement } from '@/components/plate-ui/hr-element';\nimport { ImageElement } from '@/components/plate-ui/image-element';\nimport { InlineEquationElement } from '@/components/plate-ui/inline-equation-element';\nimport { KbdLeaf } from '@/components/plate-ui/kbd-leaf';\nimport { LinkElement } from '@/components/plate-ui/link-element';\nimport { MediaAudioElement } from '@/components/plate-ui/media-audio-element';\nimport { MediaEmbedElement } from '@/components/plate-ui/media-embed-element';\nimport { MediaFileElement } from '@/components/plate-ui/media-file-element';\nimport { MediaPlaceholderElement } from '@/components/plate-ui/media-placeholder-element';\nimport { MediaVideoElement } from '@/components/plate-ui/media-video-element';\nimport { MentionElement } from '@/components/plate-ui/mention-element';\nimport { MentionInputElement } from '@/components/plate-ui/mention-input-element';\nimport { ParagraphElement } from '@/components/plate-ui/paragraph-element';\nimport { withPlaceholders } from '@/components/plate-ui/placeholder';\nimport { SlashInputElement } from '@/components/plate-ui/slash-input-element';\nimport {\n TableCellElement,\n TableCellHeaderElement,\n} from '@/components/plate-ui/table-cell-element';\nimport { TableElement } from '@/components/plate-ui/table-element';\nimport { TableRowElement } from '@/components/plate-ui/table-row-element';\nimport { TocElement } from '@/components/plate-ui/toc-element';\nimport { ToggleElement } from '@/components/plate-ui/toggle-element';\n\nimport { editorPlugins, viewPlugins } from './plugins/editor-plugins';\n\nexport const viewComponents = {\n [AudioPlugin.key]: MediaAudioElement,\n [BlockquotePlugin.key]: BlockquoteElement,\n [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),\n [CodeBlockPlugin.key]: CodeBlockElement,\n [CodeLinePlugin.key]: CodeLineElement,\n [CodePlugin.key]: CodeLeaf,\n [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,\n [ColumnItemPlugin.key]: ColumnElement,\n [ColumnPlugin.key]: ColumnGroupElement,\n [CommentsPlugin.key]: CommentLeaf,\n [DatePlugin.key]: DateElement,\n [EquationPlugin.key]: EquationElement,\n [FilePlugin.key]: MediaFileElement,\n [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }),\n [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }),\n [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }),\n [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }),\n [HighlightPlugin.key]: HighlightLeaf,\n [HorizontalRulePlugin.key]: HrElement,\n [ImagePlugin.key]: ImageElement,\n [InlineEquationPlugin.key]: InlineEquationElement,\n [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }),\n [KbdPlugin.key]: KbdLeaf,\n [LinkPlugin.key]: LinkElement,\n [MediaEmbedPlugin.key]: MediaEmbedElement,\n [MentionPlugin.key]: MentionElement,\n [ParagraphPlugin.key]: ParagraphElement,\n [PlaceholderPlugin.key]: MediaPlaceholderElement,\n [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }),\n [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }),\n [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }),\n [TableCellHeaderPlugin.key]: TableCellHeaderElement,\n [TableCellPlugin.key]: TableCellElement,\n [TablePlugin.key]: TableElement,\n [TableRowPlugin.key]: TableRowElement,\n [TocPlugin.key]: TocElement,\n [TogglePlugin.key]: ToggleElement,\n [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),\n [VideoPlugin.key]: MediaVideoElement,\n};\n\nexport const editorComponents = {\n ...viewComponents,\n [AIPlugin.key]: AILeaf,\n [EmojiInputPlugin.key]: EmojiInputElement,\n [MentionInputPlugin.key]: MentionInputElement,\n [SlashInputPlugin.key]: SlashInputElement,\n};\n\nexport const useCreateEditor = (\n {\n components,\n override,\n readOnly,\n ...options\n }: {\n components?: Record;\n plugins?: any[];\n readOnly?: boolean;\n } & Omit = {},\n deps: any[] = []\n) => {\n return usePlateEditor(\n {\n override: {\n components: {\n ...(readOnly ? viewComponents : withPlaceholders(editorComponents)),\n ...components,\n },\n ...override,\n },\n plugins: (readOnly ? viewPlugins : editorPlugins) as any,\n ...options,\n },\n deps\n );\n};\n", "path": "components/editor/use-create-editor.ts", "target": "components/use-create-editor.ts", "type": "registry:example" }, { - "content": "'use client';\n\nimport { CalloutPlugin } from '@udecode/plate-callout/react';\nimport { ParagraphPlugin } from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\n\nimport { FixedToolbarPlugin } from '@/components/editor/plugins/fixed-toolbar-plugin';\nimport { FloatingToolbarPlugin } from '@/components/editor/plugins/floating-toolbar-plugin';\n\nimport { aiPlugins } from './ai-plugins';\nimport { alignPlugin } from './align-plugin';\nimport { autoformatPlugin } from './autoformat-plugin';\nimport { basicNodesPlugins } from './basic-nodes-plugins';\nimport { blockMenuPlugins } from './block-menu-plugins';\nimport { commentsPlugin } from './comments-plugin';\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nimport { deletePlugins } from './delete-plugins';\nimport { dndPlugins } from './dnd-plugins';\nimport { equationPlugins } from './equation-plugins';\nimport { exitBreakPlugin } from './exit-break-plugin';\nimport { indentListPlugins } from './indent-list-plugins';\nimport { lineHeightPlugin } from './line-height-plugin';\nimport { linkPlugin } from './link-plugin';\nimport { mediaPlugins } from './media-plugins';\nimport { mentionPlugin } from './mention-plugin';\nimport { resetBlockTypePlugin } from './reset-block-type-plugin';\nimport { softBreakPlugin } from './soft-break-plugin';\nimport { tablePlugin } from './table-plugin';\nimport { tocPlugin } from './toc-plugin';\n\nexport const viewPlugins = [\n ...basicNodesPlugins,\n HorizontalRulePlugin,\n linkPlugin,\n DatePlugin,\n mentionPlugin,\n tablePlugin,\n TogglePlugin,\n tocPlugin,\n ...mediaPlugins,\n ...equationPlugins,\n CalloutPlugin,\n ColumnPlugin,\n\n // Marks\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n alignPlugin,\n ...indentListPlugins,\n lineHeightPlugin,\n\n // Collaboration\n commentsPlugin,\n] as const;\n\nexport const editorPlugins = [\n // AI\n ...aiPlugins,\n\n // Nodes\n ...viewPlugins,\n\n // Functionality\n SlashPlugin,\n autoformatPlugin,\n cursorOverlayPlugin,\n ...blockMenuPlugins,\n ...dndPlugins,\n EmojiPlugin,\n exitBreakPlugin,\n resetBlockTypePlugin,\n ...deletePlugins,\n softBreakPlugin,\n TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key } }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // UI\n FixedToolbarPlugin,\n FloatingToolbarPlugin,\n];\n", + "content": "'use client';\n\nimport { ParagraphPlugin } from '@udecode/plate/react';\nimport { CalloutPlugin } from '@udecode/plate-callout/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\n\nimport { FixedToolbarPlugin } from '@/components/editor/plugins/fixed-toolbar-plugin';\nimport { FloatingToolbarPlugin } from '@/components/editor/plugins/floating-toolbar-plugin';\n\nimport { aiPlugins } from './ai-plugins';\nimport { alignPlugin } from './align-plugin';\nimport { autoformatPlugin } from './autoformat-plugin';\nimport { basicNodesPlugins } from './basic-nodes-plugins';\nimport { blockMenuPlugins } from './block-menu-plugins';\nimport { commentsPlugin } from './comments-plugin';\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nimport { deletePlugins } from './delete-plugins';\nimport { dndPlugins } from './dnd-plugins';\nimport { equationPlugins } from './equation-plugins';\nimport { exitBreakPlugin } from './exit-break-plugin';\nimport { indentListPlugins } from './indent-list-plugins';\nimport { lineHeightPlugin } from './line-height-plugin';\nimport { linkPlugin } from './link-plugin';\nimport { mediaPlugins } from './media-plugins';\nimport { mentionPlugin } from './mention-plugin';\nimport { resetBlockTypePlugin } from './reset-block-type-plugin';\nimport { softBreakPlugin } from './soft-break-plugin';\nimport { tablePlugin } from './table-plugin';\nimport { tocPlugin } from './toc-plugin';\n\nexport const viewPlugins = [\n ...basicNodesPlugins,\n HorizontalRulePlugin,\n linkPlugin,\n DatePlugin,\n mentionPlugin,\n tablePlugin,\n TogglePlugin,\n tocPlugin,\n ...mediaPlugins,\n ...equationPlugins,\n CalloutPlugin,\n ColumnPlugin,\n\n // Marks\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n alignPlugin,\n ...indentListPlugins,\n lineHeightPlugin,\n\n // Collaboration\n commentsPlugin,\n] as const;\n\nexport const editorPlugins = [\n // AI\n ...aiPlugins,\n\n // Nodes\n ...viewPlugins,\n\n // Functionality\n SlashPlugin,\n autoformatPlugin,\n cursorOverlayPlugin,\n ...blockMenuPlugins,\n ...dndPlugins,\n EmojiPlugin,\n exitBreakPlugin,\n resetBlockTypePlugin,\n ...deletePlugins,\n softBreakPlugin,\n TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key } }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // UI\n FixedToolbarPlugin,\n FloatingToolbarPlugin,\n];\n", "path": "components/editor/plugins/editor-plugins.tsx", "target": "components/editor-plugins.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/align-plugin.json b/apps/www/public/r/styles/default/align-plugin.json index 5a138105c2..b8ddea54bc 100644 --- a/apps/www/public/r/styles/default/align-plugin.json +++ b/apps/www/public/r/styles/default/align-plugin.json @@ -6,7 +6,7 @@ ], "files": [ { - "content": "'use client';\n\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { ParagraphPlugin } from '@udecode/plate-common/react';\nimport { HEADING_LEVELS } from '@udecode/plate-heading';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\n\nexport const alignPlugin = AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n ...HEADING_LEVELS,\n MediaEmbedPlugin.key,\n ImagePlugin.key,\n ],\n },\n});\n", + "content": "'use client';\n\nimport { ParagraphPlugin } from '@udecode/plate/react';\nimport { AlignPlugin } from '@udecode/plate-alignment/react';\nimport { HEADING_LEVELS } from '@udecode/plate-heading';\nimport { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';\n\nexport const alignPlugin = AlignPlugin.extend({\n inject: {\n targetPlugins: [\n ParagraphPlugin.key,\n ...HEADING_LEVELS,\n MediaEmbedPlugin.key,\n ImagePlugin.key,\n ],\n },\n});\n", "path": "components/editor/plugins/align-plugin.ts", "target": "components/editor/plugins/align-plugin.ts", "type": "registry:component" diff --git a/apps/www/public/r/styles/default/autoformat-demo.json b/apps/www/public/r/styles/default/autoformat-demo.json index be4e3cb0f8..a48fbd5e8c 100644 --- a/apps/www/public/r/styles/default/autoformat-demo.json +++ b/apps/www/public/r/styles/default/autoformat-demo.json @@ -5,7 +5,7 @@ }, "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate } from '@udecode/plate-common/react';\n\nimport { editorPlugins } from '@/components/editor/plugins/editor-plugins';\nimport { useCreateEditor } from '@/components/editor/use-create-editor';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nimport { DEMO_VALUES } from './values/demo-values';\n\nexport default function Demo({ id }: { id: string }) {\n const editor = useCreateEditor({\n plugins: [...editorPlugins],\n value: DEMO_VALUES[id],\n });\n\n return (\n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate } from '@udecode/plate/react';\n\nimport { editorPlugins } from '@/components/editor/plugins/editor-plugins';\nimport { useCreateEditor } from '@/components/editor/use-create-editor';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nimport { DEMO_VALUES } from './values/demo-values';\n\nexport default function Demo({ id }: { id: string }) {\n const editor = useCreateEditor({\n plugins: [...editorPlugins],\n value: DEMO_VALUES[id],\n });\n\n return (\n \n \n \n \n \n );\n}\n", "path": "example/demo.tsx", "target": "components/demo.tsx", "type": "registry:example" @@ -17,13 +17,13 @@ "type": "registry:example" }, { - "content": "'use client';\n\nimport type { Value } from '@udecode/plate-common';\n\nimport { withProps } from '@udecode/cn';\nimport { AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n CodeSyntaxPlugin,\n} from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport {\n type CreatePlateEditorOptions,\n ParagraphPlugin,\n PlateLeaf,\n usePlateEditor,\n} from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { EmojiInputPlugin } from '@udecode/plate-emoji/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport {\n EquationPlugin,\n InlineEquationPlugin,\n} from '@udecode/plate-math/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n MentionInputPlugin,\n MentionPlugin,\n} from '@udecode/plate-mention/react';\nimport { SlashInputPlugin } from '@udecode/plate-slash-command/react';\nimport {\n TableCellHeaderPlugin,\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\n\nimport { AILeaf } from '@/components/plate-ui/ai-leaf';\nimport { BlockquoteElement } from '@/components/plate-ui/blockquote-element';\nimport { CodeBlockElement } from '@/components/plate-ui/code-block-element';\nimport { CodeLeaf } from '@/components/plate-ui/code-leaf';\nimport { CodeLineElement } from '@/components/plate-ui/code-line-element';\nimport { CodeSyntaxLeaf } from '@/components/plate-ui/code-syntax-leaf';\nimport { ColumnElement } from '@/components/plate-ui/column-element';\nimport { ColumnGroupElement } from '@/components/plate-ui/column-group-element';\nimport { CommentLeaf } from '@/components/plate-ui/comment-leaf';\nimport { DateElement } from '@/components/plate-ui/date-element';\nimport { EmojiInputElement } from '@/components/plate-ui/emoji-input-element';\nimport { EquationElement } from '@/components/plate-ui/equation-element';\nimport { HeadingElement } from '@/components/plate-ui/heading-element';\nimport { HighlightLeaf } from '@/components/plate-ui/highlight-leaf';\nimport { HrElement } from '@/components/plate-ui/hr-element';\nimport { ImageElement } from '@/components/plate-ui/image-element';\nimport { InlineEquationElement } from '@/components/plate-ui/inline-equation-element';\nimport { KbdLeaf } from '@/components/plate-ui/kbd-leaf';\nimport { LinkElement } from '@/components/plate-ui/link-element';\nimport { MediaAudioElement } from '@/components/plate-ui/media-audio-element';\nimport { MediaEmbedElement } from '@/components/plate-ui/media-embed-element';\nimport { MediaFileElement } from '@/components/plate-ui/media-file-element';\nimport { MediaPlaceholderElement } from '@/components/plate-ui/media-placeholder-element';\nimport { MediaVideoElement } from '@/components/plate-ui/media-video-element';\nimport { MentionElement } from '@/components/plate-ui/mention-element';\nimport { MentionInputElement } from '@/components/plate-ui/mention-input-element';\nimport { ParagraphElement } from '@/components/plate-ui/paragraph-element';\nimport { withPlaceholders } from '@/components/plate-ui/placeholder';\nimport { SlashInputElement } from '@/components/plate-ui/slash-input-element';\nimport {\n TableCellElement,\n TableCellHeaderElement,\n} from '@/components/plate-ui/table-cell-element';\nimport { TableElement } from '@/components/plate-ui/table-element';\nimport { TableRowElement } from '@/components/plate-ui/table-row-element';\nimport { TocElement } from '@/components/plate-ui/toc-element';\nimport { ToggleElement } from '@/components/plate-ui/toggle-element';\n\nimport { editorPlugins, viewPlugins } from './plugins/editor-plugins';\n\nexport const viewComponents = {\n [AudioPlugin.key]: MediaAudioElement,\n [BlockquotePlugin.key]: BlockquoteElement,\n [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),\n [CodeBlockPlugin.key]: CodeBlockElement,\n [CodeLinePlugin.key]: CodeLineElement,\n [CodePlugin.key]: CodeLeaf,\n [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,\n [ColumnItemPlugin.key]: ColumnElement,\n [ColumnPlugin.key]: ColumnGroupElement,\n [CommentsPlugin.key]: CommentLeaf,\n [DatePlugin.key]: DateElement,\n [EquationPlugin.key]: EquationElement,\n [FilePlugin.key]: MediaFileElement,\n [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }),\n [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }),\n [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }),\n [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }),\n [HighlightPlugin.key]: HighlightLeaf,\n [HorizontalRulePlugin.key]: HrElement,\n [ImagePlugin.key]: ImageElement,\n [InlineEquationPlugin.key]: InlineEquationElement,\n [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }),\n [KbdPlugin.key]: KbdLeaf,\n [LinkPlugin.key]: LinkElement,\n [MediaEmbedPlugin.key]: MediaEmbedElement,\n [MentionPlugin.key]: MentionElement,\n [ParagraphPlugin.key]: ParagraphElement,\n [PlaceholderPlugin.key]: MediaPlaceholderElement,\n [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }),\n [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }),\n [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }),\n [TableCellHeaderPlugin.key]: TableCellHeaderElement,\n [TableCellPlugin.key]: TableCellElement,\n [TablePlugin.key]: TableElement,\n [TableRowPlugin.key]: TableRowElement,\n [TocPlugin.key]: TocElement,\n [TogglePlugin.key]: ToggleElement,\n [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),\n [VideoPlugin.key]: MediaVideoElement,\n};\n\nexport const editorComponents = {\n ...viewComponents,\n [AIPlugin.key]: AILeaf,\n [EmojiInputPlugin.key]: EmojiInputElement,\n [MentionInputPlugin.key]: MentionInputElement,\n [SlashInputPlugin.key]: SlashInputElement,\n};\n\nexport const useCreateEditor = (\n {\n components,\n override,\n readOnly,\n ...options\n }: {\n components?: Record;\n plugins?: any[];\n readOnly?: boolean;\n } & Omit = {},\n deps: any[] = []\n) => {\n return usePlateEditor(\n {\n override: {\n components: {\n ...(readOnly ? viewComponents : withPlaceholders(editorComponents)),\n ...components,\n },\n ...override,\n },\n plugins: (readOnly ? viewPlugins : editorPlugins) as any,\n ...options,\n },\n deps\n );\n};\n", + "content": "'use client';\n\nimport type { Value } from '@udecode/plate';\n\nimport { withProps } from '@udecode/cn';\nimport {\n type CreatePlateEditorOptions,\n ParagraphPlugin,\n PlateLeaf,\n usePlateEditor,\n} from '@udecode/plate/react';\nimport { AIPlugin } from '@udecode/plate-ai/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n CodeSyntaxPlugin,\n} from '@udecode/plate-code-block/react';\nimport { CommentsPlugin } from '@udecode/plate-comments/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { EmojiInputPlugin } from '@udecode/plate-emoji/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { TocPlugin } from '@udecode/plate-heading/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react';\nimport { LinkPlugin } from '@udecode/plate-link/react';\nimport {\n EquationPlugin,\n InlineEquationPlugin,\n} from '@udecode/plate-math/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n MediaEmbedPlugin,\n PlaceholderPlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n MentionInputPlugin,\n MentionPlugin,\n} from '@udecode/plate-mention/react';\nimport { SlashInputPlugin } from '@udecode/plate-slash-command/react';\nimport {\n TableCellHeaderPlugin,\n TableCellPlugin,\n TablePlugin,\n TableRowPlugin,\n} from '@udecode/plate-table/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\n\nimport { AILeaf } from '@/components/plate-ui/ai-leaf';\nimport { BlockquoteElement } from '@/components/plate-ui/blockquote-element';\nimport { CodeBlockElement } from '@/components/plate-ui/code-block-element';\nimport { CodeLeaf } from '@/components/plate-ui/code-leaf';\nimport { CodeLineElement } from '@/components/plate-ui/code-line-element';\nimport { CodeSyntaxLeaf } from '@/components/plate-ui/code-syntax-leaf';\nimport { ColumnElement } from '@/components/plate-ui/column-element';\nimport { ColumnGroupElement } from '@/components/plate-ui/column-group-element';\nimport { CommentLeaf } from '@/components/plate-ui/comment-leaf';\nimport { DateElement } from '@/components/plate-ui/date-element';\nimport { EmojiInputElement } from '@/components/plate-ui/emoji-input-element';\nimport { EquationElement } from '@/components/plate-ui/equation-element';\nimport { HeadingElement } from '@/components/plate-ui/heading-element';\nimport { HighlightLeaf } from '@/components/plate-ui/highlight-leaf';\nimport { HrElement } from '@/components/plate-ui/hr-element';\nimport { ImageElement } from '@/components/plate-ui/image-element';\nimport { InlineEquationElement } from '@/components/plate-ui/inline-equation-element';\nimport { KbdLeaf } from '@/components/plate-ui/kbd-leaf';\nimport { LinkElement } from '@/components/plate-ui/link-element';\nimport { MediaAudioElement } from '@/components/plate-ui/media-audio-element';\nimport { MediaEmbedElement } from '@/components/plate-ui/media-embed-element';\nimport { MediaFileElement } from '@/components/plate-ui/media-file-element';\nimport { MediaPlaceholderElement } from '@/components/plate-ui/media-placeholder-element';\nimport { MediaVideoElement } from '@/components/plate-ui/media-video-element';\nimport { MentionElement } from '@/components/plate-ui/mention-element';\nimport { MentionInputElement } from '@/components/plate-ui/mention-input-element';\nimport { ParagraphElement } from '@/components/plate-ui/paragraph-element';\nimport { withPlaceholders } from '@/components/plate-ui/placeholder';\nimport { SlashInputElement } from '@/components/plate-ui/slash-input-element';\nimport {\n TableCellElement,\n TableCellHeaderElement,\n} from '@/components/plate-ui/table-cell-element';\nimport { TableElement } from '@/components/plate-ui/table-element';\nimport { TableRowElement } from '@/components/plate-ui/table-row-element';\nimport { TocElement } from '@/components/plate-ui/toc-element';\nimport { ToggleElement } from '@/components/plate-ui/toggle-element';\n\nimport { editorPlugins, viewPlugins } from './plugins/editor-plugins';\n\nexport const viewComponents = {\n [AudioPlugin.key]: MediaAudioElement,\n [BlockquotePlugin.key]: BlockquoteElement,\n [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),\n [CodeBlockPlugin.key]: CodeBlockElement,\n [CodeLinePlugin.key]: CodeLineElement,\n [CodePlugin.key]: CodeLeaf,\n [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,\n [ColumnItemPlugin.key]: ColumnElement,\n [ColumnPlugin.key]: ColumnGroupElement,\n [CommentsPlugin.key]: CommentLeaf,\n [DatePlugin.key]: DateElement,\n [EquationPlugin.key]: EquationElement,\n [FilePlugin.key]: MediaFileElement,\n [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }),\n [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }),\n [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }),\n [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }),\n [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }),\n [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }),\n [HighlightPlugin.key]: HighlightLeaf,\n [HorizontalRulePlugin.key]: HrElement,\n [ImagePlugin.key]: ImageElement,\n [InlineEquationPlugin.key]: InlineEquationElement,\n [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }),\n [KbdPlugin.key]: KbdLeaf,\n [LinkPlugin.key]: LinkElement,\n [MediaEmbedPlugin.key]: MediaEmbedElement,\n [MentionPlugin.key]: MentionElement,\n [ParagraphPlugin.key]: ParagraphElement,\n [PlaceholderPlugin.key]: MediaPlaceholderElement,\n [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }),\n [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }),\n [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }),\n [TableCellHeaderPlugin.key]: TableCellHeaderElement,\n [TableCellPlugin.key]: TableCellElement,\n [TablePlugin.key]: TableElement,\n [TableRowPlugin.key]: TableRowElement,\n [TocPlugin.key]: TocElement,\n [TogglePlugin.key]: ToggleElement,\n [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),\n [VideoPlugin.key]: MediaVideoElement,\n};\n\nexport const editorComponents = {\n ...viewComponents,\n [AIPlugin.key]: AILeaf,\n [EmojiInputPlugin.key]: EmojiInputElement,\n [MentionInputPlugin.key]: MentionInputElement,\n [SlashInputPlugin.key]: SlashInputElement,\n};\n\nexport const useCreateEditor = (\n {\n components,\n override,\n readOnly,\n ...options\n }: {\n components?: Record;\n plugins?: any[];\n readOnly?: boolean;\n } & Omit = {},\n deps: any[] = []\n) => {\n return usePlateEditor(\n {\n override: {\n components: {\n ...(readOnly ? viewComponents : withPlaceholders(editorComponents)),\n ...components,\n },\n ...override,\n },\n plugins: (readOnly ? viewPlugins : editorPlugins) as any,\n ...options,\n },\n deps\n );\n};\n", "path": "components/editor/use-create-editor.ts", "target": "components/use-create-editor.ts", "type": "registry:example" }, { - "content": "'use client';\n\nimport { CalloutPlugin } from '@udecode/plate-callout/react';\nimport { ParagraphPlugin } from '@udecode/plate-common/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\n\nimport { FixedToolbarPlugin } from '@/components/editor/plugins/fixed-toolbar-plugin';\nimport { FloatingToolbarPlugin } from '@/components/editor/plugins/floating-toolbar-plugin';\n\nimport { aiPlugins } from './ai-plugins';\nimport { alignPlugin } from './align-plugin';\nimport { autoformatPlugin } from './autoformat-plugin';\nimport { basicNodesPlugins } from './basic-nodes-plugins';\nimport { blockMenuPlugins } from './block-menu-plugins';\nimport { commentsPlugin } from './comments-plugin';\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nimport { deletePlugins } from './delete-plugins';\nimport { dndPlugins } from './dnd-plugins';\nimport { equationPlugins } from './equation-plugins';\nimport { exitBreakPlugin } from './exit-break-plugin';\nimport { indentListPlugins } from './indent-list-plugins';\nimport { lineHeightPlugin } from './line-height-plugin';\nimport { linkPlugin } from './link-plugin';\nimport { mediaPlugins } from './media-plugins';\nimport { mentionPlugin } from './mention-plugin';\nimport { resetBlockTypePlugin } from './reset-block-type-plugin';\nimport { softBreakPlugin } from './soft-break-plugin';\nimport { tablePlugin } from './table-plugin';\nimport { tocPlugin } from './toc-plugin';\n\nexport const viewPlugins = [\n ...basicNodesPlugins,\n HorizontalRulePlugin,\n linkPlugin,\n DatePlugin,\n mentionPlugin,\n tablePlugin,\n TogglePlugin,\n tocPlugin,\n ...mediaPlugins,\n ...equationPlugins,\n CalloutPlugin,\n ColumnPlugin,\n\n // Marks\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n alignPlugin,\n ...indentListPlugins,\n lineHeightPlugin,\n\n // Collaboration\n commentsPlugin,\n] as const;\n\nexport const editorPlugins = [\n // AI\n ...aiPlugins,\n\n // Nodes\n ...viewPlugins,\n\n // Functionality\n SlashPlugin,\n autoformatPlugin,\n cursorOverlayPlugin,\n ...blockMenuPlugins,\n ...dndPlugins,\n EmojiPlugin,\n exitBreakPlugin,\n resetBlockTypePlugin,\n ...deletePlugins,\n softBreakPlugin,\n TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key } }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // UI\n FixedToolbarPlugin,\n FloatingToolbarPlugin,\n];\n", + "content": "'use client';\n\nimport { ParagraphPlugin } from '@udecode/plate/react';\nimport { CalloutPlugin } from '@udecode/plate-callout/react';\nimport { DatePlugin } from '@udecode/plate-date/react';\nimport { DocxPlugin } from '@udecode/plate-docx';\nimport { EmojiPlugin } from '@udecode/plate-emoji/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n FontSizePlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { JuicePlugin } from '@udecode/plate-juice';\nimport { KbdPlugin } from '@udecode/plate-kbd/react';\nimport { ColumnPlugin } from '@udecode/plate-layout/react';\nimport { MarkdownPlugin } from '@udecode/plate-markdown';\nimport { SlashPlugin } from '@udecode/plate-slash-command/react';\nimport { TogglePlugin } from '@udecode/plate-toggle/react';\nimport { TrailingBlockPlugin } from '@udecode/plate-trailing-block';\n\nimport { FixedToolbarPlugin } from '@/components/editor/plugins/fixed-toolbar-plugin';\nimport { FloatingToolbarPlugin } from '@/components/editor/plugins/floating-toolbar-plugin';\n\nimport { aiPlugins } from './ai-plugins';\nimport { alignPlugin } from './align-plugin';\nimport { autoformatPlugin } from './autoformat-plugin';\nimport { basicNodesPlugins } from './basic-nodes-plugins';\nimport { blockMenuPlugins } from './block-menu-plugins';\nimport { commentsPlugin } from './comments-plugin';\nimport { cursorOverlayPlugin } from './cursor-overlay-plugin';\nimport { deletePlugins } from './delete-plugins';\nimport { dndPlugins } from './dnd-plugins';\nimport { equationPlugins } from './equation-plugins';\nimport { exitBreakPlugin } from './exit-break-plugin';\nimport { indentListPlugins } from './indent-list-plugins';\nimport { lineHeightPlugin } from './line-height-plugin';\nimport { linkPlugin } from './link-plugin';\nimport { mediaPlugins } from './media-plugins';\nimport { mentionPlugin } from './mention-plugin';\nimport { resetBlockTypePlugin } from './reset-block-type-plugin';\nimport { softBreakPlugin } from './soft-break-plugin';\nimport { tablePlugin } from './table-plugin';\nimport { tocPlugin } from './toc-plugin';\n\nexport const viewPlugins = [\n ...basicNodesPlugins,\n HorizontalRulePlugin,\n linkPlugin,\n DatePlugin,\n mentionPlugin,\n tablePlugin,\n TogglePlugin,\n tocPlugin,\n ...mediaPlugins,\n ...equationPlugins,\n CalloutPlugin,\n ColumnPlugin,\n\n // Marks\n FontColorPlugin,\n FontBackgroundColorPlugin,\n FontSizePlugin,\n HighlightPlugin,\n KbdPlugin,\n\n // Block Style\n alignPlugin,\n ...indentListPlugins,\n lineHeightPlugin,\n\n // Collaboration\n commentsPlugin,\n] as const;\n\nexport const editorPlugins = [\n // AI\n ...aiPlugins,\n\n // Nodes\n ...viewPlugins,\n\n // Functionality\n SlashPlugin,\n autoformatPlugin,\n cursorOverlayPlugin,\n ...blockMenuPlugins,\n ...dndPlugins,\n EmojiPlugin,\n exitBreakPlugin,\n resetBlockTypePlugin,\n ...deletePlugins,\n softBreakPlugin,\n TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key } }),\n\n // Deserialization\n DocxPlugin,\n MarkdownPlugin.configure({ options: { indentList: true } }),\n JuicePlugin,\n\n // UI\n FixedToolbarPlugin,\n FloatingToolbarPlugin,\n];\n", "path": "components/editor/plugins/editor-plugins.tsx", "target": "components/editor-plugins.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/autoformat-list-plugin.json b/apps/www/public/r/styles/default/autoformat-list-plugin.json index b6c3b0d956..825545eb41 100644 --- a/apps/www/public/r/styles/default/autoformat-list-plugin.json +++ b/apps/www/public/r/styles/default/autoformat-list-plugin.json @@ -12,7 +12,7 @@ ], "files": [ { - "content": "'use client';\n\nimport type {\n AutoformatBlockRule,\n AutoformatRule,\n} from '@udecode/plate-autoformat';\nimport type { SlateEditor } from '@udecode/plate-common';\nimport type { TTodoListItemElement } from '@udecode/plate-list';\n\nimport {\n autoformatArrow,\n autoformatLegal,\n autoformatLegalHtml,\n autoformatMath,\n autoformatPunctuation,\n autoformatSmartQuotes,\n} from '@udecode/plate-autoformat';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { insertEmptyCodeBlock } from '@udecode/plate-code-block';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n} from '@udecode/plate-code-block/react';\nimport {\n getParentNode,\n insertNodes,\n isBlock,\n isElement,\n isType,\n setNodes,\n} from '@udecode/plate-common';\nimport { ParagraphPlugin } from '@udecode/plate-common/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { toggleList, unwrapList } from '@udecode/plate-list';\nimport {\n BulletedListPlugin,\n ListItemPlugin,\n NumberedListPlugin,\n TodoListPlugin,\n} from '@udecode/plate-list/react';\nimport { TogglePlugin, openNextToggles } from '@udecode/plate-toggle/react';\n\nexport const preFormat: AutoformatBlockRule['preFormat'] = (editor) =>\n unwrapList(editor);\n\nexport const format = (editor: SlateEditor, customFormatting: any) => {\n if (editor.selection) {\n const parentEntry = getParentNode(editor, editor.selection);\n\n if (!parentEntry) return;\n\n const [node] = parentEntry;\n\n if (\n isElement(node) &&\n !isType(editor, node, CodeBlockPlugin.key) &&\n !isType(editor, node, CodeLinePlugin.key)\n ) {\n customFormatting();\n }\n }\n};\n\nexport const formatList = (editor: SlateEditor, elementType: string) => {\n format(editor, () =>\n toggleList(editor, {\n type: elementType,\n })\n );\n};\n\nexport const autoformatMarks: AutoformatRule[] = [\n {\n match: '***',\n mode: 'mark',\n type: [BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '__*',\n mode: 'mark',\n type: [UnderlinePlugin.key, ItalicPlugin.key],\n },\n {\n match: '__**',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key],\n },\n {\n match: '___***',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '**',\n mode: 'mark',\n type: BoldPlugin.key,\n },\n {\n match: '__',\n mode: 'mark',\n type: UnderlinePlugin.key,\n },\n {\n match: '*',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '_',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '~~',\n mode: 'mark',\n type: StrikethroughPlugin.key,\n },\n {\n match: '^',\n mode: 'mark',\n type: SuperscriptPlugin.key,\n },\n {\n match: '~',\n mode: 'mark',\n type: SubscriptPlugin.key,\n },\n {\n match: '==',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '≡',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '`',\n mode: 'mark',\n type: CodePlugin.key,\n },\n];\n\nexport const autoformatBlocks: AutoformatRule[] = [\n {\n match: '# ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h1,\n },\n {\n match: '## ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h2,\n },\n {\n match: '### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h3,\n },\n {\n match: '#### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h4,\n },\n {\n match: '##### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h5,\n },\n {\n match: '###### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h6,\n },\n {\n match: '> ',\n mode: 'block',\n preFormat,\n type: BlockquotePlugin.key,\n },\n {\n format: (editor) => {\n insertEmptyCodeBlock(editor, {\n defaultType: ParagraphPlugin.key,\n insertNodesOptions: { select: true },\n });\n },\n match: '```',\n mode: 'block',\n preFormat,\n triggerAtBlockStart: false,\n type: CodeBlockPlugin.key,\n },\n {\n match: '+ ',\n mode: 'block',\n preFormat: openNextToggles,\n type: TogglePlugin.key,\n },\n {\n format: (editor) => {\n setNodes(editor, { type: HorizontalRulePlugin.key });\n insertNodes(editor, {\n children: [{ text: '' }],\n type: ParagraphPlugin.key,\n });\n },\n match: ['---', '—-', '___ '],\n mode: 'block',\n type: HorizontalRulePlugin.key,\n },\n];\n\nexport const autoformatLists: AutoformatRule[] = [\n {\n format: (editor) => formatList(editor, BulletedListPlugin.key),\n match: ['* ', '- '],\n mode: 'block',\n preFormat,\n type: ListItemPlugin.key,\n },\n {\n format: (editor) => formatList(editor, NumberedListPlugin.key),\n match: [String.raw`^\\d+\\.$ `, String.raw`^\\d+\\)$ `],\n matchByRegex: true,\n mode: 'block',\n preFormat,\n type: ListItemPlugin.key,\n },\n {\n match: '[] ',\n mode: 'block',\n type: TodoListPlugin.key,\n },\n {\n format: (editor) =>\n setNodes(\n editor,\n { checked: true, type: TodoListPlugin.key },\n {\n match: (n) => isBlock(editor, n),\n }\n ),\n match: '[x] ',\n mode: 'block',\n type: TodoListPlugin.key,\n },\n];\n\nexport const autoformatListPlugin = AutoformatPlugin.configure({\n options: {\n enableUndoOnDelete: true,\n rules: [\n ...autoformatBlocks,\n ...autoformatMarks,\n ...autoformatSmartQuotes,\n ...autoformatPunctuation,\n ...autoformatLegal,\n ...autoformatLegalHtml,\n ...autoformatArrow,\n ...autoformatMath,\n ...autoformatLists,\n ],\n },\n});\n", + "content": "'use client';\n\nimport type { SlateEditor } from '@udecode/plate';\nimport type {\n AutoformatBlockRule,\n AutoformatRule,\n} from '@udecode/plate-autoformat';\n\nimport { ElementApi, isType } from '@udecode/plate';\nimport { ParagraphPlugin } from '@udecode/plate/react';\nimport {\n autoformatArrow,\n autoformatLegal,\n autoformatLegalHtml,\n autoformatMath,\n autoformatPunctuation,\n autoformatSmartQuotes,\n} from '@udecode/plate-autoformat';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { insertEmptyCodeBlock } from '@udecode/plate-code-block';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n} from '@udecode/plate-code-block/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport { toggleList, unwrapList } from '@udecode/plate-list';\nimport {\n BulletedListPlugin,\n ListItemPlugin,\n NumberedListPlugin,\n TodoListPlugin,\n} from '@udecode/plate-list/react';\nimport { TogglePlugin, openNextToggles } from '@udecode/plate-toggle/react';\n\nexport const preFormat: AutoformatBlockRule['preFormat'] = (editor) =>\n unwrapList(editor);\n\nexport const format = (editor: SlateEditor, customFormatting: any) => {\n if (editor.selection) {\n const parentEntry = editor.api.parent(editor.selection);\n\n if (!parentEntry) return;\n\n const [node] = parentEntry;\n\n if (\n ElementApi.isElement(node) &&\n !isType(editor, node, CodeBlockPlugin.key) &&\n !isType(editor, node, CodeLinePlugin.key)\n ) {\n customFormatting();\n }\n }\n};\n\nexport const formatList = (editor: SlateEditor, elementType: string) => {\n format(editor, () =>\n toggleList(editor, {\n type: elementType,\n })\n );\n};\n\nexport const autoformatMarks: AutoformatRule[] = [\n {\n match: '***',\n mode: 'mark',\n type: [BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '__*',\n mode: 'mark',\n type: [UnderlinePlugin.key, ItalicPlugin.key],\n },\n {\n match: '__**',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key],\n },\n {\n match: '___***',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '**',\n mode: 'mark',\n type: BoldPlugin.key,\n },\n {\n match: '__',\n mode: 'mark',\n type: UnderlinePlugin.key,\n },\n {\n match: '*',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '_',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '~~',\n mode: 'mark',\n type: StrikethroughPlugin.key,\n },\n {\n match: '^',\n mode: 'mark',\n type: SuperscriptPlugin.key,\n },\n {\n match: '~',\n mode: 'mark',\n type: SubscriptPlugin.key,\n },\n {\n match: '==',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '≡',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '`',\n mode: 'mark',\n type: CodePlugin.key,\n },\n];\n\nexport const autoformatBlocks: AutoformatRule[] = [\n {\n match: '# ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h1,\n },\n {\n match: '## ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h2,\n },\n {\n match: '### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h3,\n },\n {\n match: '#### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h4,\n },\n {\n match: '##### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h5,\n },\n {\n match: '###### ',\n mode: 'block',\n preFormat,\n type: HEADING_KEYS.h6,\n },\n {\n match: '> ',\n mode: 'block',\n preFormat,\n type: BlockquotePlugin.key,\n },\n {\n format: (editor) => {\n insertEmptyCodeBlock(editor, {\n defaultType: ParagraphPlugin.key,\n insertNodesOptions: { select: true },\n });\n },\n match: '```',\n mode: 'block',\n preFormat,\n triggerAtBlockStart: false,\n type: CodeBlockPlugin.key,\n },\n {\n match: '+ ',\n mode: 'block',\n preFormat: openNextToggles,\n type: TogglePlugin.key,\n },\n {\n format: (editor) => {\n editor.tf.setNodes({ type: HorizontalRulePlugin.key });\n editor.tf.insertNodes({\n children: [{ text: '' }],\n type: ParagraphPlugin.key,\n });\n },\n match: ['---', '—-', '___ '],\n mode: 'block',\n type: HorizontalRulePlugin.key,\n },\n];\n\nexport const autoformatLists: AutoformatRule[] = [\n {\n format: (editor) => formatList(editor, BulletedListPlugin.key),\n match: ['* ', '- '],\n mode: 'block',\n preFormat,\n type: ListItemPlugin.key,\n },\n {\n format: (editor) => formatList(editor, NumberedListPlugin.key),\n match: [String.raw`^\\d+\\.$ `, String.raw`^\\d+\\)$ `],\n matchByRegex: true,\n mode: 'block',\n preFormat,\n type: ListItemPlugin.key,\n },\n {\n match: '[] ',\n mode: 'block',\n type: TodoListPlugin.key,\n },\n {\n format: (editor) =>\n editor.tf.setNodes(\n { checked: true, type: TodoListPlugin.key },\n {\n match: (n) => editor.api.isBlock(n),\n }\n ),\n match: '[x] ',\n mode: 'block',\n type: TodoListPlugin.key,\n },\n];\n\nexport const autoformatListPlugin = AutoformatPlugin.configure({\n options: {\n enableUndoOnDelete: true,\n rules: [\n ...autoformatBlocks,\n ...autoformatMarks,\n ...autoformatSmartQuotes,\n ...autoformatPunctuation,\n ...autoformatLegal,\n ...autoformatLegalHtml,\n ...autoformatArrow,\n ...autoformatMath,\n ...autoformatLists,\n ],\n },\n});\n", "path": "components/editor/plugins/autoformat-list-plugin.ts", "target": "components/editor/plugins/autoformat-list-plugin.ts", "type": "registry:component" diff --git a/apps/www/public/r/styles/default/autoformat-plugin.json b/apps/www/public/r/styles/default/autoformat-plugin.json index 5c4e50489c..03b3029881 100644 --- a/apps/www/public/r/styles/default/autoformat-plugin.json +++ b/apps/www/public/r/styles/default/autoformat-plugin.json @@ -12,7 +12,7 @@ ], "files": [ { - "content": "'use client';\n\nimport type { AutoformatRule } from '@udecode/plate-autoformat';\nimport type { SlateEditor } from '@udecode/plate-common';\n\nimport {\n autoformatArrow,\n autoformatLegal,\n autoformatLegalHtml,\n autoformatMath,\n autoformatPunctuation,\n autoformatSmartQuotes,\n} from '@udecode/plate-autoformat';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { insertEmptyCodeBlock } from '@udecode/plate-code-block';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n} from '@udecode/plate-code-block/react';\nimport {\n getParentNode,\n insertNodes,\n isElement,\n isType,\n setNodes,\n} from '@udecode/plate-common';\nimport { ParagraphPlugin } from '@udecode/plate-common/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport {\n INDENT_LIST_KEYS,\n ListStyleType,\n toggleIndentList,\n} from '@udecode/plate-indent-list';\nimport { TogglePlugin, openNextToggles } from '@udecode/plate-toggle/react';\n\nexport const format = (editor: SlateEditor, customFormatting: any) => {\n if (editor.selection) {\n const parentEntry = getParentNode(editor, editor.selection);\n\n if (!parentEntry) return;\n\n const [node] = parentEntry;\n\n if (\n isElement(node) &&\n !isType(editor, node, CodeBlockPlugin.key) &&\n !isType(editor, node, CodeLinePlugin.key)\n ) {\n customFormatting();\n }\n }\n};\n\nexport const autoformatMarks: AutoformatRule[] = [\n {\n match: '***',\n mode: 'mark',\n type: [BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '__*',\n mode: 'mark',\n type: [UnderlinePlugin.key, ItalicPlugin.key],\n },\n {\n match: '__**',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key],\n },\n {\n match: '___***',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '**',\n mode: 'mark',\n type: BoldPlugin.key,\n },\n {\n match: '__',\n mode: 'mark',\n type: UnderlinePlugin.key,\n },\n {\n match: '*',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '_',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '~~',\n mode: 'mark',\n type: StrikethroughPlugin.key,\n },\n {\n match: '^',\n mode: 'mark',\n type: SuperscriptPlugin.key,\n },\n {\n match: '~',\n mode: 'mark',\n type: SubscriptPlugin.key,\n },\n {\n match: '==',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '≡',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '`',\n mode: 'mark',\n type: CodePlugin.key,\n },\n];\n\nexport const autoformatBlocks: AutoformatRule[] = [\n {\n match: '# ',\n mode: 'block',\n type: HEADING_KEYS.h1,\n },\n {\n match: '## ',\n mode: 'block',\n type: HEADING_KEYS.h2,\n },\n {\n match: '### ',\n mode: 'block',\n type: HEADING_KEYS.h3,\n },\n {\n match: '#### ',\n mode: 'block',\n type: HEADING_KEYS.h4,\n },\n {\n match: '##### ',\n mode: 'block',\n type: HEADING_KEYS.h5,\n },\n {\n match: '###### ',\n mode: 'block',\n type: HEADING_KEYS.h6,\n },\n {\n match: '> ',\n mode: 'block',\n type: BlockquotePlugin.key,\n },\n {\n format: (editor) => {\n insertEmptyCodeBlock(editor, {\n defaultType: ParagraphPlugin.key,\n insertNodesOptions: { select: true },\n });\n },\n match: '```',\n mode: 'block',\n triggerAtBlockStart: false,\n type: CodeBlockPlugin.key,\n },\n {\n match: '+ ',\n mode: 'block',\n preFormat: openNextToggles,\n type: TogglePlugin.key,\n },\n {\n format: (editor) => {\n setNodes(editor, { type: HorizontalRulePlugin.key });\n insertNodes(editor, {\n children: [{ text: '' }],\n type: ParagraphPlugin.key,\n });\n },\n match: ['---', '—-', '___ '],\n mode: 'block',\n type: HorizontalRulePlugin.key,\n },\n];\n\nexport const autoformatIndentLists: AutoformatRule[] = [\n {\n format: (editor) => {\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Disc,\n });\n },\n match: ['* ', '- '],\n mode: 'block',\n type: 'list',\n },\n {\n format: (editor) =>\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Decimal,\n }),\n match: [String.raw`^\\d+\\.$ `, String.raw`^\\d+\\)$ `],\n matchByRegex: true,\n mode: 'block',\n type: 'list',\n },\n {\n format: (editor) => {\n toggleIndentList(editor, {\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n setNodes(editor, {\n checked: false,\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n },\n match: ['[] '],\n mode: 'block',\n type: 'list',\n },\n {\n format: (editor) => {\n toggleIndentList(editor, {\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n setNodes(editor, {\n checked: true,\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n },\n match: ['[x] '],\n mode: 'block',\n type: 'list',\n },\n];\n\nexport const autoformatPlugin = AutoformatPlugin.configure({\n options: {\n enableUndoOnDelete: true,\n rules: [\n ...autoformatBlocks,\n ...autoformatMarks,\n ...autoformatSmartQuotes,\n ...autoformatPunctuation,\n ...autoformatLegal,\n ...autoformatLegalHtml,\n ...autoformatArrow,\n ...autoformatMath,\n ...autoformatIndentLists,\n ],\n },\n});\n", + "content": "'use client';\n\nimport type { SlateEditor } from '@udecode/plate';\nimport type { AutoformatRule } from '@udecode/plate-autoformat';\n\nimport { ElementApi, isType } from '@udecode/plate';\nimport { ParagraphPlugin } from '@udecode/plate/react';\nimport {\n autoformatArrow,\n autoformatLegal,\n autoformatLegalHtml,\n autoformatMath,\n autoformatPunctuation,\n autoformatSmartQuotes,\n} from '@udecode/plate-autoformat';\nimport { AutoformatPlugin } from '@udecode/plate-autoformat/react';\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n SubscriptPlugin,\n SuperscriptPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { BlockquotePlugin } from '@udecode/plate-block-quote/react';\nimport { insertEmptyCodeBlock } from '@udecode/plate-code-block';\nimport {\n CodeBlockPlugin,\n CodeLinePlugin,\n} from '@udecode/plate-code-block/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';\nimport {\n INDENT_LIST_KEYS,\n ListStyleType,\n toggleIndentList,\n} from '@udecode/plate-indent-list';\nimport { TogglePlugin, openNextToggles } from '@udecode/plate-toggle/react';\n\nexport const format = (editor: SlateEditor, customFormatting: any) => {\n if (editor.selection) {\n const parentEntry = editor.api.parent(editor.selection);\n\n if (!parentEntry) return;\n\n const [node] = parentEntry;\n\n if (\n ElementApi.isElement(node) &&\n !isType(editor, node, CodeBlockPlugin.key) &&\n !isType(editor, node, CodeLinePlugin.key)\n ) {\n customFormatting();\n }\n }\n};\n\nexport const autoformatMarks: AutoformatRule[] = [\n {\n match: '***',\n mode: 'mark',\n type: [BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '__*',\n mode: 'mark',\n type: [UnderlinePlugin.key, ItalicPlugin.key],\n },\n {\n match: '__**',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key],\n },\n {\n match: '___***',\n mode: 'mark',\n type: [UnderlinePlugin.key, BoldPlugin.key, ItalicPlugin.key],\n },\n {\n match: '**',\n mode: 'mark',\n type: BoldPlugin.key,\n },\n {\n match: '__',\n mode: 'mark',\n type: UnderlinePlugin.key,\n },\n {\n match: '*',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '_',\n mode: 'mark',\n type: ItalicPlugin.key,\n },\n {\n match: '~~',\n mode: 'mark',\n type: StrikethroughPlugin.key,\n },\n {\n match: '^',\n mode: 'mark',\n type: SuperscriptPlugin.key,\n },\n {\n match: '~',\n mode: 'mark',\n type: SubscriptPlugin.key,\n },\n {\n match: '==',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '≡',\n mode: 'mark',\n type: HighlightPlugin.key,\n },\n {\n match: '`',\n mode: 'mark',\n type: CodePlugin.key,\n },\n];\n\nexport const autoformatBlocks: AutoformatRule[] = [\n {\n match: '# ',\n mode: 'block',\n type: HEADING_KEYS.h1,\n },\n {\n match: '## ',\n mode: 'block',\n type: HEADING_KEYS.h2,\n },\n {\n match: '### ',\n mode: 'block',\n type: HEADING_KEYS.h3,\n },\n {\n match: '#### ',\n mode: 'block',\n type: HEADING_KEYS.h4,\n },\n {\n match: '##### ',\n mode: 'block',\n type: HEADING_KEYS.h5,\n },\n {\n match: '###### ',\n mode: 'block',\n type: HEADING_KEYS.h6,\n },\n {\n match: '> ',\n mode: 'block',\n type: BlockquotePlugin.key,\n },\n {\n format: (editor) => {\n insertEmptyCodeBlock(editor, {\n defaultType: ParagraphPlugin.key,\n insertNodesOptions: { select: true },\n });\n },\n match: '```',\n mode: 'block',\n triggerAtBlockStart: false,\n type: CodeBlockPlugin.key,\n },\n {\n match: '+ ',\n mode: 'block',\n preFormat: openNextToggles,\n type: TogglePlugin.key,\n },\n {\n format: (editor) => {\n editor.tf.setNodes({ type: HorizontalRulePlugin.key });\n editor.tf.insertNodes({\n children: [{ text: '' }],\n type: ParagraphPlugin.key,\n });\n },\n match: ['---', '—-', '___ '],\n mode: 'block',\n type: HorizontalRulePlugin.key,\n },\n];\n\nexport const autoformatIndentLists: AutoformatRule[] = [\n {\n format: (editor) => {\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Disc,\n });\n },\n match: ['* ', '- '],\n mode: 'block',\n type: 'list',\n },\n {\n format: (editor) =>\n toggleIndentList(editor, {\n listStyleType: ListStyleType.Decimal,\n }),\n match: [String.raw`^\\d+\\.$ `, String.raw`^\\d+\\)$ `],\n matchByRegex: true,\n mode: 'block',\n type: 'list',\n },\n {\n format: (editor) => {\n toggleIndentList(editor, {\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n editor.tf.setNodes({\n checked: false,\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n },\n match: ['[] '],\n mode: 'block',\n type: 'list',\n },\n {\n format: (editor) => {\n toggleIndentList(editor, {\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n editor.tf.setNodes({\n checked: true,\n listStyleType: INDENT_LIST_KEYS.todo,\n });\n },\n match: ['[x] '],\n mode: 'block',\n type: 'list',\n },\n];\n\nexport const autoformatPlugin = AutoformatPlugin.configure({\n options: {\n enableUndoOnDelete: true,\n rules: [\n ...autoformatBlocks,\n ...autoformatMarks,\n ...autoformatSmartQuotes,\n ...autoformatPunctuation,\n ...autoformatLegal,\n ...autoformatLegalHtml,\n ...autoformatArrow,\n ...autoformatMath,\n ...autoformatIndentLists,\n ],\n },\n});\n", "path": "components/editor/plugins/autoformat-plugin.ts", "target": "components/editor/plugins/autoformat-plugin.ts", "type": "registry:component" diff --git a/apps/www/public/r/styles/default/basic-editor-default-demo.json b/apps/www/public/r/styles/default/basic-editor-default-demo.json index 88d4fcdce6..367dd07c4d 100644 --- a/apps/www/public/r/styles/default/basic-editor-default-demo.json +++ b/apps/www/public/r/styles/default/basic-editor-default-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport {\n Plate,\n PlateContent,\n usePlateEditor,\n} from '@udecode/plate-common/react';\n\nexport default function BasicEditorDefaultDemo() {\n const editor = usePlateEditor();\n\n return (\n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate, PlateContent, usePlateEditor } from '@udecode/plate/react';\n\nexport default function BasicEditorDefaultDemo() {\n const editor = usePlateEditor();\n\n return (\n \n \n \n );\n}\n", "path": "example/basic-editor-default-demo.tsx", "target": "components/basic-editor-default-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-editor-handler-demo.json b/apps/www/public/r/styles/default/basic-editor-handler-demo.json index c040f0b0f3..bcebf6f122 100644 --- a/apps/www/public/r/styles/default/basic-editor-handler-demo.json +++ b/apps/www/public/r/styles/default/basic-editor-handler-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport type { Value } from '@udecode/plate-common';\n\nimport { Plate, usePlateEditor } from '@udecode/plate-common/react';\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from '@/components/ui/accordion';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nconst value = [\n {\n children: [\n {\n text: 'This is editable plain text with react and history plugins, just like a textarea!',\n },\n ],\n type: 'p',\n },\n];\n\nexport default function BasicEditorHandlerDemo() {\n const [debugValue, setDebugValue] = useState(value);\n\n const localValue =\n typeof window !== 'undefined' && localStorage.getItem('editorContent');\n\n const editor = usePlateEditor({\n value: localValue ? JSON.parse(localValue) : value,\n });\n\n return (\n {\n localStorage.setItem('editorContent', JSON.stringify(value));\n setDebugValue(value);\n }}\n editor={editor}\n >\n \n \n \n\n \n \n Debug Value\n {JSON.stringify(debugValue)}\n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React, { useState } from 'react';\n\nimport type { Value } from '@udecode/plate';\n\nimport { Plate, usePlateEditor } from '@udecode/plate/react';\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from '@/components/ui/accordion';\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nconst value = [\n {\n children: [\n {\n text: 'This is editable plain text with react and history plugins, just like a textarea!',\n },\n ],\n type: 'p',\n },\n];\n\nexport default function BasicEditorHandlerDemo() {\n const [debugValue, setDebugValue] = useState(value);\n\n const localValue =\n typeof window !== 'undefined' && localStorage.getItem('editorContent');\n\n const editor = usePlateEditor({\n value: localValue ? JSON.parse(localValue) : value,\n });\n\n return (\n {\n localStorage.setItem('editorContent', JSON.stringify(value));\n setDebugValue(value);\n }}\n editor={editor}\n >\n \n \n \n\n \n \n Debug Value\n {JSON.stringify(debugValue)}\n \n \n \n );\n}\n", "path": "example/basic-editor-handler-demo.tsx", "target": "components/basic-editor-handler-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-editor-styling-demo.json b/apps/www/public/r/styles/default/basic-editor-styling-demo.json index 6bee058f10..3995945655 100644 --- a/apps/www/public/r/styles/default/basic-editor-styling-demo.json +++ b/apps/www/public/r/styles/default/basic-editor-styling-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate, usePlateEditor } from '@udecode/plate-common/react';\n\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nexport default function BasicEditorStylingDemo() {\n const editor = usePlateEditor();\n\n return (\n \n \n \n \n \n );\n}\n", + "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate, usePlateEditor } from '@udecode/plate/react';\n\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nexport default function BasicEditorStylingDemo() {\n const editor = usePlateEditor();\n\n return (\n \n \n \n \n \n );\n}\n", "path": "example/basic-editor-styling-demo.tsx", "target": "components/basic-editor-styling-demo.tsx", "type": "registry:example" diff --git a/apps/www/public/r/styles/default/basic-editor-value-demo.json b/apps/www/public/r/styles/default/basic-editor-value-demo.json index 092ddd3690..039d53e998 100644 --- a/apps/www/public/r/styles/default/basic-editor-value-demo.json +++ b/apps/www/public/r/styles/default/basic-editor-value-demo.json @@ -1,7 +1,7 @@ { "files": [ { - "content": "'use client';\n\nimport React from 'react';\n\nimport { Plate, usePlateEditor } from '@udecode/plate-common/react';\n\nimport { Editor, EditorContainer } from '@/components/plate-ui/editor';\n\nconst value = [\n {\n children: [\n {\n text: 'This is editable plain text with react and history plugins, just like a