import type { ControlContext, ControlDef, ControlItem } from './types'; /** * Drop every control whose id is in `hidden`, the one filter behind the top-level `hideControls` * option. Applied at each build point so a named control disappears from the toolbar, its overflow * menu and the right-click menu at once. Separators are left in place; menus drop them anyway and * the toolbar tidies its own runs after filtering. */ export declare function filterHidden(items: readonly ControlItem[], hidden: ReadonlySet): readonly ControlItem[]; /** * The shared menu machinery. * * A `.zine-controls-menu` is built the same way in two places: the toolbar's overflow (the ⋮ * button) and the right-click context menu. Rather than let those drift, both build their items, * read their state, and run their actions through the helpers here, so a menu looks and behaves * identically wherever it is anchored. Placement and dismissal stay with each owner, because a * popover hanging off a toolbar button and one opening at the cursor differ only there. */ /** A control's label, which may depend on the current state. */ export declare function titleOf(def: ControlDef, ctx: ControlContext): string; /** A control's glyph, which may likewise depend on state (an RTL mirror, say). */ export declare function iconOf(def: ControlDef, ctx: ControlContext): string | undefined; /** The element itself if it can be disabled, else any inputs/buttons it wraps. */ export declare function formFields(el: HTMLElement): (HTMLButtonElement | HTMLInputElement)[]; /** Toggle the pending-action state on a button: a trailing spinner, disabled while it spins. */ export declare function setBusy(btn: HTMLButtonElement, busy: boolean): void; /** * Run a control's action, holding the button busy while a slow one (a cross-origin file fetched to * save or print) settles. `onAfter` re-reads state once the action has run, and again when a * pending one finishes. A disabled or already-busy button does nothing. */ export declare function activateControl(def: ControlDef, trigger: HTMLButtonElement, ctx: ControlContext, onAfter: () => void): void; /** * A control button. Bar buttons are icon-only with the title as tooltip; menu items and any * control without an icon also carry a visible label. `onActivate` is left to the caller so the * toolbar can route a press through its submenu logic while a menu item just acts. */ export declare function buildControlButton(doc: Document, def: ControlDef, className: string, ctx: ControlContext, onActivate: (def: ControlDef, btn: HTMLButtonElement) => void, withLabel?: boolean): HTMLButtonElement; /** * Re-read one control's state after the book changes and reflect it on its element. * * Applies to custom `render` widgets as well as plain buttons: the predicates live on `ControlDef`, * so a widget may be any element and each piece of state is applied however that element supports * it. `visible` overrides the `isVisible` predicate for a control whose visibility is decided * elsewhere (a submenu shown only when it has visible children). */ export declare function applyControlItemState(el: HTMLElement, def: ControlDef, ctx: ControlContext, doc: Document, visible?: boolean): void; /** * A `.zine-controls-menu`: a column of control items with `role=menu`. Owns the items it builds so * it can re-read their state and clean up after itself. The owner supplies the context (whose * `close()` dismisses this menu) and drives when to build, refresh, and destroy; where the menu is * placed and how it is dismissed are the owner's business. */ export declare class ControlMenu { #private; readonly el: HTMLElement; constructor(doc: Document, context: () => ControlContext, onAfterAction: () => void, hidden?: ReadonlySet); /** Fill the menu from a list of controls, dropping separators and anything not applicable. */ build(children: readonly ControlItem[]): void; /** Re-read every item's state. */ refresh(): void; /** Whether the menu (or something inside it) contains `node`. */ contains(node: Node | null): boolean; focusFirst(): void; destroy(): void; } /** A submenu is only worth showing if something inside it is. Keeps a menu trigger from opening * onto nothing when every entry has hidden itself. */ export declare function hasVisibleChildren(def: ControlDef, ctx: ControlContext, hidden?: ReadonlySet): boolean;