@openeditor/custom-block 0.0.47 → 0.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/editor.d.ts CHANGED
@@ -26,6 +26,14 @@ type OpenEditorCustomBlockEditorAdapter<TData extends OpenEditorCustomBlockData
26
26
  render: ComponentType<OpenEditorCustomBlockEditorContext<TData>>;
27
27
  };
28
28
  declare const defineOpenEditorCustomBlockEditor: <TData extends OpenEditorCustomBlockData>(adapter: OpenEditorCustomBlockEditorAdapter<TData>) => OpenEditorCustomBlockEditorAdapter<TData>;
29
+ type OpenEditorCustomBlockEvent = {
30
+ type: string;
31
+ button?: unknown;
32
+ };
33
+ declare const shouldStopOpenEditorCustomBlockEvent: (event: OpenEditorCustomBlockEvent) => boolean;
34
+ declare const stopOpenEditorCustomBlockEventPropagation: (event: OpenEditorCustomBlockEvent & {
35
+ stopPropagation: () => void;
36
+ }) => void;
29
37
  type OpenEditorCustomBlockEditorSurfaceProps = {
30
38
  node: ProseMirrorNode;
31
39
  registry: OpenEditorCustomBlockRegistry;
@@ -46,4 +54,4 @@ declare const createOpenEditorCustomBlockEditorExtension: (options: {
46
54
  host: OpenEditorCustomBlockEditorHost;
47
55
  }) => Node<any, any>;
48
56
 
49
- export { type OpenEditorCustomBlockDocumentEditorProps, type OpenEditorCustomBlockEditorAdapter, type OpenEditorCustomBlockEditorContext, type OpenEditorCustomBlockEditorHost, OpenEditorCustomBlockEditorSurface, type OpenEditorCustomBlockEditorSurfaceProps, createOpenEditorCustomBlockEditorExtension, defineOpenEditorCustomBlockEditor };
57
+ export { type OpenEditorCustomBlockDocumentEditorProps, type OpenEditorCustomBlockEditorAdapter, type OpenEditorCustomBlockEditorContext, type OpenEditorCustomBlockEditorHost, OpenEditorCustomBlockEditorSurface, type OpenEditorCustomBlockEditorSurfaceProps, createOpenEditorCustomBlockEditorExtension, defineOpenEditorCustomBlockEditor, shouldStopOpenEditorCustomBlockEvent, stopOpenEditorCustomBlockEventPropagation };
package/dist/editor.js CHANGED
@@ -5,6 +5,14 @@ import { jsxs, jsx } from 'react/jsx-runtime';
5
5
 
6
6
  // src/editor.tsx
7
7
  var defineOpenEditorCustomBlockEditor = (adapter) => adapter;
8
+ var shouldStopOpenEditorCustomBlockEvent = (event) => {
9
+ if (event.type === "contextmenu") return true;
10
+ if (event.type !== "mousedown" && event.type !== "pointerdown") return false;
11
+ return "button" in event && typeof event.button === "number" && event.button !== 0;
12
+ };
13
+ var stopOpenEditorCustomBlockEventPropagation = (event) => {
14
+ if (shouldStopOpenEditorCustomBlockEvent(event)) event.stopPropagation();
15
+ };
8
16
  var EditorAdapterErrorBoundary = class extends Component {
9
17
  state = { failed: false };
10
18
  static getDerivedStateFromError() {
@@ -66,20 +74,29 @@ var createOpenEditorCustomBlockEditorExtension = (options) => Node.create({
66
74
  addAttributes: () => ({ "openeditor-id": { default: null }, blockId: { default: null }, version: { default: null }, data: { default: {} } }),
67
75
  renderHTML: ({ node }) => ["div", { "data-openeditor-custom-block": node.attrs.blockId ?? "unknown" }],
68
76
  addNodeView() {
69
- return ReactNodeViewRenderer((props) => /* @__PURE__ */ jsx(NodeViewWrapper, { "data-openeditor-custom-block": props.node.attrs.blockId ?? "unknown", children: /* @__PURE__ */ jsx(
70
- OpenEditorCustomBlockEditorSurface,
77
+ return ReactNodeViewRenderer((props) => /* @__PURE__ */ jsx(
78
+ NodeViewWrapper,
71
79
  {
72
- adapters: options.adapters,
73
- host: options.host,
74
- node: props.node.toJSON(),
75
- registry: options.registry,
76
- selected: props.selected,
77
- updateNode: (next) => props.updateAttributes(next.attrs ?? {})
80
+ "data-openeditor-custom-block": props.node.attrs.blockId ?? "unknown",
81
+ onContextMenu: stopOpenEditorCustomBlockEventPropagation,
82
+ onMouseDown: stopOpenEditorCustomBlockEventPropagation,
83
+ onPointerDown: stopOpenEditorCustomBlockEventPropagation,
84
+ children: /* @__PURE__ */ jsx(
85
+ OpenEditorCustomBlockEditorSurface,
86
+ {
87
+ adapters: options.adapters,
88
+ host: options.host,
89
+ node: props.node.toJSON(),
90
+ registry: options.registry,
91
+ selected: props.selected,
92
+ updateNode: (next) => props.updateAttributes(next.attrs ?? {})
93
+ }
94
+ )
78
95
  }
79
- ) }));
96
+ ));
80
97
  }
81
98
  });
82
99
 
83
- export { OpenEditorCustomBlockEditorSurface, createOpenEditorCustomBlockEditorExtension, defineOpenEditorCustomBlockEditor };
100
+ export { OpenEditorCustomBlockEditorSurface, createOpenEditorCustomBlockEditorExtension, defineOpenEditorCustomBlockEditor, shouldStopOpenEditorCustomBlockEvent, stopOpenEditorCustomBlockEventPropagation };
84
101
  //# sourceMappingURL=editor.js.map
85
102
  //# sourceMappingURL=editor.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/editor.tsx"],"names":["adapter"],"mappings":"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","file":"editor.js","sourcesContent":["import type { OpenEditorDocument, ProseMirrorNode } from \"@openeditor/core\";\nimport {\n type OpenEditorCustomBlockData,\n type OpenEditorCustomBlockDefinition,\n type OpenEditorCustomBlockHost,\n type OpenEditorCustomBlockRegistry,\n} from \"./index\";\nimport { Component, useEffect, useRef, type ComponentType, type ReactNode } from \"react\";\nimport { Node } from \"@tiptap/core\";\nimport { NodeViewWrapper, ReactNodeViewRenderer, type ReactNodeViewProps } from \"@tiptap/react\";\n\nexport type OpenEditorCustomBlockDocumentEditorProps = {\n value: OpenEditorDocument;\n onChange: (value: OpenEditorDocument) => void;\n ariaLabel: string;\n};\nexport type OpenEditorCustomBlockEditorHost = OpenEditorCustomBlockHost & {\n fields: { document: ComponentType<OpenEditorCustomBlockDocumentEditorProps> };\n};\nexport type OpenEditorCustomBlockEditorContext<TData extends OpenEditorCustomBlockData> = {\n data: Readonly<TData>;\n instanceId: string;\n host: OpenEditorCustomBlockEditorHost;\n updateData: (update: TData | ((current: Readonly<TData>) => TData)) => void;\n selected: boolean;\n};\nexport type OpenEditorCustomBlockEditorAdapter<TData extends OpenEditorCustomBlockData = any> = {\n block: OpenEditorCustomBlockDefinition<TData>;\n render: ComponentType<OpenEditorCustomBlockEditorContext<TData>>;\n};\nexport const defineOpenEditorCustomBlockEditor = <TData extends OpenEditorCustomBlockData>(adapter: OpenEditorCustomBlockEditorAdapter<TData>) => adapter;\n\nexport type OpenEditorCustomBlockEditorSurfaceProps = {\n node: ProseMirrorNode;\n registry: OpenEditorCustomBlockRegistry;\n adapters: readonly OpenEditorCustomBlockEditorAdapter[];\n host: OpenEditorCustomBlockEditorHost;\n updateNode: (node: ProseMirrorNode) => void;\n selected?: boolean;\n fallback?: (input: { node: ProseMirrorNode; status: string }) => ReactNode;\n};\n\nclass EditorAdapterErrorBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false };\n static getDerivedStateFromError() { return { failed: true }; }\n componentDidCatch() {}\n render() {\n return this.state.failed\n ? <div data-openeditor-custom-block-error=\"editor-error\" role=\"status\">Custom block editor unavailable.</div>\n : this.props.children;\n }\n}\n\nconst ReadyEditorSurface = ({ resolved, adapter, host, updateNode, selected }: { resolved: Extract<ReturnType<OpenEditorCustomBlockRegistry[\"resolve\"]>, { status: \"ready\" }>; adapter: OpenEditorCustomBlockEditorAdapter; host: OpenEditorCustomBlockEditorHost; updateNode: (node: ProseMirrorNode) => void; selected: boolean }) => {\n const persistedMigration = useRef<string | null>(null);\n useEffect(() => {\n if (!resolved.migrated) { persistedMigration.current = null; return; }\n const migrationKey = `${String(resolved.node.attrs?.[\"openeditor-id\"])}:${String(resolved.node.attrs?.version)}`;\n if (persistedMigration.current === migrationKey) return;\n persistedMigration.current = migrationKey;\n updateNode(resolved.node);\n }, [resolved.migrated, resolved.node, updateNode]);\n const Render = adapter.render;\n const instanceId = String(resolved.node.attrs?.[\"openeditor-id\"]);\n const updateData = (update: OpenEditorCustomBlockData | ((current: Readonly<OpenEditorCustomBlockData>) => OpenEditorCustomBlockData)) => {\n const data = typeof update === \"function\" ? update(resolved.data) : update;\n updateNode({ ...resolved.node, attrs: { ...resolved.node.attrs, data } });\n };\n return (\n <EditorAdapterErrorBoundary key={`${String(resolved.node.attrs?.[\"openeditor-id\"])}:${resolved.definition.id}`}>\n <Render data={resolved.data} host={host} instanceId={instanceId} selected={selected} updateData={updateData} />\n </EditorAdapterErrorBoundary>\n );\n};\n\nexport const OpenEditorCustomBlockEditorSurface = ({ node, registry, adapters, host, updateNode, selected = false, fallback }: OpenEditorCustomBlockEditorSurfaceProps) => {\n const ids = new Set<string>();\n for (const adapter of adapters) {\n if (ids.has(adapter.block.id)) throw new Error(`Duplicate custom block editor adapter \"${adapter.block.id}\".`);\n ids.add(adapter.block.id);\n }\n const resolved = registry.resolve(node);\n if (resolved.status !== \"ready\") return fallback?.({ node, status: resolved.status }) ?? <div data-openeditor-custom-block-error={resolved.status} role=\"status\">Custom block unavailable: {resolved.status}.</div>;\n const adapter = adapters.find((item) => item.block.id === resolved.definition.id);\n if (!adapter) return fallback?.({ node, status: \"missing-editor\" }) ?? <div data-openeditor-custom-block-error=\"missing-editor\" role=\"status\">Custom block editor unavailable.</div>;\n if (adapter.block !== resolved.definition) return fallback?.({ node, status: \"incompatible-editor\" }) ?? <div data-openeditor-custom-block-error=\"incompatible-editor\" role=\"status\">Custom block editor unavailable.</div>;\n return <ReadyEditorSurface adapter={adapter} host={host} resolved={resolved} selected={selected} updateNode={(next) => { const checked = registry.resolve(next); if (checked.status !== \"ready\") throw new Error(`Invalid data for custom block \"${resolved.definition.id}\".`); updateNode(checked.node); }} />;\n};\n\n/** Installs the editor lifecycle on the one fixed customBlock schema node. */\nexport const createOpenEditorCustomBlockEditorExtension = (options: {\n registry: OpenEditorCustomBlockRegistry;\n adapters: readonly OpenEditorCustomBlockEditorAdapter[];\n host: OpenEditorCustomBlockEditorHost;\n}) => Node.create({\n name: \"customBlock\",\n group: \"block\",\n atom: true,\n isolating: true,\n draggable: true,\n addAttributes: () => ({ \"openeditor-id\": { default: null }, blockId: { default: null }, version: { default: null }, data: { default: {} } }),\n renderHTML: ({ node }) => [\"div\", { \"data-openeditor-custom-block\": node.attrs.blockId ?? \"unknown\" }],\n addNodeView() {\n return ReactNodeViewRenderer((props: ReactNodeViewProps) => (\n <NodeViewWrapper data-openeditor-custom-block={props.node.attrs.blockId ?? \"unknown\"}>\n <OpenEditorCustomBlockEditorSurface\n adapters={options.adapters}\n host={options.host}\n node={props.node.toJSON()}\n registry={options.registry}\n selected={props.selected}\n updateNode={(next) => props.updateAttributes(next.attrs ?? {})}\n />\n </NodeViewWrapper>\n ));\n },\n});\n"]}
1
+ {"version":3,"sources":["../src/editor.tsx"],"names":["adapter"],"mappings":"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","file":"editor.js","sourcesContent":["import type { OpenEditorDocument, ProseMirrorNode } from \"@openeditor/core\";\nimport {\n type OpenEditorCustomBlockData,\n type OpenEditorCustomBlockDefinition,\n type OpenEditorCustomBlockHost,\n type OpenEditorCustomBlockRegistry,\n} from \"./index\";\nimport { Component, useEffect, useRef, type ComponentType, type ReactNode } from \"react\";\nimport { Node } from \"@tiptap/core\";\nimport { NodeViewWrapper, ReactNodeViewRenderer, type ReactNodeViewProps } from \"@tiptap/react\";\n\nexport type OpenEditorCustomBlockDocumentEditorProps = {\n value: OpenEditorDocument;\n onChange: (value: OpenEditorDocument) => void;\n ariaLabel: string;\n};\nexport type OpenEditorCustomBlockEditorHost = OpenEditorCustomBlockHost & {\n fields: { document: ComponentType<OpenEditorCustomBlockDocumentEditorProps> };\n};\nexport type OpenEditorCustomBlockEditorContext<TData extends OpenEditorCustomBlockData> = {\n data: Readonly<TData>;\n instanceId: string;\n host: OpenEditorCustomBlockEditorHost;\n updateData: (update: TData | ((current: Readonly<TData>) => TData)) => void;\n selected: boolean;\n};\nexport type OpenEditorCustomBlockEditorAdapter<TData extends OpenEditorCustomBlockData = any> = {\n block: OpenEditorCustomBlockDefinition<TData>;\n render: ComponentType<OpenEditorCustomBlockEditorContext<TData>>;\n};\nexport const defineOpenEditorCustomBlockEditor = <TData extends OpenEditorCustomBlockData>(adapter: OpenEditorCustomBlockEditorAdapter<TData>) => adapter;\n\ntype OpenEditorCustomBlockEvent = {\n type: string;\n button?: unknown;\n};\n\nexport const shouldStopOpenEditorCustomBlockEvent = (event: OpenEditorCustomBlockEvent): boolean => {\n if (event.type === \"contextmenu\") return true;\n if (event.type !== \"mousedown\" && event.type !== \"pointerdown\") return false;\n return \"button\" in event && typeof event.button === \"number\" && event.button !== 0;\n};\n\nexport const stopOpenEditorCustomBlockEventPropagation = (\n event: OpenEditorCustomBlockEvent & { stopPropagation: () => void },\n): void => {\n if (shouldStopOpenEditorCustomBlockEvent(event)) event.stopPropagation();\n};\n\nexport type OpenEditorCustomBlockEditorSurfaceProps = {\n node: ProseMirrorNode;\n registry: OpenEditorCustomBlockRegistry;\n adapters: readonly OpenEditorCustomBlockEditorAdapter[];\n host: OpenEditorCustomBlockEditorHost;\n updateNode: (node: ProseMirrorNode) => void;\n selected?: boolean;\n fallback?: (input: { node: ProseMirrorNode; status: string }) => ReactNode;\n};\n\nclass EditorAdapterErrorBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false };\n static getDerivedStateFromError() { return { failed: true }; }\n componentDidCatch() {}\n render() {\n return this.state.failed\n ? <div data-openeditor-custom-block-error=\"editor-error\" role=\"status\">Custom block editor unavailable.</div>\n : this.props.children;\n }\n}\n\nconst ReadyEditorSurface = ({ resolved, adapter, host, updateNode, selected }: { resolved: Extract<ReturnType<OpenEditorCustomBlockRegistry[\"resolve\"]>, { status: \"ready\" }>; adapter: OpenEditorCustomBlockEditorAdapter; host: OpenEditorCustomBlockEditorHost; updateNode: (node: ProseMirrorNode) => void; selected: boolean }) => {\n const persistedMigration = useRef<string | null>(null);\n useEffect(() => {\n if (!resolved.migrated) { persistedMigration.current = null; return; }\n const migrationKey = `${String(resolved.node.attrs?.[\"openeditor-id\"])}:${String(resolved.node.attrs?.version)}`;\n if (persistedMigration.current === migrationKey) return;\n persistedMigration.current = migrationKey;\n updateNode(resolved.node);\n }, [resolved.migrated, resolved.node, updateNode]);\n const Render = adapter.render;\n const instanceId = String(resolved.node.attrs?.[\"openeditor-id\"]);\n const updateData = (update: OpenEditorCustomBlockData | ((current: Readonly<OpenEditorCustomBlockData>) => OpenEditorCustomBlockData)) => {\n const data = typeof update === \"function\" ? update(resolved.data) : update;\n updateNode({ ...resolved.node, attrs: { ...resolved.node.attrs, data } });\n };\n return (\n <EditorAdapterErrorBoundary key={`${String(resolved.node.attrs?.[\"openeditor-id\"])}:${resolved.definition.id}`}>\n <Render data={resolved.data} host={host} instanceId={instanceId} selected={selected} updateData={updateData} />\n </EditorAdapterErrorBoundary>\n );\n};\n\nexport const OpenEditorCustomBlockEditorSurface = ({ node, registry, adapters, host, updateNode, selected = false, fallback }: OpenEditorCustomBlockEditorSurfaceProps) => {\n const ids = new Set<string>();\n for (const adapter of adapters) {\n if (ids.has(adapter.block.id)) throw new Error(`Duplicate custom block editor adapter \"${adapter.block.id}\".`);\n ids.add(adapter.block.id);\n }\n const resolved = registry.resolve(node);\n if (resolved.status !== \"ready\") return fallback?.({ node, status: resolved.status }) ?? <div data-openeditor-custom-block-error={resolved.status} role=\"status\">Custom block unavailable: {resolved.status}.</div>;\n const adapter = adapters.find((item) => item.block.id === resolved.definition.id);\n if (!adapter) return fallback?.({ node, status: \"missing-editor\" }) ?? <div data-openeditor-custom-block-error=\"missing-editor\" role=\"status\">Custom block editor unavailable.</div>;\n if (adapter.block !== resolved.definition) return fallback?.({ node, status: \"incompatible-editor\" }) ?? <div data-openeditor-custom-block-error=\"incompatible-editor\" role=\"status\">Custom block editor unavailable.</div>;\n return <ReadyEditorSurface adapter={adapter} host={host} resolved={resolved} selected={selected} updateNode={(next) => { const checked = registry.resolve(next); if (checked.status !== \"ready\") throw new Error(`Invalid data for custom block \"${resolved.definition.id}\".`); updateNode(checked.node); }} />;\n};\n\n/** Installs the editor lifecycle on the one fixed customBlock schema node. */\nexport const createOpenEditorCustomBlockEditorExtension = (options: {\n registry: OpenEditorCustomBlockRegistry;\n adapters: readonly OpenEditorCustomBlockEditorAdapter[];\n host: OpenEditorCustomBlockEditorHost;\n}) => Node.create({\n name: \"customBlock\",\n group: \"block\",\n atom: true,\n isolating: true,\n draggable: true,\n addAttributes: () => ({ \"openeditor-id\": { default: null }, blockId: { default: null }, version: { default: null }, data: { default: {} } }),\n renderHTML: ({ node }) => [\"div\", { \"data-openeditor-custom-block\": node.attrs.blockId ?? \"unknown\" }],\n addNodeView() {\n return ReactNodeViewRenderer((props: ReactNodeViewProps) => (\n <NodeViewWrapper\n data-openeditor-custom-block={props.node.attrs.blockId ?? \"unknown\"}\n onContextMenu={stopOpenEditorCustomBlockEventPropagation}\n onMouseDown={stopOpenEditorCustomBlockEventPropagation}\n onPointerDown={stopOpenEditorCustomBlockEventPropagation}\n >\n <OpenEditorCustomBlockEditorSurface\n adapters={options.adapters}\n host={options.host}\n node={props.node.toJSON()}\n registry={options.registry}\n selected={props.selected}\n updateNode={(next) => props.updateAttributes(next.attrs ?? {})}\n />\n </NodeViewWrapper>\n ));\n },\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openeditor/custom-block",
3
- "version": "0.0.47",
3
+ "version": "0.0.48",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "repository": {
@@ -33,8 +33,8 @@
33
33
  "./package.json": "./package.json"
34
34
  },
35
35
  "dependencies": {
36
- "@openeditor/core": "0.0.47",
37
- "@openeditor/extensions": "0.0.47"
36
+ "@openeditor/core": "0.0.48",
37
+ "@openeditor/extensions": "0.0.48"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@tiptap/core": ">=3.29.2",