import { EventEmitter } from 'eventemitter3'; /** * @typedef {function(CommandItem): void} CommandCallback * A callback function that's executed when a toolbar button is clicked * @param {CommandItem} params - Command parameters * @param {ToolbarItem} params.item - An instance of the useToolbarItem composable * @param {unknown} [params.argument] - The argument passed to the command */ /** * @typedef {Object} ToolbarConfig * @property {string | null} [selector] - CSS selector for the toolbar container, or `null` to skip mounting * @property {string[]} [toolbarGroups=['left', 'center', 'right']] - Groups to organize toolbar items * @property {string} [role='editor'] - Role of the toolbar ('editor' or 'viewer') * @property {object} [icons] - Custom icons for toolbar items * @property {object} [texts] - Custom texts for toolbar items * @property {import('../../core/types/EditorConfig.js').FontConfig[] | null} [fonts] - Font options for the font picker dropdown * @property {boolean} [hideButtons=true] - Whether to hide buttons when the editor is not focused * @property {boolean} [pagination=false] - Whether to show pagination controls * @property {string} [mode='docx'] - Editor mode * @property {string[]} [excludeItems=[]] - Items to exclude from the toolbar * @property {Record} [groups] - Custom groups configuration * @property {object} [editor=null] - The editor instance * @property {string} [aiApiKey] - API key for AI integration * @property {string} [aiEndpoint] - Endpoint for AI integration * @property {Array> | ToolbarItem[]} [customButtons=[]] - Custom buttons to add to the toolbar. SuperDoc forwards the structural `Array>` shape from `Modules.toolbar.customButtons`; the runtime wraps each entry into a full `ToolbarItem` via `useToolbarItem`. * @property {boolean} [showFormattingMarksButton=false] - Show the formatting marks (pilcrow) button in the toolbar. Distinct from `layoutEngineOptions.showFormattingMarks`, which controls whether the marks render in the document. * @property {boolean} [showTableOfContentsButton=false] - Show the table of contents insert button in the toolbar. Off by default until the feature is generally available. * @property {boolean} [isDev] - Dev-mode flag forwarded from `SuperDoc.isDev`; gates debug tooltips and overlays. * @property {object} [superdoc] - The owning SuperDoc instance. Set by SuperDoc when constructing the toolbar; the toolbar uses it to dispatch commands back through the parent. * @property {boolean} [responsiveToContainer=false] - When `true`, the toolbar measures the container width instead of the document width when deciding which items to collapse. * @property {string} [uiDisplayFallbackFont] - Forwarded from `Config.uiDisplayFallbackFont`; used as the default font for the toolbar's font picker when no explicit font is selected. * @property {string} [documentMode] - Forwarded from `Config.documentMode`. Currently unused inside SuperToolbar (the toolbar reads the live mode via the `documentMode` toolbar item); kept on the type so SuperDoc's pass-through compiles cleanly. */ /** * @typedef {Object} ToolbarItem * * Reactive toolbar item wrapper produced by `useToolbarItem`. Each * field is a Vue `Ref`-shaped container with a `.value`. The `.value` * types are tightened here (was `*` / `any`) so consumers configuring * custom toolbar buttons get real IntelliSense on the values they * pass through. * * @property {{ value: string }} id - The unique ID of the toolbar item * @property {{ value: string }} name - The name of the toolbar item * @property {string} type - The type of toolbar item (button, options, separator, dropdown, overflow) * @property {{ value: string }} group - The group the item belongs to * @property {string|CommandCallback} command - The command to execute * @property {string} [noArgumentCommand] - The command to execute when no argument is provided * @property {{ value: string | undefined }} icon - The icon for the item (icon-name string) * @property {{ value: string | undefined }} tooltip - The tooltip text * @property {boolean} [restoreEditorFocus] - Whether to restore editor focus after command execution * @property {{ value: Record }} attributes - Additional attributes for the item * @property {{ value: boolean }} disabled - Whether the item is disabled * @property {{ value: boolean }} active - Whether the item is active * @property {{ value: boolean }} expand - Whether the item is expanded * @property {{ value: ToolbarItem[] }} nestedOptions - Nested options for the item * @property {{ value: Record | undefined }} style - Custom style for the item * @property {{ value: boolean }} isNarrow - Whether the item has narrow styling * @property {{ value: boolean }} isWide - Whether the item has wide styling * @property {{ value: number | string | undefined }} minWidth - Minimum width of the item * * `argument.value` and `selectedValue.value` are intentionally * `unknown` (not `any`): consumers pass arbitrary data through these * to their custom command callbacks, so the toolbar cannot promise a * narrower shape without becoming wrong. `unknown` forces the * consumer to narrow at the call site they own. * * @property {{ value: unknown }} argument - The argument to pass to the command (consumer-typed) * @property {{ value: ToolbarItem | undefined }} parentItem - The parent of this item if nested * @property {{ value: ToolbarItem | undefined }} childItem - The child of this item if it has one * @property {{ value: string | undefined }} iconColor - The color of the icon (CSS color) * @property {{ value: boolean }} hasCaret - Whether the item has a dropdown caret * @property {{ value: Record | undefined }} dropdownStyles - Custom styles for the dropdown * @property {{ value: boolean }} tooltipVisible - Whether the tooltip is visible * @property {{ value: number | undefined }} tooltipTimeout - Timeout for the tooltip (ms) * @property {{ value: string | undefined }} defaultLabel - The default label for the item * @property {{ value: string | undefined }} label - The label for the item * @property {{ value: boolean }} hideLabel - Whether to hide the label * @property {{ value: boolean }} inlineTextInputVisible - Whether inline text input is visible * @property {{ value: boolean }} hasInlineTextInput - Whether the item has inline text input * @property {{ value: string | undefined }} markName - The name of the mark (e.g. 'bold') * @property {{ value: string | undefined }} labelAttr - The attribute for the label * @property {{ value: boolean }} allowWithoutEditor - Whether the item can be used without an editor * @property {{ value: string | undefined }} dropdownValueKey - The key for dropdown value * @property {{ value: unknown }} selectedValue - The selected value (consumer-typed) * @property {{ value: HTMLInputElement | null }} inputRef - Reference to an input element * @property {Function} unref - Function to get unreferenced values * @property {Function} activate - Function to activate the item * @property {Function} deactivate - Function to deactivate the item * @property {Function} setDisabled - Function to set the disabled state * @property {Function} resetDisabled - Function to reset the disabled state * @property {Function} onActivate - Function called when the item is activated * @property {Function} onDeactivate - Function called when the item is deactivated */ /** * @typedef {Object} CommandItem * @property {ToolbarItem} item - The toolbar item * @property {unknown} [argument] - The argument to pass to the command (consumer-typed) * @property {unknown} [option] - The selected nested option for option-style commands (consumer-typed) */ /** * A customizable toolbar for the Super Editor * @class * @extends EventEmitter */ export class SuperToolbar extends EventEmitter { /** * Mark toggle names used to identify mark commands that need special handling * when the editor is not focused. * @type {Set} * @private */ private static "__#private@#MARK_TOGGLE_NAMES"; /** * Creates a new SuperToolbar instance * @param {ToolbarConfig} config - The configuration for the toolbar * @returns {void} */ constructor(config: ToolbarConfig); /** * Default configuration for the toolbar * @type {ToolbarConfig} */ config: ToolbarConfig; /** * Visible toolbar items in their resolved order. Populated by * `#initToolbarItems` after `useToolbarItem` builds the reactive * wrappers; mutated when items move to overflow on resize. * @type {ToolbarItem[]} */ toolbarItems: ToolbarItem[]; /** * Items moved into the overflow menu when the container is narrower * than the toolbar's natural width. * @type {ToolbarItem[]} */ overflowItems: ToolbarItem[]; /** * Dev mode flag forwarded from `SuperDoc`'s config. Enables extra * dropdowns (e.g. extension picker) used only by internal tooling. * @type {boolean} */ isDev: boolean; /** * Role propagated from the parent `SuperDoc` (typically `'editor'` * or `'viewer'`); drives feature gating in the toolbar items. * @type {string} */ role: string; /** * Back-reference to the owning `SuperDoc` instance. Marked private * because it exposes the full SuperDoc internal graph and should * not be part of the toolbar's public TypeScript surface. Internal * paths that need a method on the parent SuperDoc reach for it * through this field. * @type {unknown} * @private */ private superdoc; /** * Mounted toolbar container element, set after `render()`. Null * before the first render or after `destroy()`. * @type {HTMLElement | null} */ toolbarContainer: HTMLElement | null; /** * Mounted Vue component instance from `this.app.mount(...)`. Not * consumer API: zero docs/examples reference `superdoc.toolbar.toolbar`, * and no .ts or .js cross-file reader exists. The wrapper * `SuperDoc.toolbar` (this class) is the documented public surface; * this nested `.toolbar` field is the internal Vue mount handle. * * Same SD-3213f-style TS surface hide as `commentsList` and * `SuperDoc.app`; not runtime privacy. * * @type {import('vue').ComponentPublicInstance | null} * @private */ private toolbar; controller: import('../../../../../../superdoc/src/headless-toolbar.js').HeadlessToolbarController | null; snapshot: import('../../../../../../superdoc/src/headless-toolbar.js').ToolbarSnapshot | null; _unsubscribeController: (() => void) | null; /** * Queue of mark commands to execute when editor regains focus. * @type {Array<{command: string, argument: *, item: ToolbarItem}>} * @private */ private pendingMarkCommands; /** * Persisted stored marks to re-apply when the selection is empty and has no formatting. * @type {import('prosemirror-model').Mark[]|null} * @private */ private stickyStoredMarks; /** * Bound event handlers stored for proper cleanup when switching editors. * @type {{transaction: Function|null, selectionUpdate: Function|null, focus: Function|null, fontsChanged: Function|null}} * @private */ private _boundEditorHandlers; /** * Signature of the last-built document font options. Fonts resolve in several steps after a document * opens, so `fonts-changed` fires repeatedly; this skips rebuilding the dropdown when the options did * not actually change. * @private */ private _lastFontOptionsSignature; /** * Timeout ID for restoring editor focus after toolbar command execution. * Tracked for cleanup on destroy to prevent callbacks firing after toolbar is unmounted. * @type {number|null} * @private */ private _restoreFocusTimeoutId; app: import('vue').App | undefined; activeEditor: object | null | undefined; createHeadlessToolbar(): import('../../../../../../superdoc/src/headless-toolbar.js').HeadlessToolbarController | null; initHeadlessToolbar(): void; destroyHeadlessToolbar(): void; /** * The toolbar expects an active Super Editor instance. * Removes listeners from the previous editor (if any) before attaching to the new one. * @param {Object|null} editor - The editor instance to attach to the toolbar, or null to detach * @returns {void} */ setActiveEditor(editor: Object | null): void; /** * Get toolbar items by group name * @param {string} groupName - The name of the group * @returns {ToolbarItem[]} An array of toolbar items in the specified group */ getToolbarItemByGroup(groupName: string): ToolbarItem[]; /** * Get a toolbar item by name * @param {string} name - The name of the toolbar item * @returns {ToolbarItem|undefined} The toolbar item with the specified name or undefined if not found */ getToolbarItemByName(name: string): ToolbarItem | undefined; /** * Get the width used for responsive toolbar decisions. * @returns {number} Available width in pixels */ getAvailableWidth(): number; /** * Update the toolbar state based on the current editor state * Updates active/inactive state of all toolbar items * @returns {void} */ updateToolbarState(): void; /** * Handler for toolbar resize events * @returns {void} */ onToolbarResize: () => void; /** * React to editor transactions. Might want to debounce this. * @param {Object} params - Transaction parameters * @param {Object} params.transaction - The transaction object * @returns {void} */ onEditorTransaction({ transaction }: { transaction: Object; }): void; /** * Main handler for toolbar commands * @param {CommandItem} params - Command parameters * @param {ToolbarItem} params.item - An instance of the useToolbarItem composable * @param {unknown} [params.argument] - The argument passed to the command * @returns {void} All control-flow branches use a bare `return;`; this method * side-effects (emits events, mutates state) and produces no value. */ emitCommand({ item, argument, option }: CommandItem): void; /** * Execute and clear any queued mark commands immediately. Queued commands * normally replay on the editor's next 'selectionUpdate', which is * asynchronous; toolbar focus handoffs (Tab from the font inputs back to * the editor) call this directly so a fast first keystroke cannot outrun * the queued setFontFamily/setFontSize replay. * @returns {boolean} True when pending commands were flushed. */ flushPendingMarkCommands(): boolean; /** * Processes and executes pending mark commands when editor selection updates. * This is triggered by the editor's 'selectionUpdate' event after focus is restored. * @returns {void} */ onEditorSelectionUpdate(): void; /** * Rebuild the toolbar (and so the font dropdown) when the active document's font picture resolves. * Fonts load asynchronously after a document opens, so document font options can change with no edit. * @returns {void} */ onEditorFontsChanged(): void; /** * Handles editor focus events by flushing any pending mark commands. * This is triggered by the editor's 'focus' event. * @returns {void} */ onEditorFocus(): void; /** * Determines if a toolbar item represents a mark toggle command. * Mark toggles include text formatting commands like bold, italic, underline, etc. * @param {ToolbarItem} item - The toolbar item to check * @returns {boolean} True if the item is a mark toggle, false otherwise */ isMarkToggle(item: ToolbarItem): boolean; /** * Cleans up resources when the toolbar is destroyed. * Clears any pending timeouts and unmounts the Vue app so the Toolbar * component's onBeforeUnmount hook runs and removes its window listeners. * @returns {void} */ destroy(): void; #private; } /** * A callback function that's executed when a toolbar button is clicked */ export type CommandCallback = (arg0: CommandItem) => void; export type ToolbarConfig = { /** * - CSS selector for the toolbar container, or `null` to skip mounting */ selector?: string | null | undefined; /** * - Groups to organize toolbar items */ toolbarGroups?: string[] | undefined; /** * - Role of the toolbar ('editor' or 'viewer') */ role?: string | undefined; /** * - Custom icons for toolbar items */ icons?: object | undefined; /** * - Custom texts for toolbar items */ texts?: object | undefined; /** * - Font options for the font picker dropdown */ fonts?: import('../../../../../../superdoc/src/super-editor.js').FontConfig[] | null | undefined; /** * - Whether to hide buttons when the editor is not focused */ hideButtons?: boolean | undefined; /** * - Whether to show pagination controls */ pagination?: boolean | undefined; /** * - Editor mode */ mode?: string | undefined; /** * - Items to exclude from the toolbar */ excludeItems?: string[] | undefined; /** * - Custom groups configuration */ groups?: Record | undefined; /** * - The editor instance */ editor?: object | undefined; /** * - API key for AI integration */ aiApiKey?: string | undefined; /** * - Endpoint for AI integration */ aiEndpoint?: string | undefined; /** * - Custom buttons to add to the toolbar. SuperDoc forwards the structural `Array>` shape from `Modules.toolbar.customButtons`; the runtime wraps each entry into a full `ToolbarItem` via `useToolbarItem`. */ customButtons?: Record[] | ToolbarItem[] | undefined; /** * - Show the formatting marks (pilcrow) button in the toolbar. Distinct from `layoutEngineOptions.showFormattingMarks`, which controls whether the marks render in the document. */ showFormattingMarksButton?: boolean | undefined; /** * - Show the table of contents insert button in the toolbar. Off by default until the feature is generally available. */ showTableOfContentsButton?: boolean | undefined; /** * - Dev-mode flag forwarded from `SuperDoc.isDev`; gates debug tooltips and overlays. */ isDev?: boolean | undefined; /** * - The owning SuperDoc instance. Set by SuperDoc when constructing the toolbar; the toolbar uses it to dispatch commands back through the parent. */ superdoc?: object | undefined; /** * - When `true`, the toolbar measures the container width instead of the document width when deciding which items to collapse. */ responsiveToContainer?: boolean | undefined; /** * - Forwarded from `Config.uiDisplayFallbackFont`; used as the default font for the toolbar's font picker when no explicit font is selected. */ uiDisplayFallbackFont?: string | undefined; /** * - Forwarded from `Config.documentMode`. Currently unused inside SuperToolbar (the toolbar reads the live mode via the `documentMode` toolbar item); kept on the type so SuperDoc's pass-through compiles cleanly. */ documentMode?: string | undefined; }; /** * Reactive toolbar item wrapper produced by `useToolbarItem`. Each * field is a Vue `Ref`-shaped container with a `.value`. The `.value` * types are tightened here (was `*` / `any`) so consumers configuring * custom toolbar buttons get real IntelliSense on the values they * pass through. */ export type ToolbarItem = { /** * - The unique ID of the toolbar item */ id: { value: string; }; /** * - The name of the toolbar item */ name: { value: string; }; /** * - The type of toolbar item (button, options, separator, dropdown, overflow) */ type: string; /** * - The group the item belongs to */ group: { value: string; }; /** * - The command to execute */ command: string | CommandCallback; /** * - The command to execute when no argument is provided */ noArgumentCommand?: string | undefined; /** * - The icon for the item (icon-name string) */ icon: { value: string | undefined; }; /** * - The tooltip text */ tooltip: { value: string | undefined; }; /** * - Whether to restore editor focus after command execution */ restoreEditorFocus?: boolean | undefined; /** * - Additional attributes for the item */ attributes: { value: Record; }; /** * - Whether the item is disabled */ disabled: { value: boolean; }; /** * - Whether the item is active */ active: { value: boolean; }; /** * - Whether the item is expanded */ expand: { value: boolean; }; /** * - Nested options for the item */ nestedOptions: { value: ToolbarItem[]; }; /** * - Custom style for the item */ style: { value: Record | undefined; }; /** * - Whether the item has narrow styling */ isNarrow: { value: boolean; }; /** * - Whether the item has wide styling */ isWide: { value: boolean; }; /** * - Minimum width of the item * * `argument.value` and `selectedValue.value` are intentionally * `unknown` (not `any`): consumers pass arbitrary data through these * to their custom command callbacks, so the toolbar cannot promise a * narrower shape without becoming wrong. `unknown` forces the * consumer to narrow at the call site they own. */ minWidth: { value: number | string | undefined; }; /** * - The argument to pass to the command (consumer-typed) */ argument: { value: unknown; }; /** * - The parent of this item if nested */ parentItem: { value: ToolbarItem | undefined; }; /** * - The child of this item if it has one */ childItem: { value: ToolbarItem | undefined; }; /** * - The color of the icon (CSS color) */ iconColor: { value: string | undefined; }; /** * - Whether the item has a dropdown caret */ hasCaret: { value: boolean; }; /** * - Custom styles for the dropdown */ dropdownStyles: { value: Record | undefined; }; /** * - Whether the tooltip is visible */ tooltipVisible: { value: boolean; }; /** * - Timeout for the tooltip (ms) */ tooltipTimeout: { value: number | undefined; }; /** * - The default label for the item */ defaultLabel: { value: string | undefined; }; /** * - The label for the item */ label: { value: string | undefined; }; /** * - Whether to hide the label */ hideLabel: { value: boolean; }; /** * - Whether inline text input is visible */ inlineTextInputVisible: { value: boolean; }; /** * - Whether the item has inline text input */ hasInlineTextInput: { value: boolean; }; /** * - The name of the mark (e.g. 'bold') */ markName: { value: string | undefined; }; /** * - The attribute for the label */ labelAttr: { value: string | undefined; }; /** * - Whether the item can be used without an editor */ allowWithoutEditor: { value: boolean; }; /** * - The key for dropdown value */ dropdownValueKey: { value: string | undefined; }; /** * - The selected value (consumer-typed) */ selectedValue: { value: unknown; }; /** * - Reference to an input element */ inputRef: { value: HTMLInputElement | null; }; /** * - Function to get unreferenced values */ unref: Function; /** * - Function to activate the item */ activate: Function; /** * - Function to deactivate the item */ deactivate: Function; /** * - Function to set the disabled state */ setDisabled: Function; /** * - Function to reset the disabled state */ resetDisabled: Function; /** * - Function called when the item is activated */ onActivate: Function; /** * - Function called when the item is deactivated */ onDeactivate: Function; }; export type CommandItem = { /** * - The toolbar item */ item: ToolbarItem; /** * - The argument to pass to the command (consumer-typed) */ argument?: unknown; /** * - The selected nested option for option-style commands (consumer-typed) */ option?: unknown; }; //# sourceMappingURL=super-toolbar.d.ts.map