/** * Widget registry (spec: "Widget System — three tiers, one registry"). * Built-ins are just pre-registered entries here — not special-cased — * symmetric with registerLayer/registerAction/registerSource. */ import type { RuntimeContext } from "./ctx"; /** What a widget implementation gets instead of the raw OmWidgetElement (keeps this module decoupled from the elements/ layer). */ export interface WidgetHost { root: ShadowRoot; $(sel: string): Element | null; $$(sel: string): NodeListOf; getAttribute(name: string): string | null; hasAttribute(name: string): boolean; /** Element.closest — satisfied structurally by the widget element itself; widgets needing owning-map attributes use closest("om-map") (e.g. basemap-switcher's current selection). */ closest(selector: string): Element | null; /** Per-instance mutable stash for state that must survive across renders (e.g. a Vega view to `.finalize()` before re-embedding). */ state: Record; } export interface WidgetImpl { /** Default watch tokens when the element has no `watch` attribute. */ watch?: string[]; /** * Compact button widget (spec: "Widget Layout Manager / Button * clustering") — adjacent compact widgets in one slot auto-merge into a * single visual control group (shared rounded container, dividers, one * shadow). Per-widget opt-out: `cluster="false"`. Non-compact widgets * (panels: legend, filter, search) never cluster. */ compact?: boolean; /** * Never affected by hide-all (spec: "Widget Layout Manager / Hide-all") — * `widgets-hidden` leaves this widget visible. Attribution declares it * (license compliance) and so does the widgets-toggle button (it must * stay clickable to un-hide). Third-party always-visible chrome sets it * here rather than the core hardcoding a type list. */ neverHides?: boolean; render(ctx: RuntimeContext, host: WidgetHost): void | Promise; /** * Optional teardown, called by when the element is REMOVED for * real — an author delete, or an SPA unmounting the whole — never * on the transient disconnect of a slot/fold/cluster reparent (om-widget * distinguishes the two; see its disconnectedCallback). For releasing * resources the document would otherwise pin past the widget's life: blob * URLs, external listeners, large cached tables held in `host.state`. * May fire again after a re-connect if the widget is removed a second * time, so implementations must tolerate repeat calls. */ destroy?(host: WidgetHost): void; } /** Clusterable (spec: "Widget Layout Manager") — the type is compact AND the author didn't opt out. One predicate for the cluster pass AND the validation lint. */ export declare function isClusterableWidget(el: Element): boolean; /** Exempt from hide-all — the type declares `neverHides` (attribution, widgets-toggle). */ export declare function widgetNeverHides(type: string | null): boolean; export declare function registerWidget(name: string, impl: WidgetImpl): void; export declare function getWidget(name: string): WidgetImpl | undefined;