@domternal/react 0.9.0 → 0.10.0
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 +3 -3
- package/dist/Domternal.d.ts +87 -0
- package/dist/Domternal.d.ts.map +1 -0
- package/dist/DomternalEditor.d.ts +48 -0
- package/dist/DomternalEditor.d.ts.map +1 -0
- package/dist/DomternalFloatingMenu.d.ts +35 -0
- package/dist/DomternalFloatingMenu.d.ts.map +1 -0
- package/dist/EditorContent.d.ts +22 -0
- package/dist/EditorContent.d.ts.map +1 -0
- package/dist/EditorContext.d.ts +36 -0
- package/dist/EditorContext.d.ts.map +1 -0
- package/dist/bubble-menu/DomternalBubbleMenu.d.ts +24 -0
- package/dist/bubble-menu/DomternalBubbleMenu.d.ts.map +1 -0
- package/dist/bubble-menu/useBubbleMenu.d.ts +57 -0
- package/dist/bubble-menu/useBubbleMenu.d.ts.map +1 -0
- package/dist/emoji-picker/DomternalEmojiPicker.d.ts +11 -0
- package/dist/emoji-picker/DomternalEmojiPicker.d.ts.map +1 -0
- package/dist/emoji-picker/useEmojiPicker.d.ts +24 -0
- package/dist/emoji-picker/useEmojiPicker.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -13
- package/dist/index.js.map +1 -1
- package/dist/node-views/NodeViewContent.d.ts +11 -0
- package/dist/node-views/NodeViewContent.d.ts.map +1 -0
- package/dist/node-views/NodeViewWrapper.d.ts +11 -0
- package/dist/node-views/NodeViewWrapper.d.ts.map +1 -0
- package/dist/node-views/ReactNodeViewContext.d.ts +12 -0
- package/dist/node-views/ReactNodeViewContext.d.ts.map +1 -0
- package/dist/node-views/ReactNodeViewRenderer.d.ts +104 -0
- package/dist/node-views/ReactNodeViewRenderer.d.ts.map +1 -0
- package/dist/notion-color-picker/DomternalNotionColorPicker.d.ts +25 -0
- package/dist/notion-color-picker/DomternalNotionColorPicker.d.ts.map +1 -0
- package/dist/notion-color-picker/index.d.ts +5 -0
- package/dist/notion-color-picker/index.d.ts.map +1 -0
- package/dist/notion-color-picker/useNotionColorPicker.d.ts +47 -0
- package/dist/notion-color-picker/useNotionColorPicker.d.ts.map +1 -0
- package/dist/toolbar/DomternalToolbar.d.ts +12 -0
- package/dist/toolbar/DomternalToolbar.d.ts.map +1 -0
- package/dist/toolbar/ToolbarButton.d.ts +15 -0
- package/dist/toolbar/ToolbarButton.d.ts.map +1 -0
- package/dist/toolbar/ToolbarDropdown.d.ts +17 -0
- package/dist/toolbar/ToolbarDropdown.d.ts.map +1 -0
- package/dist/toolbar/ToolbarDropdownPanel.d.ts +10 -0
- package/dist/toolbar/ToolbarDropdownPanel.d.ts.map +1 -0
- package/dist/toolbar/useComputedStyle.d.ts +12 -0
- package/dist/toolbar/useComputedStyle.d.ts.map +1 -0
- package/dist/toolbar/useKeyboardNav.d.ts +6 -0
- package/dist/toolbar/useKeyboardNav.d.ts.map +1 -0
- package/dist/toolbar/useToolbarController.d.ts +21 -0
- package/dist/toolbar/useToolbarController.d.ts.map +1 -0
- package/dist/toolbar/useToolbarIcons.d.ts +12 -0
- package/dist/toolbar/useToolbarIcons.d.ts.map +1 -0
- package/dist/toolbar/useTooltip.d.ts +5 -0
- package/dist/toolbar/useTooltip.d.ts.map +1 -0
- package/dist/useEditor.d.ts +82 -0
- package/dist/useEditor.d.ts.map +1 -0
- package/dist/useEditorState.d.ts +27 -0
- package/dist/useEditorState.d.ts.map +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -21,14 +21,14 @@ See <u>[Packages & Bundle Size](https://domternal.dev/v1/packages)</u> for a ful
|
|
|
21
21
|
- **Vue components** - composable `Domternal` component, `useEditor`/`useEditorState` composables, toolbar, bubble menu, floating menu, emoji picker, notion color picker, custom node views (Vue 3.3+)
|
|
22
22
|
- **Vanilla wrapper** - framework-free class-based API for Astro, Svelte, Solid, plain HTML, and Web Components - editor, toolbar, bubble menu, floating menu, emoji picker, notion color picker
|
|
23
23
|
- **Notion-style block UX** - drag-to-reorder, block context menu, slash command, smart paste, keyboard reorder, floating Table of Contents
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
24
|
+
- **70+ extensions across 16 packages** - nodes, marks, and behavior extensions
|
|
25
|
+
- **125+ chainable commands** - `editor.chain().focus().toggleBold().run()`
|
|
26
26
|
- **Full table support** - cell merging, column resize, row/column controls, cell toolbar, all free and MIT licensed
|
|
27
27
|
- **Tree-shakeable** - import only what you use, your bundler strips the rest
|
|
28
28
|
- **~44 KB gzipped** (own code), <u>[see Packages](https://domternal.dev/v1/packages)</u> for full bundle breakdown with ProseMirror
|
|
29
29
|
- **TypeScript first** - 100% typed, zero `any`
|
|
30
30
|
- **15,000+ tests** - 4,000+ unit and 11,000+ E2E across 230+ Playwright specs and 4 demo apps
|
|
31
|
-
- **Light and dark theme** -
|
|
31
|
+
- **Light and dark theme** - 120+ CSS custom properties for full visual control
|
|
32
32
|
- **Inline styles export** - `getHTML({ styled: true })` produces inline CSS ready for email clients, CMS, and Google Docs
|
|
33
33
|
- **SSR helpers** - `generateHTML`, `generateJSON`, `generateText` for server-side rendering
|
|
34
34
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type DependencyList, type ReactNode } from 'react';
|
|
2
|
+
import { type UseEditorOptions } from './useEditor.js';
|
|
3
|
+
import { type DomternalToolbarProps } from './toolbar/DomternalToolbar.js';
|
|
4
|
+
import { type DomternalBubbleMenuProps } from './bubble-menu/DomternalBubbleMenu.js';
|
|
5
|
+
import { type DomternalFloatingMenuProps } from './DomternalFloatingMenu.js';
|
|
6
|
+
import { type DomternalEmojiPickerProps } from './emoji-picker/DomternalEmojiPicker.js';
|
|
7
|
+
export interface DomternalProps extends UseEditorOptions {
|
|
8
|
+
/** Optional dependency array for forced editor recreation. */
|
|
9
|
+
deps?: DependencyList;
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Composable root component that creates an editor and provides it to all
|
|
14
|
+
* subcomponents via context. No need to pass `editor` prop to children.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <Domternal extensions={[Bold, Italic]} content="<p>Hello</p>">
|
|
19
|
+
* <Domternal.Toolbar />
|
|
20
|
+
* <Domternal.Content />
|
|
21
|
+
* <Domternal.BubbleMenu contexts={{ text: ['bold', 'italic'] }} />
|
|
22
|
+
* <Domternal.EmojiPicker emojis={emojis} />
|
|
23
|
+
* </Domternal>
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example Loading state (shown during SSR and until the editor exists)
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <Domternal extensions={extensions}>
|
|
29
|
+
* <Domternal.Loading>Loading editor...</Domternal.Loading>
|
|
30
|
+
* <Domternal.Toolbar />
|
|
31
|
+
* <Domternal.Content />
|
|
32
|
+
* </Domternal>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example Editor on the very first render (client-only apps)
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <Domternal extensions={extensions} immediatelyRender>
|
|
38
|
+
* <Domternal.Toolbar />
|
|
39
|
+
* <Domternal.Content />
|
|
40
|
+
* </Domternal>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function Domternal({ children, deps, ...options }: DomternalProps): ReactNode;
|
|
44
|
+
export declare namespace Domternal {
|
|
45
|
+
var Content: typeof DomternalContent;
|
|
46
|
+
var Loading: typeof DomternalLoading;
|
|
47
|
+
var Toolbar: typeof DomternalToolbarSub;
|
|
48
|
+
var BubbleMenu: typeof DomternalBubbleMenuSub;
|
|
49
|
+
var FloatingMenu: typeof DomternalFloatingMenuSub;
|
|
50
|
+
var EmojiPicker: typeof DomternalEmojiPickerSub;
|
|
51
|
+
}
|
|
52
|
+
/** Renders the editor content area. Mounts the editor view DOM from context. */
|
|
53
|
+
declare function DomternalContent({ className }: {
|
|
54
|
+
className?: string;
|
|
55
|
+
}): ReactNode;
|
|
56
|
+
declare namespace DomternalContent {
|
|
57
|
+
var displayName: string;
|
|
58
|
+
}
|
|
59
|
+
/** Renders children only while editor is not yet ready (SSR loading state). */
|
|
60
|
+
declare function DomternalLoading({ children }: {
|
|
61
|
+
children: ReactNode;
|
|
62
|
+
}): ReactNode;
|
|
63
|
+
declare namespace DomternalLoading {
|
|
64
|
+
var displayName: string;
|
|
65
|
+
}
|
|
66
|
+
/** Toolbar subcomponent. Uses editor from context automatically. */
|
|
67
|
+
declare function DomternalToolbarSub(props: Omit<DomternalToolbarProps, 'editor'>): ReactNode;
|
|
68
|
+
declare namespace DomternalToolbarSub {
|
|
69
|
+
var displayName: string;
|
|
70
|
+
}
|
|
71
|
+
/** BubbleMenu subcomponent. Uses editor from context automatically. */
|
|
72
|
+
declare function DomternalBubbleMenuSub(props: Omit<DomternalBubbleMenuProps, 'editor'>): ReactNode;
|
|
73
|
+
declare namespace DomternalBubbleMenuSub {
|
|
74
|
+
var displayName: string;
|
|
75
|
+
}
|
|
76
|
+
/** FloatingMenu subcomponent. Uses editor from context automatically. */
|
|
77
|
+
declare function DomternalFloatingMenuSub(props: Omit<DomternalFloatingMenuProps, 'editor'>): ReactNode;
|
|
78
|
+
declare namespace DomternalFloatingMenuSub {
|
|
79
|
+
var displayName: string;
|
|
80
|
+
}
|
|
81
|
+
/** EmojiPicker subcomponent. Uses editor from context automatically. */
|
|
82
|
+
declare function DomternalEmojiPickerSub(props: Omit<DomternalEmojiPickerProps, 'editor'>): ReactNode;
|
|
83
|
+
declare namespace DomternalEmojiPickerSub {
|
|
84
|
+
var displayName: string;
|
|
85
|
+
}
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=Domternal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Domternal.d.ts","sourceRoot":"","sources":["../src/Domternal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/E,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAuB,KAAK,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAC1G,OAAO,EAAyB,KAAK,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACpG,OAAO,EAAwB,KAAK,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AAI9G,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,8DAA8D;IAC9D,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,EAAE,cAAc,GAAG,SAAS,CAQnF;yBARe,SAAS;;;;;;;;AAYzB,gFAAgF;AAChF,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAqB1E;kBArBQ,gBAAgB;;;AAuBzB,+EAA+E;AAC/E,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAI1E;kBAJQ,gBAAgB;;;AAMzB,oEAAoE;AACpE,iBAAS,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,GAAG,SAAS,CAEpF;kBAFQ,mBAAmB;;;AAI5B,uEAAuE;AACvE,iBAAS,sBAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,wBAAwB,EAAE,QAAQ,CAAC,GAAG,SAAS,CAE1F;kBAFQ,sBAAsB;;;AAI/B,yEAAyE;AACzE,iBAAS,wBAAwB,CAAC,KAAK,EAAE,IAAI,CAAC,0BAA0B,EAAE,QAAQ,CAAC,GAAG,SAAS,CAE9F;kBAFQ,wBAAwB;;;AAIjC,wEAAwE;AACxE,iBAAS,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,yBAAyB,EAAE,QAAQ,CAAC,GAAG,SAAS,CAE5F;kBAFQ,uBAAuB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Content, JSONContent, Editor } from '@domternal/core';
|
|
2
|
+
import { type UseEditorOptions } from './useEditor.js';
|
|
3
|
+
export interface DomternalEditorProps extends Omit<UseEditorOptions, 'outputFormat'> {
|
|
4
|
+
/** Additional CSS class for the .dm-editor wrapper. */
|
|
5
|
+
className?: string;
|
|
6
|
+
/** Output format for onChange. @default 'html' */
|
|
7
|
+
outputFormat?: 'html' | 'json';
|
|
8
|
+
/** Controlled value. When provided, editor content syncs to this value. */
|
|
9
|
+
value?: Content;
|
|
10
|
+
/** Called when content changes (controlled mode). */
|
|
11
|
+
onChange?: (value: string | JSONContent) => void;
|
|
12
|
+
/** Additional content rendered inside the dm-editor wrapper. */
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export interface DomternalEditorRef {
|
|
16
|
+
editor: Editor | null;
|
|
17
|
+
htmlContent: string;
|
|
18
|
+
jsonContent: JSONContent | null;
|
|
19
|
+
isEmpty: boolean;
|
|
20
|
+
isFocused: boolean;
|
|
21
|
+
isEditable: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* All-in-one editor component with integrated state management and context.
|
|
25
|
+
*
|
|
26
|
+
* Wraps children with EditorProvider automatically, so toolbar, bubble menu,
|
|
27
|
+
* and emoji picker components can access the editor via context.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const editorRef = useRef<DomternalEditorRef>(null);
|
|
32
|
+
*
|
|
33
|
+
* <DomternalEditor
|
|
34
|
+
* ref={editorRef}
|
|
35
|
+
* extensions={[Bold, Italic, Heading]}
|
|
36
|
+
* content="<p>Hello</p>"
|
|
37
|
+
* onUpdate={({ editor }) => console.log(editor.getHTML())}
|
|
38
|
+
* />
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example Controlled mode
|
|
42
|
+
* ```tsx
|
|
43
|
+
* const [html, setHtml] = useState('<p>Hello</p>');
|
|
44
|
+
* <DomternalEditor value={html} onChange={setHtml} outputFormat="html" />
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const DomternalEditor: import("react").ForwardRefExoticComponent<DomternalEditorProps & import("react").RefAttributes<DomternalEditorRef>>;
|
|
48
|
+
//# sourceMappingURL=DomternalEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomternalEditor.d.ts","sourceRoot":"","sources":["../src/DomternalEditor.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIlE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,cAAc,CAAC;IAClF,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,KAAK,IAAI,CAAC;IACjD,gEAAgE;IAChE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,eAAe,qHA4E3B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Editor, FloatingMenuItemsOverride, FloatingMenuKeymap, FloatingMenuOptions, IconSet } from '@domternal/core';
|
|
3
|
+
export interface DomternalFloatingMenuProps {
|
|
4
|
+
/** The editor instance. If omitted, uses EditorProvider context. */
|
|
5
|
+
editor?: Editor;
|
|
6
|
+
/** Custom visibility predicate. */
|
|
7
|
+
shouldShow?: FloatingMenuOptions['shouldShow'];
|
|
8
|
+
/** Pixel offset from trigger anchor. @default 0 */
|
|
9
|
+
offset?: number;
|
|
10
|
+
/** Items override (array replaces defaults; function transforms them). */
|
|
11
|
+
items?: FloatingMenuItemsOverride;
|
|
12
|
+
/** Keyboard shortcuts for entering the menu via keyboard. */
|
|
13
|
+
keymap?: FloatingMenuKeymap;
|
|
14
|
+
/** Custom icon set (falls back to `@domternal/core`'s `defaultIcons`). */
|
|
15
|
+
icons?: IconSet;
|
|
16
|
+
/**
|
|
17
|
+
* When true, the menu does NOT auto-show on every empty paragraph;
|
|
18
|
+
* it only opens when the BlockHandle `+` button (or any caller of
|
|
19
|
+
* `showFloatingMenu`) explicitly triggers it. Notion-style behaviour.
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
requireExplicitTrigger?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Optional custom content. When provided, the default grouped-item
|
|
25
|
+
* rendering is skipped and children are rendered inside the menu element.
|
|
26
|
+
*/
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Block-insert floating menu. Renders defaults collected from the editor's
|
|
31
|
+
* extensions via `addFloatingMenuItems()`; pass `items` to override or
|
|
32
|
+
* `children` to render a fully custom UI.
|
|
33
|
+
*/
|
|
34
|
+
export declare function DomternalFloatingMenu({ editor: editorProp, shouldShow, offset, items, keymap, icons, requireExplicitTrigger, children, }: DomternalFloatingMenuProps): ReactNode;
|
|
35
|
+
//# sourceMappingURL=DomternalFloatingMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomternalFloatingMenu.d.ts","sourceRoot":"","sources":["../src/DomternalFloatingMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAO,KAAK,EACV,MAAM,EAEN,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,OAAO,EACR,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,UAAU,CAAC,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC/C,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,yBAAyB,CAAC;IAClC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,0EAA0E;IAC1E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EAAE,UAAU,EAClB,UAAU,EACV,MAAU,EACV,KAAK,EACL,MAAM,EACN,KAAK,EACL,sBAA8B,EAC9B,QAAQ,GACT,EAAE,0BAA0B,GAAG,SAAS,CAiMxC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type HTMLAttributes, type Ref, type ReactNode } from 'react';
|
|
2
|
+
import type { Editor } from '@domternal/core';
|
|
3
|
+
export interface EditorContentProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** The editor instance to render. */
|
|
5
|
+
editor: Editor | null;
|
|
6
|
+
/** Ref to the underlying div element. */
|
|
7
|
+
innerRef?: Ref<HTMLDivElement>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Renders the ProseMirror editor view into a div element.
|
|
11
|
+
*
|
|
12
|
+
* Use this with `useEditor` for a flexible, decoupled pattern where the
|
|
13
|
+
* editor hook and rendering are separated:
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const { editor } = useEditor({ extensions, content });
|
|
18
|
+
* return <EditorContent editor={editor} className="my-editor" />;
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function EditorContent({ editor, innerRef, ...htmlProps }: EditorContentProps): ReactNode;
|
|
22
|
+
//# sourceMappingURL=EditorContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorContent.d.ts","sourceRoot":"","sources":["../src/EditorContent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,kBAAmB,SAAQ,cAAc,CAAC,cAAc,CAAC;IACxE,qCAAqC;IACrC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,EAAE,kBAAkB,GAAG,SAAS,CA6B/F"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Editor } from '@domternal/core';
|
|
3
|
+
interface EditorContextValue {
|
|
4
|
+
editor: Editor | null;
|
|
5
|
+
}
|
|
6
|
+
export interface EditorProviderProps {
|
|
7
|
+
/** The editor instance to provide to descendants. */
|
|
8
|
+
editor: Editor | null;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Provides an editor instance to all descendant components via React Context.
|
|
13
|
+
*
|
|
14
|
+
* Components like DomternalToolbar, DomternalBubbleMenu, DomternalFloatingMenu,
|
|
15
|
+
* and DomternalEmojiPicker will automatically use this editor when no explicit
|
|
16
|
+
* `editor` prop is passed.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const { editor } = useEditor({ extensions, content });
|
|
21
|
+
*
|
|
22
|
+
* <EditorProvider editor={editor}>
|
|
23
|
+
* <DomternalToolbar />
|
|
24
|
+
* <EditorContent editor={editor} />
|
|
25
|
+
* <DomternalBubbleMenu contexts={{ text: ['bold', 'italic'] }} />
|
|
26
|
+
* </EditorProvider>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function EditorProvider({ editor, children }: EditorProviderProps): ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Access the editor instance from the nearest EditorProvider.
|
|
32
|
+
* Returns `{ editor: null }` when used outside a provider, no throw.
|
|
33
|
+
*/
|
|
34
|
+
export declare function useCurrentEditor(): EditorContextValue;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=EditorContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorContext.d.ts","sourceRoot":"","sources":["../src/EditorContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAID,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,mBAAmB,GAAG,SAAS,CAGnF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,kBAAkB,CAErD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Editor, BubbleMenuOptions, IconSet } from '@domternal/core';
|
|
3
|
+
export interface DomternalBubbleMenuProps {
|
|
4
|
+
/** The editor instance. If omitted, uses EditorProvider context. */
|
|
5
|
+
editor?: Editor;
|
|
6
|
+
/** Custom visibility function. */
|
|
7
|
+
shouldShow?: BubbleMenuOptions['shouldShow'];
|
|
8
|
+
/** Position relative to selection. @default 'top' */
|
|
9
|
+
placement?: 'top' | 'bottom';
|
|
10
|
+
/** Pixel offset from selection. @default 8 */
|
|
11
|
+
offset?: number;
|
|
12
|
+
/** Debounce delay in ms. @default 0 */
|
|
13
|
+
updateDelay?: number;
|
|
14
|
+
/** Fixed item names, e.g. ['bold', 'italic', 'code']. */
|
|
15
|
+
items?: string[];
|
|
16
|
+
/** Context-aware: map context names to item arrays, true for all, or null to disable. */
|
|
17
|
+
contexts?: Record<string, string[] | true | null>;
|
|
18
|
+
/** Custom icon overrides. Falls back to default Phosphor icons for unmapped keys. */
|
|
19
|
+
icons?: IconSet;
|
|
20
|
+
/** Additional content rendered after buttons. */
|
|
21
|
+
children?: React.ReactNode;
|
|
22
|
+
}
|
|
23
|
+
export declare function DomternalBubbleMenu({ editor: editorProp, shouldShow, placement, offset, updateDelay, items, contexts, icons, children, }: DomternalBubbleMenuProps): ReactNode;
|
|
24
|
+
//# sourceMappingURL=DomternalBubbleMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomternalBubbleMenu.d.ts","sourceRoot":"","sources":["../../src/bubble-menu/DomternalBubbleMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAkC,MAAM,iBAAiB,CAAC;AAK1G,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC7C,qDAAqD;IACrD,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC7B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IAClD,qFAAqF;IACrF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAMD,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EAAE,UAAU,EAClB,UAAU,EACV,SAAS,EACT,MAAM,EACN,WAAW,EACX,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,GACT,EAAE,wBAAwB,GAAG,SAAS,CA2ItC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type MouseEvent as ReactMouseEvent, type RefObject } from 'react';
|
|
2
|
+
import type { Editor, IconSet, ToolbarButton, ToolbarDropdown, BubbleMenuOptions } from '@domternal/core';
|
|
3
|
+
interface BubbleMenuSeparator {
|
|
4
|
+
type: 'separator';
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
export type BubbleMenuItem = ToolbarButton | ToolbarDropdown | BubbleMenuSeparator;
|
|
8
|
+
/**
|
|
9
|
+
* Live state for the bubble-menu trailing buttons. Mirrors Angular's
|
|
10
|
+
* `syncTrailingButtonsState` output. Computed per editor transaction and
|
|
11
|
+
* coalesced into a single object so each transaction triggers at most one
|
|
12
|
+
* re-render.
|
|
13
|
+
*/
|
|
14
|
+
export interface BubbleMenuTrailingState {
|
|
15
|
+
/** True when current selection is a NodeSelection (image, HR, ...). Trailing buttons hide in that case. */
|
|
16
|
+
isNodeSelection: boolean;
|
|
17
|
+
/** True when the `notionColorPicker` extension is loaded on this editor (cached once per editor). */
|
|
18
|
+
showColorPickerButton: boolean;
|
|
19
|
+
/** True when the `blockContextMenu` extension is loaded on this editor (cached once per editor). */
|
|
20
|
+
showBlockMenuButton: boolean;
|
|
21
|
+
/** True when the selection spans more than one top-level block (multi-block "..." disable). */
|
|
22
|
+
blockMenuButtonDisabled: boolean;
|
|
23
|
+
/** CSS color value for the "A" trigger glyph (e.g. `var(--dm-block-text-yellow)`), or null. */
|
|
24
|
+
currentTextColorVar: string | null;
|
|
25
|
+
/** CSS color value for the "A" trigger underline, or null. */
|
|
26
|
+
currentBgColorVar: string | null;
|
|
27
|
+
/** True when any token-based text or background color is applied at the cursor. */
|
|
28
|
+
hasAnyColor: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface UseBubbleMenuOptions {
|
|
31
|
+
editor: Editor | null;
|
|
32
|
+
shouldShow?: BubbleMenuOptions['shouldShow'] | undefined;
|
|
33
|
+
placement?: 'top' | 'bottom' | undefined;
|
|
34
|
+
offset?: number | undefined;
|
|
35
|
+
updateDelay?: number | undefined;
|
|
36
|
+
items?: string[] | undefined;
|
|
37
|
+
contexts?: Record<string, string[] | true | null> | undefined;
|
|
38
|
+
icons?: IconSet | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface UseBubbleMenuResult {
|
|
41
|
+
menuRef: RefObject<HTMLDivElement | null>;
|
|
42
|
+
resolvedItems: BubbleMenuItem[];
|
|
43
|
+
isItemActive: (item: ToolbarButton) => boolean;
|
|
44
|
+
isItemDisabled: (item: ToolbarButton) => boolean;
|
|
45
|
+
executeCommand: (item: ToolbarButton, event?: ReactMouseEvent | MouseEvent) => void;
|
|
46
|
+
activeVersion: number;
|
|
47
|
+
getCachedIcon: (name: string) => string;
|
|
48
|
+
/** Live trailing-button state (color preview, node-selection gate, multi-block disable). */
|
|
49
|
+
trailing: BubbleMenuTrailingState;
|
|
50
|
+
/** Open the Notion color picker by emitting `notionColorOpen` with the trigger as anchor. */
|
|
51
|
+
openColorPicker: (anchor: HTMLElement) => void;
|
|
52
|
+
/** Open the block context menu by dispatching `dm:block-context-menu-open` on `.dm-editor`. */
|
|
53
|
+
openBlockContextMenu: (anchor: HTMLElement) => void;
|
|
54
|
+
}
|
|
55
|
+
export declare function useBubbleMenu(options: UseBubbleMenuOptions): UseBubbleMenuResult;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=useBubbleMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBubbleMenu.d.ts","sourceRoot":"","sources":["../../src/bubble-menu/useBubbleMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,UAAU,IAAI,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQxG,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAsB1G,UAAU,mBAAmB;IAAG,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACjE,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,eAAe,GAAG,mBAAmB,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,2GAA2G;IAC3G,eAAe,EAAE,OAAO,CAAC;IACzB,qGAAqG;IACrG,qBAAqB,EAAE,OAAO,CAAC;IAC/B,oGAAoG;IACpG,mBAAmB,EAAE,OAAO,CAAC;IAC7B,+FAA+F;IAC/F,uBAAuB,EAAE,OAAO,CAAC;IACjC,+FAA+F;IAC/F,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mFAAmF;IACnF,WAAW,EAAE,OAAO,CAAC;CACtB;AA8BD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IACzD,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9D,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC1C,aAAa,EAAE,cAAc,EAAE,CAAC;IAChC,YAAY,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;IAC/C,cAAc,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC;IACjD,cAAc,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,UAAU,KAAK,IAAI,CAAC;IACpF,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,4FAA4F;IAC5F,QAAQ,EAAE,uBAAuB,CAAC;IAClC,6FAA6F;IAC7F,eAAe,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/C,+FAA+F;IAC/F,oBAAoB,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CACrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB,CAgahF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Editor } from '@domternal/core';
|
|
3
|
+
import { type EmojiPickerItem } from './useEmojiPicker.js';
|
|
4
|
+
export interface DomternalEmojiPickerProps {
|
|
5
|
+
/** The editor instance. If omitted, uses EditorProvider context. */
|
|
6
|
+
editor?: Editor;
|
|
7
|
+
/** Array of emoji items with emoji, name, and group. */
|
|
8
|
+
emojis: EmojiPickerItem[];
|
|
9
|
+
}
|
|
10
|
+
export declare function DomternalEmojiPicker({ editor: editorProp, emojis }: DomternalEmojiPickerProps): ReactNode;
|
|
11
|
+
//# sourceMappingURL=DomternalEmojiPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomternalEmojiPicker.d.ts","sourceRoot":"","sources":["../../src/emoji-picker/DomternalEmojiPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAsB3E,MAAM,WAAW,yBAAyB;IACxC,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,wBAAgB,oBAAoB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,yBAAyB,GAAG,SAAS,CAuJzG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
import type { Editor } from '@domternal/core';
|
|
3
|
+
export interface EmojiPickerItem {
|
|
4
|
+
emoji: string;
|
|
5
|
+
name: string;
|
|
6
|
+
group: string;
|
|
7
|
+
}
|
|
8
|
+
export interface UseEmojiPickerResult {
|
|
9
|
+
isOpen: boolean;
|
|
10
|
+
searchQuery: string;
|
|
11
|
+
activeCategory: string;
|
|
12
|
+
categories: Map<string, EmojiPickerItem[]>;
|
|
13
|
+
categoryNames: string[];
|
|
14
|
+
filteredEmojis: EmojiPickerItem[];
|
|
15
|
+
frequentlyUsed: EmojiPickerItem[];
|
|
16
|
+
pickerRef: RefObject<HTMLDivElement | null>;
|
|
17
|
+
selectEmoji: (item: EmojiPickerItem) => void;
|
|
18
|
+
onSearch: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
19
|
+
scrollToCategory: (cat: string) => void;
|
|
20
|
+
onGridScroll: () => void;
|
|
21
|
+
close: () => void;
|
|
22
|
+
}
|
|
23
|
+
export declare function useEmojiPicker(editor: Editor | null, emojis: EmojiPickerItem[]): UseEmojiPickerResult;
|
|
24
|
+
//# sourceMappingURL=useEmojiPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEmojiPicker.d.ts","sourceRoot":"","sources":["../../src/emoji-picker/useEmojiPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;IAC3C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,SAAS,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC5C,WAAW,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC/D,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,oBAAoB,CAyNrG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,YAAY,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,YAAY,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACxF,YAAY,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAClG,YAAY,EACV,+BAA+B,EAC/B,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAGxE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGzF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC3E,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, forwardRef, useImperativeHandle, useRef, useEffect, useState, useMemo, useCallback, useSyncExternalStore, useContext, Fragment, useLayoutEffect, createElement } from 'react';
|
|
2
|
-
import { Editor, Document, Paragraph, Text, BaseKeymap, History, positionFloatingOnce, PluginKey, createFloatingMenuPlugin, FloatingMenuController, defaultIcons, positionFloating, ToolbarController, defaultBubbleContexts, createBubbleMenuPlugin } from '@domternal/core';
|
|
2
|
+
import { Editor, Document, Paragraph, Text, BaseKeymap, History, refocusEditorAfterCommand, positionFloatingOnce, PluginKey, createFloatingMenuPlugin, FloatingMenuController, defaultIcons, positionFloating, ToolbarController, defaultBubbleContexts, createBubbleMenuPlugin } from '@domternal/core';
|
|
3
3
|
export { Editor, generateHTML, generateJSON, generateText } from '@domternal/core';
|
|
4
4
|
import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
@@ -800,9 +800,7 @@ function DomternalToolbar({ editor: editorProp, icons, layout }) {
|
|
|
800
800
|
return;
|
|
801
801
|
}
|
|
802
802
|
controllerRef.current?.executeCommand(item);
|
|
803
|
-
|
|
804
|
-
editor.view.focus();
|
|
805
|
-
});
|
|
803
|
+
refocusEditorAfterCommand(editor.view);
|
|
806
804
|
}, [editor, closeDropdown, controllerRef]);
|
|
807
805
|
const onDropdownItemClick = useCallback((item, event) => {
|
|
808
806
|
if (!editor) return;
|
|
@@ -817,9 +815,7 @@ function DomternalToolbar({ editor: editorProp, icons, layout }) {
|
|
|
817
815
|
} else {
|
|
818
816
|
controllerRef.current?.executeCommand(item);
|
|
819
817
|
}
|
|
820
|
-
|
|
821
|
-
editor.view.focus();
|
|
822
|
-
});
|
|
818
|
+
refocusEditorAfterCommand(editor.view);
|
|
823
819
|
}, [editor, closeDropdown, controllerRef]);
|
|
824
820
|
const onButtonFocus = useCallback((name) => {
|
|
825
821
|
const index = controllerRef.current?.getFlatIndex(name) ?? -1;
|
|
@@ -1316,9 +1312,7 @@ function DomternalBubbleMenu({
|
|
|
1316
1312
|
executeSubItem: (sub) => {
|
|
1317
1313
|
closeDropdown();
|
|
1318
1314
|
executeCommand(sub);
|
|
1319
|
-
|
|
1320
|
-
editor?.view.focus();
|
|
1321
|
-
});
|
|
1315
|
+
if (editor) refocusEditorAfterCommand(editor.view);
|
|
1322
1316
|
}
|
|
1323
1317
|
},
|
|
1324
1318
|
item.name
|
|
@@ -1589,9 +1583,7 @@ function DomternalFloatingMenu({
|
|
|
1589
1583
|
const onItemClick = useCallback((item) => {
|
|
1590
1584
|
if (!editor || !controllerRef.current) return;
|
|
1591
1585
|
controllerRef.current.execute(item);
|
|
1592
|
-
|
|
1593
|
-
editor.view.focus();
|
|
1594
|
-
});
|
|
1586
|
+
refocusEditorAfterCommand(editor.view);
|
|
1595
1587
|
}, [editor]);
|
|
1596
1588
|
const onMenuKeyDown = useCallback((e) => {
|
|
1597
1589
|
const ctl = controllerRef.current;
|