/** * Puts an editor's GUI on screen and takes it off again. * * Everything about *where* an editor lives — inline in the cell or portalled * into a popup — plus the accessibility wiring that has to follow it (the * invalid state, the error message, the live-region announcement) is owned * here, so {@link EditorManager} can stay a state machine and never touch the * DOM directly. * * @packageDocumentation */ import type { ICellEditor } from '../types/cell-editor.types'; import type { InvalidResult } from '../types/validation.types'; import { FocusManager } from './focus-manager'; import { PopupService } from './popup-service'; /** * Reports a validation failure to the user outside the cell. * * Wired to the grid's `ToastService` by `GridCore`. A function rather than the * service itself so this module keeps no dependency on the toast implementation * and stays trivially testable. */ export type InvalidReporter = (result: InvalidResult) => void; /** Options for {@link EditorHost.mount}. */ export interface EditorMountOptions { readonly editor: ICellEditor; /** The `.pg-cell` element. */ readonly cellEl: HTMLElement; /** The `.pg-cell__inner` element an inline editor replaces the contents of. */ readonly innerEl: HTMLElement; /** Accessible name for the editor — the column header. */ readonly label: string; /** Invoked when a popup editor is dismissed by an outside click. */ readonly onDismiss: () => void; } /** A mounted editor, owning everything that has to be undone on teardown. */ export interface MountedEditor { /** The editor's root element, as returned by `getGui()`. */ readonly gui: HTMLElement; /** `true` when the editor was portalled rather than placed inline. */ readonly isPopup: boolean; /** * Signals a validation failure: flashes the cell, marks the control invalid * for assistive technology, and reports the message through the configured * {@link InvalidReporter}. Pass `null` to clear the invalid state. */ setInvalid(result: InvalidResult | null): void; /** Removes the editor, restores the cell, and releases every listener. */ unmount(): void; } /** * Mounts editors inline or in a popup. * * One instance per grid, composed from a {@link PopupService} and a * {@link FocusManager} rather than inheriting from or hard-coding either — the * service composition the architecture calls for, and what lets a host * application swap the popup implementation without touching this class. */ export declare class EditorHost { private readonly popups; private readonly focus; /** * The grid's single polite live region, created lazily. * * One per grid rather than one per session: a region has to be in the DOM * *before* text is written into it for assistive technology to announce the * change, so creating it per edit would silently announce nothing. */ private liveRegion; /** Where a rejected value's message is sent. See {@link setInvalidReporter}. */ private report; /** Pending flash timers, so teardown cannot leave a class stuck on a cell. */ private readonly flashTimers; constructor(popups: PopupService, focus: FocusManager); /** * Registers where validation failures are surfaced. * * `GridCore` points this at the grid's `ToastService`. Left unset — in a * bare-bones embedding or a unit test — the failure still flashes the cell * and is announced to assistive technology; only the toast is skipped. */ setInvalidReporter(report: InvalidReporter): void; /** * Places `editor` on screen. * * The cell's rendered content is hidden rather than removed for an inline * editor, so cancelling an edit restores the original cell without asking the * renderer to run again — which matters for a cell holding an `` mid-load * or a painted ``. */ mount(options: EditorMountOptions): MountedEditor; /** * Pulses the cell's border red once. * * The class is removed and re-added across a reflow so a second rejection in * a row replays the animation instead of being swallowed by the first one * still running — the same restart technique the commit flash uses. */ private flashInvalid; /** Cancels a pending flash timer for `cellEl`, if any. */ private clearFlash; /** * Announces `message` politely. * * The text is cleared and re-set on the next frame when it repeats, because a * live region whose content does not change produces no announcement — so * failing the same rule twice in a row would be silent. */ private announce; /** Creates the grid's live region on first use. See {@link liveRegion}. */ private ensureLiveRegion; /** Removes the live region and cancels any pending flash. Called on grid destroy. */ destroy(): void; } //# sourceMappingURL=editor-host.d.ts.map