UNPKG

@udecode/plate-core

Version:

The core of Plate – a plugin system for slate

1 lines 739 kB
{"version":3,"sources":["../../src/react/slate-react.ts","../../src/react/components/EditorHotkeysEffect.tsx","../../src/react/stores/element/useElement.ts","../../src/react/stores/plate/createPlateStore.ts","../../src/react/libs/jotai.ts","../../src/react/editor/withPlate.ts","../../src/lib/editor/withSlate.ts","../../src/internal/plugin/resolvePlugins.ts","../../src/lib/plugin/createSlatePlugin.ts","../../src/internal/utils/isFunction.ts","../../src/internal/utils/mergePlugins.ts","../../src/lib/plugin/getEditorPlugin.ts","../../src/internal/plugin/resolvePlugin.ts","../../src/lib/plugin/getSlatePlugin.ts","../../src/lib/plugins/AstPlugin.ts","../../src/lib/plugins/HistoryPlugin.ts","../../src/lib/plugins/paragraph/BaseParagraphPlugin.ts","../../src/lib/plugins/override/withBreakRules.ts","../../src/lib/plugins/override/withDeleteRules.ts","../../src/lib/plugins/override/withMergeRules.ts","../../src/lib/plugins/override/withNormalizeRules.ts","../../src/lib/plugins/override/OverridePlugin.ts","../../src/internal/plugin/pipeInsertFragment.ts","../../src/internal/plugin/pipeTransformData.ts","../../src/internal/plugin/pipeTransformFragment.ts","../../src/lib/utils/applyDeepToNodes.ts","../../src/lib/utils/defaultsDeepToNodes.ts","../../src/lib/utils/getInjectMatch.ts","../../src/lib/utils/getKeysByTypes.ts","../../src/lib/utils/getInjectedPlugins.ts","../../src/lib/utils/getPluginNodeProps.ts","../../src/lib/static/utils/getNodeDataAttributes.ts","../../src/internal/plugin/pipeInjectNodeProps.tsx","../../src/internal/plugin/isEditOnlyDisabled.ts","../../src/internal/plugin/pluginInjectNodeProps.ts","../../src/lib/static/utils/pipeDecorate.ts","../../src/lib/static/deserialize/checkUtils.ts","../../src/lib/utils/getSlateClass.ts","../../src/lib/utils/hotkeys.ts","../../src/lib/utils/mergeDeepToNodes.ts","../../src/lib/utils/normalizeDescendantsToDocumentFragment.ts","../../src/lib/plugins/affinity/AffinityPlugin.ts","../../src/lib/plugins/affinity/queries/getEdgeNodes.ts","../../../../node_modules/is-plain-object/dist/is-plain-object.mjs","../../../../node_modules/immer/src/utils/env.ts","../../../../node_modules/immer/src/utils/errors.ts","../../../../node_modules/immer/src/utils/common.ts","../../../../node_modules/immer/src/utils/plugins.ts","../../../../node_modules/immer/src/core/scope.ts","../../../../node_modules/immer/src/core/finalize.ts","../../../../node_modules/immer/src/core/proxy.ts","../../../../node_modules/immer/src/core/immerClass.ts","../../../../node_modules/immer/src/core/current.ts","../../../../node_modules/immer/src/plugins/patches.ts","../../../../node_modules/immer/src/plugins/mapset.ts","../../../../node_modules/immer/src/immer.ts","../../../../node_modules/slate/src/interfaces/path-ref.ts","../../../../node_modules/slate/src/interfaces/point-ref.ts","../../../../node_modules/slate/src/interfaces/range-ref.ts","../../../../node_modules/slate/src/utils/weak-maps.ts","../../../../node_modules/slate/src/interfaces/path.ts","../../../../../../../.yarn/berry/cache/@babel-runtime-npm-7.23.2-d013d6cf7e-10.zip/node_modules/@babel/runtime/helpers/esm/typeof.js","../../../../../../../.yarn/berry/cache/@babel-runtime-npm-7.23.2-d013d6cf7e-10.zip/node_modules/@babel/runtime/helpers/esm/toPrimitive.js","../../../../../../../.yarn/berry/cache/@babel-runtime-npm-7.23.2-d013d6cf7e-10.zip/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js","../../../../../../../.yarn/berry/cache/@babel-runtime-npm-7.23.2-d013d6cf7e-10.zip/node_modules/@babel/runtime/helpers/esm/defineProperty.js","../../../../node_modules/slate/src/interfaces/transforms/general.ts","../../../../node_modules/slate/src/interfaces/transforms/node.ts","../../../../node_modules/slate/src/interfaces/transforms/selection.ts","../../../../node_modules/slate/src/utils/deep-equal.ts","../../../../../../../.yarn/berry/cache/@babel-runtime-npm-7.23.2-d013d6cf7e-10.zip/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../../../../../../../.yarn/berry/cache/@babel-runtime-npm-7.23.2-d013d6cf7e-10.zip/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js","../../../../node_modules/slate/src/interfaces/range.ts","../../../../node_modules/slate/src/interfaces/element.ts","../../../../node_modules/slate/src/interfaces/node.ts","../../../../node_modules/slate/src/interfaces/operation.ts","../../../../node_modules/slate/src/editor/is-editor.ts","../../../../node_modules/slate/src/interfaces/editor.ts","../../../../node_modules/slate/src/interfaces/location.ts","../../../../node_modules/slate/src/interfaces/point.ts","../../../../node_modules/slate/src/interfaces/scrubber.ts","../../../../node_modules/slate/src/interfaces/text.ts","../../../../node_modules/slate/src/utils/get-default-insert-location.ts","../../../../node_modules/slate/src/utils/match-path.ts","../../../../node_modules/slate/src/utils/string.ts","../../../../node_modules/slate/src/interfaces/transforms/text.ts","../../../../node_modules/slate/src/interfaces/transforms/index.ts","../../../../node_modules/slate/src/core/batch-dirty-paths.ts","../../../../node_modules/slate/src/core/update-dirty-paths.ts","../../../../node_modules/slate/src/core/apply.ts","../../../../node_modules/slate/src/core/get-dirty-paths.ts","../../../../node_modules/slate/src/core/get-fragment.ts","../../../../node_modules/slate/src/core/normalize-node.ts","../../../../node_modules/slate/src/core/should-normalize.ts","../../../../node_modules/slate/src/editor/above.ts","../../../../node_modules/slate/src/editor/add-mark.ts","../../../../node_modules/slate/src/editor/after.ts","../../../../node_modules/slate/src/editor/before.ts","../../../../node_modules/slate/src/editor/delete-backward.ts","../../../../node_modules/slate/src/editor/delete-forward.ts","../../../../node_modules/slate/src/editor/delete-fragment.ts","../../../../node_modules/slate/src/editor/edges.ts","../../../../node_modules/slate/src/editor/element-read-only.ts","../../../../node_modules/slate/src/editor/end.ts","../../../../node_modules/slate/src/editor/first.ts","../../../../node_modules/slate/src/editor/fragment.ts","../../../../node_modules/slate/src/editor/get-void.ts","../../../../node_modules/slate/src/editor/has-blocks.ts","../../../../node_modules/slate/src/editor/has-inlines.ts","../../../../node_modules/slate/src/editor/has-path.ts","../../../../node_modules/slate/src/editor/has-texts.ts","../../../../node_modules/slate/src/editor/insert-break.ts","../../../../node_modules/slate/src/editor/insert-node.ts","../../../../node_modules/slate/src/editor/insert-soft-break.ts","../../../../node_modules/slate/src/editor/insert-text.ts","../../../../node_modules/slate/src/editor/is-block.ts","../../../../node_modules/slate/src/editor/is-edge.ts","../../../../node_modules/slate/src/editor/is-empty.ts","../../../../node_modules/slate/src/editor/is-end.ts","../../../../node_modules/slate/src/editor/is-normalizing.ts","../../../../node_modules/slate/src/editor/is-start.ts","../../../../node_modules/slate/src/editor/last.ts","../../../../node_modules/slate/src/editor/leaf.ts","../../../../node_modules/slate/src/editor/levels.ts","../../../../node_modules/slate/src/editor/marks.ts","../../../../node_modules/slate/src/editor/next.ts","../../../../node_modules/slate/src/editor/node.ts","../../../../node_modules/slate/src/editor/nodes.ts","../../../../node_modules/slate/src/editor/normalize.ts","../../../../node_modules/slate/src/editor/parent.ts","../../../../node_modules/slate/src/editor/path-ref.ts","../../../../node_modules/slate/src/editor/path-refs.ts","../../../../node_modules/slate/src/editor/path.ts","../../../../node_modules/slate/src/editor/point-ref.ts","../../../../node_modules/slate/src/editor/point-refs.ts","../../../../node_modules/slate/src/editor/point.ts","../../../../node_modules/slate/src/editor/positions.ts","../../../../node_modules/slate/src/editor/previous.ts","../../../../node_modules/slate/src/editor/range-ref.ts","../../../../node_modules/slate/src/editor/range-refs.ts","../../../../node_modules/slate/src/editor/range.ts","../../../../node_modules/slate/src/editor/remove-mark.ts","../../../../node_modules/slate/src/editor/set-normalizing.ts","../../../../node_modules/slate/src/editor/start.ts","../../../../node_modules/slate/src/editor/string.ts","../../../../node_modules/slate/src/editor/unhang-range.ts","../../../../node_modules/slate/src/editor/without-normalizing.ts","../../../../node_modules/slate/src/editor/should-merge-nodes-remove-prev-node.ts","../../../../node_modules/slate/src/transforms-text/delete-text.ts","../../../../node_modules/slate/src/transforms-text/insert-fragment.ts","../../../../node_modules/slate/src/transforms-selection/collapse.ts","../../../../node_modules/slate/src/transforms-selection/deselect.ts","../../../../node_modules/slate/src/transforms-selection/move.ts","../../../../node_modules/slate/src/transforms-selection/select.ts","../../../../node_modules/slate/src/transforms-selection/set-point.ts","../../../../node_modules/slate/src/transforms-selection/set-selection.ts","../../../../node_modules/slate/src/transforms-node/insert-nodes.ts","../../../../node_modules/slate/src/transforms-node/lift-nodes.ts","../../../../node_modules/slate/src/transforms-node/merge-nodes.ts","../../../../node_modules/slate/src/transforms-node/move-nodes.ts","../../../../node_modules/slate/src/transforms-node/remove-nodes.ts","../../../../node_modules/slate/src/transforms-node/set-nodes.ts","../../../../node_modules/slate/src/transforms-node/split-nodes.ts","../../../../node_modules/slate/src/transforms-node/unset-nodes.ts","../../../../node_modules/slate/src/transforms-node/unwrap-nodes.ts","../../../../node_modules/slate/src/transforms-node/wrap-nodes.ts","../../../../node_modules/slate/src/create-editor.ts","../../src/lib/plugins/affinity/queries/getMarkBoundaryAffinity.ts","../../src/lib/plugins/affinity/queries/isNodeAffinity.ts","../../src/lib/plugins/affinity/transforms/setAffinitySelection.ts","../../src/lib/plugins/debug/DebugPlugin.ts","../../src/lib/plugins/dom/DOMPlugin.ts","../../src/lib/plugins/dom/withScrolling.ts","../../src/lib/plugins/html/HtmlPlugin.ts","../../src/lib/plugins/html/utils/isHtmlElement.ts","../../src/lib/plugins/html/utils/isHtmlText.ts","../../src/lib/plugins/html/utils/inlineTagNames.ts","../../src/lib/plugins/html/utils/isHtmlInlineElement.ts","../../src/lib/plugins/html/utils/isHtmlBlockElement.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseString.ts","../../src/lib/plugins/html/utils/collapse-white-space/isLastNonEmptyTextOfInlineFormattingContext.ts","../../src/lib/plugins/html/utils/collapse-white-space/stateTransforms.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceText.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceNode.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceChildren.ts","../../src/lib/plugins/html/utils/collapse-white-space/inferWhiteSpaceRule.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceElement.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpace.ts","../../src/lib/plugins/html/utils/htmlBodyToFragment.ts","../../src/lib/plugins/html/utils/deserializeHtmlNodeChildren.ts","../../src/lib/plugins/html/utils/htmlBrToNewLine.ts","../../src/lib/plugins/html/utils/htmlElementToElement.ts","../../src/lib/plugins/html/utils/pluginDeserializeHtml.ts","../../src/lib/plugins/html/utils/getDataNodeProps.ts","../../src/lib/plugins/html/utils/pipeDeserializeHtmlElement.ts","../../src/lib/plugins/html/utils/htmlElementToLeaf.ts","../../src/lib/plugins/html/utils/pipeDeserializeHtmlLeaf.ts","../../src/lib/plugins/html/utils/htmlTextNodeToString.ts","../../src/lib/plugins/html/utils/deserializeHtmlNode.ts","../../src/lib/plugins/html/utils/deserializeHtmlElement.ts","../../src/lib/plugins/html/utils/htmlStringToDOMNode.ts","../../src/lib/plugins/html/utils/deserializeHtml.ts","../../src/lib/plugins/html/utils/parseHtmlDocument.ts","../../src/lib/plugins/length/LengthPlugin.ts","../../src/lib/plugins/node-id/NodeIdPlugin.ts","../../src/lib/plugins/node-id/withNodeId.ts","../../src/lib/plugins/slate-extension/SlateExtensionPlugin.ts","../../src/internal/plugin/pipeNormalizeInitialValue.ts","../../src/lib/plugins/slate-extension/transforms/init.ts","../../src/lib/plugins/slate-extension/transforms/insertExitBreak.ts","../../src/lib/plugins/slate-extension/transforms/resetBlock.ts","../../src/lib/plugins/slate-extension/transforms/setValue.ts","../../src/lib/utils/pipeInsertDataQuery.ts","../../src/lib/plugins/ParserPlugin.ts","../../src/lib/plugins/getCorePlugins.ts","../../src/lib/libs/zustand.ts","../../src/react/plugins/SlateReactExtensionPlugin.ts","../../src/react/plugin/toPlatePlugin.ts","../../src/react/plugin/createPlatePlugin.ts","../../src/react/plugin/getEditorPlugin.ts","../../src/react/plugin/getPlugin.ts","../../src/react/plugin/omitPluginContext.ts","../../src/react/plugins/event-editor/EventEditorStore.ts","../../src/react/plugins/event-editor/useFocusEditorEvents.ts","../../src/react/plugins/event-editor/EventEditorPlugin.ts","../../src/react/plugins/event-editor/getEventPlateId.ts","../../src/react/plugins/paragraph/ParagraphPlugin.tsx","../../src/react/plugins/react/withPlateReact.ts","../../src/react/plugins/react/ReactPlugin.ts","../../src/react/editor/getPlateCorePlugins.ts","../../src/react/utils/createPlateFallbackEditor.ts","../../src/react/utils/dom-attributes.ts","../../src/react/utils/getRenderNodeProps.ts","../../src/react/utils/pipeHandler.ts","../../src/react/utils/pipeOnChange.ts","../../src/react/utils/pipeRenderElement.tsx","../../src/react/hooks/useEditableProps.ts","../../src/react/utils/pipeRenderLeaf.tsx","../../src/react/utils/pluginRenderLeaf.tsx","../../src/react/components/plate-nodes.tsx","../../src/react/utils/pipeRenderText.tsx","../../src/react/utils/pluginRenderText.tsx","../../src/react/hooks/useNodePath.ts","../../src/react/hooks/useSlateProps.ts","../../src/react/utils/pluginRenderElement.tsx","../../src/react/stores/element/useElementStore.tsx","../../src/react/stores/element/usePath.ts","../../src/react/stores/plate-controller/plateControllerStore.ts","../../src/react/stores/plate/useEditorPlugin.ts","../../src/react/stores/plate/useEditorSelector.ts","../../src/react/stores/plate/usePluginOption.ts","../../src/react/stores/element/useElementSelector.ts","../../src/react/stores/event-editor/useEventPlateId.ts","../../src/react/components/EditorMethodsEffect.ts","../../src/react/components/EditorRefEffect.tsx","../../src/react/components/Plate.tsx","../../src/internal/hooks/usePlateInstancesWarn.ts","../../src/react/components/PlateContainer.tsx","../../src/react/components/PlateContent.tsx","../../src/react/components/PlateControllerEffect.ts","../../src/react/components/PlateSlate.tsx","../../src/react/components/PlateTest.tsx","../../src/react/editor/usePlateEditor.ts","../../src/react/components/withHOC.tsx"],"sourcesContent":["// Components\nexport {\n type RenderPlaceholderProps,\n DefaultPlaceholder,\n Editable,\n Slate,\n} from 'slate-react';\n\n// Hooks\nexport {\n useComposing,\n useFocused,\n useReadOnly,\n useSelected,\n} from 'slate-react';\n\n// Plugin\nexport { withReact } from 'slate-react';\n","import React, { useEffect } from 'react';\n\nimport { useHotkeys } from '@udecode/react-hotkeys';\nimport { isDefined } from '@udecode/utils';\n\nimport type { Shortcut } from '../plugin';\n\nimport { useEditorRef } from '../stores';\n\nexport function EditorHotkeysEffect({\n id,\n editableRef,\n}: {\n editableRef: React.RefObject<HTMLDivElement | null>;\n id?: string;\n}) {\n const editor = useEditorRef(id);\n\n return (\n <>\n {Object.entries(editor.meta.shortcuts).map(\n ([hotkeyString, hotkeyConfig]) => {\n if (\n !hotkeyConfig ||\n !isDefined(hotkeyConfig.keys) ||\n !hotkeyConfig.handler\n ) {\n return null;\n }\n\n return (\n <HotkeyEffect\n id={id}\n key={hotkeyString}\n editableRef={editableRef}\n hotkeyConfig={hotkeyConfig}\n />\n );\n }\n )}\n </>\n );\n}\n\nfunction HotkeyEffect({\n id,\n editableRef,\n hotkeyConfig,\n}: {\n editableRef: React.RefObject<HTMLDivElement | null>;\n hotkeyConfig: Shortcut;\n id?: string;\n}) {\n const editor = useEditorRef(id);\n const { keys, handler, ...options } = hotkeyConfig;\n\n const setHotkeyRef = useHotkeys<HTMLDivElement>(\n keys!,\n (event, eventDetails) => {\n if (\n handler!({\n editor,\n event,\n eventDetails,\n }) !== false &&\n !isDefined(options.preventDefault)\n ) {\n // Prevent default if handler returns false and preventDefault is true\n event.preventDefault();\n }\n },\n {\n enableOnContentEditable: true,\n ...options,\n },\n []\n );\n\n useEffect(() => {\n if (editableRef.current) {\n setHotkeyRef(editableRef.current);\n }\n }, [setHotkeyRef, editableRef]);\n\n return null;\n}\n","import type { TElement } from '@udecode/slate';\n\nimport { useAtomStoreValue } from 'jotai-x';\n\nimport { useEditorRef } from '../plate';\nimport { SCOPE_ELEMENT, useElementStore } from './useElementStore';\n\n/**\n * Get the element by plugin key. If no element is found in the context, it will\n * return an empty object.\n */\nexport const useElement = <T extends TElement = TElement>(\n pluginKey = SCOPE_ELEMENT\n): T => {\n const editor = useEditorRef();\n const value = useAtomStoreValue(useElementStore(pluginKey), 'element');\n\n if (!value) {\n editor.api.debug.warn(\n `useElement(${pluginKey}) hook must be used inside the node component's context`,\n 'USE_ELEMENT_CONTEXT'\n );\n\n return {} as T;\n }\n\n return value as T;\n};\n","import React, { useMemo } from 'react';\n\nimport { atom } from 'jotai';\nimport { useAtomStoreSet, useAtomStoreState, useAtomStoreValue } from 'jotai-x';\n\nimport type { PlateEditor } from '../../editor/PlateEditor';\nimport type { PlateChangeKey, PlateStoreState } from './PlateStore';\n\nimport { createAtomStore } from '../../libs';\nimport { createPlateFallbackEditor } from '../../utils';\nimport {\n usePlateControllerExists,\n usePlateControllerStore,\n} from '../plate-controller';\n\nexport type PlateStore = ReturnType<typeof usePlateStore>;\n\nexport const PLATE_SCOPE = 'plate';\n\nexport const GLOBAL_PLATE_SCOPE = Symbol('global-plate');\n\nexport const createPlateStore = <E extends PlateEditor = PlateEditor>({\n id,\n composing = false,\n containerRef = { current: null },\n decorate = null,\n editor,\n isMounted = false,\n primary = true,\n readOnly = null,\n renderElement = null,\n renderLeaf = null,\n renderText = null,\n scrollRef = { current: null },\n versionDecorate = 1,\n versionEditor = 1,\n versionSelection = 1,\n versionValue = 1,\n onChange = null,\n onSelectionChange = null,\n onValueChange = null,\n ...state\n}: Partial<PlateStoreState<E>> = {}) =>\n createAtomStore(\n {\n composing,\n containerRef,\n decorate,\n editor,\n isMounted,\n primary,\n readOnly,\n renderElement,\n renderLeaf,\n renderText,\n scrollRef,\n versionDecorate,\n versionEditor,\n versionSelection,\n versionValue,\n onChange,\n onSelectionChange,\n onValueChange,\n ...state,\n } as PlateStoreState<E>,\n {\n name: 'plate',\n suppressWarnings: true,\n extend: (atoms) => ({\n trackedEditor: atom((get) => ({\n editor: get(atoms.editor),\n version: get(atoms.versionEditor),\n })),\n trackedSelection: atom((get) => ({\n selection: get(atoms.editor).selection,\n version: get(atoms.versionSelection),\n })),\n trackedValue: atom((get) => ({\n value: get(atoms.editor).children,\n version: get(atoms.versionValue),\n })),\n }),\n }\n );\n\nconst {\n PlateProvider: PlateStoreProvider,\n plateStore,\n usePlateSet: usePlateLocalSet,\n usePlateState: usePlateLocalState,\n usePlateStore: usePlateLocalStore,\n usePlateValue: usePlateLocalValue,\n} = createPlateStore();\n\nexport { plateStore, PlateStoreProvider, usePlateLocalStore };\n\nexport const usePlateStore = (id?: string) => {\n // Try to fetch the store from a Plate provider\n const localStore =\n usePlateLocalStore({ scope: id, warnIfNoStore: false }) ?? null;\n\n const [localStoreExists] = React.useState(!!localStore.store);\n\n // If no store was found, try to fetch the store from a PlateController\n const store = (\n localStoreExists\n ? localStore\n : // eslint-disable-next-line react-hooks/rules-of-hooks\n usePlateControllerStore(id)\n ) as typeof localStore;\n\n /**\n * If we still have no store, there are two possibilities.\n *\n * Case 1: There is neither a Plate nor a PlateController above us in the\n * tree. In this case, throw an error, since calling the hook will never\n * work.\n *\n * Case 2: There is a PlateController, but it has no active editor. In this\n * case, return a fallback store until an editor becomes active.\n */\n const plateControllerExists = usePlateControllerExists();\n const fallbackStore = useMemo(createPlateStore, []).usePlateStore();\n\n if (!store) {\n if (plateControllerExists) {\n return fallbackStore;\n }\n\n throw new Error(\n `Plate hooks must be used inside a Plate or PlateController`\n );\n }\n return store;\n};\n\nexport const usePlateSet: typeof usePlateLocalSet = (key, options) => {\n const store = usePlateStore(\n typeof options === 'string' ? options : options?.scope\n );\n\n return useAtomStoreSet(store, key);\n};\n\nexport const usePlateValue = ((key, options) => {\n const store = usePlateStore(\n typeof options === 'string' ? options : options?.scope\n );\n\n return useAtomStoreValue(store, key);\n}) as typeof usePlateLocalValue;\n\nexport const usePlateState = ((key, options) => {\n const store = usePlateStore(\n typeof options === 'string' ? options : options?.scope\n );\n\n return useAtomStoreState(store, key);\n}) as typeof usePlateLocalState;\n\n// ─── Selectors ───────────────────────────────────────────────────────────────\n\n/** Get the closest `Plate` id. */\nexport const useEditorId = (): string =>\n useAtomStoreValue(usePlateStore(), 'editor').id;\n\nexport const useEditorContainerRef = (id?: string) => {\n return useAtomStoreValue(usePlateStore(id), 'containerRef');\n};\n\nexport const useEditorScrollRef = (id?: string) => {\n return useAtomStoreValue(usePlateStore(id), 'scrollRef');\n};\n\n/** Returns the scrollRef if it exists, otherwise returns the containerRef. */\nexport const useScrollRef = (id?: string) => {\n const scrollRef = useEditorScrollRef(id);\n const containerRef = useEditorContainerRef(id);\n\n return scrollRef.current ? scrollRef : containerRef;\n};\n\nexport const useEditorMounted = (id?: string): boolean => {\n return !!useAtomStoreValue(usePlateStore(id), 'isMounted');\n};\n\n/**\n * Whether the editor is read-only. You can also use `useReadOnly` from\n * `slate-react` in node components.\n */\nexport const useEditorReadOnly = (id?: string): boolean => {\n return !!useAtomStoreValue(usePlateStore(id), 'readOnly');\n};\n\n/** Whether the editor is composing. */\nexport const useEditorComposing = (id?: string): boolean => {\n return !!useAtomStoreValue(usePlateStore(id), 'composing');\n};\n\n/**\n * Get a reference to the editor instance that remains stable across re-renders.\n * The editor object is enhanced with a `store` property that provides access to\n * the Plate store.\n *\n * @example\n * ```tsx\n * const editor = useEditorRef();\n * const readOnly = useAtomStoreValue(editor.store, 'readOnly');\n */\nexport const useEditorRef = <E extends PlateEditor = PlateEditor>(\n id?: string\n): E & { store: PlateStore } => {\n const store = usePlateStore(id);\n const editor: any =\n (useAtomStoreValue(store, 'editor') as E) ?? createPlateFallbackEditor();\n\n editor.store = store;\n\n return editor;\n};\n\n/** Get the editor selection (deeply memoized). */\nexport const useEditorSelection = (id?: string) =>\n usePlateStore(id).useTrackedSelectionValue().selection;\n\n/** Get editor state which is updated on editor change. */\nexport const useEditorState = <E extends PlateEditor = PlateEditor>(\n id?: string\n): E => {\n return usePlateStore(id).useTrackedEditorValue().editor;\n};\n\n/** Version incremented on each editor change. */\nexport const useEditorVersion = (id?: string) => {\n return useAtomStoreValue(usePlateStore(id), 'versionEditor');\n};\n\n/** Version incremented on selection change. */\nexport const useSelectionVersion = (id?: string) => {\n return useAtomStoreValue(usePlateStore(id), 'versionSelection');\n};\n\n/** Get the editor value (deeply memoized). */\nexport const useEditorValue = (id?: string) =>\n usePlateStore(id).useTrackedValueValue().value;\n\n/** Version incremented on value change. */\nexport const useValueVersion = (id?: string) => {\n return useAtomStoreValue(usePlateStore(id), 'versionValue');\n};\n\n// ─── Actions ─────────────────────────────────────────────────────────────────\n\nexport const useIncrementVersion = (key: PlateChangeKey, id?: string) => {\n const previousVersionRef = React.useRef(1);\n\n const store = usePlateStore(id);\n\n const setVersionDecorate = useAtomStoreSet(store, 'versionDecorate');\n const setVersionSelection = useAtomStoreSet(store, 'versionSelection');\n const setVersionValue = useAtomStoreSet(store, 'versionValue');\n const setVersionEditor = useAtomStoreSet(store, 'versionEditor');\n\n return React.useCallback(() => {\n const nextVersion = previousVersionRef.current + 1;\n\n switch (key) {\n case 'versionDecorate': {\n setVersionDecorate(nextVersion);\n\n break;\n }\n case 'versionEditor': {\n setVersionEditor(nextVersion);\n\n break;\n }\n case 'versionSelection': {\n setVersionSelection(nextVersion);\n\n break;\n }\n case 'versionValue': {\n setVersionValue(nextVersion);\n\n break;\n }\n }\n\n previousVersionRef.current = nextVersion;\n }, [\n key,\n setVersionDecorate,\n setVersionEditor,\n setVersionSelection,\n setVersionValue,\n ]);\n};\n\nexport const useRedecorate = (id?: string) => {\n const updateDecorate = useIncrementVersion('versionDecorate', id);\n\n return React.useCallback(() => {\n updateDecorate();\n }, [updateDecorate]);\n};\n","export { atom } from 'jotai';\n\nexport {\n createAtomStore,\n useStoreAtomState,\n useStoreAtomValue,\n useStoreSetAtom,\n} from 'jotai-x';\n\nexport {\n useStoreSelect,\n useStoreState,\n useStoreValue,\n useTracked,\n useTrackedStore,\n} from 'zustand-x';\n","import { type Editor, type Value, createEditor } from '@udecode/slate';\n\nimport type { AnyPlatePlugin } from '../plugin';\nimport type { EventEditorPlugin, SlateReactExtensionPlugin } from '../plugins';\nimport type { PlateEditor, TPlateEditor } from './PlateEditor';\n\nimport {\n type AnyPluginConfig,\n type BaseWithSlateOptions,\n type CorePlugin,\n type InferPlugins,\n withSlate,\n} from '../../lib';\nimport { getPlateCorePlugins } from './getPlateCorePlugins';\n\nexport type PlateCorePlugin =\n | CorePlugin\n | typeof EventEditorPlugin\n | typeof SlateReactExtensionPlugin;\n\nexport type WithPlateOptions<\n V extends Value = Value,\n P extends AnyPluginConfig = PlateCorePlugin,\n> = BaseWithSlateOptions<P> &\n Pick<\n Partial<AnyPlatePlugin>,\n | 'api'\n | 'decorate'\n | 'extendEditor'\n | 'handlers'\n | 'inject'\n | 'normalizeInitialValue'\n | 'options'\n | 'override'\n | 'priority'\n | 'render'\n | 'shortcuts'\n | 'transforms'\n | 'useHooks'\n > & {\n // override?: {\n // /** Enable or disable plugins */\n // enabled?: Partial<Record<KeyofPlugins<InferPlugins<P[]>>, boolean>>;\n // plugins?: Partial<\n // Record<\n // KeyofPlugins<InferPlugins<P[]>>,\n // Partial<EditorPlatePlugin<AnyPluginConfig>>\n // >\n // >;\n // };\n value?: ((editor: PlateEditor) => V) | V | string;\n rootPlugin?: (plugin: AnyPlatePlugin) => AnyPlatePlugin;\n };\n\n/**\n * Applies Plate enhancements to an editor instance (React version).\n *\n * @remarks\n * This function supports React-specific features including component rendering,\n * event handlers, and React hooks integration.\n * @see {@link createPlateEditor} for a higher-level React editor creation function.\n * @see {@link usePlateEditor} for a memoized version in React components.\n * @see {@link withSlate} for the non-React version of editor enhancement.\n */\nexport const withPlate = <\n V extends Value = Value,\n P extends AnyPluginConfig = PlateCorePlugin,\n>(\n e: Editor,\n { plugins = [], ...options }: WithPlateOptions<V, P> = {}\n): TPlateEditor<V, InferPlugins<P[]>> => {\n const editor = withSlate<V, P>(e, {\n ...options,\n plugins: [...getPlateCorePlugins(), ...plugins],\n } as any) as unknown as TPlateEditor<V, InferPlugins<P[]>>;\n\n return editor;\n};\n\nexport type CreatePlateEditorOptions<\n V extends Value = Value,\n P extends AnyPluginConfig = PlateCorePlugin,\n> = WithPlateOptions<V, P> & {\n /**\n * Initial editor to be extended with `withPlate`.\n *\n * @default createEditor()\n */\n editor?: Editor;\n};\n\n/**\n * Creates a Plate editor (React version).\n *\n * This function creates a fully configured Plate editor instance with\n * React-specific enhancements including component rendering, event handlers,\n * and hooks integration. It applies all specified plugins and configurations to\n * create a functional editor.\n *\n * Examples:\n *\n * ```ts\n * const editor = createPlateEditor({\n * plugins: [ParagraphPlugin, HeadingPlugin],\n * value: [{ type: 'p', children: [{ text: 'Hello world!' }] }],\n * });\n *\n * // Editor with custom components\n * const editor = createPlateEditor({\n * plugins: [ParagraphPlugin.withComponent(ParagraphElement)],\n * components: { [CodePlugin.key]: CodeLeaf },\n * });\n *\n * // Editor with React-specific options\n * const editor = createPlateEditor({\n * plugins: [ParagraphPlugin],\n * handlers: { onKeyDown: customKeyHandler },\n * });\n * ```\n *\n * @see {@link createSlateEditor} for a non-React version of editor creation.\n * @see {@link usePlateEditor} for a memoized version in React components.\n * @see {@link withPlate} for the underlying function that applies Plate enhancements to an editor.\n */\nexport const createPlateEditor = <\n V extends Value = Value,\n P extends AnyPluginConfig = PlateCorePlugin,\n>({\n editor = createEditor(),\n ...options\n}: CreatePlateEditorOptions<V, P> = {}): TPlateEditor<V, InferPlugins<P[]>> => {\n return withPlate<V, P>(editor, options);\n};\n","import {\n type Editor,\n type TSelection,\n type Value,\n createEditor,\n} from '@udecode/slate';\nimport { nanoid } from 'nanoid';\n\nimport type { AnyPluginConfig, NodeComponents } from '../plugin/BasePlugin';\nimport type { AnySlatePlugin } from '../plugin/SlatePlugin';\nimport type { NodeIdConfig } from '../plugins/node-id/NodeIdPlugin';\nimport type { InferPlugins, SlateEditor, TSlateEditor } from './SlateEditor';\n\nimport { resolvePlugins } from '../../internal/plugin/resolvePlugins';\nimport { createSlatePlugin } from '../plugin/createSlatePlugin';\nimport { getPluginType, getSlatePlugin } from '../plugin/getSlatePlugin';\nimport { type CorePlugin, getCorePlugins } from '../plugins/getCorePlugins';\n\nexport type BaseWithSlateOptions<P extends AnyPluginConfig = CorePlugin> = {\n /**\n * Unique identifier for the editor instance.\n *\n * @default nanoid()\n */\n id?: string;\n /**\n * Determines which mark/element to apply at boundaries between different\n * marks, based on cursor movement using the left/right arrow keys.\n *\n * Example: <text bold>Bold</text><cursor><text italic>Italic</text>\n *\n * If the cursor moved here from the left (via → key), typing applies\n * **bold**.\n *\n * If the cursor moved here from the right (via ← key), typing applies\n * _italic_.\n *\n * Without mark affinity, the preceding mark (**bold**) is always applied\n * regardless of direction.\n *\n * @default true\n */\n affinity?: boolean;\n /**\n * Select the editor after initialization.\n *\n * @default false\n *\n * - `true` | 'end': Select the end of the editor\n * - `false`: Do not select anything\n * - `'start'`: Select the start of the editor\n */\n autoSelect?: boolean | 'end' | 'start';\n /** Specifies the component for each plugin key. */\n components?: NodeComponents;\n /** Specifies the component for each plugin key. */\n // components?: Partial<\n // Record<KeyofNodePlugins<InferPlugins<P[]>>, NodeComponent | null>\n // >;\n /**\n * Specifies the maximum number of characters allowed in the editor. When the\n * limit is reached, further input will be prevented.\n */\n maxLength?: number;\n /**\n * Configuration for automatic node ID generation and management.\n *\n * Unless set to `false`, the editor automatically adds unique IDs to nodes\n * through the core NodeIdPlugin:\n *\n * - Normalizes the initial value for missing IDs\n * - Adds IDs to new nodes during insertion\n * - Preserves or reuses IDs on undo/redo and copy/paste operations\n * - Handles ID conflicts and duplicates\n *\n * @default { idKey: 'id', filterInline: true, filterText: true, idCreator: () => nanoid(10) }\n */\n nodeId?: NodeIdConfig['options'] | boolean;\n // override?: {\n // components?: Partial<\n // Record<KeyofNodePlugins<InferPlugins<P[]>>, NodeComponent | null>\n // >;\n // };\n /**\n * Array of plugins to be loaded into the editor. Plugins extend the editor's\n * functionality and define custom behavior.\n */\n plugins?: P[];\n /**\n * Editor read-only initial state. For dynamic read-only control, use the\n * `Plate.readOnly` prop instead.\n *\n * @default false\n */\n readOnly?: boolean;\n /**\n * Initial selection state for the editor. Defines where the cursor should be\n * positioned when the editor loads.\n */\n selection?: TSelection;\n /**\n * When `true`, normalizes the initial `value` passed to the editor. This is\n * useful when adding normalization rules to already existing content or when\n * the initial value might not conform to the current schema.\n *\n * Note: Normalization may take time for large documents.\n *\n * @default false\n */\n shouldNormalizeEditor?: boolean;\n /**\n * When `true`, skips the initial value, selection, and normalization logic.\n * Useful when the editor state is managed externally (e.g., with Yjs\n * collaboration) or when you want to manually control the initialization\n * process.\n *\n * @default false\n */\n skipInitialization?: boolean;\n};\n\nexport type WithSlateOptions<\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n> = BaseWithSlateOptions<P> &\n Pick<\n Partial<AnySlatePlugin>,\n | 'api'\n | 'decorate'\n | 'extendEditor'\n | 'inject'\n | 'normalizeInitialValue'\n | 'options'\n | 'override'\n | 'transforms'\n > & {\n // override?: {\n // /** Enable or disable plugins */\n // enabled?: Partial<Record<KeyofPlugins<InferPlugins<P[]>>, boolean>>;\n // plugins?: Partial<\n // Record<\n // KeyofPlugins<InferPlugins<P[]>>,\n // PartialEditorPlugin<AnyPluginConfig>\n // >\n // >;\n // };\n /**\n * Initial content for the editor.\n *\n * Can be:\n *\n * - A static value (array of nodes)\n * - An HTML string that will be deserialized\n * - A function that returns a value or Promise<value>\n * - `null` for an empty editor\n *\n * @default [{ type: 'p'; children: [{ text: '' }] }]\n */\n value?: ((editor: SlateEditor) => Promise<V> | V) | V | string | null;\n /** Function to configure the root plugin */\n rootPlugin?: (plugin: AnySlatePlugin) => AnySlatePlugin;\n };\n\n/**\n * Applies Plate enhancements to an editor instance (non-React version).\n *\n * @remarks\n * This function supports server-side usage as it doesn't include React-specific\n * features like component rendering or hooks integration.\n * @see {@link createSlateEditor} for a higher-level non-React editor creation function.\n * @see {@link createPlateEditor} for a React-specific version of editor creation.\n * @see {@link usePlateEditor} for a memoized React version.\n * @see {@link withPlate} for the React-specific enhancement function.\n */\nexport const withSlate = <\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n>(\n e: Editor,\n {\n id,\n affinity = true,\n autoSelect,\n maxLength,\n nodeId,\n plugins = [],\n readOnly = false,\n rootPlugin,\n selection,\n shouldNormalizeEditor,\n skipInitialization,\n value,\n ...pluginConfig\n }: WithSlateOptions<V, P> = {}\n): TSlateEditor<V, InferPlugins<P[]>> => {\n const editor = e as SlateEditor;\n\n editor.id = id ?? editor.id ?? nanoid();\n editor.meta.key = editor.meta.key ?? nanoid();\n editor.meta.isFallback = false;\n editor.dom = {\n composing: false,\n currentKeyboardEvent: null,\n focused: false,\n prevSelection: null,\n readOnly,\n };\n\n editor.getApi = () => editor.api as any;\n editor.getTransforms = () => editor.transforms as any;\n editor.getPlugin = (plugin) => getSlatePlugin(editor, plugin) as any;\n editor.getType = (pluginKey) => getPluginType(editor, pluginKey);\n editor.getInjectProps = (plugin) => {\n const nodeProps =\n editor.getPlugin<AnySlatePlugin>(plugin).inject?.nodeProps ?? ({} as any);\n\n nodeProps.nodeKey = nodeProps.nodeKey ?? editor.getType(plugin.key);\n nodeProps.styleKey = nodeProps.styleKey ?? nodeProps.nodeKey;\n\n return nodeProps;\n };\n editor.getOptionsStore = (plugin) => {\n return editor.getPlugin(plugin).optionsStore;\n };\n editor.getOptions = (plugin) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return editor.getPlugin(plugin).options;\n\n return editor.getOptionsStore(plugin).get('state');\n };\n editor.getOption = (plugin, key, ...args) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return editor.getPlugin(plugin).options[key];\n\n if (!(key in store.get('state')) && !(key in store.selectors)) {\n editor.api.debug.error(\n `editor.getOption: ${key as string} option is not defined in plugin ${plugin.key}.`,\n 'OPTION_UNDEFINED'\n );\n return;\n }\n\n return (store.get as any)(key, ...args);\n };\n editor.setOption = (plugin: any, key: any, ...args: any) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return;\n\n if (!(key in store.get('state'))) {\n editor.api.debug.error(\n `editor.setOption: ${key} option is not defined in plugin ${plugin.key}.`,\n 'OPTION_UNDEFINED'\n );\n return;\n }\n\n (store.set as any)(key, ...args);\n };\n editor.setOptions = (plugin: any, options: any) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return;\n if (typeof options === 'object') {\n store.set('state', (draft: any) => {\n Object.assign(draft, options);\n });\n } else if (typeof options === 'function') {\n store.set('state', options);\n }\n };\n\n // Plugin initialization code\n const corePlugins = getCorePlugins({\n affinity,\n maxLength,\n nodeId,\n plugins,\n });\n\n let rootPluginInstance = createSlatePlugin({\n key: 'root',\n priority: 10_000,\n ...pluginConfig,\n override: {\n ...pluginConfig.override,\n components: {\n ...pluginConfig.components,\n ...pluginConfig.override?.components,\n },\n },\n plugins: [...corePlugins, ...plugins],\n });\n\n // Apply rootPlugin configuration if provided\n if (rootPlugin) {\n rootPluginInstance = rootPlugin(rootPluginInstance) as any;\n }\n\n resolvePlugins(editor, [rootPluginInstance]);\n\n /** Ignore normalizeNode overrides if shouldNormalizeNode returns false */\n const normalizeNode = editor.tf.normalizeNode;\n editor.tf.normalizeNode = (...args) => {\n if (!editor.api.shouldNormalizeNode(args[0])) {\n return;\n }\n\n return normalizeNode(...args);\n };\n editor.normalizeNode = editor.tf.normalizeNode;\n\n if (!skipInitialization) {\n void editor.tf.init({\n autoSelect,\n selection,\n shouldNormalizeEditor,\n value,\n });\n }\n\n return editor as any;\n};\n\nexport type CreateSlateEditorOptions<\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n> = WithSlateOptions<V, P> & {\n /**\n * Initial editor to be extended with `withSlate`.\n *\n * @default createEditor()\n */\n editor?: Editor;\n};\n\n/**\n * Creates a Slate editor (non-React version).\n *\n * This function creates a fully configured Plate editor instance that can be\n * used in non-React environments or server-side contexts. It applies all the\n * specified plugins and configurations to create a functional editor.\n *\n * Examples:\n *\n * ```ts\n * const editor = createSlateEditor({\n * plugins: [ParagraphPlugin, HeadingPlugin],\n * value: [{ type: 'p', children: [{ text: 'Hello world!' }] }],\n * });\n *\n * // Editor with custom configuration\n * const editor = createSlateEditor({\n * plugins: [ParagraphPlugin],\n * maxLength: 1000,\n * nodeId: { idCreator: () => uuidv4() },\n * autoSelect: 'end',\n * });\n *\n * // Server-side editor\n * const editor = createSlateEditor({\n * plugins: [ParagraphPlugin],\n * value: '<p>HTML content</p>',\n * skipInitialization: true,\n * });\n * ```\n *\n * @see {@link createPlateEditor} for a React-specific version of editor creation.\n * @see {@link usePlateEditor} for a memoized React version.\n * @see {@link withSlate} for the underlying function that applies Slate enhancements to an editor.\n */\nexport const createSlateEditor = <\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n>({\n editor = createEditor(),\n ...options\n}: CreateSlateEditorOptions<V, P> = {}) => {\n return withSlate<V, P>(editor, options);\n};\n","import {\n assignLegacyApi,\n assignLegacyTransforms,\n syncLegacyMethods,\n} from '@udecode/slate';\nimport { isDefined } from '@udecode/utils';\nimport merge from 'lodash/merge.js';\nimport { createZustandStore } from 'zustand-x';\n\nimport type { SlateEditor, SlatePlugin, SlatePlugins } from '../../lib';\n\nimport { getEditorPlugin } from '../../lib/plugin';\nimport { mergePlugins } from '../utils/mergePlugins';\nimport { resolvePlugin } from './resolvePlugin';\n\n/**\n * Initialize and configure the editor's plugin system. This function sets up\n * the editor's plugins, resolving core and custom plugins, and applying any\n * overrides specified in the plugins.\n */\nexport const resolvePlugins = (\n editor: SlateEditor,\n plugins: SlatePlugins = []\n) => {\n editor.plugins = {};\n editor.meta.pluginList = [];\n editor.meta.shortcuts = {} as Record<\n string,\n SlatePlugin['shortcuts'][string]\n >;\n editor.meta.components = {};\n editor.meta.pluginCache = {\n decorate: [],\n handlers: {\n onChange: [],\n },\n inject: {\n nodeProps: [],\n },\n node: {\n isContainer: [],\n isElement: [],\n isInline: [],\n isLeaf: [],\n isMarkableVoid: [],\n isNotSelectable: [],\n isStrictSiblings: [],\n isVoid: [],\n types: {},\n },\n normalizeInitialValue: [],\n render: {\n aboveEditable: [],\n aboveNodes: [],\n aboveSlate: [],\n afterContainer: [],\n afterEditable: [],\n beforeContainer: [],\n beforeEditable: [],\n belowNodes: [],\n belowRootNodes: [],\n },\n rules: {\n match: [],\n },\n useHooks: [],\n };\n\n const resolvedPlugins = resolveAndSortPlugins(editor, plugins);\n\n applyPluginsToEditor(editor, resolvedPlugins);\n\n resolvePluginOverrides(editor);\n\n resolvePluginStores(editor);\n\n // Last pass\n editor.meta.pluginList.forEach((plugin: SlatePlugin) => {\n if (plugin.extendEditor) {\n editor = plugin.extendEditor(getEditorPlugin(editor, plugin) as any);\n\n // Sync any editor methods that were modified by extendEditor\n syncLegacyMethods(editor);\n }\n\n // Sync overridden plugin methods to legacy editor methods\n resolvePluginMethods(editor, plugin);\n\n if (plugin.node?.isContainer) {\n editor.meta.pluginCache.node.isContainer.push(plugin.key);\n }\n\n editor.meta.pluginCache.node.types[plugin.node.type] = plugin.key;\n\n if (plugin.inject?.nodeProps) {\n editor.meta.pluginCache.inject.nodeProps.push(plugin.key);\n }\n\n if (plugin.render?.node) {\n editor.meta.components[plugin.key] = plugin.render.node;\n }\n\n if (plugin.node?.isLeaf) {\n editor.meta.pluginCache.node.isLeaf.push(plugin.key);\n }\n\n if (plugin.node?.isElement) {\n editor.meta.pluginCache.node.isElement.push(plugin.key);\n }\n\n if (plugin.node?.isInline) {\n editor.meta.pluginCache.node.isInline.push(plugin.key);\n }\n\n if (plugin.node?.isVoid) {\n editor.meta.pluginCache.node.isVoid.push(plugin.key);\n }\n\n if (plugin.node?.isMarkableVoid) {\n editor.meta.pluginCache.node.isMarkableVoid.push(plugin.key);\n }\n\n if (plugin.node?.isStrictSiblings) {\n editor.meta.pluginCache.node.isStrictSiblings.push(plugin.key);\n }\n\n if (plugin.node?.isSelectable === false) {\n editor.meta.pluginCache.node.isNotSelectable.push(plugin.key);\n }\n\n if (plugin.render.aboveEditable) {\n editor.meta.pluginCache.render.aboveEditable.push(plugin.key);\n }\n\n if (plugin.render.aboveSlate) {\n editor.meta.pluginCache.render.aboveSlate.push(plugin.key);\n }\n\n if (plugin.render.afterEditable) {\n editor.meta.pluginCache.render.afterEditable.push(plugin.key);\n }\n\n if (plugin.render.beforeEditable) {\n editor.meta.pluginCache.render.beforeEditable.push(plugin.key);\n }\n\n if (plugin.rules?.match) {\n editor.meta.pluginCache.rules.match.push(plugin.key);\n }\n\n if (plugin.render.afterContainer) {\n editor.meta.pluginCache.render.afterContainer.push(plugin.key);\n }\n\n if (plugin.render.beforeContainer) {\n editor.meta.pluginCache.render.beforeContainer.push(plugin.key);\n }\n\n if (plugin.render.belowRootNodes) {\n editor.meta.pluginCache.render.belowRootNodes.push(plugin.key);\n }\n\n if (plugin.normalizeInitialValue) {\n editor.meta.pluginCache.normalizeInitialValue.push(plugin.key);\n }\n\n if (plugin.decorate) {\n editor.meta.pluginCache.decorate.push(plugin.key);\n }\n\n if (plugin.render.aboveNodes) {\n editor.meta.pluginCache.render.aboveNodes.push(plugin.key);\n }\n\n if (plugin.render.belowNodes) {\n editor.meta.pluginCache.render.belowNodes.push(plugin.key);\n }\n\n if ((plugin as any).useHooks) {\n editor.meta.pluginCache.useHooks.push(plugin.key);\n }\n\n if ((plugin as any).handlers?.onChange) {\n editor.meta.pluginCache.handlers.onChange.push(plugin.key);\n }\n });\n\n resolvePluginShortcuts(editor);\n\n return editor;\n};\n\nconst resolvePluginStores = (editor: SlateEditor) => {\n // Create zustand stores for each plugin\n editor.meta.pluginList.forEach((plugin) => {\n let store = createZustandStore(plugin.options, {\n mutative: true,\n name: plugin.key,\n });\n\n // Apply option extensions\n if (\n (plugin as any).__selectorExtensions &&\n (plugin as any).__selectorExtensions.length > 0\n ) {\n (plugin as any).__selectorExtensions.forEach((extension: any) => {\n const extendedOptions = extension(getEditorPlugin(editor, plugin));\n\n store = store.extendSelectors(() => extendedOptions);\n });\n }\n\n plugin.optionsStore = store;\n });\n};\n\nconst resolvePluginMethods = (editor: SlateEditor, plugin: any) => {\n // Merge APIs\n Object.entries(plugin.api).forEach(([apiKey, apiFunction]) => {\n (editor.api as any)[apiKey] = apiFunction;\n });\n\n // Apply API and transform extensions\n if (plugin.__apiExtensions && plugin.__apiExtensions.length > 0) {\n plugin.__apiExtensions.forEach(\n ({ extension, isOverride, isPluginSpecific, isTransform }: any) => {\n const newExtensions = extension(getEditorPlugin(editor, plugin) as any);\n\n if (isOverride) {\n // Handle combined API and transforms override\n if (newExtensions.api) {\n merge(editor.api, newExtensions.api);\n merge(plugin.api, newExtensions.api);\n assignLegacyApi(editor, editor.api);\n }\n if (newExtensions.transforms) {\n merge(editor.transforms, newExtensions.transforms);\n merge(plugin.transforms, newExtensions.transforms);\n assignLegacyTransforms(editor, newExtensions.transforms);\n }\n } else if (isTransform) {\n // Handle transforms\n if (isPluginSpecific) {\n