@domternal/vanilla 0.14.0 → 1.0.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 +24 -5
- package/dist/index.d.ts +17 -90
- package/dist/index.js +204 -246
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
[](https://github.com/domternal/domternal/blob/main/LICENSE)
|
|
5
5
|
|
|
6
6
|
Framework-free DOM components for the [Domternal](https://domternal.dev) editor.
|
|
7
|
-
|
|
8
|
-
`
|
|
9
|
-
`DomternalEmojiPicker
|
|
7
|
+
Most are classes you instantiate against a host element: `DomternalEditor`,
|
|
8
|
+
`DomternalToolbar`, `DomternalBubbleMenu`, `DomternalFloatingMenu`, and
|
|
9
|
+
`DomternalEmojiPicker`. `DomternalNotionColorPicker` is the exception: it takes only an
|
|
10
|
+
options object and resolves its own `.dm-editor` host from the editor. Every class extends
|
|
10
11
|
`EventTarget`, exposes plain getters and mutator methods, dispatches `CustomEvent`s for state
|
|
11
12
|
changes, and tears down with an idempotent `destroy()`. Use it in Astro, Svelte, Solid,
|
|
12
13
|
Lit, Web Components, or plain HTML - anywhere without a framework runtime.
|
|
@@ -21,8 +22,8 @@ Lit, Web Components, or plain HTML - anywhere without a framework runtime.
|
|
|
21
22
|
pnpm add @domternal/core @domternal/theme @domternal/vanilla
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
`@domternal/core` is a peer dependency. `@domternal/theme` supplies the editor
|
|
25
|
-
(import it once in your app).
|
|
25
|
+
`@domternal/core` (>=1.0.0) is a peer dependency. `@domternal/theme` supplies the editor
|
|
26
|
+
styles (import it once in your app).
|
|
26
27
|
|
|
27
28
|
## Usage
|
|
28
29
|
|
|
@@ -70,6 +71,24 @@ The matching mount points:
|
|
|
70
71
|
> SSR. Module-scope imports stay SSR-safe, so gate instantiation behind a client-side
|
|
71
72
|
> entry point (e.g. an Astro `<script>` block or `client:only`).
|
|
72
73
|
|
|
74
|
+
## Options
|
|
75
|
+
|
|
76
|
+
`DomternalEditorOptions`, the second constructor argument:
|
|
77
|
+
|
|
78
|
+
| Option | Type | Default | Description |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| `extensions` | `AnyExtension[]` | `[]` | Extensions merged on top of `DEFAULT_EXTENSIONS`. |
|
|
81
|
+
| `history` | `boolean` | `true` | Whether the built-in History extension is loaded. Turn it off when an extension brings its own undo. |
|
|
82
|
+
| `content` | `Content` | `''` | Initial content, HTML string or JSON. |
|
|
83
|
+
| `editable` | `boolean` | `true` | Whether the editor is editable. |
|
|
84
|
+
| `preset` | `'classic' \| 'notion'` | `'classic'` | `'notion'` paints `dm-notion-mode` on the `.dm-editor` host and switches preset-aware extensions to their Notion behavior. Create-time only. |
|
|
85
|
+
| `autofocus` | `FocusPosition` | `false` | Where to place the caret on mount. |
|
|
86
|
+
| `outputFormat` | `'html' \| 'json'` | `'html'` | Format hint for host frameworks comparing controlled content. Does not change editor behavior. |
|
|
87
|
+
|
|
88
|
+
`onCreate`, `onUpdate`, `onSelectionChange`, `onFocus`, `onBlur`, and `onDestroy` callbacks are
|
|
89
|
+
accepted alongside them, and the same moments are dispatched on the instance as `create`,
|
|
90
|
+
`update`, `selectionchange`, `focus`, `blur`, and `destroy` `CustomEvent`s.
|
|
91
|
+
|
|
73
92
|
## Exports
|
|
74
93
|
|
|
75
94
|
- `DomternalEditor` / `DomternalEditorOptions` - wraps core's `Editor`, plus
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { PluginKey, IconSet,
|
|
1
|
+
import { PluginKey, IconSet, AnyExtension, Editor, Content, EditorPreset, FocusPosition, JSONContent, ToolbarController, ToolbarLayoutEntry, ToolbarButton, ToolbarDropdown, BubbleMenuOptions, BubbleContexts, FloatingMenuController, FloatingMenuOptions, FloatingMenuItemsOverride, FloatingMenuKeymap } from '@domternal/core';
|
|
2
|
+
export { BubbleMenuItem, BubbleMenuSeparator, BubbleItemMaps as ItemMaps, ResolvedPosShape, SelectionShape, buildBubbleItemMaps as buildItemMaps, detectBubbleContext as detectContext, filterBubbleItemsBySchema as filterBySchema, getBubbleFormatItems as getFormatItems, isInsideTableCell, resolveBubbleNames as resolveNames } from '@domternal/core';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* SSR-safe environment check.
|
|
@@ -200,6 +201,12 @@ interface DomternalEditorOptions {
|
|
|
200
201
|
content?: Content;
|
|
201
202
|
/** Whether the editor is editable. @default true */
|
|
202
203
|
editable?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Editing experience preset. `'notion'` paints `dm-notion-mode` on the
|
|
206
|
+
* `.dm-editor` host and switches preset-aware extensions to their Notion
|
|
207
|
+
* behavior, replacing the hand-written class. Create-time only.
|
|
208
|
+
*/
|
|
209
|
+
preset?: EditorPreset;
|
|
203
210
|
/** Where to autofocus on mount. @default false */
|
|
204
211
|
autofocus?: FocusPosition;
|
|
205
212
|
/**
|
|
@@ -434,85 +441,6 @@ declare function getComputedStyleAtCursor(editor: Editor, prop: string): string
|
|
|
434
441
|
*/
|
|
435
442
|
declare function getInlineStyleAtCursor(editor: Editor, prop: string): string | null;
|
|
436
443
|
|
|
437
|
-
interface ResolvedPosShape {
|
|
438
|
-
parent: {
|
|
439
|
-
type: {
|
|
440
|
-
name: string;
|
|
441
|
-
spec: {
|
|
442
|
-
marks?: string;
|
|
443
|
-
};
|
|
444
|
-
};
|
|
445
|
-
};
|
|
446
|
-
depth: number;
|
|
447
|
-
node: (depth: number) => {
|
|
448
|
-
type: {
|
|
449
|
-
name: string;
|
|
450
|
-
};
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
interface SelectionShape {
|
|
454
|
-
empty: boolean;
|
|
455
|
-
$from: ResolvedPosShape;
|
|
456
|
-
$to: ResolvedPosShape;
|
|
457
|
-
node?: {
|
|
458
|
-
type: {
|
|
459
|
-
name: string;
|
|
460
|
-
};
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
interface BubbleMenuSeparator {
|
|
464
|
-
type: 'separator';
|
|
465
|
-
name: string;
|
|
466
|
-
}
|
|
467
|
-
type BubbleMenuItem = ToolbarButton | ToolbarDropdown | BubbleMenuSeparator;
|
|
468
|
-
interface ItemMaps {
|
|
469
|
-
itemMap: Map<string, ToolbarButton>;
|
|
470
|
-
dropdownMap: Map<string, ToolbarDropdown>;
|
|
471
|
-
/** Bubble defaults indexed by context name (e.g. 'text', 'codeBlock'). */
|
|
472
|
-
bubbleDefaults: Map<string, BubbleMenuItem[]>;
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Walks `editor.toolbarItems` and indexes them by name. Dropdowns are kept
|
|
476
|
-
* separately so the bubble menu can resolve them by name (e.g. text-align).
|
|
477
|
-
*/
|
|
478
|
-
declare function buildItemMaps(editor: Editor): ItemMaps;
|
|
479
|
-
/**
|
|
480
|
-
* Resolve a name array to BubbleMenuItems via the item/dropdown maps.
|
|
481
|
-
* Dropdowns take priority over buttons sharing the same name. Pipe `|`
|
|
482
|
-
* tokens become separator entries.
|
|
483
|
-
*/
|
|
484
|
-
declare function resolveNames(names: string[], itemMap: Map<string, ToolbarButton>, dropdownMap: Map<string, ToolbarDropdown>): BubbleMenuItem[];
|
|
485
|
-
/**
|
|
486
|
-
* All `format`-group buttons sorted by priority (used by `context: true`
|
|
487
|
-
* shorthand to show "all format marks for this context").
|
|
488
|
-
*/
|
|
489
|
-
declare function getFormatItems(itemMap: Map<string, ToolbarButton>): ToolbarButton[];
|
|
490
|
-
/**
|
|
491
|
-
* Determine the active bubble-menu context based on the selection. Returns
|
|
492
|
-
* `null` when no context matches (menu should not show).
|
|
493
|
-
*
|
|
494
|
-
* Resolution order:
|
|
495
|
-
* 1. CellSelection (`$anchorCell`) - no menu inside table cell selections
|
|
496
|
-
* 2. NodeSelection (image, HR, etc.) - return the node's type name
|
|
497
|
-
* 3. Empty selection - no context (caret-only)
|
|
498
|
-
* 4. Inside a table cell - return 'table' (when from/to share a cell)
|
|
499
|
-
* 5. `$from.parent.type.name` if listed in contexts
|
|
500
|
-
* 6. 'text' if the parent allows marks
|
|
501
|
-
*/
|
|
502
|
-
declare function detectContext(selection: SelectionShape, ctxs: Record<string, string[] | true | null>): string | null;
|
|
503
|
-
/**
|
|
504
|
-
* Filter items by what the schema actually allows in the given context.
|
|
505
|
-
* E.g. inside a `codeBlock` node, marks like Bold/Italic aren't permitted.
|
|
506
|
-
*
|
|
507
|
-
* Pass-through for 'text' and 'table' contexts (schema check would be
|
|
508
|
-
* lossy there because marks are allowed but some items still apply).
|
|
509
|
-
*/
|
|
510
|
-
declare function filterBySchema(editor: Editor, contextName: string, schemaItems: ToolbarButton[]): ToolbarButton[];
|
|
511
|
-
/**
|
|
512
|
-
* Detect whether `$pos` is inside a table cell (cell or header).
|
|
513
|
-
*/
|
|
514
|
-
declare function isInsideTableCell($pos: ResolvedPosShape): boolean;
|
|
515
|
-
|
|
516
444
|
/**
|
|
517
445
|
* Live state for the bubble-menu trailing buttons.
|
|
518
446
|
*
|
|
@@ -570,7 +498,7 @@ interface DomternalBubbleMenuOptions extends CustomContentOption {
|
|
|
570
498
|
* to item name list, `true` (show all format items), or `null` (no menu for
|
|
571
499
|
* this context). Defaults to `defaultBubbleContexts(editor)`.
|
|
572
500
|
*/
|
|
573
|
-
contexts?:
|
|
501
|
+
contexts?: BubbleContexts;
|
|
574
502
|
/** Custom icon overrides. Falls back to default Phosphor icons for unmapped keys. */
|
|
575
503
|
icons?: IconSet;
|
|
576
504
|
}
|
|
@@ -584,14 +512,13 @@ interface DomternalBubbleMenuOptions extends CustomContentOption {
|
|
|
584
512
|
* "..." for block context menu) are rendered automatically when the
|
|
585
513
|
* corresponding extensions are loaded.
|
|
586
514
|
*
|
|
587
|
-
* Re-renders are batched via `requestAnimationFrame`.
|
|
588
|
-
*
|
|
589
|
-
*
|
|
515
|
+
* Re-renders are batched via `requestAnimationFrame`. The structure is rebuilt
|
|
516
|
+
* only when the item list changes; a state-only render updates the nodes on
|
|
517
|
+
* screen, so a press that outlives a transaction still produces a click.
|
|
590
518
|
*
|
|
591
|
-
* **Stable identity convention.**
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
* (e.g. as a popover anchor) should:
|
|
519
|
+
* **Stable identity convention.** A trigger survives a state-only render but
|
|
520
|
+
* NOT an item-list change, so consumers holding a reference to one (e.g. as a
|
|
521
|
+
* popover anchor) should still:
|
|
595
522
|
* - Either listen for `selectionUpdate` / `transaction` and re-resolve the
|
|
596
523
|
* anchor via `host.querySelector('.dm-ncp-trigger')` on demand
|
|
597
524
|
* - Or match the trigger by class + container (`closest('.dm-bubble-menu')`)
|
|
@@ -661,7 +588,7 @@ declare class DomternalBubbleMenu extends EventTarget {
|
|
|
661
588
|
* plugin at construction; this only changes WHICH items render once the
|
|
662
589
|
* menu is visible.
|
|
663
590
|
*/
|
|
664
|
-
setContexts(contexts:
|
|
591
|
+
setContexts(contexts: BubbleContexts | undefined): void;
|
|
665
592
|
/** Replace the icon set. `undefined` restores default Phosphor icons. */
|
|
666
593
|
setIcons(icons: IconSet | undefined): void;
|
|
667
594
|
/** Close any open dropdown (text-align). No-op if nothing is open. */
|
|
@@ -873,4 +800,4 @@ declare class DomternalEmojiPicker extends EventTarget {
|
|
|
873
800
|
destroy(): void;
|
|
874
801
|
}
|
|
875
802
|
|
|
876
|
-
export { type
|
|
803
|
+
export { type BubbleMenuTrailingState, type CustomContentOption, DEFAULT_EXTENSIONS, DROPDOWN_CARET, DomternalBubbleMenu, type DomternalBubbleMenuOptions, DomternalEditor, type DomternalEditorOptions, DomternalEmojiPicker, type DomternalEmojiPickerOptions, DomternalFloatingMenu, type DomternalFloatingMenuOptions, DomternalNotionColorPicker, type DomternalNotionColorPickerOptions, DomternalToolbar, type DomternalToolbarOptions, type EmojiPickerItem, INITIAL_TRAILING_STATE, type IconCache, assertBrowser, computeTrailingState, createIconCache, createPluginKey, getComputedStyleAtCursor, getInlineStyleAtCursor, getTooltip, isBrowser, renderIconInto, resolveIcon, subscribe };
|