import * as _angular_core from '@angular/core'; import { InjectionToken, Signal, Provider } from '@angular/core'; import { WritingDirection, RovingTabindex, ListNavigationAction } from 'forty-cdk/core'; type TabsActivationMode = 'automatic' | 'manual'; /** * Registry entry for one `ForTabsTrigger`. Part of the registration protocol, * so it is never exported from `public-api.ts` — see {@link TabsContext}. */ interface ForTabsTriggerHandle { readonly host: HTMLElement; readonly id: Signal; readonly value: Signal; readonly disabled: Signal; } /** * Registry entry for one `ForTabsContent`. Part of the registration protocol, * so it is never exported from `public-api.ts` — see {@link TabsContext}. */ interface ForTabsContentHandle { readonly host: HTMLElement; readonly id: Signal; readonly value: Signal; } /** * Coordination contract owned by `ForTabs`. Triggers and contents register * with the root so each side can look up its pair (for `aria-controls` and * `aria-labelledby` wiring), and the root drives keyboard navigation. */ interface ForTabsContext { readonly value: Signal; readonly disabled: Signal; readonly orientation: Signal<'horizontal' | 'vertical'>; readonly dir: Signal; readonly activationMode: Signal; readonly roving: RovingTabindex; isSelected(value: string): boolean; /** Selects `value` if the tabs widget is interactive. */ select(value: string): void; /** Moves focus from `currentTrigger`. In automatic mode also selects the new tab. */ navigate(currentTrigger: HTMLElement, action: ListNavigationAction): void; /** * Looks up the trigger id for a given tab value. Reactive. * * Triggers and contents register synchronously in their constructors, so the * pairing resolves during the first change-detection pass — including a real * server render, where `afterNextRender` never fires and a deferred * registration would leave the pre-hydration DOM without its * `aria-labelledby` / `aria-controls` linkage. A handle whose `value` binding * has not been written yet reads the `unsetInput` sentinel and is skipped — * it can never pair with a lookup value — and the tracked dependency re-runs * the lookup once that binding lands. */ triggerIdFor(value: string): string | null; /** * Looks up the content id for a given tab value. Reactive. Same * synchronous-registration and not-yet-bound handling as * {@link triggerIdFor}. */ contentIdFor(value: string): string | null; /** True when `el` is the first enabled trigger in registration order. */ isFirstEnabledTrigger(el: HTMLElement): boolean; /** * True when some registered, enabled trigger matches the current `value`. * Distinguishes "another trigger owns the tab stop" from "the selected * value points at a removed / disabled trigger" so the per-trigger * tabindex fallback can re-engage the first-enabled entry point instead of * stranding the tablist. Reactive. */ hasSelectedTrigger(): boolean; } /** * DI token for the tabs widget's coordination surface, provided by `[forTabs]`. * * Publicly typed as the read surface {@link ForTabsContext}, which is the whole of what the * token promises a consumer. The pieces read the same token at an internal type that adds * the trigger / content registration protocol, so a wrapper re-providing it must alias it to * the root: `{ provide: FOR_TABS_CONTEXT, useExisting: MyTabs }`, where `MyTabs` extends * `ForTabs`. A value that merely satisfies the declared type resolves too, and is rejected * in dev mode by the first piece to reach the protocol. */ declare const FOR_TABS_CONTEXT: InjectionToken; /** * The tabs widget's internal coordination surface: everything * {@link ForTabsContext} publishes plus the trigger / content registration * protocol the id pairing and keyboard navigation are driven from. * * Never exported from `public-api.ts`. It is the type the pieces read * {@link FOR_TABS_CONTEXT} at, so a consumer who injects that token gets the * read surface while the pieces get the wiring protocol. `ForTabs` declares the * protocol members TS-`private`, which keeps them out of the emitted `.d.ts` * while `useExisting` still satisfies this contract at runtime. */ interface TabsContext extends ForTabsContext { registerTrigger(handle: ForTabsTriggerHandle): void; unregisterTrigger(handle: ForTabsTriggerHandle): void; registerContent(handle: ForTabsContentHandle): void; unregisterContent(handle: ForTabsContentHandle): void; } /** * Root of the Tabs primitive. Owns the selected value, activation mode, * orientation, and disabled state. Provides the shared context to descendant * `ForTabsList` / `ForTabsTrigger` / `ForTabsContent` directives. * * Implements the [WAI-ARIA Tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/). * * `activationMode='automatic'` (default): arrow nav moves focus AND selects * the new tab. Use when panel content is cheap to render. * `activationMode='manual'`: arrow nav only moves focus; the user must press * Space / Enter to activate. Use when panel content is expensive. */ declare class ForTabs implements ForTabsContext { #private; /** * Two-way bindable. The selected tab's value, or `null` when nothing is * selected. `null` is the canonical unset state — distinct from a tab whose * `value` is the empty string `''`, which is a legal, selectable value. The * `model()` change emitter (`(valueChange)`) fires only on internal * selection changes (trigger click or automatic-mode arrow nav), never on * consumer writes via `[(value)]` — observe transitions without binding back. */ readonly value: _angular_core.ModelSignal; /** * Whether arrow navigation also selects the focused tab (`'automatic'`, the default) or only * moves focus until the user presses Enter or Space (`'manual'`). The default is read from * `provideForTabsDefaults` for the surrounding scope. */ readonly activationMode: _angular_core.InputSignal; /** * Axis the arrow keys navigate. Reflected as `data-orientation`. */ readonly orientation: _angular_core.InputSignal<"horizontal" | "vertical">; /** * Writing direction. When unset (default `null`), the inherited ambient * direction is resolved from the nearest ancestor carrying a `dir` attribute * (or ``), defaulting to `'ltr'`. An explicit `[dir]` always wins. * The resolved value is reflected to the host `dir` attribute and swaps * ArrowLeft / ArrowRight semantics in RTL. */ readonly _dirInput: _angular_core.InputSignal; readonly dir: _angular_core.Signal; /** * Whether every trigger in the list is disabled. Individual triggers may also disable themselves. */ readonly disabled: _angular_core.InputSignalWithTransform; /** * Whether arrow navigation wraps around past the first / last enabled * trigger. Default `true` — matches the WAI-ARIA Tabs APG. Set to `false` * for a non-wrapping tablist. The default is read from * `provideForTabsDefaults` for the surrounding scope. */ readonly loop: _angular_core.InputSignalWithTransform; readonly roving: RovingTabindex; isSelected(v: string): boolean; select(v: string): void; navigate(currentTrigger: HTMLElement, action: ListNavigationAction): void; private registerTrigger; private unregisterTrigger; private registerContent; private unregisterContent; triggerIdFor(value: string): string | null; contentIdFor(value: string): string | null; isFirstEnabledTrigger(el: HTMLElement): boolean; hasSelectedTrigger(): boolean; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * The `role="tablist"` container — wraps the `ForTabsTrigger` elements (and * only those — panels live as siblings of the list). Reflects the parent's * orientation as `aria-orientation`. */ declare class ForTabsList { protected readonly group: TabsContext; /** Accessible name for the tab list. Defers to a consumer `aria-labelledby`. */ readonly ariaLabel: _angular_core.InputSignal; protected readonly resolvedAriaLabel: _angular_core.Signal; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Header button for one tab. Apply on a `