@domternal/core 0.15.0 → 1.0.1

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/index.d.ts CHANGED
@@ -806,12 +806,25 @@ declare class ExtensionManager {
806
806
  /**
807
807
  * Recursively flattens extensions by expanding addExtensions()
808
808
  * This allows extension bundles like StarterKit to work
809
+ *
810
+ * `autoIncluded` collects everything that arrived through an
811
+ * `addExtensions()` rather than from the caller's own list, which is what
812
+ * lets deduplication tell a default apart from a choice.
809
813
  */
810
814
  private flattenExtensions;
811
815
  /**
812
- * Removes duplicate extensions by name, keeping the last occurrence.
813
- * This allows parent extensions to auto-include children via addExtensions()
814
- * while letting users override with explicitly configured versions.
816
+ * Removes duplicate extensions by name.
817
+ *
818
+ * A version the caller listed themselves always wins over one a bundle
819
+ * included on their behalf, and position does not enter into it. Keeping
820
+ * the last occurrence alone said the same thing only while every bundle was
821
+ * listed first, which is the habit for StarterKit and no rule at all: an
822
+ * extension that includes a default and is written LOWER in the list, as
823
+ * `Export` and its `Print` are, silently replaced the configured copy
824
+ * above it and the caller's options went missing with it.
825
+ *
826
+ * Between two of the same kind the later one still wins, so two bundles
827
+ * offering the same default resolve as they always have.
815
828
  */
816
829
  private deduplicateExtensions;
817
830
  /**
@@ -968,8 +981,8 @@ declare class ExtensionManager {
968
981
  * Applies inline CSS styles to serialized HTML so it renders correctly
969
982
  * when pasted outside the editor (email clients, CMS, Google Docs, etc.).
970
983
  *
971
- * Uses hardcoded light-theme defaults (same approach as Google Docs, Notion,
972
- * TinyMCE). Optionally accepts overrides for custom styling.
984
+ * Uses hardcoded light-theme defaults (same approach as Google Docs or
985
+ * Notion). Optionally accepts overrides for custom styling.
973
986
  *
974
987
  * Only structural styles are inlined (borders, padding, margins, fonts).
975
988
  * Colors are NOT inlined - explicit colors (TextColor, Highlight, cell bg)
@@ -2806,12 +2819,479 @@ declare function refocusEditorAfterCommand(view: {
2806
2819
  * supplied one. Returns a richer item set when the editor resolves to the
2807
2820
  * Notion preset (the `preset` option, or the `.dm-notion-mode` class the
2808
2821
  * getter also honors), so the bubble menu mirrors the Notion UX by leading
2809
- * with `ai` and including `link` and `textAlign`.
2822
+ * with the `ai` and `comment` selection actions, then offering the block-type
2823
+ * dropdown and `link` ahead of the formatting marks.
2810
2824
  *
2811
2825
  * Consumers can always override by passing their own `contexts` prop.
2812
2826
  */
2813
2827
  declare function defaultBubbleContexts(editor: Editor): Record<string, string[]>;
2814
2828
 
2829
+ /**
2830
+ * Drop the separators that ended up with nothing to separate.
2831
+ *
2832
+ * A menu built from a flat list of names (`['ai', '|', 'bold', ...]`) resolves
2833
+ * each name against the extensions the editor actually loaded, and silently
2834
+ * skips the ones it cannot find. That is what lets one default list serve every
2835
+ * build: an editor without the AI extension simply does not show `ai`. The
2836
+ * separators do not take part in that, because a `|` always resolves. So the
2837
+ * list shrinks around them and they stay, and a bar that was drawn between two
2838
+ * groups is left leading the menu, trailing it, or standing next to another
2839
+ * bar with nothing in between.
2840
+ *
2841
+ * This is the pass that finishes the job. Run it after everything that can
2842
+ * remove an item, which includes schema filtering as well as name resolution:
2843
+ * a separator can be orphaned by a selection whose node type does not allow
2844
+ * the marks on one side of it, and that is decided per transaction rather than
2845
+ * once at construction.
2846
+ *
2847
+ * The trailing buttons a menu appends afterwards are not visible here, so a
2848
+ * caller that appends its own leading separator has to ask whether anything
2849
+ * came before it. What this guarantees is the half it can: the list is empty,
2850
+ * or it begins and ends with something that is not a separator.
2851
+ *
2852
+ * Written against `{ type: string }` rather than a menu's item union because
2853
+ * every surface spells its item type differently and none of the differences
2854
+ * matter here.
2855
+ *
2856
+ * A list with nothing to drop comes back as the SAME array, not a copy. React
2857
+ * and Vue hand this straight to their state, and a fresh array every time is a
2858
+ * re-render every time: this runs once per transaction, and pointer motion
2859
+ * alone dispatches those. Most lists never need collapsing, so most passes
2860
+ * cost nothing.
2861
+ */
2862
+ declare function collapseSeparators<T extends {
2863
+ type: string;
2864
+ }>(items: readonly T[]): T[];
2865
+
2866
+ /**
2867
+ * Extension - Base class for all extensions
2868
+ *
2869
+ * Extensions provide functionality without contributing to the schema.
2870
+ * For schema contributions, use Node (for block/inline nodes) or Mark (for inline formatting).
2871
+ *
2872
+ * Three-tier model:
2873
+ * - Extension (type: 'extension') → Pure functionality (History, Placeholder, etc.)
2874
+ * - Node (type: 'node') → Schema nodes (Paragraph, Heading, etc.)
2875
+ * - Mark (type: 'mark') → Schema marks (Bold, Italic, etc.)
2876
+ *
2877
+ * @example
2878
+ * const History = Extension.create({
2879
+ * name: 'history',
2880
+ * addOptions() {
2881
+ * return { depth: 100 };
2882
+ * },
2883
+ * addKeyboardShortcuts() {
2884
+ * return {
2885
+ * 'Mod-z': () => this.editor.commands.undo(),
2886
+ * 'Mod-Shift-z': () => this.editor.commands.redo(),
2887
+ * };
2888
+ * },
2889
+ * });
2890
+ */
2891
+
2892
+ /**
2893
+ * Editor interface for Extension
2894
+ * Forward declaration to avoid circular dependency
2895
+ */
2896
+ interface ExtensionEditorInterface {
2897
+ readonly state: EditorState;
2898
+ readonly view: EditorView;
2899
+ readonly schema: unknown;
2900
+ readonly commands: SingleCommands;
2901
+ }
2902
+ /**
2903
+ * Marks an object as a Domternal extension, recognisably across copies.
2904
+ *
2905
+ * `Symbol.for` rather than `Symbol()`: the whole point is that an extension
2906
+ * built by a SECOND physical copy of this module still carries a mark the
2907
+ * first copy can read. A copy-local symbol would be a different key and every
2908
+ * foreign extension would look like a hand-written object instead.
2909
+ *
2910
+ * The value is deliberately `true` rather than a per-copy token. Which copy an
2911
+ * extension came from is answered by `instanceof Extension`, and that answer is
2912
+ * exact; this only separates "a Domternal extension from somewhere" from "a
2913
+ * plain object somebody passed in", which must keep working as it always has.
2914
+ */
2915
+ declare const EXTENSION_BRAND: unique symbol;
2916
+ /**
2917
+ * Base class for all extensions
2918
+ *
2919
+ * @typeParam Options - Extension options type
2920
+ * @typeParam Storage - Extension storage type
2921
+ */
2922
+ declare class Extension<Options = unknown, Storage = unknown> {
2923
+ /**
2924
+ * Brand read by `ExtensionManager` to tell an extension built by another
2925
+ * copy of `@domternal/core` from a plain object. See `EXTENSION_BRAND`.
2926
+ */
2927
+ readonly [EXTENSION_BRAND] = true;
2928
+ /**
2929
+ * Extension type identifier
2930
+ * Used to distinguish between Extension, Node, and Mark
2931
+ * Subclasses override this to 'node' or 'mark'
2932
+ */
2933
+ readonly type: 'extension' | 'node' | 'mark';
2934
+ /**
2935
+ * Unique extension name
2936
+ */
2937
+ readonly name: string;
2938
+ /**
2939
+ * Extension options (immutable after creation)
2940
+ */
2941
+ readonly options: Options;
2942
+ /**
2943
+ * Extension storage (mutable state)
2944
+ * Accessible via editor.storage[extensionName]
2945
+ */
2946
+ storage: Storage;
2947
+ /**
2948
+ * The original configuration object
2949
+ */
2950
+ readonly config: ExtensionConfig<Options, Storage>;
2951
+ /**
2952
+ * Editor instance (set by ExtensionManager after creation)
2953
+ * null until ExtensionManager binds it
2954
+ */
2955
+ editor: ExtensionEditorInterface | null;
2956
+ /**
2957
+ * Reference to the parent config method when using extend().
2958
+ * Set temporarily during config method execution so overridden
2959
+ * methods can call `this.parent?.()` to invoke the original.
2960
+ */
2961
+ parent?: ((...args: unknown[]) => unknown) | undefined;
2962
+ /**
2963
+ * Protected constructor - use Extension.create() instead
2964
+ */
2965
+ protected constructor(config: ExtensionConfig<Options, Storage>);
2966
+ /**
2967
+ * Creates a new extension instance
2968
+ *
2969
+ * @param config - Extension configuration
2970
+ * @returns New extension instance
2971
+ *
2972
+ * @example
2973
+ * const MyExtension = Extension.create({
2974
+ * name: 'myExtension',
2975
+ * addOptions() {
2976
+ * return { enabled: true };
2977
+ * },
2978
+ * });
2979
+ */
2980
+ static create<O = unknown, S = unknown>(config: ExtensionConfig<O, S>): Extension<O, S>;
2981
+ /**
2982
+ * Creates a new extension with merged options
2983
+ * Original extension is not modified
2984
+ *
2985
+ * **Note:** Options are merged shallowly using object spread (`...`).
2986
+ * Nested objects are replaced entirely, not deeply merged.
2987
+ *
2988
+ * @param options - Options to merge with existing options
2989
+ * @returns New extension instance with merged options
2990
+ *
2991
+ * @example
2992
+ * const configured = MyExtension.configure({ enabled: false });
2993
+ *
2994
+ * @example
2995
+ * // Shallow merge behavior with nested objects:
2996
+ * // Given: options = { nested: { a: 1, b: 2 } }
2997
+ * // configure({ nested: { b: 3 } })
2998
+ * // Result: { nested: { b: 3 } } - 'a' is lost!
2999
+ * // To preserve nested values, spread manually:
3000
+ * // configure({ nested: { ...original.options.nested, b: 3 } })
3001
+ */
3002
+ configure(options: Partial<Options>): Extension<Options, Storage>;
3003
+ /**
3004
+ * Returns a fresh, unbound copy built from the same `config`: `editor` reset to
3005
+ * null and `options`/`storage` re-derived, while `configure()`/`extend()`
3006
+ * results are preserved (they live in `config`). Polymorphic: a `Node`/`Mark`
3007
+ * clones to its own subclass.
3008
+ *
3009
+ * `ExtensionManager` clones every extension so each editor owns its instances
3010
+ * and binding one editor can't mutate extensions shared with another.
3011
+ */
3012
+ clone(): Extension<Options, Storage>;
3013
+ /**
3014
+ * Creates a new extension with extended configuration
3015
+ * Original extension is not modified
3016
+ *
3017
+ * **Note:** Config is merged shallowly using object spread (`...`).
3018
+ * Config properties (like `addCommands`, `addKeyboardShortcuts`) are
3019
+ * replaced entirely, not combined with the base extension's config.
3020
+ *
3021
+ * @param extendedConfig - Configuration to extend/override
3022
+ * @returns New extension instance with extended config
3023
+ *
3024
+ * @example
3025
+ * const Extended = MyExtension.extend({
3026
+ * name: 'extendedExtension',
3027
+ * addCommands() {
3028
+ * return { customCommand: () => ({ tr }) => true };
3029
+ * },
3030
+ * });
3031
+ *
3032
+ * @example
3033
+ * // To preserve base extension's commands while adding new ones:
3034
+ * const Extended = BaseExtension.extend({
3035
+ * addCommands() {
3036
+ * const baseCommands = BaseExtension.config.addCommands?.call(this) ?? {};
3037
+ * return {
3038
+ * ...baseCommands,
3039
+ * newCommand: () => ({ tr }) => true,
3040
+ * };
3041
+ * },
3042
+ * });
3043
+ */
3044
+ extend<ExtendedOptions = Options, ExtendedStorage = Storage>(extendedConfig: Partial<ExtensionConfigBase<ExtendedOptions, ExtendedStorage>> & ThisType<ExtensionContext<ExtendedOptions, ExtendedStorage>>): Extension<ExtendedOptions, ExtendedStorage>;
3045
+ }
3046
+
3047
+ /**
3048
+ * Floating menu shown when text is selected. Contextual formatting toolbar.
3049
+ */
3050
+
3051
+ declare const bubbleMenuPluginKey: PluginKey<any>;
3052
+ interface BubbleMenuOptions {
3053
+ /**
3054
+ * The HTML element that contains the menu.
3055
+ * Must be provided by the user.
3056
+ */
3057
+ element: HTMLElement | null;
3058
+ /**
3059
+ * Duration in ms to wait before showing the menu.
3060
+ * @default 0
3061
+ */
3062
+ updateDelay: number;
3063
+ /**
3064
+ * Function to determine if the menu should be shown.
3065
+ * By default, shows for text selections with actual content in an editable editor.
3066
+ */
3067
+ shouldShow: (props: {
3068
+ editor: Editor;
3069
+ view: EditorView;
3070
+ state: EditorState;
3071
+ from: number;
3072
+ to: number;
3073
+ }) => boolean;
3074
+ /**
3075
+ * Placement of the menu relative to the selection.
3076
+ * @default 'top'
3077
+ */
3078
+ placement: 'top' | 'bottom';
3079
+ /**
3080
+ * Offset in pixels from the selection.
3081
+ * @default 8
3082
+ */
3083
+ offset: number;
3084
+ }
3085
+ interface CreateBubbleMenuPluginOptions {
3086
+ pluginKey: PluginKey;
3087
+ editor: Editor;
3088
+ element: HTMLElement;
3089
+ shouldShow?: BubbleMenuOptions['shouldShow'];
3090
+ placement?: 'top' | 'bottom';
3091
+ offset?: number;
3092
+ updateDelay?: number;
3093
+ }
3094
+ /**
3095
+ * Creates a standalone BubbleMenu ProseMirror plugin.
3096
+ * Can be used by framework wrappers (Angular, React, Vue) to create the plugin
3097
+ * independently of the extension system.
3098
+ */
3099
+ declare function createBubbleMenuPlugin(options: CreateBubbleMenuPluginOptions): Plugin;
3100
+ declare const BubbleMenu: Extension<BubbleMenuOptions, unknown>;
3101
+
3102
+ /**
3103
+ * The bubble menu's item pipeline: what the editor registered, what the
3104
+ * selection is, and what the consumer asked for, resolved into the finished
3105
+ * list a menu renders.
3106
+ *
3107
+ * It lives in core because four surfaces need it and each of them is only a
3108
+ * renderer. Vanilla, React, Vue and Angular each carried their own copy of
3109
+ * every function below, four transcriptions of one algorithm kept in step by
3110
+ * hand. They did not stay in step: the separator cleanup that this module now
3111
+ * ends with had to be written four times to fix one defect, which is the
3112
+ * clearest argument that the algorithm was never theirs to hold.
3113
+ *
3114
+ * ProseMirror shapes are duck-typed here rather than imported. A selection or
3115
+ * a schema can arrive from a different copy of prosemirror-state, and
3116
+ * `instanceof` across two copies is false for objects that are otherwise
3117
+ * identical; reading the fields is the check that survives it.
3118
+ */
3119
+
3120
+ interface ResolvedPosShape {
3121
+ parent: {
3122
+ type: {
3123
+ name: string;
3124
+ spec: {
3125
+ marks?: string;
3126
+ };
3127
+ };
3128
+ };
3129
+ depth: number;
3130
+ node: (depth: number) => {
3131
+ type: {
3132
+ name: string;
3133
+ };
3134
+ };
3135
+ }
3136
+ interface SelectionShape {
3137
+ empty: boolean;
3138
+ $from: ResolvedPosShape;
3139
+ $to: ResolvedPosShape;
3140
+ node?: {
3141
+ type: {
3142
+ name: string;
3143
+ };
3144
+ };
3145
+ }
3146
+ interface BubbleMenuSeparator {
3147
+ type: 'separator';
3148
+ name: string;
3149
+ }
3150
+ type BubbleMenuItem = ToolbarButton | ToolbarDropdown | BubbleMenuSeparator;
3151
+ /**
3152
+ * What a consumer may say about one context: an explicit name list, `true`
3153
+ * for every formatting mark the schema allows there, or `null` for no menu.
3154
+ */
3155
+ type BubbleContexts = Record<string, string[] | true | null>;
3156
+ interface BubbleItemMaps {
3157
+ itemMap: Map<string, ToolbarButton>;
3158
+ dropdownMap: Map<string, ToolbarDropdown>;
3159
+ /** Bubble defaults indexed by context name (e.g. 'text', 'codeBlock'). */
3160
+ bubbleDefaults: Map<string, BubbleMenuItem[]>;
3161
+ }
3162
+ /**
3163
+ * Walks `editor.toolbarItems` and indexes them by name. Dropdowns are kept
3164
+ * separately so the bubble menu can resolve them by name (e.g. text-align).
3165
+ *
3166
+ * A dropdown's children are indexed as buttons as well, which is what lets a
3167
+ * consumer name one alignment directly instead of the whole dropdown.
3168
+ */
3169
+ declare function buildBubbleItemMaps(editor: Editor): BubbleItemMaps;
3170
+ /**
3171
+ * Resolve a name array to BubbleMenuItems via the item/dropdown maps.
3172
+ * Dropdowns take priority over buttons sharing the same name. Pipe `|`
3173
+ * tokens become separator entries.
3174
+ *
3175
+ * A name the editor does not carry is skipped, which is what lets one list
3176
+ * serve every build: a default naming `ai` shows it where the Pro extension
3177
+ * is installed and says nothing where it is not. The separator beside such a
3178
+ * name is not skipped with it, because a `|` always resolves; that is what
3179
+ * `collapseSeparators` is for, and why it has to run after this rather than
3180
+ * inside it.
3181
+ */
3182
+ declare function resolveBubbleNames(names: string[], itemMap: Map<string, ToolbarButton>, dropdownMap: Map<string, ToolbarDropdown>): BubbleMenuItem[];
3183
+ /**
3184
+ * All `format`-group buttons sorted by priority (used by the `true` shorthand
3185
+ * to show "all format marks for this context").
3186
+ */
3187
+ declare function getBubbleFormatItems(itemMap: Map<string, ToolbarButton>): ToolbarButton[];
3188
+ /**
3189
+ * Determine the active bubble-menu context based on the selection. Returns
3190
+ * `null` when no context matches (menu should not show).
3191
+ *
3192
+ * Resolution order:
3193
+ * 1. CellSelection (`$anchorCell`) - no menu inside table cell selections
3194
+ * 2. NodeSelection (image, HR, etc.) - return the node's type name
3195
+ * 3. Empty selection - no context (caret-only)
3196
+ * 4. Inside a table cell - return 'table' (when from/to share a cell)
3197
+ * 5. `$from.parent.type.name` if listed in contexts
3198
+ * 6. 'text' if the parent allows marks
3199
+ */
3200
+ declare function detectBubbleContext(selection: SelectionShape, ctxs: BubbleContexts): string | null;
3201
+ /**
3202
+ * Filter items by what the schema actually allows in the given context.
3203
+ * E.g. inside a `codeBlock` node, marks like Bold/Italic aren't permitted.
3204
+ *
3205
+ * Pass-through for 'text' and 'table' contexts (schema check would be
3206
+ * lossy there because marks are allowed but some items still apply).
3207
+ */
3208
+ declare function filterBubbleItemsBySchema(editor: Editor, contextName: string, schemaItems: ToolbarButton[]): ToolbarButton[];
3209
+ /** Detect whether `$pos` is inside a table cell (cell or header). */
3210
+ declare function isInsideTableCell($pos: ResolvedPosShape): boolean;
3211
+ interface ResolveBubbleMenuItemsOptions {
3212
+ editor: Editor;
3213
+ maps: BubbleItemMaps;
3214
+ /** The consumer's `contexts`, or undefined for the fixed-list path. */
3215
+ contexts?: BubbleContexts | undefined;
3216
+ /**
3217
+ * The list to show when `contexts` is absent and the selection is not a
3218
+ * node the editor registered a default for. Already resolved, because it
3219
+ * never changes with the selection.
3220
+ */
3221
+ fallbackItems: BubbleMenuItem[];
3222
+ }
3223
+ /**
3224
+ * The whole decision, in one place: which list this selection gets, filtered
3225
+ * by what the schema allows, with the orphaned separators removed.
3226
+ *
3227
+ * The cleanup is the last step rather than a step inside name resolution
3228
+ * because filtering removes items too: a selection inside a node type that
3229
+ * refuses a mark strands a separator exactly the way a missing extension
3230
+ * does, and only decides it per transaction.
3231
+ */
3232
+ declare function resolveBubbleMenuItems(options: ResolveBubbleMenuItemsOptions): BubbleMenuItem[];
3233
+ /**
3234
+ * The default `shouldShow`, which has to agree with the resolution above:
3235
+ * a menu that opens on a selection resolving to nothing is an empty box, and
3236
+ * one that stays shut on a selection with items is a feature nobody can
3237
+ * reach.
3238
+ */
3239
+ declare function createBubbleShouldShow(maps: BubbleItemMaps, contexts?: BubbleContexts): BubbleMenuOptions['shouldShow'];
3240
+
3241
+ /**
3242
+ * Two packages disagreeing about which copy of `module` they use.
3243
+ *
3244
+ * `message` is the whole story, already formatted: what broke, why it cannot
3245
+ * work, and the one-line fix for each package manager and bundler. Callers
3246
+ * decide only whether to warn or throw.
3247
+ */
3248
+ interface ProseMirrorCopyConflict {
3249
+ /** Package whose copies disagree, e.g. `prosemirror-model`. */
3250
+ module: string;
3251
+ /** Package that registered the copy the page settled on. */
3252
+ firstConsumer: string;
3253
+ /** Package that arrived with a different one. */
3254
+ secondConsumer: string;
3255
+ /** Ready-to-print explanation and fix. */
3256
+ message: string;
3257
+ }
3258
+ /**
3259
+ * Records which copy of `module` a package is using, and reports a conflict
3260
+ * when that disagrees with the copy already registered.
3261
+ *
3262
+ * Returns `null` on the first registration and on every later one that
3263
+ * matches, so the happy path costs one `Map` lookup. Registering a conflicting
3264
+ * copy does NOT replace the recorded one: the first registration wins, which
3265
+ * keeps `firstConsumer` stable no matter how many latecomers arrive.
3266
+ *
3267
+ * @param module Package name, e.g. `prosemirror-model`.
3268
+ * @param copy An export of that package, the same one for every caller. See
3269
+ * the contract in this file's header.
3270
+ * @param consumer Package doing the registering, used in the message.
3271
+ */
3272
+ declare function registerProseMirrorCopy(module: string, copy: object, consumer: string): ProseMirrorCopyConflict | null;
3273
+ /**
3274
+ * Registers a copy and throws when it conflicts.
3275
+ *
3276
+ * For the call sites where a duplicate is already fatal and the only question
3277
+ * is which error the developer reads: the collaboration binding, for one,
3278
+ * throws `Can not convert <> to a Fragment` from inside y-prosemirror one call
3279
+ * later, naming neither package involved.
3280
+ *
3281
+ * @throws ExtensionConfigurationError so `new Editor(...)` fails loudly rather
3282
+ * than being swallowed by the per-extension error isolation.
3283
+ */
3284
+ declare function assertSingleProseMirrorCopy(module: string, copy: object, consumer: string): void;
3285
+ /**
3286
+ * Registers a copy and warns once per module, for call sites where a duplicate
3287
+ * is a strong signal but not necessarily fatal yet: two editors built from two
3288
+ * copies of the core work fine until a node crosses between them.
3289
+ *
3290
+ * Deduped through `globalThis` as well, so a page holding two copies of this
3291
+ * module still prints one warning rather than one per editor per copy.
3292
+ */
3293
+ declare function warnOnDuplicateProseMirrorCopy(module: string, copy: object, consumer: string): ProseMirrorCopyConflict | null;
3294
+
2815
3295
  interface InsertAsListItemChildArgs {
2816
3296
  /** Existing transaction to mutate. Caller dispatches. */
2817
3297
  tr: Transaction;
@@ -3528,168 +4008,6 @@ declare const findChildren: (node: Node$1, predicate: (node: Node$1) => boolean)
3528
4008
 
3529
4009
  declare const defaultBlockAt: (match: ContentMatch) => NodeType | null;
3530
4010
 
3531
- /**
3532
- * Extension - Base class for all extensions
3533
- *
3534
- * Extensions provide functionality without contributing to the schema.
3535
- * For schema contributions, use Node (for block/inline nodes) or Mark (for inline formatting).
3536
- *
3537
- * Three-tier model:
3538
- * - Extension (type: 'extension') → Pure functionality (History, Placeholder, etc.)
3539
- * - Node (type: 'node') → Schema nodes (Paragraph, Heading, etc.)
3540
- * - Mark (type: 'mark') → Schema marks (Bold, Italic, etc.)
3541
- *
3542
- * @example
3543
- * const History = Extension.create({
3544
- * name: 'history',
3545
- * addOptions() {
3546
- * return { depth: 100 };
3547
- * },
3548
- * addKeyboardShortcuts() {
3549
- * return {
3550
- * 'Mod-z': () => this.editor.commands.undo(),
3551
- * 'Mod-Shift-z': () => this.editor.commands.redo(),
3552
- * };
3553
- * },
3554
- * });
3555
- */
3556
-
3557
- /**
3558
- * Editor interface for Extension
3559
- * Forward declaration to avoid circular dependency
3560
- */
3561
- interface ExtensionEditorInterface {
3562
- readonly state: EditorState;
3563
- readonly view: EditorView;
3564
- readonly schema: unknown;
3565
- readonly commands: SingleCommands;
3566
- }
3567
- /**
3568
- * Base class for all extensions
3569
- *
3570
- * @typeParam Options - Extension options type
3571
- * @typeParam Storage - Extension storage type
3572
- */
3573
- declare class Extension<Options = unknown, Storage = unknown> {
3574
- /**
3575
- * Extension type identifier
3576
- * Used to distinguish between Extension, Node, and Mark
3577
- * Subclasses override this to 'node' or 'mark'
3578
- */
3579
- readonly type: 'extension' | 'node' | 'mark';
3580
- /**
3581
- * Unique extension name
3582
- */
3583
- readonly name: string;
3584
- /**
3585
- * Extension options (immutable after creation)
3586
- */
3587
- readonly options: Options;
3588
- /**
3589
- * Extension storage (mutable state)
3590
- * Accessible via editor.storage[extensionName]
3591
- */
3592
- storage: Storage;
3593
- /**
3594
- * The original configuration object
3595
- */
3596
- readonly config: ExtensionConfig<Options, Storage>;
3597
- /**
3598
- * Editor instance (set by ExtensionManager after creation)
3599
- * null until ExtensionManager binds it
3600
- */
3601
- editor: ExtensionEditorInterface | null;
3602
- /**
3603
- * Reference to the parent config method when using extend().
3604
- * Set temporarily during config method execution so overridden
3605
- * methods can call `this.parent?.()` to invoke the original.
3606
- */
3607
- parent?: ((...args: unknown[]) => unknown) | undefined;
3608
- /**
3609
- * Protected constructor - use Extension.create() instead
3610
- */
3611
- protected constructor(config: ExtensionConfig<Options, Storage>);
3612
- /**
3613
- * Creates a new extension instance
3614
- *
3615
- * @param config - Extension configuration
3616
- * @returns New extension instance
3617
- *
3618
- * @example
3619
- * const MyExtension = Extension.create({
3620
- * name: 'myExtension',
3621
- * addOptions() {
3622
- * return { enabled: true };
3623
- * },
3624
- * });
3625
- */
3626
- static create<O = unknown, S = unknown>(config: ExtensionConfig<O, S>): Extension<O, S>;
3627
- /**
3628
- * Creates a new extension with merged options
3629
- * Original extension is not modified
3630
- *
3631
- * **Note:** Options are merged shallowly using object spread (`...`).
3632
- * Nested objects are replaced entirely, not deeply merged.
3633
- *
3634
- * @param options - Options to merge with existing options
3635
- * @returns New extension instance with merged options
3636
- *
3637
- * @example
3638
- * const configured = MyExtension.configure({ enabled: false });
3639
- *
3640
- * @example
3641
- * // Shallow merge behavior with nested objects:
3642
- * // Given: options = { nested: { a: 1, b: 2 } }
3643
- * // configure({ nested: { b: 3 } })
3644
- * // Result: { nested: { b: 3 } } - 'a' is lost!
3645
- * // To preserve nested values, spread manually:
3646
- * // configure({ nested: { ...original.options.nested, b: 3 } })
3647
- */
3648
- configure(options: Partial<Options>): Extension<Options, Storage>;
3649
- /**
3650
- * Returns a fresh, unbound copy built from the same `config`: `editor` reset to
3651
- * null and `options`/`storage` re-derived, while `configure()`/`extend()`
3652
- * results are preserved (they live in `config`). Polymorphic: a `Node`/`Mark`
3653
- * clones to its own subclass.
3654
- *
3655
- * `ExtensionManager` clones every extension so each editor owns its instances
3656
- * and binding one editor can't mutate extensions shared with another.
3657
- */
3658
- clone(): Extension<Options, Storage>;
3659
- /**
3660
- * Creates a new extension with extended configuration
3661
- * Original extension is not modified
3662
- *
3663
- * **Note:** Config is merged shallowly using object spread (`...`).
3664
- * Config properties (like `addCommands`, `addKeyboardShortcuts`) are
3665
- * replaced entirely, not combined with the base extension's config.
3666
- *
3667
- * @param extendedConfig - Configuration to extend/override
3668
- * @returns New extension instance with extended config
3669
- *
3670
- * @example
3671
- * const Extended = MyExtension.extend({
3672
- * name: 'extendedExtension',
3673
- * addCommands() {
3674
- * return { customCommand: () => ({ tr }) => true };
3675
- * },
3676
- * });
3677
- *
3678
- * @example
3679
- * // To preserve base extension's commands while adding new ones:
3680
- * const Extended = BaseExtension.extend({
3681
- * addCommands() {
3682
- * const baseCommands = BaseExtension.config.addCommands?.call(this) ?? {};
3683
- * return {
3684
- * ...baseCommands,
3685
- * newCommand: () => ({ tr }) => true,
3686
- * };
3687
- * },
3688
- * });
3689
- */
3690
- extend<ExtendedOptions = Options, ExtendedStorage = Storage>(extendedConfig: Partial<ExtensionConfigBase<ExtendedOptions, ExtendedStorage>> & ThisType<ExtensionContext<ExtendedOptions, ExtendedStorage>>): Extension<ExtendedOptions, ExtendedStorage>;
3691
- }
3692
-
3693
4011
  /**
3694
4012
  * Node - Base class for node extensions
3695
4013
  *
@@ -6460,61 +6778,6 @@ interface LinkPopoverOptions {
6460
6778
  }
6461
6779
  declare const LinkPopover: Extension<LinkPopoverOptions, unknown>;
6462
6780
 
6463
- /**
6464
- * Floating menu shown when text is selected. Contextual formatting toolbar.
6465
- */
6466
-
6467
- declare const bubbleMenuPluginKey: PluginKey<any>;
6468
- interface BubbleMenuOptions {
6469
- /**
6470
- * The HTML element that contains the menu.
6471
- * Must be provided by the user.
6472
- */
6473
- element: HTMLElement | null;
6474
- /**
6475
- * Duration in ms to wait before showing the menu.
6476
- * @default 0
6477
- */
6478
- updateDelay: number;
6479
- /**
6480
- * Function to determine if the menu should be shown.
6481
- * By default, shows for text selections with actual content in an editable editor.
6482
- */
6483
- shouldShow: (props: {
6484
- editor: Editor;
6485
- view: EditorView;
6486
- state: EditorState;
6487
- from: number;
6488
- to: number;
6489
- }) => boolean;
6490
- /**
6491
- * Placement of the menu relative to the selection.
6492
- * @default 'top'
6493
- */
6494
- placement: 'top' | 'bottom';
6495
- /**
6496
- * Offset in pixels from the selection.
6497
- * @default 8
6498
- */
6499
- offset: number;
6500
- }
6501
- interface CreateBubbleMenuPluginOptions {
6502
- pluginKey: PluginKey;
6503
- editor: Editor;
6504
- element: HTMLElement;
6505
- shouldShow?: BubbleMenuOptions['shouldShow'];
6506
- placement?: 'top' | 'bottom';
6507
- offset?: number;
6508
- updateDelay?: number;
6509
- }
6510
- /**
6511
- * Creates a standalone BubbleMenu ProseMirror plugin.
6512
- * Can be used by framework wrappers (Angular, React, Vue) to create the plugin
6513
- * independently of the extension system.
6514
- */
6515
- declare function createBubbleMenuPlugin(options: CreateBubbleMenuPluginOptions): Plugin;
6516
- declare const BubbleMenu: Extension<BubbleMenuOptions, unknown>;
6517
-
6518
6781
  /**
6519
6782
  * StarterKit Extension
6520
6783
  *
@@ -6650,6 +6913,6 @@ declare const StarterKit: Extension<StarterKitOptions, unknown>;
6650
6913
  * @domternal/core
6651
6914
  * Framework-agnostic ProseMirror editor engine
6652
6915
  */
6653
- declare const VERSION = "0.15.0";
6916
+ declare const VERSION = "1.0.1";
6654
6917
 
6655
- export { type AnyExtension, type AnyExtensionConfig, type AttributeSpec, type AttributeSpecs, type AutolinkPluginOptions, BaseKeymap, type BaseKeymapOptions, BlockColor, type BlockColorOptions, Blockquote, type BlockquoteOptions, Bold, type BoldOptions, BubbleMenu, type BubbleMenuOptions, type BuildCommandPropsOptions, BulletList, type BulletListOptions, type CanChainedCommands, CanChecker, type CanCheckerEditor, type CanCheckerOptions, type CanCommands, ChainBuilder, type ChainBuilderEditor, type ChainBuilderOptions, type ChainFailure, type ChainedCommands, CharacterCount, type CharacterCountOptions, type CharacterCountStorage, type ClearContentOptions, ClearFormatting, Code, CodeBlock, type CodeBlockOptions, type CodeOptions, type Command, type CommandEditor, CommandManager, type CommandManagerEditor, type CommandMap, type CommandProps, type CommandPropsEditor, type CommandSpec, type Content, type ContentErrorProps, type CreateBubbleMenuPluginOptions, type CreateDocumentOptions, type CreateEventProps, type CreateFloatingMenuPluginOptions, DEFAULT_BLOCK_COLORS, DEFAULT_BLOCK_COLOR_TYPES, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_NOTION_COLOR_PALETTE, DEFAULT_TEXT_COLORS, Document$1 as Document, Dropcursor, type DropcursorOptions, Editor, type EditorEventName, type EditorEvents, type EditorInstance, type EditorOptions, type EditorPreset, EventEmitter, Extension, type ExtensionConfig, type ExtensionConfigBase, ExtensionConfigurationError, type ExtensionEditor, ExtensionManager, type ExtensionManagerEditor, type ExtensionManagerOptions, FLOATING_MENU_META, FLOATING_MENU_NO_FOCUS, type FindChildResult, type FindParentNodeResult, FloatingMenuController, type FloatingMenuGroup, type FloatingMenuItem, type FloatingMenuItemsOverride, type FloatingMenuKeymap, type FloatingMenuOptions, Focus, type FocusEventProps, type FocusOptions, type FocusPosition, FontFamily, type FontFamilyOptions, FontSize, type FontSizeOptions, Gapcursor, type GenerateHTMLOptions, type GenerateJSONOptions, type GenerateTextOptions, type GlobalAttributeSpec, type GlobalAttributes, HardBreak, type HardBreakOptions, Heading, type HeadingOptions, Highlight, type HighlightOptions, History, type HistoryOptions, HorizontalRule, type HorizontalRuleOptions, type IconSet, type InlineStyleOverrides, type InsertAsListItemChildArgs, type InsertAsListItemChildResult, InvisibleChars, type InvisibleCharsOptions, type InvisibleCharsStorage, type IsNodeEmptyOptions, type IsValidUrlOptions, Italic, type ItalicOptions, type JSONAttribute, type JSONContent, type JSONMark, type KeyboardShortcutCommand, LIST_ITEM_TYPE_NAMES, LineHeight, type LineHeightOptions, Link, type LinkAttributes, type LinkClickPluginOptions, type LinkExitPluginOptions, type LinkOptions, type LinkPastePluginOptions, LinkPopover, type LinkPopoverOptions, ListIndent, ListItem, type ListItemCursorContext, type ListItemOptions, ListKeymap, type ListKeymapOptions, Mark, type MarkConfig, type MarkInputRuleOptions, type MarkParseRule, type MarkRange, type MarkRenderHTMLProps, type MountEventProps, Node, type NodeConfig, type NodeInputRuleOptions, type NodeParseRule, type NodeRenderHTMLProps, type NodeViewContext, NotionColorPicker, type NotionColorPickerOptions, type NotionColorPickerStorage, OrderedList, type OrderedListOptions, Paragraph, type ParagraphOptions, Placeholder, type PlaceholderOptions, type PositionFloatingOptions, Print, type PrintOptions, type PrintStorage, type Range, type RawCommands, Selection, SelectionDecoration, type SelectionDecorationOptions, type SelectionOptions, type SelectionStorage, type SetContentOptions, type SingleCommands, type SplitListForInsertRange, StarterKit, type StarterKitOptions, Strike, type StrikeOptions, Subscript, type SubscriptOptions, Superscript, type SuperscriptOptions, TaskItem, type TaskItemOptions, TaskList, type TaskListOptions, Text, TextAlign, type TextAlignOptions, TextColor, type TextColorOptions, type TextInputRuleOptions, TextStyle, type TextStyleOptions, type TextblockTypeInputRuleOptions, type ToolbarButton, ToolbarController, type ToolbarControllerEditor, type ToolbarDropdown, type ToolbarGroup, type ToolbarItem, type ToolbarLayoutDropdown, type ToolbarLayoutEntry, type ToolbarSeparator, TrailingNode, type TrailingNodeOptions, type TransactionEventProps, Typography, type TypographyOptions, Underline, type UnderlineOptions, UniqueID, type UniqueIDOptions, VERSION, type WrappingInputRuleOptions, announce, applyInlineStyles, autolinkPlugin, autolinkPluginKey, blur, bubbleMenuPluginKey, buildCommandProps, builtInCommands, callOrReturn, characterCountPluginKey, clearContent, copyThemeClass, createAccumulatingDispatch, createBubbleMenuPlugin, createCanChecker, createChainBuilder, createDocument, createFloatingMenuPlugin, defaultBlockAt, defaultBubbleContexts, defaultFloatingMenuShouldShow, defaultIcons, deleteSelection, findChildren, findListItemAncestorDepth, findParentNode, floatingMenuPluginKey, focus, focusPluginKey, generateHTML, generateJSON, generateText, getListItemCursorContext, getMarkRange, groupFloatingMenuItems, hideFloatingMenu, indentBlockAsListChild, inlineStyles, insertAsListItemChild, insertChildrenZoneSibling, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isInListItemLabel, isInsideListItem, isNodeEmpty, isValidUrl, lift, liftCurrentListItem, liftEmptyChildrenZoneParagraph, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, nodeInputRule, outdentBlockFromListItem, placeholderPluginKey, positionFloating, positionFloatingOnce, refocusEditorAfterCommand, resetAttributes, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, showFloatingMenu, splitListForInsert, stripInlineColorConflicts, textInputRule, textblockTypeInputRule, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, wrapIn, wrappingInputRule, writeToClipboard };
6918
+ export { type AnyExtension, type AnyExtensionConfig, type AttributeSpec, type AttributeSpecs, type AutolinkPluginOptions, BaseKeymap, type BaseKeymapOptions, BlockColor, type BlockColorOptions, Blockquote, type BlockquoteOptions, Bold, type BoldOptions, type BubbleContexts, type BubbleItemMaps, BubbleMenu, type BubbleMenuItem, type BubbleMenuOptions, type BubbleMenuSeparator, type BuildCommandPropsOptions, BulletList, type BulletListOptions, type CanChainedCommands, CanChecker, type CanCheckerEditor, type CanCheckerOptions, type CanCommands, ChainBuilder, type ChainBuilderEditor, type ChainBuilderOptions, type ChainFailure, type ChainedCommands, CharacterCount, type CharacterCountOptions, type CharacterCountStorage, type ClearContentOptions, ClearFormatting, Code, CodeBlock, type CodeBlockOptions, type CodeOptions, type Command, type CommandEditor, CommandManager, type CommandManagerEditor, type CommandMap, type CommandProps, type CommandPropsEditor, type CommandSpec, type Content, type ContentErrorProps, type CreateBubbleMenuPluginOptions, type CreateDocumentOptions, type CreateEventProps, type CreateFloatingMenuPluginOptions, DEFAULT_BLOCK_COLORS, DEFAULT_BLOCK_COLOR_TYPES, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_NOTION_COLOR_PALETTE, DEFAULT_TEXT_COLORS, Document$1 as Document, Dropcursor, type DropcursorOptions, Editor, type EditorEventName, type EditorEvents, type EditorInstance, type EditorOptions, type EditorPreset, EventEmitter, Extension, type ExtensionConfig, type ExtensionConfigBase, ExtensionConfigurationError, type ExtensionEditor, ExtensionManager, type ExtensionManagerEditor, type ExtensionManagerOptions, FLOATING_MENU_META, FLOATING_MENU_NO_FOCUS, type FindChildResult, type FindParentNodeResult, FloatingMenuController, type FloatingMenuGroup, type FloatingMenuItem, type FloatingMenuItemsOverride, type FloatingMenuKeymap, type FloatingMenuOptions, Focus, type FocusEventProps, type FocusOptions, type FocusPosition, FontFamily, type FontFamilyOptions, FontSize, type FontSizeOptions, Gapcursor, type GenerateHTMLOptions, type GenerateJSONOptions, type GenerateTextOptions, type GlobalAttributeSpec, type GlobalAttributes, HardBreak, type HardBreakOptions, Heading, type HeadingOptions, Highlight, type HighlightOptions, History, type HistoryOptions, HorizontalRule, type HorizontalRuleOptions, type IconSet, type InlineStyleOverrides, type InsertAsListItemChildArgs, type InsertAsListItemChildResult, InvisibleChars, type InvisibleCharsOptions, type InvisibleCharsStorage, type IsNodeEmptyOptions, type IsValidUrlOptions, Italic, type ItalicOptions, type JSONAttribute, type JSONContent, type JSONMark, type KeyboardShortcutCommand, LIST_ITEM_TYPE_NAMES, LineHeight, type LineHeightOptions, Link, type LinkAttributes, type LinkClickPluginOptions, type LinkExitPluginOptions, type LinkOptions, type LinkPastePluginOptions, LinkPopover, type LinkPopoverOptions, ListIndent, ListItem, type ListItemCursorContext, type ListItemOptions, ListKeymap, type ListKeymapOptions, Mark, type MarkConfig, type MarkInputRuleOptions, type MarkParseRule, type MarkRange, type MarkRenderHTMLProps, type MountEventProps, Node, type NodeConfig, type NodeInputRuleOptions, type NodeParseRule, type NodeRenderHTMLProps, type NodeViewContext, NotionColorPicker, type NotionColorPickerOptions, type NotionColorPickerStorage, OrderedList, type OrderedListOptions, Paragraph, type ParagraphOptions, Placeholder, type PlaceholderOptions, type PositionFloatingOptions, Print, type PrintOptions, type PrintStorage, type ProseMirrorCopyConflict, type Range, type RawCommands, type ResolveBubbleMenuItemsOptions, type ResolvedPosShape, Selection, SelectionDecoration, type SelectionDecorationOptions, type SelectionOptions, type SelectionShape, type SelectionStorage, type SetContentOptions, type SingleCommands, type SplitListForInsertRange, StarterKit, type StarterKitOptions, Strike, type StrikeOptions, Subscript, type SubscriptOptions, Superscript, type SuperscriptOptions, TaskItem, type TaskItemOptions, TaskList, type TaskListOptions, Text, TextAlign, type TextAlignOptions, TextColor, type TextColorOptions, type TextInputRuleOptions, TextStyle, type TextStyleOptions, type TextblockTypeInputRuleOptions, type ToolbarButton, ToolbarController, type ToolbarControllerEditor, type ToolbarDropdown, type ToolbarGroup, type ToolbarItem, type ToolbarLayoutDropdown, type ToolbarLayoutEntry, type ToolbarSeparator, TrailingNode, type TrailingNodeOptions, type TransactionEventProps, Typography, type TypographyOptions, Underline, type UnderlineOptions, UniqueID, type UniqueIDOptions, VERSION, type WrappingInputRuleOptions, announce, applyInlineStyles, assertSingleProseMirrorCopy, autolinkPlugin, autolinkPluginKey, blur, bubbleMenuPluginKey, buildBubbleItemMaps, buildCommandProps, builtInCommands, callOrReturn, characterCountPluginKey, clearContent, collapseSeparators, copyThemeClass, createAccumulatingDispatch, createBubbleMenuPlugin, createBubbleShouldShow, createCanChecker, createChainBuilder, createDocument, createFloatingMenuPlugin, defaultBlockAt, defaultBubbleContexts, defaultFloatingMenuShouldShow, defaultIcons, deleteSelection, detectBubbleContext, filterBubbleItemsBySchema, findChildren, findListItemAncestorDepth, findParentNode, floatingMenuPluginKey, focus, focusPluginKey, generateHTML, generateJSON, generateText, getBubbleFormatItems, getListItemCursorContext, getMarkRange, groupFloatingMenuItems, hideFloatingMenu, indentBlockAsListChild, inlineStyles, insertAsListItemChild, insertChildrenZoneSibling, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isInListItemLabel, isInsideListItem, isInsideTableCell, isNodeEmpty, isValidUrl, lift, liftCurrentListItem, liftEmptyChildrenZoneParagraph, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, nodeInputRule, outdentBlockFromListItem, placeholderPluginKey, positionFloating, positionFloatingOnce, refocusEditorAfterCommand, registerProseMirrorCopy, resetAttributes, resolveBubbleMenuItems, resolveBubbleNames, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, showFloatingMenu, splitListForInsert, stripInlineColorConflicts, textInputRule, textblockTypeInputRule, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, warnOnDuplicateProseMirrorCopy, wrapIn, wrappingInputRule, writeToClipboard };