import { ReactiveController, ReactiveElement } from 'lit'; import { PendingSpinnerResult } from '../../../directives/pending-spinner/index.js'; /** Minimum interface required from any element that hosts a {@link PendingController}. */ export interface PendingControllerHost extends ReactiveElement { /** Whether the host is in a pending (busy) state. */ pending: boolean; /** * Optional explicit accessible label used during the pending state. When * omitted, the controller derives a busy label from * {@link PendingControllerOptions.resolveAccessibleName}. */ pendingLabel?: string; } /** Configuration options for {@link PendingController}. */ export interface PendingControllerOptions { /** * Milliseconds to wait after `pending` becomes true before activating the * pending visual, so the host does not flash to its busy appearance for * operations that complete quickly. Defaults to `1000`. */ delay?: number; /** * CSS selector, resolved within the host's `renderRoot`, for the element * whose inline size should be frozen while pending (via * `--swc-pending-inline-size`) so the host does not resize when its label or * icon is hidden. Defaults to `'button'`. Pass `null` to skip the freeze. */ targetSelector?: string | null; /** * Returns the host's non-busy accessible name, used to derive the default * busy label (`", busy"`). Keeps the controller decoupled from how the * host resolves its own name. */ resolveAccessibleName?: () => string | null; } /** * A Lit {@link ReactiveController} that manages the pending (busy) *state* of a * host element: the delayed visual activation, freezing the host's inline size * while busy, and deriving the pending accessible name. Rendering is handled * separately by the `renderPendingSpinner` directive * (`@adobe/spectrum-wc-core/directives/pending-spinner`); wiring (the * `pending` / `pending-label` properties and click suppression) is handled by * `PendingMixin` (`@adobe/spectrum-wc-core/mixins`). * * The accessible name and `aria-disabled` are applied by the host's own * template, keyed off `host.pending` for an immediate (non-delayed) response; * this controller exposes {@link getPendingAccessibleName} for the host to read. * * @example * ```ts * const pendingController = new PendingController(this, { * resolveAccessibleName: () => this.textContent?.trim() || null, * }); * // in render(): class=${classMap({ active: pendingController.pendingActive })} * ``` */ export declare class PendingController implements ReactiveController { private readonly _host; private readonly _delay; private readonly _targetSelector; private readonly _resolveAccessibleName; private _timer; /** Tracks the last-seen `pending` value so transitions can be detected in `hostUpdate`. */ private _wasPending; /** * Whether the pending visual is currently active. Becomes `true` only after * the configured delay so the host does not flash to its busy appearance for * operations that complete quickly. Read this from the host's `render`. */ get pendingActive(): boolean; private _pendingActive; constructor(host: PendingControllerHost, options?: PendingControllerOptions); /** * Derives the pending-state accessible label. Prefers an explicit * `pendingLabel`, then the resolved non-busy name plus a ", busy" suffix, * then a fixed "Busy" fallback. */ getPendingAccessibleName(): string; /** * Renders the pending spinner for the controller's current state via the * `renderPendingSpinner` directive. Exposed here so a host gets the indicator * straight from the controller, without importing the directive separately. * Returns `nothing` while the host is not pending. */ renderPendingState(): PendingSpinnerResult; hostConnected(): void; hostUpdate(): void; hostDisconnected(): void; private _activateAfterDelay; private _deactivate; private _clearTimer; private get _freezeTarget(); private _freezeInlineSize; private _releaseInlineSize; }