@openeditor/react 0.0.29 → 0.0.31
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/README.md +32 -1
- package/dist/index.d.ts +55 -13
- package/dist/index.js +3201 -706
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -2,17 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
Headless React bindings for OpenEditor's web editor runtime.
|
|
4
4
|
|
|
5
|
-
Pass `
|
|
5
|
+
Pass `imageRuntime` and `attachmentRuntime` to `useOpenEditorController` for
|
|
6
|
+
host-backed media and to `OpenEditorViewer` for identity-based URL resolution.
|
|
7
|
+
Progress, cancellation, retry input, and errors remain transient node-view state
|
|
8
|
+
and are never emitted through document JSON.
|
|
9
|
+
|
|
10
|
+
An inserted image starts as an empty image node—never a fake placeholder URL.
|
|
11
|
+
The built-in node view offers upload, drag/drop, URL embedding, replacement,
|
|
12
|
+
alternative-text editing, progress, retry, and removal. The upload button is
|
|
13
|
+
shown only when the host supplies `selectImage` and `uploadImage`:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
const imageRuntime = {
|
|
17
|
+
selectImage: () => chooseImageFromYourPicker(),
|
|
18
|
+
validateImage: (input) => input.size && input.size > 15_000_000
|
|
19
|
+
? { accepted: false, message: "Image is too large." }
|
|
20
|
+
: { accepted: true },
|
|
21
|
+
uploadImage: (input, { signal, onProgress } = {}) =>
|
|
22
|
+
uploadToYourStorage(input.source, { signal, onProgress }),
|
|
23
|
+
resolveImage: (imageId, { signal } = {}) =>
|
|
24
|
+
resolveImageFromYourStorage(imageId, { signal }),
|
|
25
|
+
replaceImage: (imageId, input, options) =>
|
|
26
|
+
replaceImageInYourStorage(imageId, input.source, options),
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const controller = useOpenEditorController({ imageRuntime });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`uploadImage` and `replaceImage` return an `OpenEditorImageSnapshot`. Store a
|
|
33
|
+
durable `imageId`, public `src`, or both; `resolveImage` may return a temporary
|
|
34
|
+
owner-preview URL such as a `blob:` URL without serializing it.
|
|
6
35
|
|
|
7
36
|
## Public surface
|
|
8
37
|
|
|
9
38
|
- `useOpenEditorController` for editor state, commands, document exports, and selection state
|
|
10
39
|
- `OpenEditorContent` for the editable Tiptap-backed content surface
|
|
40
|
+
- `OpenEditorBubbleMenu` for Tiptap-owned selection visibility and positioning
|
|
11
41
|
- `OpenEditorViewer` for read-only React rendering
|
|
12
42
|
- `OpenEditorPageHeader` for host-backed page title and icon editing
|
|
13
43
|
- `getDefaultBlockPickerItems` for host-owned block rails, pickers, and command palettes
|
|
14
44
|
- `getDefaultSlashMenuItems` for UI packages that want the built-in insert actions
|
|
15
45
|
- stable-identity block targeting and transaction-backed copy, duplicate, move, and delete commands
|
|
46
|
+
- a first-class `controller.table` domain API for selection-aware row, column, header, cell, and table commands
|
|
16
47
|
- `OpenEditorBlockDragHandle` and `useOpenEditorBlockInteraction` for headless block-handle UIs
|
|
17
48
|
- `defineOpenEditorReactNode` for consumer-owned React blocks
|
|
18
49
|
- `defineOpenEditorReactExtension` for advanced integrations that contribute multiple Tiptap extensions
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties, RefObject, ComponentType } from 'react';
|
|
3
|
-
import { OpenEditorBlockRef, OpenEditorDocument, BlockSpec, ProseMirrorNode, OpenEditorUrlPolicy, OpenEditorUrlContext, OpenEditorPageRuntime, OpenEditorAttachmentRuntime, OpenEditorPageSnapshot, OpenEditorAuthoringCapabilities } from '@openeditor/core';
|
|
4
|
-
export { OpenEditorBlockRef, OpenEditorPageRuntime, OpenEditorPageSnapshot, OpenEditorUrlContext, OpenEditorUrlPolicy, openEditorPublicUrlPolicy, openEditorUnsafeUrlPolicy } from '@openeditor/core';
|
|
3
|
+
import { OpenEditorBlockRef, OpenEditorDocument, BlockSpec, ProseMirrorNode, OpenEditorUrlPolicy, OpenEditorUrlContext, OpenEditorPageRuntime, OpenEditorAttachmentRuntime, OpenEditorImageRuntime, OpenEditorPageSnapshot, OpenEditorAuthoringCapabilities } from '@openeditor/core';
|
|
4
|
+
export { OpenEditorBlockRef, OpenEditorImageRuntime, OpenEditorImageSnapshot, OpenEditorImageUploadInput, OpenEditorPageRuntime, OpenEditorPageSnapshot, OpenEditorUrlContext, OpenEditorUrlPolicy, openEditorPublicUrlPolicy, openEditorUnsafeUrlPolicy } from '@openeditor/core';
|
|
5
5
|
import { ExportFormat, OpenEditorExporters } from '@openeditor/exporters';
|
|
6
6
|
export { seedDocument } from '@openeditor/extensions';
|
|
7
|
-
import { AnyExtension, NodeConfig } from '@tiptap/core';
|
|
7
|
+
import { Editor, AnyExtension, NodeConfig } from '@tiptap/core';
|
|
8
8
|
import { ReactNodeViewProps } from '@tiptap/react';
|
|
9
9
|
export { NodeViewContent, NodeViewWrapper, ReactNodeViewProps as OpenEditorNodeViewProps } from '@tiptap/react';
|
|
10
10
|
|
|
@@ -29,6 +29,27 @@ declare function OpenEditorThemeProvider({ children, className, theme }: {
|
|
|
29
29
|
theme: OpenEditorTheme;
|
|
30
30
|
}): react.JSX.Element;
|
|
31
31
|
|
|
32
|
+
declare const openEditorTableCommands: readonly ["addRowBefore", "addRowAfter", "deleteRow", "addColumnBefore", "addColumnAfter", "deleteColumn", "toggleHeaderRow", "toggleHeaderColumn", "mergeCells", "splitCell", "deleteTable"];
|
|
33
|
+
type OpenEditorTableCommand = (typeof openEditorTableCommands)[number];
|
|
34
|
+
type OpenEditorTableState = {
|
|
35
|
+
active: boolean;
|
|
36
|
+
rows: number;
|
|
37
|
+
columns: number;
|
|
38
|
+
headerRow: boolean;
|
|
39
|
+
headerColumn: boolean;
|
|
40
|
+
cellSelection: boolean;
|
|
41
|
+
canMergeCells: boolean;
|
|
42
|
+
canSplitCell: boolean;
|
|
43
|
+
};
|
|
44
|
+
type OpenEditorTableController = {
|
|
45
|
+
getState: () => OpenEditorTableState;
|
|
46
|
+
can: (command: OpenEditorTableCommand) => boolean;
|
|
47
|
+
run: (command: OpenEditorTableCommand) => boolean;
|
|
48
|
+
};
|
|
49
|
+
declare const getOpenEditorTableState: (editor: Editor | null) => OpenEditorTableState;
|
|
50
|
+
declare const canRunOpenEditorTableCommand: (editor: Editor | null, command: OpenEditorTableCommand) => boolean;
|
|
51
|
+
declare const runOpenEditorTableCommand: (editor: Editor | null, command: OpenEditorTableCommand) => boolean;
|
|
52
|
+
|
|
32
53
|
type OpenEditorReactProps = OpenEditorAuthoringCapabilities & {
|
|
33
54
|
initialDocument?: OpenEditorDocument;
|
|
34
55
|
editable?: boolean;
|
|
@@ -37,6 +58,7 @@ type OpenEditorReactProps = OpenEditorAuthoringCapabilities & {
|
|
|
37
58
|
onFilePasteDrop?: (file: File) => boolean;
|
|
38
59
|
pageRuntime?: OpenEditorPageRuntime;
|
|
39
60
|
attachmentRuntime?: OpenEditorAttachmentRuntime<any>;
|
|
61
|
+
imageRuntime?: OpenEditorImageRuntime<any>;
|
|
40
62
|
slashMenuItems?: readonly OpenEditorSlashMenuItem[];
|
|
41
63
|
/** Consumer-owned blocks. Extension names and node types must be unique. */
|
|
42
64
|
extensions?: readonly OpenEditorReactExtension[];
|
|
@@ -65,6 +87,8 @@ type OpenEditorController = {
|
|
|
65
87
|
setSelectedBlock: (blockName: string) => void;
|
|
66
88
|
getContent: () => OpenEditorDocument;
|
|
67
89
|
setContent: (document: OpenEditorDocument) => void;
|
|
90
|
+
focus: () => void;
|
|
91
|
+
getPositionRect: (position: number) => OpenEditorOverlayRect | null;
|
|
68
92
|
setParagraph: () => void;
|
|
69
93
|
toggleHeading: (level: 1 | 2 | 3 | 4 | 5 | 6) => void;
|
|
70
94
|
toggleBold: () => void;
|
|
@@ -77,6 +101,7 @@ type OpenEditorController = {
|
|
|
77
101
|
toggleTaskList: () => void;
|
|
78
102
|
toggleBlockquote: () => void;
|
|
79
103
|
toggleCodeBlock: () => void;
|
|
104
|
+
table: OpenEditorTableController;
|
|
80
105
|
undo: () => void;
|
|
81
106
|
redo: () => void;
|
|
82
107
|
insertBlock: (blockName?: string, range?: InsertRange) => boolean;
|
|
@@ -98,9 +123,11 @@ type OpenEditorController = {
|
|
|
98
123
|
extensions: readonly OpenEditorReactExtension[];
|
|
99
124
|
pageRuntime?: OpenEditorPageRuntime;
|
|
100
125
|
attachmentRuntime?: OpenEditorAttachmentRuntime<any>;
|
|
126
|
+
imageRuntime?: OpenEditorImageRuntime<any>;
|
|
101
127
|
enabledBlocks?: readonly string[];
|
|
102
128
|
slashState: SlashState | null;
|
|
103
|
-
|
|
129
|
+
dismissSlashMenu: () => void;
|
|
130
|
+
registerSlashMenuKeyboardHandler: (handler: (event: globalThis.KeyboardEvent) => boolean) => () => void;
|
|
104
131
|
};
|
|
105
132
|
type OpenEditorContentProps = {
|
|
106
133
|
controller: OpenEditorController;
|
|
@@ -126,11 +153,6 @@ type SlashState = {
|
|
|
126
153
|
top: number;
|
|
127
154
|
anchorRect?: OpenEditorOverlayRect;
|
|
128
155
|
};
|
|
129
|
-
type SelectionBubbleState = {
|
|
130
|
-
left: number;
|
|
131
|
-
top: number;
|
|
132
|
-
anchorRect?: OpenEditorOverlayRect;
|
|
133
|
-
};
|
|
134
156
|
type OpenEditorSlashMenuIconProps = {
|
|
135
157
|
"aria-hidden"?: boolean;
|
|
136
158
|
className?: string;
|
|
@@ -212,6 +234,7 @@ type OpenEditorViewerProps = {
|
|
|
212
234
|
extensions?: readonly OpenEditorReactExtension[];
|
|
213
235
|
pageRuntime?: OpenEditorPageRuntime;
|
|
214
236
|
attachmentRuntime?: OpenEditorAttachmentRuntime<any>;
|
|
237
|
+
imageRuntime?: OpenEditorImageRuntime<any>;
|
|
215
238
|
/** Safe by default. Supply an explicit host policy for trusted preview URLs such as `blob:`. */
|
|
216
239
|
urlPolicy?: OpenEditorUrlPolicy;
|
|
217
240
|
};
|
|
@@ -231,7 +254,26 @@ type OpenEditorPageHeaderProps = {
|
|
|
231
254
|
};
|
|
232
255
|
/** Canonical Notion-style page metadata editor shared by host page surfaces. */
|
|
233
256
|
declare const OpenEditorPageHeader: ({ page, runtime, className, onPageChange, }: OpenEditorPageHeaderProps) => react.JSX.Element;
|
|
234
|
-
declare const useOpenEditorController: ({ initialDocument, editable, placeholder, onChange, onFilePasteDrop, pageRuntime, attachmentRuntime, enabledBlocks, slashMenuItems, extensions, blockActions, }?: OpenEditorReactProps) => OpenEditorController;
|
|
257
|
+
declare const useOpenEditorController: ({ initialDocument, editable, placeholder, onChange, onFilePasteDrop, pageRuntime, attachmentRuntime, imageRuntime, enabledBlocks, slashMenuItems, extensions, blockActions, }?: OpenEditorReactProps) => OpenEditorController;
|
|
258
|
+
type OpenEditorBubbleMenuProps = {
|
|
259
|
+
controller: OpenEditorController;
|
|
260
|
+
children: ReactNode;
|
|
261
|
+
className?: string;
|
|
262
|
+
container?: HTMLElement | null;
|
|
263
|
+
scrollTarget?: HTMLElement | Window | null;
|
|
264
|
+
style?: CSSProperties;
|
|
265
|
+
};
|
|
266
|
+
type OpenEditorTableBubbleMenuProps = {
|
|
267
|
+
controller: OpenEditorController;
|
|
268
|
+
children: (state: OpenEditorTableState) => ReactNode;
|
|
269
|
+
className?: string;
|
|
270
|
+
container?: HTMLElement | null;
|
|
271
|
+
style?: CSSProperties;
|
|
272
|
+
};
|
|
273
|
+
/** Selection-aware positioning and lifecycle owned by Tiptap's BubbleMenu plugin. */
|
|
274
|
+
declare const OpenEditorBubbleMenu: ({ controller, children, className, container, scrollTarget, style, }: OpenEditorBubbleMenuProps) => react.JSX.Element | null;
|
|
275
|
+
/** A table-owned contextual surface, anchored to the complete selected table. */
|
|
276
|
+
declare const OpenEditorTableBubbleMenu: ({ controller, children, className, container, style, }: OpenEditorTableBubbleMenuProps) => react.JSX.Element | null;
|
|
235
277
|
declare const useOpenEditorBlockInteraction: (controller: OpenEditorController) => OpenEditorBlockInteractionSnapshot;
|
|
236
278
|
type OpenEditorBlockDragHandleProps = {
|
|
237
279
|
controller: OpenEditorController;
|
|
@@ -254,7 +296,7 @@ declare const sortBlockPickerItems: (items: readonly OpenEditorBlockPickerItem[]
|
|
|
254
296
|
declare const getDefaultBlockPickerItems: (controller: OpenEditorController) => OpenEditorBlockPickerItem[];
|
|
255
297
|
declare const getDefaultSlashMenuItems: (controller: OpenEditorController) => OpenEditorSlashMenuItem[];
|
|
256
298
|
declare const OpenEditorContent: ({ controller, className, }: OpenEditorContentProps) => react.JSX.Element;
|
|
257
|
-
declare const OpenEditorViewer: ({ document, className, renderers, extensions, pageRuntime, attachmentRuntime, urlPolicy, }: OpenEditorViewerProps) => react.JSX.Element;
|
|
258
|
-
declare const useOpenEditor: ({ initialDocument, editable, placeholder, onChange, onFilePasteDrop, pageRuntime, attachmentRuntime, enabledBlocks, slashMenuItems, extensions, blockActions, }?: OpenEditorReactProps) => OpenEditorController;
|
|
299
|
+
declare const OpenEditorViewer: ({ document, className, renderers, extensions, pageRuntime, attachmentRuntime, imageRuntime, urlPolicy, }: OpenEditorViewerProps) => react.JSX.Element;
|
|
300
|
+
declare const useOpenEditor: ({ initialDocument, editable, placeholder, onChange, onFilePasteDrop, pageRuntime, attachmentRuntime, imageRuntime, enabledBlocks, slashMenuItems, extensions, blockActions, }?: OpenEditorReactProps) => OpenEditorController;
|
|
259
301
|
|
|
260
|
-
export { type InsertRange, type OpenEditorBlockAction, type OpenEditorBlockActionContext, OpenEditorBlockDragHandle, type OpenEditorBlockDragHandleProps, type OpenEditorBlockPickerItem, OpenEditorContent, type OpenEditorContentProps, type OpenEditorController, type OpenEditorExtensionMenu, type OpenEditorOverlayRect, OpenEditorPageHeader, type OpenEditorPageHeaderProps, type OpenEditorReactConfig, type OpenEditorReactExtension, type OpenEditorReactNodeExtension, type OpenEditorReactProps, type OpenEditorSlashMenuIcon, type OpenEditorSlashMenuIconProps, type OpenEditorSlashMenuItem, type OpenEditorTheme, OpenEditorThemeProvider, type OpenEditorThemeStyle, type OpenEditorThemeToken, OpenEditorViewer, type OpenEditorViewerProps, type OpenEditorViewerRenderer, type
|
|
302
|
+
export { type InsertRange, type OpenEditorBlockAction, type OpenEditorBlockActionContext, OpenEditorBlockDragHandle, type OpenEditorBlockDragHandleProps, type OpenEditorBlockPickerItem, OpenEditorBubbleMenu, type OpenEditorBubbleMenuProps, OpenEditorContent, type OpenEditorContentProps, type OpenEditorController, type OpenEditorExtensionMenu, type OpenEditorOverlayRect, OpenEditorPageHeader, type OpenEditorPageHeaderProps, type OpenEditorReactConfig, type OpenEditorReactExtension, type OpenEditorReactNodeExtension, type OpenEditorReactProps, type OpenEditorSlashMenuIcon, type OpenEditorSlashMenuIconProps, type OpenEditorSlashMenuItem, OpenEditorTableBubbleMenu, type OpenEditorTableBubbleMenuProps, type OpenEditorTableCommand, type OpenEditorTableController, type OpenEditorTableState, type OpenEditorTheme, OpenEditorThemeProvider, type OpenEditorThemeStyle, type OpenEditorThemeToken, OpenEditorViewer, type OpenEditorViewerProps, type OpenEditorViewerRenderer, type SlashState, canRunOpenEditorTableCommand, createOpenEditorThemeStyle, defineOpenEditorReactExtension, defineOpenEditorReactNode, formatAttachmentSize, getDefaultBlockPickerItems, getDefaultSlashMenuItems, getOpenEditorTableState, openEditorTableCommands, openEditorThemeTokenNames, runOpenEditorTableCommand, sortBlockPickerItems, sortSlashMenuItems, useOpenEditor, useOpenEditorBlockInteraction, useOpenEditorController, useOpenEditorThemeStyle };
|