forty-cdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/README.md +122 -0
- package/aspect-ratio/README.md +76 -0
- package/avatar/README.md +100 -0
- package/breadcrumbs/README.md +49 -0
- package/breakpoints/README.md +81 -0
- package/button/README.md +49 -0
- package/calendar/README.md +458 -0
- package/carousel/README.md +358 -0
- package/checkbox/README.md +146 -0
- package/combobox/README.md +535 -0
- package/context-menu/README.md +139 -0
- package/date-field/README.md +184 -0
- package/date-picker/README.md +338 -0
- package/dialog/README.md +388 -0
- package/disclosure/README.md +114 -0
- package/drag-drop/README.md +359 -0
- package/drawer/README.md +560 -0
- package/dropdown-menu/README.md +176 -0
- package/fesm2022/forty-cdk-accordion.mjs +348 -0
- package/fesm2022/forty-cdk-accordion.mjs.map +1 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs +74 -0
- package/fesm2022/forty-cdk-aspect-ratio.mjs.map +1 -0
- package/fesm2022/forty-cdk-avatar.mjs +308 -0
- package/fesm2022/forty-cdk-avatar.mjs.map +1 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs +125 -0
- package/fesm2022/forty-cdk-breadcrumbs.mjs.map +1 -0
- package/fesm2022/forty-cdk-breakpoints.mjs +117 -0
- package/fesm2022/forty-cdk-breakpoints.mjs.map +1 -0
- package/fesm2022/forty-cdk-button.mjs +134 -0
- package/fesm2022/forty-cdk-button.mjs.map +1 -0
- package/fesm2022/forty-cdk-calendar.mjs +2034 -0
- package/fesm2022/forty-cdk-calendar.mjs.map +1 -0
- package/fesm2022/forty-cdk-carousel.mjs +968 -0
- package/fesm2022/forty-cdk-carousel.mjs.map +1 -0
- package/fesm2022/forty-cdk-checkbox.mjs +226 -0
- package/fesm2022/forty-cdk-checkbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-combobox.mjs +2596 -0
- package/fesm2022/forty-cdk-combobox.mjs.map +1 -0
- package/fesm2022/forty-cdk-context-menu.mjs +413 -0
- package/fesm2022/forty-cdk-context-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-core.mjs +9022 -0
- package/fesm2022/forty-cdk-core.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-field.mjs +744 -0
- package/fesm2022/forty-cdk-date-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-date-picker.mjs +1011 -0
- package/fesm2022/forty-cdk-date-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-dialog.mjs +707 -0
- package/fesm2022/forty-cdk-dialog.mjs.map +1 -0
- package/fesm2022/forty-cdk-disclosure.mjs +190 -0
- package/fesm2022/forty-cdk-disclosure.mjs.map +1 -0
- package/fesm2022/forty-cdk-drag-drop.mjs +1180 -0
- package/fesm2022/forty-cdk-drag-drop.mjs.map +1 -0
- package/fesm2022/forty-cdk-drawer.mjs +1641 -0
- package/fesm2022/forty-cdk-drawer.mjs.map +1 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs +350 -0
- package/fesm2022/forty-cdk-dropdown-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-field.mjs +425 -0
- package/fesm2022/forty-cdk-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-fieldset.mjs +164 -0
- package/fesm2022/forty-cdk-fieldset.mjs.map +1 -0
- package/fesm2022/forty-cdk-file-upload.mjs +221 -0
- package/fesm2022/forty-cdk-file-upload.mjs.map +1 -0
- package/fesm2022/forty-cdk-hover-card.mjs +496 -0
- package/fesm2022/forty-cdk-hover-card.mjs.map +1 -0
- package/fesm2022/forty-cdk-input.mjs +274 -0
- package/fesm2022/forty-cdk-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-internationalized-date.mjs +1 -1
- package/fesm2022/forty-cdk-internationalized-date.mjs.map +1 -1
- package/fesm2022/forty-cdk-listbox.mjs +1279 -0
- package/fesm2022/forty-cdk-listbox.mjs.map +1 -0
- package/fesm2022/forty-cdk-menu.mjs +1439 -0
- package/fesm2022/forty-cdk-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-menubar.mjs +787 -0
- package/fesm2022/forty-cdk-menubar.mjs.map +1 -0
- package/fesm2022/forty-cdk-meter.mjs +211 -0
- package/fesm2022/forty-cdk-meter.mjs.map +1 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs +1145 -0
- package/fesm2022/forty-cdk-navigation-menu.mjs.map +1 -0
- package/fesm2022/forty-cdk-number-input.mjs +559 -0
- package/fesm2022/forty-cdk-number-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-otp-input.mjs +527 -0
- package/fesm2022/forty-cdk-otp-input.mjs.map +1 -0
- package/fesm2022/forty-cdk-pagination.mjs +323 -0
- package/fesm2022/forty-cdk-pagination.mjs.map +1 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs +297 -0
- package/fesm2022/forty-cdk-pane-resizer.mjs.map +1 -0
- package/fesm2022/forty-cdk-popover.mjs +698 -0
- package/fesm2022/forty-cdk-popover.mjs.map +1 -0
- package/fesm2022/forty-cdk-progress.mjs +226 -0
- package/fesm2022/forty-cdk-progress.mjs.map +1 -0
- package/fesm2022/forty-cdk-radio-group.mjs +378 -0
- package/fesm2022/forty-cdk-radio-group.mjs.map +1 -0
- package/fesm2022/forty-cdk-scroll-area.mjs +640 -0
- package/fesm2022/forty-cdk-scroll-area.mjs.map +1 -0
- package/fesm2022/forty-cdk-search.mjs +205 -0
- package/fesm2022/forty-cdk-search.mjs.map +1 -0
- package/fesm2022/forty-cdk-select.mjs +1661 -0
- package/fesm2022/forty-cdk-select.mjs.map +1 -0
- package/fesm2022/forty-cdk-separator.mjs +82 -0
- package/fesm2022/forty-cdk-separator.mjs.map +1 -0
- package/fesm2022/forty-cdk-signal-forms.mjs +97 -0
- package/fesm2022/forty-cdk-signal-forms.mjs.map +1 -0
- package/fesm2022/forty-cdk-slider.mjs +803 -0
- package/fesm2022/forty-cdk-slider.mjs.map +1 -0
- package/fesm2022/forty-cdk-stepper.mjs +886 -0
- package/fesm2022/forty-cdk-stepper.mjs.map +1 -0
- package/fesm2022/forty-cdk-switch.mjs +137 -0
- package/fesm2022/forty-cdk-switch.mjs.map +1 -0
- package/fesm2022/forty-cdk-table.mjs +1518 -0
- package/fesm2022/forty-cdk-table.mjs.map +1 -0
- package/fesm2022/forty-cdk-tabs.mjs +400 -0
- package/fesm2022/forty-cdk-tabs.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-field.mjs +593 -0
- package/fesm2022/forty-cdk-time-field.mjs.map +1 -0
- package/fesm2022/forty-cdk-time-picker.mjs +1013 -0
- package/fesm2022/forty-cdk-time-picker.mjs.map +1 -0
- package/fesm2022/forty-cdk-toast.mjs +1153 -0
- package/fesm2022/forty-cdk-toast.mjs.map +1 -0
- package/fesm2022/forty-cdk-toggle.mjs +516 -0
- package/fesm2022/forty-cdk-toggle.mjs.map +1 -0
- package/fesm2022/forty-cdk-toolbar.mjs +374 -0
- package/fesm2022/forty-cdk-toolbar.mjs.map +1 -0
- package/fesm2022/forty-cdk-tooltip.mjs +672 -0
- package/fesm2022/forty-cdk-tooltip.mjs.map +1 -0
- package/fesm2022/forty-cdk-tree.mjs +2007 -0
- package/fesm2022/forty-cdk-tree.mjs.map +1 -0
- package/fesm2022/forty-cdk-virtualization.mjs +1 -1
- package/fesm2022/forty-cdk-virtualization.mjs.map +1 -1
- package/fesm2022/forty-cdk.mjs +0 -43310
- package/fesm2022/forty-cdk.mjs.map +1 -1
- package/field/README.md +97 -0
- package/fieldset/README.md +86 -0
- package/file-upload/README.md +73 -0
- package/hover-card/README.md +171 -0
- package/input/README.md +156 -0
- package/listbox/README.md +424 -0
- package/menu/README.md +181 -0
- package/menubar/README.md +140 -0
- package/meter/README.md +128 -0
- package/navigation-menu/README.md +253 -0
- package/number-input/README.md +171 -0
- package/otp-input/README.md +198 -0
- package/package.json +213 -1
- package/pagination/README.md +61 -0
- package/pane-resizer/README.md +136 -0
- package/popover/README.md +262 -0
- package/progress/README.md +115 -0
- package/radio-group/README.md +129 -0
- package/scroll-area/README.md +184 -0
- package/search/README.md +42 -0
- package/select/README.md +488 -0
- package/separator/README.md +84 -0
- package/signal-forms/README.md +72 -0
- package/slider/README.md +152 -0
- package/stepper/README.md +292 -0
- package/switch/README.md +116 -0
- package/table/README.md +769 -0
- package/tabs/README.md +130 -0
- package/time-field/README.md +157 -0
- package/time-picker/README.md +172 -0
- package/toast/README.md +398 -0
- package/toggle/README.md +224 -0
- package/toolbar/README.md +109 -0
- package/tooltip/README.md +274 -0
- package/tree/README.md +708 -0
- package/types/forty-cdk-accordion.d.ts +242 -0
- package/types/forty-cdk-aspect-ratio.d.ts +59 -0
- package/types/forty-cdk-avatar.d.ts +133 -0
- package/types/forty-cdk-breadcrumbs.d.ts +92 -0
- package/types/forty-cdk-breakpoints.d.ts +141 -0
- package/types/forty-cdk-button.d.ts +80 -0
- package/types/forty-cdk-calendar.d.ts +914 -0
- package/types/forty-cdk-carousel.d.ts +530 -0
- package/types/forty-cdk-checkbox.d.ts +141 -0
- package/types/forty-cdk-combobox.d.ts +1259 -0
- package/types/forty-cdk-context-menu.d.ts +313 -0
- package/types/forty-cdk-core.d.ts +5774 -0
- package/types/forty-cdk-date-field.d.ts +307 -0
- package/types/forty-cdk-date-picker.d.ts +622 -0
- package/types/forty-cdk-dialog.d.ts +546 -0
- package/types/forty-cdk-disclosure.d.ts +127 -0
- package/types/forty-cdk-drag-drop.d.ts +456 -0
- package/types/forty-cdk-drawer.d.ts +871 -0
- package/types/forty-cdk-dropdown-menu.d.ts +242 -0
- package/types/forty-cdk-field.d.ts +236 -0
- package/types/forty-cdk-fieldset.d.ts +119 -0
- package/types/forty-cdk-file-upload.d.ts +124 -0
- package/types/forty-cdk-hover-card.d.ts +320 -0
- package/types/forty-cdk-input.d.ts +169 -0
- package/types/forty-cdk-internationalized-date.d.ts +1 -1
- package/types/forty-cdk-listbox.d.ts +513 -0
- package/types/forty-cdk-menu.d.ts +629 -0
- package/types/forty-cdk-menubar.d.ts +451 -0
- package/types/forty-cdk-meter.d.ts +122 -0
- package/types/forty-cdk-navigation-menu.d.ts +514 -0
- package/types/forty-cdk-number-input.d.ts +319 -0
- package/types/forty-cdk-otp-input.d.ts +248 -0
- package/types/forty-cdk-pagination.d.ts +214 -0
- package/types/forty-cdk-pane-resizer.d.ts +145 -0
- package/types/forty-cdk-popover.d.ts +509 -0
- package/types/forty-cdk-progress.d.ts +143 -0
- package/types/forty-cdk-radio-group.d.ts +222 -0
- package/types/forty-cdk-scroll-area.d.ts +258 -0
- package/types/forty-cdk-search.d.ts +142 -0
- package/types/forty-cdk-select.d.ts +899 -0
- package/types/forty-cdk-separator.d.ts +59 -0
- package/types/forty-cdk-signal-forms.d.ts +58 -0
- package/types/forty-cdk-slider.d.ts +379 -0
- package/types/forty-cdk-stepper.d.ts +650 -0
- package/types/forty-cdk-switch.d.ts +87 -0
- package/types/forty-cdk-table.d.ts +723 -0
- package/types/forty-cdk-tabs.d.ts +235 -0
- package/types/forty-cdk-time-field.d.ts +307 -0
- package/types/forty-cdk-time-picker.d.ts +578 -0
- package/types/forty-cdk-toast.d.ts +598 -0
- package/types/forty-cdk-toggle.d.ts +310 -0
- package/types/forty-cdk-toolbar.d.ts +217 -0
- package/types/forty-cdk-tooltip.d.ts +436 -0
- package/types/forty-cdk-tree.d.ts +688 -0
- package/types/forty-cdk.d.ts +1 -19743
|
@@ -0,0 +1,899 @@
|
|
|
1
|
+
import * as _floating_ui_dom from '@floating-ui/dom';
|
|
2
|
+
import { ReferenceElement } from '@floating-ui/dom';
|
|
3
|
+
import * as _angular_core from '@angular/core';
|
|
4
|
+
import { InjectionToken, ModelSignal, Signal, Provider } from '@angular/core';
|
|
5
|
+
import { FormValueControl } from '@angular/forms/signals';
|
|
6
|
+
import { FloatingSide, FloatingAlign, WritingDirection, CollectionHandle, ListNavigationAction, VetoableNativeEvent, FormUiControlBase, VetoableEvent } from 'forty-cdk/core';
|
|
7
|
+
import * as forty_cdk_select from 'forty-cdk/select';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Why a select requested close. Mirrors the menu primitive vocabulary so
|
|
11
|
+
* downstream code that switches on close reasons stays consistent.
|
|
12
|
+
*/
|
|
13
|
+
type ForSelectCloseReason = 'escape' | 'pointerDownOutside' | 'focusOutside' | 'select' | 'tab' | 'programmatic';
|
|
14
|
+
/**
|
|
15
|
+
* Where focus lands when the listbox opens. `'selected'` snaps to the first
|
|
16
|
+
* currently-selected enabled option (matches native `<select>`); falls back
|
|
17
|
+
* to `'first'` if no selection is enabled.
|
|
18
|
+
*/
|
|
19
|
+
type ForSelectInitialFocus = 'first' | 'last' | 'selected';
|
|
20
|
+
/**
|
|
21
|
+
* Handle every `[forSelectOption]` registers with the root. The collection
|
|
22
|
+
* orders entries by DOM document order so groups, separators, and `@for`
|
|
23
|
+
* loops don't perturb keyboard navigation.
|
|
24
|
+
*
|
|
25
|
+
* Generic over the option value type `T` (default `unknown` at the contract
|
|
26
|
+
* level; `string` at the public root). The handle carries the raw value so
|
|
27
|
+
* the root can match it against `value()` via `isItemEqualToValue`.
|
|
28
|
+
*/
|
|
29
|
+
interface ForSelectOptionHandle<T = unknown> extends CollectionHandle {
|
|
30
|
+
readonly value: Signal<T>;
|
|
31
|
+
/**
|
|
32
|
+
* The option's resolved display label as a reactive `Signal<string>` — the
|
|
33
|
+
* trimmed `textContent` of the host. The root folds it into a persisted
|
|
34
|
+
* snapshot so `selectedLabels` and closed-state typeahead resolve labels
|
|
35
|
+
* without peeking at `textContent` from inside a `computed`.
|
|
36
|
+
*/
|
|
37
|
+
readonly label: Signal<string>;
|
|
38
|
+
readonly disabled: Signal<boolean>;
|
|
39
|
+
/** Stable host `id` — the activedescendant target in the virtualized path. */
|
|
40
|
+
readonly id: Signal<string>;
|
|
41
|
+
/**
|
|
42
|
+
* Zero-based absolute position in the full source data. Required in the
|
|
43
|
+
* virtualized path (drives the position snapshot + `aria-posinset`); `null`
|
|
44
|
+
* outside it.
|
|
45
|
+
*/
|
|
46
|
+
readonly posInSet: Signal<number | null>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Coordination contract owned by `[forSelect]`. Trigger, content, value,
|
|
50
|
+
* options, groups and separators all inject this token to read state and
|
|
51
|
+
* delegate behavior — they don't import the root class directly.
|
|
52
|
+
*
|
|
53
|
+
* Generic over the option value type `T` (default `string` at the public
|
|
54
|
+
* root). When a consumer binds object items the directive infers `T` from
|
|
55
|
+
* `[(value)]` and the per-piece signatures specialize accordingly. Items are
|
|
56
|
+
* compared via the consumer-provided `isItemEqualToValue` and serialized for
|
|
57
|
+
* the form's hidden inputs via `itemToFormValue`; option text labels are
|
|
58
|
+
* still read from the rendered `textContent`.
|
|
59
|
+
*/
|
|
60
|
+
interface ForSelectContext<T = unknown> {
|
|
61
|
+
readonly value: ModelSignal<readonly T[]>;
|
|
62
|
+
readonly open: ModelSignal<boolean>;
|
|
63
|
+
readonly multiple: Signal<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* The select's effective disabled — its own `disabled` input OR'd with a
|
|
66
|
+
* surrounding disabled `[forFieldset]`. Trigger and options read this so a
|
|
67
|
+
* disabled select (or fieldset) is inert and exposes `aria-disabled`.
|
|
68
|
+
*/
|
|
69
|
+
readonly effectiveDisabled: Signal<boolean>;
|
|
70
|
+
readonly readonly: Signal<boolean>;
|
|
71
|
+
readonly required: Signal<boolean>;
|
|
72
|
+
readonly invalid: Signal<boolean>;
|
|
73
|
+
readonly pending: Signal<boolean>;
|
|
74
|
+
/**
|
|
75
|
+
* When `true`, the listbox is a trapped / inert / scroll-locked modal
|
|
76
|
+
* surface (routed through `_internal/modal-shell`) instead of the anchored
|
|
77
|
+
* popover. Read once when `[forSelectContent]` mounts; all anchored-
|
|
78
|
+
* positioning state below is a no-op while modal.
|
|
79
|
+
*/
|
|
80
|
+
readonly modal: Signal<boolean>;
|
|
81
|
+
readonly dismissible: Signal<boolean>;
|
|
82
|
+
readonly returnFocus: Signal<boolean>;
|
|
83
|
+
/**
|
|
84
|
+
* Positioning algorithm. `'popper'` (default) is standard floating-ui
|
|
85
|
+
* anchored placement; `'item-aligned'` overlays the listbox so the
|
|
86
|
+
* selected option's center aligns with the trigger's center (macOS-style
|
|
87
|
+
* native `<select>`). All `side`/`align`/`*Offset`/`sticky`/
|
|
88
|
+
* `hideWhenDetached`/`clipUntilPositioned`/`avoidCollisions` inputs are no-ops in
|
|
89
|
+
* `'item-aligned'` mode (only `collisionPadding` is honored).
|
|
90
|
+
*/
|
|
91
|
+
readonly position: Signal<'popper' | 'item-aligned'>;
|
|
92
|
+
readonly side: Signal<FloatingSide | undefined>;
|
|
93
|
+
readonly align: Signal<FloatingAlign | undefined>;
|
|
94
|
+
readonly sideOffset: Signal<number>;
|
|
95
|
+
readonly alignOffset: Signal<number>;
|
|
96
|
+
readonly avoidCollisions: Signal<boolean>;
|
|
97
|
+
readonly collisionPadding: Signal<number>;
|
|
98
|
+
readonly arrowPadding: Signal<number>;
|
|
99
|
+
readonly sticky: Signal<'partial' | 'always' | false>;
|
|
100
|
+
readonly hideWhenDetached: Signal<boolean>;
|
|
101
|
+
readonly clipUntilPositioned: Signal<boolean>;
|
|
102
|
+
readonly loop: Signal<boolean>;
|
|
103
|
+
readonly orientation: Signal<'horizontal' | 'vertical'>;
|
|
104
|
+
readonly dir: Signal<WritingDirection>;
|
|
105
|
+
readonly selectionFollowsFocus: Signal<boolean>;
|
|
106
|
+
readonly placeholder: Signal<string>;
|
|
107
|
+
/** Where focus should land after the content mounts. Triggers set this before flipping `open`. */
|
|
108
|
+
readonly initialFocus: Signal<ForSelectInitialFocus>;
|
|
109
|
+
setInitialFocus(target: ForSelectInitialFocus): void;
|
|
110
|
+
readonly triggerId: Signal<string>;
|
|
111
|
+
readonly contentId: Signal<string>;
|
|
112
|
+
readonly ariaLabel: Signal<string | null>;
|
|
113
|
+
/** Compare two items for equality. Defaults to `===`; overridden for object values. */
|
|
114
|
+
readonly isItemEqualToValue: Signal<(a: T, b: T) => boolean>;
|
|
115
|
+
/** Serialize an item for the hidden input's `value` attribute. Defaults to `String(item)`. */
|
|
116
|
+
readonly itemToFormValue: Signal<(item: T) => string>;
|
|
117
|
+
/**
|
|
118
|
+
* Element floating-ui anchors the listbox against. Prefers an optional
|
|
119
|
+
* `[forSelectAnchor]` when registered, otherwise falls back to the trigger.
|
|
120
|
+
* Decoupled from `trigger` so the trigger keeps driving `aria-controls`,
|
|
121
|
+
* the click toggle, focus return, and its outside-pointer exemption
|
|
122
|
+
* regardless of where the listbox paints.
|
|
123
|
+
*/
|
|
124
|
+
readonly anchor: Signal<ReferenceElement | null>;
|
|
125
|
+
/** The button trigger — exempt from outside-pointer checks and the focus-return target. */
|
|
126
|
+
readonly trigger: Signal<HTMLElement | null>;
|
|
127
|
+
registerTrigger(el: HTMLElement): void;
|
|
128
|
+
unregisterTrigger(el: HTMLElement): void;
|
|
129
|
+
/**
|
|
130
|
+
* Register / unregister an optional `[forSelectAnchor]` positioning element.
|
|
131
|
+
* At most one anchor per root; a second registration throws. Reference-based
|
|
132
|
+
* unregister, so an anchor torn down inside `@if` restores the trigger
|
|
133
|
+
* fallback cleanly.
|
|
134
|
+
*/
|
|
135
|
+
registerAnchor(el: HTMLElement): void;
|
|
136
|
+
unregisterAnchor(el: HTMLElement): void;
|
|
137
|
+
/** The mounted `[forSelectContent]` element. */
|
|
138
|
+
readonly content: Signal<HTMLElement | null>;
|
|
139
|
+
registerContent(el: HTMLElement): void;
|
|
140
|
+
unregisterContent(el: HTMLElement): void;
|
|
141
|
+
registerOption(handle: ForSelectOptionHandle<T>): void;
|
|
142
|
+
unregisterOption(handle: ForSelectOptionHandle<T>): void;
|
|
143
|
+
/** All registered options in DOM order. */
|
|
144
|
+
readonly options: Signal<readonly ForSelectOptionHandle<T>[]>;
|
|
145
|
+
/** Resolved labels of the options whose value is in `value()`, in selection order. */
|
|
146
|
+
readonly selectedLabels: Signal<readonly string[]>;
|
|
147
|
+
/**
|
|
148
|
+
* Host element of the first enabled, currently-selected option, or `null`
|
|
149
|
+
* when no selection exists. Used by `position="item-aligned"` to anchor
|
|
150
|
+
* the listbox over the trigger; falls back to the first enabled option
|
|
151
|
+
* inside the listbox when this is `null`.
|
|
152
|
+
*/
|
|
153
|
+
readonly selectedOptionEl: Signal<HTMLElement | null>;
|
|
154
|
+
isSelected(value: T): boolean;
|
|
155
|
+
/** Toggle in multi-mode, replace + close in single-mode. No-op on disabled / readonly. */
|
|
156
|
+
activate(value: T): void;
|
|
157
|
+
/** Move focus inside the open listbox in response to an arrow / Home / End key. */
|
|
158
|
+
navigate(currentOption: HTMLElement, action: ListNavigationAction): void;
|
|
159
|
+
/** Open-state typeahead: focus the first enabled option whose text matches the buffered prefix. */
|
|
160
|
+
handleTypeahead(event: KeyboardEvent): void;
|
|
161
|
+
/**
|
|
162
|
+
* Closed-state typeahead (single mode only). Selects the first matching
|
|
163
|
+
* option directly without opening the listbox — mirrors native `<select>`
|
|
164
|
+
* behavior. Returns `true` if the key was consumed by typeahead.
|
|
165
|
+
*/
|
|
166
|
+
handleClosedTypeahead(event: KeyboardEvent): boolean;
|
|
167
|
+
focusFirstEnabledOption(): boolean;
|
|
168
|
+
focusLastEnabledOption(): boolean;
|
|
169
|
+
/** Focus the first enabled option whose value is currently selected. Returns `false` if none. */
|
|
170
|
+
focusSelectedOption(): boolean;
|
|
171
|
+
toggle(initialFocus?: ForSelectInitialFocus): void;
|
|
172
|
+
openMenu(initialFocus?: ForSelectInitialFocus): void;
|
|
173
|
+
closeMenu(reason: ForSelectCloseReason): void;
|
|
174
|
+
/**
|
|
175
|
+
* Reason of the most recent close, or `null` while the listbox is open
|
|
176
|
+
* (or before any close). Read by `[forSelectContent]` so `'tab'` closes
|
|
177
|
+
* skip the return-focus step — Tab needs the browser to advance focus
|
|
178
|
+
* from the trigger, and a re-focus would steal it back.
|
|
179
|
+
*/
|
|
180
|
+
readonly lastCloseReason: Signal<ForSelectCloseReason | null>;
|
|
181
|
+
/**
|
|
182
|
+
* Commit the focused option's value (single mode) and close the listbox
|
|
183
|
+
* with reason `'tab'`. Moves focus to the trigger synchronously so the
|
|
184
|
+
* browser's Tab default action advances focus from there to the next
|
|
185
|
+
* (or previous) focusable in tab order. Multi-mode skips the value-set
|
|
186
|
+
* — selection toggles already happened via Space / Enter / click.
|
|
187
|
+
*/
|
|
188
|
+
commitOnTab(value: T): void;
|
|
189
|
+
emitEscapeKeyDown(event: KeyboardEvent): void;
|
|
190
|
+
emitPointerDownOutside(veto: VetoableNativeEvent<PointerEvent>): void;
|
|
191
|
+
emitFocusOutside(veto: VetoableNativeEvent<FocusEvent>): void;
|
|
192
|
+
emitInteractOutside(veto: VetoableNativeEvent<PointerEvent | FocusEvent>): void;
|
|
193
|
+
/** Implicit close requested by the shell after an un-vetoed outside interaction. */
|
|
194
|
+
requestClose(reason: 'pointerDownOutside' | 'focusOutside'): void;
|
|
195
|
+
/** Modal-path Escape forwarder: emit only; the modal shell builds the veto and owns the close. */
|
|
196
|
+
forwardEscapeKeyDown(veto: VetoableNativeEvent<KeyboardEvent>): void;
|
|
197
|
+
/**
|
|
198
|
+
* Hooks into the auto-focus pipeline. Content fires these just before
|
|
199
|
+
* its imperative `.focus()` (open) or the trigger return-focus (close);
|
|
200
|
+
* `event.preventDefault()` skips the move. Returns `true` when the
|
|
201
|
+
* consumer vetoed.
|
|
202
|
+
*/
|
|
203
|
+
emitAutoFocusOnOpen(): boolean;
|
|
204
|
+
emitAutoFocusOnClose(): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Full source length when virtualizing, `undefined` in the default
|
|
207
|
+
* DOM-focus path. Drives each option's `aria-setsize` / `aria-posinset`
|
|
208
|
+
* and the focus-model branch.
|
|
209
|
+
*/
|
|
210
|
+
readonly totalCount: Signal<number | undefined>;
|
|
211
|
+
/**
|
|
212
|
+
* The active option's `id` in the virtualized activedescendant model,
|
|
213
|
+
* `null` in the default path. The content surface reflects it as
|
|
214
|
+
* `aria-activedescendant`; options read it for `data-highlighted`.
|
|
215
|
+
*/
|
|
216
|
+
readonly activeDescendantId: Signal<string | null>;
|
|
217
|
+
/**
|
|
218
|
+
* Virtualized-path open hook. Called by `[forSelectContent]` after it
|
|
219
|
+
* focuses its own surface on open: seeds `aria-activedescendant` to the
|
|
220
|
+
* committed option (scrolling it into view via `(scrollToIndex)`), or the
|
|
221
|
+
* first enabled option when nothing is selected.
|
|
222
|
+
*/
|
|
223
|
+
seedVirtualizedInitialFocus(): void;
|
|
224
|
+
/**
|
|
225
|
+
* Virtualized-path keyboard handler. Called by `[forSelectContent]`'s host
|
|
226
|
+
* keydown only when `totalCount()` is set: Arrow/Home/End navigation,
|
|
227
|
+
* Enter/Space activation of the active descendant, single-mode Tab commit,
|
|
228
|
+
* and typeahead — all in the activedescendant model.
|
|
229
|
+
*/
|
|
230
|
+
handleVirtualizedKeydown(event: KeyboardEvent): void;
|
|
231
|
+
/**
|
|
232
|
+
* Called by an option on click in the virtualized path: moves
|
|
233
|
+
* `aria-activedescendant` to that option and returns DOM focus to the
|
|
234
|
+
* content surface. No-op in the default path.
|
|
235
|
+
*/
|
|
236
|
+
notifyOptionClick(optionId: string): void;
|
|
237
|
+
/** Flip the `touched` model. Called by trigger on blur-to-outside and on dismiss events. */
|
|
238
|
+
markTouched(): void;
|
|
239
|
+
}
|
|
240
|
+
declare const FOR_SELECT_CONTEXT: InjectionToken<ForSelectContext<unknown>>;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Headless implementation of the [WAI-ARIA select-only combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/).
|
|
244
|
+
* Implements `FormValueControl<readonly T[]>` from
|
|
245
|
+
* `@angular/forms/signals` for `[formField]` auto-wiring.
|
|
246
|
+
*
|
|
247
|
+
* Generic over the option value type `T` (default `string`). When the
|
|
248
|
+
* consumer binds object items the directive infers `T` from `[(value)]` and
|
|
249
|
+
* `[forSelectOption][value]`; object identity is resolved by the
|
|
250
|
+
* consumer-supplied `[isItemEqualToValue]` and the hidden inputs serialize
|
|
251
|
+
* via `[itemToFormValue]`. Option display text is read from the rendered
|
|
252
|
+
* `textContent`, so no separate label function is needed — supply the
|
|
253
|
+
* optional `[itemToLabel]` only when a pre-set object value must render its
|
|
254
|
+
* label before the listbox is ever opened (the documented `@if (open())`
|
|
255
|
+
* pattern).
|
|
256
|
+
*
|
|
257
|
+
* Selection is always modeled as `readonly T[]`:
|
|
258
|
+
* - In single mode (`multiple=false`, default), the array has 0 or 1 element
|
|
259
|
+
* and option activation closes the listbox.
|
|
260
|
+
* - In multi mode, option activation toggles and the listbox stays open.
|
|
261
|
+
*
|
|
262
|
+
* Typeahead has two modes mirroring native `<select>`:
|
|
263
|
+
* - **Closed trigger** (single mode only): printable keys select the matching
|
|
264
|
+
* option immediately without opening the listbox.
|
|
265
|
+
* - **Open listbox**: printable keys move focus to the first matching option
|
|
266
|
+
* (selection still requires Enter / Space / click).
|
|
267
|
+
*/
|
|
268
|
+
declare class ForSelect<T = string> extends FormUiControlBase implements FormValueControl<readonly T[]>, ForSelectContext<T> {
|
|
269
|
+
#private;
|
|
270
|
+
/**
|
|
271
|
+
* Two-way bindable. Selected option values. Single-mode keeps 0 or 1
|
|
272
|
+
* element. The `model()` change emitter (`(valueChange)`) fires only on
|
|
273
|
+
* internal selection changes, never on consumer writes via `[(value)]`.
|
|
274
|
+
*/
|
|
275
|
+
readonly value: _angular_core.ModelSignal<readonly T[]>;
|
|
276
|
+
/**
|
|
277
|
+
* Compare two items for equality. Defaults to `===`, which is the
|
|
278
|
+
* correct identity for primitive `T` (e.g. strings, numbers). Override
|
|
279
|
+
* when binding object items so the directive can locate selected entries
|
|
280
|
+
* by id (or any other stable key) instead of by reference:
|
|
281
|
+
* `[isItemEqualToValue]="(a, b) => a.id === b.id"`.
|
|
282
|
+
*/
|
|
283
|
+
readonly isItemEqualToValue: _angular_core.InputSignal<(a: T, b: T) => boolean>;
|
|
284
|
+
/**
|
|
285
|
+
* Serialize an item for the hidden input that participates in native
|
|
286
|
+
* form submission. Defaults to identity for strings and to
|
|
287
|
+
* `JSON.stringify` for non-string items so the primitive works out of
|
|
288
|
+
* the box round-tripping objects. Override to emit a specific wire
|
|
289
|
+
* format — typically a per-item id — when the backend expects that:
|
|
290
|
+
* `[itemToFormValue]="(it) => it.id"`.
|
|
291
|
+
*/
|
|
292
|
+
readonly itemToFormValue: _angular_core.InputSignal<(item: T) => string>;
|
|
293
|
+
/**
|
|
294
|
+
* Resolve the display label for an item without the listbox mounted.
|
|
295
|
+
* When set, {@link selectedLabels} (and therefore `[forSelectValue]`)
|
|
296
|
+
* renders this for any selected value, so a pre-set object value shows
|
|
297
|
+
* its label on first paint — before the listbox has ever been opened, in
|
|
298
|
+
* the documented `@if (forSelect.open())` pattern. Without it, object-value
|
|
299
|
+
* labels resolve from the rendered option `textContent`, which is only
|
|
300
|
+
* available once the content mounts; the serialized form value is shown as
|
|
301
|
+
* a last-resort fallback in the meantime: `[itemToLabel]="(c) => c.name"`.
|
|
302
|
+
*
|
|
303
|
+
* Defaults to `undefined` (string mode renders the value verbatim, so no
|
|
304
|
+
* label function is needed).
|
|
305
|
+
*/
|
|
306
|
+
readonly itemToLabel: _angular_core.InputSignal<((item: T) => string) | undefined>;
|
|
307
|
+
/**
|
|
308
|
+
* Read-only single-select convenience view of {@link value}. Returns the
|
|
309
|
+
* sole value when exactly one is selected (regardless of `multiple`),
|
|
310
|
+
* otherwise `null` (zero, or 2+ selected). Lets single-select consumers
|
|
311
|
+
* read `selected()` instead of unwrapping `value()[0]`. The array-backed
|
|
312
|
+
* `value` model remains the source of truth and the `FormValueControl`
|
|
313
|
+
* contract; this is a derived accessor.
|
|
314
|
+
*/
|
|
315
|
+
readonly selected: _angular_core.Signal<T | null>;
|
|
316
|
+
/**
|
|
317
|
+
* Two-way bindable. Whether the listbox is currently shown. The `model()`
|
|
318
|
+
* change emitter (`(openChange)`) fires only on internal transitions
|
|
319
|
+
* (trigger toggle, Escape, outside dismissal, single-mode option select),
|
|
320
|
+
* never on consumer writes via `[(open)]`.
|
|
321
|
+
*/
|
|
322
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
323
|
+
readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
324
|
+
/**
|
|
325
|
+
* Presentation mode. When `true`, `[forSelectContent]` mounts as a trapped /
|
|
326
|
+
* inert / scroll-locked modal surface (routed through `_internal/modal-shell`)
|
|
327
|
+
* instead of the default anchored popover — the batteries-included touch
|
|
328
|
+
* presentation a consumer opts into with `[modal]="isCoarsePointer()"`. The
|
|
329
|
+
* form-value wiring (`[(value)]`, `name`) is unchanged.
|
|
330
|
+
*
|
|
331
|
+
* Read once when the content mounts (the two shells are structurally
|
|
332
|
+
* different; switching at runtime would need a remount, and the surface
|
|
333
|
+
* mounts lazily via `@if (open())` well after `modal` settles). Every
|
|
334
|
+
* anchored-positioning input — `position`, `side`, `align`, `sideOffset`,
|
|
335
|
+
* `alignOffset`, `sticky`, `hideWhenDetached`, `clipUntilPositioned`, `avoidCollisions`,
|
|
336
|
+
* `collisionPadding`, `arrowPadding` — is a no-op in this mode. Default
|
|
337
|
+
* `false` (non-breaking). The swipe / snap-point sheet is deliberately not
|
|
338
|
+
* this mode — compose a `ForListbox` inside a `ForDrawer` for that.
|
|
339
|
+
*/
|
|
340
|
+
readonly modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
341
|
+
/**
|
|
342
|
+
* Positioning algorithm.
|
|
343
|
+
*
|
|
344
|
+
* - `'popper'` (default): standard floating-ui anchored placement using
|
|
345
|
+
* `side` / `align` / `sideOffset` / `alignOffset`, with `flip` + `shift`
|
|
346
|
+
* collision handling. Same path as Popover / DropdownMenu.
|
|
347
|
+
* - `'item-aligned'`: the listbox overlays the trigger so the selected
|
|
348
|
+
* option's vertical center aligns with the trigger's vertical center
|
|
349
|
+
* — visually the menu "snaps over" the trigger when opened, mirroring
|
|
350
|
+
* macOS native `<select>`. Falls back to the first enabled option when
|
|
351
|
+
* nothing is selected. `side`, `align`, `sideOffset`, `alignOffset`,
|
|
352
|
+
* `sticky`, `hideWhenDetached`, `clipUntilPositioned`, and `avoidCollisions` are ignored in
|
|
353
|
+
* this mode; only `collisionPadding` is honored.
|
|
354
|
+
*/
|
|
355
|
+
readonly position: _angular_core.InputSignal<"popper" | "item-aligned">;
|
|
356
|
+
/**
|
|
357
|
+
* Side the listbox is anchored to. Defaults to `'bottom'`. Pair with
|
|
358
|
+
* `align` for the full positioning API. Ignored when
|
|
359
|
+
* `position="item-aligned"`.
|
|
360
|
+
*/
|
|
361
|
+
readonly side: _angular_core.InputSignal<FloatingSide | undefined>;
|
|
362
|
+
/** Alignment along the chosen `side`. Defaults to `'start'`. */
|
|
363
|
+
readonly align: _angular_core.InputSignal<FloatingAlign | undefined>;
|
|
364
|
+
/**
|
|
365
|
+
* Gap (px) between trigger and listbox along the main axis. Default `4`.
|
|
366
|
+
* The default is read from
|
|
367
|
+
* `provideForSelectDefaults` for the surrounding scope.
|
|
368
|
+
*/
|
|
369
|
+
readonly sideOffset: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
370
|
+
/** Gap (px) along the cross axis. Default `0`. */
|
|
371
|
+
readonly alignOffset: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
372
|
+
/** When `true` (default), `flip` and `shift` keep the listbox inside the viewport. */
|
|
373
|
+
readonly avoidCollisions: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
374
|
+
/**
|
|
375
|
+
* Padding (px) applied uniformly to flip / shift / size. Default `8`.
|
|
376
|
+
* The default is read from `provideForSelectDefaults` for the surrounding
|
|
377
|
+
* scope.
|
|
378
|
+
*/
|
|
379
|
+
readonly collisionPadding: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
380
|
+
/** Padding (px) for the `arrow` middleware. Default `0`. */
|
|
381
|
+
readonly arrowPadding: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
382
|
+
/** Stickiness behaviour for `shift`. Default `'partial'`. */
|
|
383
|
+
readonly sticky: _angular_core.InputSignal<false | "partial" | "always">;
|
|
384
|
+
/** When `true`, sets `data-detached=""` while the trigger is scrolled off-screen. */
|
|
385
|
+
readonly hideWhenDetached: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
386
|
+
/**
|
|
387
|
+
* When `true` (default), the content is clipped until floating-ui resolves
|
|
388
|
+
* its first position, preventing a flash at the viewport corner. Set to
|
|
389
|
+
* `false` so a dramatic `animate.enter` plays from its first frame (the
|
|
390
|
+
* surface may flash briefly at the unresolved position while positioning
|
|
391
|
+
* computes).
|
|
392
|
+
*/
|
|
393
|
+
readonly clipUntilPositioned: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
394
|
+
readonly loop: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
395
|
+
readonly orientation: _angular_core.InputSignal<"horizontal" | "vertical">;
|
|
396
|
+
/**
|
|
397
|
+
* Total number of items in the source data. When set, switches the listbox
|
|
398
|
+
* to the virtualized `aria-activedescendant` focus model and populates
|
|
399
|
+
* `aria-setsize` on each rendered option. Leave unset (default) for the
|
|
400
|
+
* standard DOM-focus model.
|
|
401
|
+
*/
|
|
402
|
+
readonly totalCount: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
|
|
403
|
+
/**
|
|
404
|
+
* Inclusive-exclusive `[start, end)` index range of the currently rendered
|
|
405
|
+
* options, provided by `injectVirtualizer`. Used to decide whether a
|
|
406
|
+
* navigation target is in the visible window.
|
|
407
|
+
*/
|
|
408
|
+
readonly visibleRange: _angular_core.InputSignal<readonly [number, number] | undefined>;
|
|
409
|
+
/**
|
|
410
|
+
* Emitted when navigation (or open-time scroll-to-selected) reaches an
|
|
411
|
+
* option outside the rendered window. Pass to `injectVirtualizer`'s
|
|
412
|
+
* `scrollToIndex` so the correct option mounts.
|
|
413
|
+
*/
|
|
414
|
+
readonly scrollToIndex: _angular_core.OutputEmitterRef<number>;
|
|
415
|
+
/**
|
|
416
|
+
* Writing direction. When unset (default `null`), the inherited ambient
|
|
417
|
+
* direction is resolved from the nearest ancestor carrying a `dir` attribute
|
|
418
|
+
* (or `<html dir>`), defaulting to `'ltr'`. An explicit `[dir]` always wins.
|
|
419
|
+
* The resolved value is reflected to the host `dir` attribute.
|
|
420
|
+
*/
|
|
421
|
+
readonly _dirInput: _angular_core.InputSignal<WritingDirection | null>;
|
|
422
|
+
readonly dir: _angular_core.Signal<WritingDirection>;
|
|
423
|
+
/**
|
|
424
|
+
* Single-mode only. When true, arrow nav also selects the focused option
|
|
425
|
+
* while the listbox is open. APG calls this optional and recommends
|
|
426
|
+
* caution — leave off unless your UX truly benefits. Default `false`.
|
|
427
|
+
*/
|
|
428
|
+
readonly selectionFollowsFocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
429
|
+
/** Placeholder shown by `[forSelectValue]` when no option is selected. */
|
|
430
|
+
readonly placeholder: _angular_core.InputSignal<string>;
|
|
431
|
+
/** When true (default), Escape, pointer-down outside, and focus outside close the listbox. */
|
|
432
|
+
readonly dismissible: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
433
|
+
/** When true (default), focus returns to the trigger on close. */
|
|
434
|
+
readonly returnFocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
435
|
+
/** Manual `aria-label` on `[forSelectContent]` when the trigger isn't a meaningful name. */
|
|
436
|
+
readonly ariaLabel: _angular_core.InputSignal<string | null>;
|
|
437
|
+
readonly escapeKeyDown: _angular_core.OutputEmitterRef<VetoableNativeEvent<KeyboardEvent>>;
|
|
438
|
+
readonly pointerDownOutside: _angular_core.OutputEmitterRef<VetoableNativeEvent<PointerEvent>>;
|
|
439
|
+
readonly focusOutside: _angular_core.OutputEmitterRef<VetoableNativeEvent<FocusEvent>>;
|
|
440
|
+
readonly interactOutside: _angular_core.OutputEmitterRef<VetoableNativeEvent<PointerEvent | FocusEvent>>;
|
|
441
|
+
/**
|
|
442
|
+
* Fires just before the listbox sends focus to the selected option
|
|
443
|
+
* (or first / last enabled) on mount. Call `preventDefault()` on the
|
|
444
|
+
* emitted veto to skip the imperative focus move.
|
|
445
|
+
*/
|
|
446
|
+
readonly autoFocusOnOpen: _angular_core.OutputEmitterRef<VetoableEvent>;
|
|
447
|
+
/**
|
|
448
|
+
* Fires just before focus returns to the trigger on unmount. Call
|
|
449
|
+
* `preventDefault()` on the veto to suppress the return-focus.
|
|
450
|
+
*/
|
|
451
|
+
readonly autoFocusOnClose: _angular_core.OutputEmitterRef<VetoableEvent>;
|
|
452
|
+
readonly triggerId: _angular_core.WritableSignal<string>;
|
|
453
|
+
readonly contentId: _angular_core.WritableSignal<string>;
|
|
454
|
+
readonly initialFocus: _angular_core.Signal<ForSelectInitialFocus>;
|
|
455
|
+
readonly lastCloseReason: _angular_core.Signal<ForSelectCloseReason | null>;
|
|
456
|
+
readonly trigger: _angular_core.Signal<HTMLElement | null>;
|
|
457
|
+
/**
|
|
458
|
+
* Element floating-ui anchors the listbox against. Prefers an optional
|
|
459
|
+
* `[forSelectAnchor]` when registered, otherwise falls back to the trigger
|
|
460
|
+
* so existing selects without an anchor keep their behavior. Decoupled from
|
|
461
|
+
* `trigger` so the trigger keeps driving `aria-controls`, the click toggle,
|
|
462
|
+
* focus return, and its dismissal exemption regardless of where the listbox
|
|
463
|
+
* paints.
|
|
464
|
+
*/
|
|
465
|
+
readonly anchor: _angular_core.Signal<_floating_ui_dom.ReferenceElement | null>;
|
|
466
|
+
readonly content: _angular_core.Signal<HTMLElement | null>;
|
|
467
|
+
readonly options: _angular_core.Signal<readonly ForSelectOptionHandle<T>[]>;
|
|
468
|
+
/** The active option's `id` in the virtualized path, `null` in the default path. */
|
|
469
|
+
readonly activeDescendantId: _angular_core.Signal<string | null>;
|
|
470
|
+
/**
|
|
471
|
+
* Trimmed display labels of the selected values, in selection order. Pure
|
|
472
|
+
* derivation: when `[itemToLabel]` is supplied it is authoritative; otherwise
|
|
473
|
+
* resolve from the persisted option snapshot, then the serialized form value
|
|
474
|
+
* so non-string items still render meaningfully on a cold cache.
|
|
475
|
+
*
|
|
476
|
+
* The snapshot's labels come from each option's reactive `label` signal,
|
|
477
|
+
* which reads the rendered `textContent`. `textContent` is not a signal, so a
|
|
478
|
+
* label whose rendered text changes without a value change does not self-heal
|
|
479
|
+
* here — supply `[itemToLabel]` for a pure signal derivation that observes
|
|
480
|
+
* label changes directly.
|
|
481
|
+
*/
|
|
482
|
+
readonly selectedLabels: _angular_core.Signal<readonly string[]>;
|
|
483
|
+
readonly selectedOptionEl: _angular_core.Signal<HTMLElement | null>;
|
|
484
|
+
protected fieldLabelledElement(): HTMLElement | null;
|
|
485
|
+
protected fieldLabelledElementId(): string;
|
|
486
|
+
constructor();
|
|
487
|
+
setInitialFocus(target: ForSelectInitialFocus): void;
|
|
488
|
+
registerTrigger(el: HTMLElement): void;
|
|
489
|
+
unregisterTrigger(el: HTMLElement): void;
|
|
490
|
+
registerAnchor(el: HTMLElement): void;
|
|
491
|
+
unregisterAnchor(el: HTMLElement): void;
|
|
492
|
+
registerContent(el: HTMLElement): void;
|
|
493
|
+
unregisterContent(el: HTMLElement): void;
|
|
494
|
+
registerOption(handle: ForSelectOptionHandle<T>): void;
|
|
495
|
+
unregisterOption(handle: ForSelectOptionHandle<T>): void;
|
|
496
|
+
isSelected(v: T): boolean;
|
|
497
|
+
activate(v: T): void;
|
|
498
|
+
navigate(currentOption: HTMLElement, action: ListNavigationAction): void;
|
|
499
|
+
handleTypeahead(event: KeyboardEvent): void;
|
|
500
|
+
handleClosedTypeahead(event: KeyboardEvent): boolean;
|
|
501
|
+
focusFirstEnabledOption(): boolean;
|
|
502
|
+
focusLastEnabledOption(): boolean;
|
|
503
|
+
focusSelectedOption(): boolean;
|
|
504
|
+
toggle(initialFocus?: ForSelectInitialFocus): void;
|
|
505
|
+
openMenu(initialFocus?: ForSelectInitialFocus): void;
|
|
506
|
+
closeMenu(reason: ForSelectCloseReason): void;
|
|
507
|
+
commitOnTab(value: T): void;
|
|
508
|
+
emitEscapeKeyDown(event: KeyboardEvent): void;
|
|
509
|
+
/**
|
|
510
|
+
* Outside-interaction emit forwarders. The shared `#pendingOutsideVeto`
|
|
511
|
+
* reuse between the specific outside channels and the composite
|
|
512
|
+
* `interactOutside` lives in `injectOverlayShell`; these only fire the
|
|
513
|
+
* matching output with the veto the shell built.
|
|
514
|
+
*/
|
|
515
|
+
emitPointerDownOutside(veto: VetoableNativeEvent<PointerEvent>): void;
|
|
516
|
+
emitFocusOutside(veto: VetoableNativeEvent<FocusEvent>): void;
|
|
517
|
+
emitInteractOutside(veto: VetoableNativeEvent<PointerEvent | FocusEvent>): void;
|
|
518
|
+
/** Modal-path Escape forwarder: emit only; the modal shell owns the close. */
|
|
519
|
+
forwardEscapeKeyDown(veto: VetoableNativeEvent<KeyboardEvent>): void;
|
|
520
|
+
/**
|
|
521
|
+
* Implicit close requested by the shell after an un-vetoed outside
|
|
522
|
+
* interaction. Marks the control touched (mirroring the trigger blur) and
|
|
523
|
+
* closes with the channel's reason.
|
|
524
|
+
*/
|
|
525
|
+
requestClose(reason: 'pointerDownOutside' | 'focusOutside'): void;
|
|
526
|
+
emitAutoFocusOnOpen(): boolean;
|
|
527
|
+
emitAutoFocusOnClose(): boolean;
|
|
528
|
+
markTouched(): void;
|
|
529
|
+
seedVirtualizedInitialFocus(): void;
|
|
530
|
+
handleVirtualizedKeydown(event: KeyboardEvent): void;
|
|
531
|
+
notifyOptionClick(optionId: string): void;
|
|
532
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelect<any>, never>;
|
|
533
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelect<any>, "[forSelect]", ["forSelect"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "isItemEqualToValue": { "alias": "isItemEqualToValue"; "required": false; "isSignal": true; }; "itemToFormValue": { "alias": "itemToFormValue"; "required": false; "isSignal": true; }; "itemToLabel": { "alias": "itemToLabel"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "modal": { "alias": "modal"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "side": { "alias": "side"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "sideOffset": { "alias": "sideOffset"; "required": false; "isSignal": true; }; "alignOffset": { "alias": "alignOffset"; "required": false; "isSignal": true; }; "avoidCollisions": { "alias": "avoidCollisions"; "required": false; "isSignal": true; }; "collisionPadding": { "alias": "collisionPadding"; "required": false; "isSignal": true; }; "arrowPadding": { "alias": "arrowPadding"; "required": false; "isSignal": true; }; "sticky": { "alias": "sticky"; "required": false; "isSignal": true; }; "hideWhenDetached": { "alias": "hideWhenDetached"; "required": false; "isSignal": true; }; "clipUntilPositioned": { "alias": "clipUntilPositioned"; "required": false; "isSignal": true; }; "loop": { "alias": "loop"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "totalCount": { "alias": "totalCount"; "required": false; "isSignal": true; }; "visibleRange": { "alias": "visibleRange"; "required": false; "isSignal": true; }; "_dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "selectionFollowsFocus": { "alias": "selectionFollowsFocus"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; "returnFocus": { "alias": "returnFocus"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "open": "openChange"; "scrollToIndex": "scrollToIndex"; "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "autoFocusOnOpen": "autoFocusOnOpen"; "autoFocusOnClose": "autoFocusOnClose"; }, never, never, true, never>;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Optional positioning anchor. When present, `[forSelectContent]` is
|
|
538
|
+
* positioned against this element instead of `[forSelectTrigger]` — useful
|
|
539
|
+
* when the trigger lives inside a decorated field box (padding, prefix icon,
|
|
540
|
+
* clear / chevron buttons) and the listbox should match the visible field
|
|
541
|
+
* rather than the inner button.
|
|
542
|
+
*
|
|
543
|
+
* Only positioning changes: the trigger still owns `aria-controls`,
|
|
544
|
+
* `aria-expanded`, the click toggle, focus return on close, and its exemption
|
|
545
|
+
* from outside-pointer dismissal. If no anchor is registered the listbox falls
|
|
546
|
+
* back to anchoring against the trigger, so existing usages are unaffected.
|
|
547
|
+
*
|
|
548
|
+
* At most one `[forSelectAnchor]` may be registered per `[forSelect]`; a second
|
|
549
|
+
* one throws.
|
|
550
|
+
*
|
|
551
|
+
* ```html
|
|
552
|
+
* <div forSelect [(value)]="v">
|
|
553
|
+
* <div forSelectAnchor class="field-box">
|
|
554
|
+
* <icon />
|
|
555
|
+
* <button forSelectTrigger>…</button>
|
|
556
|
+
* <button class="clear">×</button>
|
|
557
|
+
* </div>
|
|
558
|
+
* @if (open()) {
|
|
559
|
+
* <div forSelectContent>…</div>
|
|
560
|
+
* }
|
|
561
|
+
* </div>
|
|
562
|
+
* ```
|
|
563
|
+
*/
|
|
564
|
+
declare class ForSelectAnchor {
|
|
565
|
+
#private;
|
|
566
|
+
constructor();
|
|
567
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectAnchor, never>;
|
|
568
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectAnchor, "[forSelectAnchor]", ["forSelectAnchor"], {}, {}, never, never, true, never>;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Combobox button that opens the listbox. Apply on a `<button>` so
|
|
573
|
+
* Space / Enter dispatch native click events that toggle via `(click)`.
|
|
574
|
+
*
|
|
575
|
+
* Wires APG select-only combobox attributes: `role="combobox"`,
|
|
576
|
+
* `aria-haspopup="listbox"`, `aria-expanded`, and `aria-controls` pointing
|
|
577
|
+
* to the listbox. The button is exempt from the listbox's dismissable
|
|
578
|
+
* layer — clicks on it route through `(click)` instead of triggering an
|
|
579
|
+
* outside-pointer dismissal race.
|
|
580
|
+
*
|
|
581
|
+
* The root is normally resolved via DI from the enclosing `[forSelect]`.
|
|
582
|
+
* When the trigger is declared inside an `ng-template` stamped into the root
|
|
583
|
+
* (e.g. via `ngTemplateOutlet`), DI resolves at the template's declaration
|
|
584
|
+
* site and misses the root — pass it explicitly through the selector input,
|
|
585
|
+
* `routerLink`-style: `[forSelectTrigger]="root"` with `#root="forSelect"`.
|
|
586
|
+
*
|
|
587
|
+
* Keyboard:
|
|
588
|
+
* - **Click / Enter / Space** — toggle (open focuses the selected option, or first).
|
|
589
|
+
* - **ArrowDown** — open + focus selected option (or first).
|
|
590
|
+
* - **ArrowUp** — open + focus selected option (or last when none selected).
|
|
591
|
+
* - **Typeahead** (single mode only) — printable keys select the matching
|
|
592
|
+
* option immediately without opening the listbox, mirroring native
|
|
593
|
+
* `<select>`. In multi mode the buffered key is ignored at the trigger;
|
|
594
|
+
* open the listbox first to typeahead-focus.
|
|
595
|
+
*/
|
|
596
|
+
declare class ForSelectTrigger<T = unknown> {
|
|
597
|
+
#private;
|
|
598
|
+
/**
|
|
599
|
+
* Optional explicit reference to the `[forSelect]` root, named after the
|
|
600
|
+
* selector `routerLink`-style. The bare valueless attribute keeps resolving
|
|
601
|
+
* the enclosing root via DI; pass the root explicitly
|
|
602
|
+
* (`[forSelectTrigger]="root"`, with `#root="forSelect"`) when the trigger
|
|
603
|
+
* is declared in an `ng-template` stamped inside the root — DI resolves at
|
|
604
|
+
* the template's declaration site, so the enclosing root is invisible there.
|
|
605
|
+
* The empty string (what the valueless attribute yields) is treated as unset.
|
|
606
|
+
*/
|
|
607
|
+
readonly forSelectTrigger: _angular_core.InputSignal<"" | ForSelectContext<T>>;
|
|
608
|
+
protected readonly ctx: _angular_core.Signal<ForSelectContext<T>>;
|
|
609
|
+
constructor();
|
|
610
|
+
protected onClick(): void;
|
|
611
|
+
protected onKeyDown(event: KeyboardEvent): void;
|
|
612
|
+
protected onFocusOut(event: FocusEvent): void;
|
|
613
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectTrigger<any>, never>;
|
|
614
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectTrigger<any>, "[forSelectTrigger]", ["forSelectTrigger"], { "forSelectTrigger": { "alias": "forSelectTrigger"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Renders the currently-selected option's text — or the configured
|
|
619
|
+
* placeholder when nothing is selected — into its host element via
|
|
620
|
+
* `textContent`. Apply on a `<span>` (or any inline element) inside
|
|
621
|
+
* `[forSelectTrigger]`:
|
|
622
|
+
*
|
|
623
|
+
* ```html
|
|
624
|
+
* <button forSelectTrigger>
|
|
625
|
+
* <span forSelectValue placeholder="Select fruit…"></span>
|
|
626
|
+
* </button>
|
|
627
|
+
* ```
|
|
628
|
+
*
|
|
629
|
+
* In multi mode the labels are joined by `separator` (default `', '`). For
|
|
630
|
+
* fully custom rendering, drop this directive and read
|
|
631
|
+
* `forSelect.selectedLabels()` / `forSelect.value()` from your template.
|
|
632
|
+
*/
|
|
633
|
+
declare class ForSelectValue {
|
|
634
|
+
#private;
|
|
635
|
+
/** Text shown when nothing is selected. Falls back to `[forSelect][placeholder]`. */
|
|
636
|
+
readonly placeholder: _angular_core.InputSignal<string>;
|
|
637
|
+
/** Joiner for multi-mode label rendering. Default `', '`. */
|
|
638
|
+
readonly separator: _angular_core.InputSignal<string>;
|
|
639
|
+
protected readonly isPlaceholder: _angular_core.Signal<boolean>;
|
|
640
|
+
protected readonly displayText: _angular_core.Signal<string>;
|
|
641
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectValue, never>;
|
|
642
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectValue, "[forSelectValue]", ["forSelectValue"], { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "separator": { "alias": "separator"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* The listbox surface. Carries `role="listbox"`, is portaled to
|
|
647
|
+
* `document.body`, and is positioned by `@floating-ui/dom` against the
|
|
648
|
+
* trigger.
|
|
649
|
+
*
|
|
650
|
+
* Mount/unmount of the visible content is the consumer's responsibility —
|
|
651
|
+
* wrap with `@if (open())` so `animate.enter` / `animate.leave` fire on the
|
|
652
|
+
* natural mount cycle. While mounted, a `DismissableLayer` activates
|
|
653
|
+
* (Escape, pointer-down outside, focus outside); the trigger element is
|
|
654
|
+
* exempt from outside-pointer checks so trigger clicks toggle without
|
|
655
|
+
* dismissal racing.
|
|
656
|
+
*
|
|
657
|
+
* Initial focus is sent to the selected option (`'selected'`), the first
|
|
658
|
+
* enabled option (`'first'`), or the last enabled option (`'last'`)
|
|
659
|
+
* according to the trigger's hint. On destroy, focus returns to the
|
|
660
|
+
* trigger when `returnFocus` is true.
|
|
661
|
+
*
|
|
662
|
+
* The lifecycle is owned by one of the two shared shells, picked once on
|
|
663
|
+
* construction from `[forSelect].modal`:
|
|
664
|
+
*
|
|
665
|
+
* - **non-modal (default)** — `injectOverlayShell` anchors the listbox to the
|
|
666
|
+
* trigger and branches on `[forSelect].position`:
|
|
667
|
+
* - `'popper'` (default) — standard `injectFloating` path with full
|
|
668
|
+
* anchored placement (`side`, `align`, `sideOffset`,
|
|
669
|
+
* `alignOffset`, `flip`, `shift`, `arrow`, `hideWhenDetached`).
|
|
670
|
+
* - `'item-aligned'` — `injectItemAlignedPositioner` overlays the listbox so
|
|
671
|
+
* the selected option's center aligns with the trigger's center. The
|
|
672
|
+
* anchored-placement inputs are documented as no-ops in this mode.
|
|
673
|
+
* - **modal** — `injectModalShell` traps focus, inerts the background, and
|
|
674
|
+
* locks body scroll (a centered surface the consumer positions with CSS, not
|
|
675
|
+
* trigger-anchored). The batteries-included touch presentation. Same Escape /
|
|
676
|
+
* outside-pointer dismiss, `dismissible` / `returnFocus` / `ariaLabel`, and
|
|
677
|
+
* `autoFocusOnOpen` / `autoFocusOnClose` veto hooks; every anchored-
|
|
678
|
+
* positioning input is a no-op. `aria-modal="true"` is reflected as a hint —
|
|
679
|
+
* the real modality comes from the `inert` siblings the shell applies (the
|
|
680
|
+
* surface keeps `role="listbox"`, for which several screen readers ignore
|
|
681
|
+
* `aria-modal`).
|
|
682
|
+
*
|
|
683
|
+
* Mount/unmount of the visible content is the consumer's responsibility —
|
|
684
|
+
* wrap with `@if (open())` so `animate.enter` / `animate.leave` fire on the
|
|
685
|
+
* natural mount cycle.
|
|
686
|
+
*/
|
|
687
|
+
declare class ForSelectContent {
|
|
688
|
+
#private;
|
|
689
|
+
protected readonly ctx: forty_cdk_select.ForSelectContext<unknown>;
|
|
690
|
+
constructor();
|
|
691
|
+
protected onKeyDown(event: KeyboardEvent): void;
|
|
692
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectContent, never>;
|
|
693
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectContent, "[forSelectContent]", ["forSelectContent"], {}, {}, never, never, true, never>;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Injection key the `[forSelectIndicator]` uses to resolve its parent option,
|
|
698
|
+
* decoupled from the concrete `ForSelectOption` class. `ForSelectOption`
|
|
699
|
+
* provides itself under this token, so a design system wrapping the option by
|
|
700
|
+
* subclassing re-points it at the subclass with a single provider
|
|
701
|
+
* (`{ provide: FOR_SELECT_OPTION, useExisting: MtxSelectOption }`) and the
|
|
702
|
+
* indicator keeps resolving — see `docs/wrapping-form-primitives.md`.
|
|
703
|
+
*/
|
|
704
|
+
declare const FOR_SELECT_OPTION: InjectionToken<ForSelectOption<string>>;
|
|
705
|
+
/**
|
|
706
|
+
* One option inside a `[forSelectContent]`. Apply on a `<button type="button">`
|
|
707
|
+
* so Space / Enter activation come from native button behavior — printable
|
|
708
|
+
* keys fall through to the listbox for typeahead matching.
|
|
709
|
+
*
|
|
710
|
+
* Generic over the option value type `T` (default `string`). Inferred from
|
|
711
|
+
* the `[value]` binding so consumers can pass either primitive ids or full
|
|
712
|
+
* objects (`[value]="city"` infers `T = City`); the parent `[forSelect]`
|
|
713
|
+
* must be parameterized over the same `T`. The parent's
|
|
714
|
+
* `[isItemEqualToValue]` decides how options are matched against the
|
|
715
|
+
* committed selection.
|
|
716
|
+
*
|
|
717
|
+
* Click activates: in single mode the value replaces `[(value)]` and the
|
|
718
|
+
* listbox closes; in multi mode the value toggles in/out and the listbox
|
|
719
|
+
* stays open.
|
|
720
|
+
*
|
|
721
|
+
* Keyboard while focused:
|
|
722
|
+
* - **Enter / Space** — activate (via native button click).
|
|
723
|
+
* - **ArrowDown / ArrowUp / Home / End** — move focus inside the listbox.
|
|
724
|
+
* - **Tab / Shift+Tab** — commit the focused option (single mode) and let
|
|
725
|
+
* the browser advance focus to the next / previous focusable, mirroring
|
|
726
|
+
* the WAI-ARIA select-only combobox pattern and native `<select>`.
|
|
727
|
+
* - **Escape** — close the listbox.
|
|
728
|
+
* - **Typeahead** — printable keys match by text content.
|
|
729
|
+
*/
|
|
730
|
+
declare class ForSelectOption<T = string> {
|
|
731
|
+
#private;
|
|
732
|
+
/**
|
|
733
|
+
* Stable identifier serialized into `[(value)]` and the hidden input.
|
|
734
|
+
* Defaults to `string` for back-compat; bind an object to specialize the
|
|
735
|
+
* parent `[forSelect]` over a richer `T`. The parent's
|
|
736
|
+
* `[isItemEqualToValue]` decides how options are matched against the
|
|
737
|
+
* committed selection.
|
|
738
|
+
*/
|
|
739
|
+
readonly value: _angular_core.InputSignal<T>;
|
|
740
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
741
|
+
/**
|
|
742
|
+
* Zero-based absolute position of this option in the full source data.
|
|
743
|
+
* Required in the virtualized path — drives `aria-posinset` and the parent's
|
|
744
|
+
* position snapshot. Leave unset (default `null`) outside it.
|
|
745
|
+
*/
|
|
746
|
+
readonly posInSet: _angular_core.InputSignal<number | null>;
|
|
747
|
+
readonly id: _angular_core.Signal<string>;
|
|
748
|
+
readonly selected: _angular_core.Signal<boolean>;
|
|
749
|
+
readonly effectiveDisabled: _angular_core.Signal<boolean>;
|
|
750
|
+
protected readonly ariaSetSize: _angular_core.Signal<string | null>;
|
|
751
|
+
protected readonly ariaPosInSet: _angular_core.Signal<string | null>;
|
|
752
|
+
/**
|
|
753
|
+
* True when this option is the active candidate — DOM-focused in the
|
|
754
|
+
* default path, or `aria-activedescendant` in the virtualized path.
|
|
755
|
+
* Reflected as `data-highlighted`.
|
|
756
|
+
*/
|
|
757
|
+
readonly highlighted: _angular_core.Signal<boolean>;
|
|
758
|
+
constructor();
|
|
759
|
+
protected onClick(): void;
|
|
760
|
+
protected onFocus(): void;
|
|
761
|
+
protected onBlur(): void;
|
|
762
|
+
protected onKeyDown(event: KeyboardEvent): void;
|
|
763
|
+
protected onPointerDown(event: PointerEvent): void;
|
|
764
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectOption<any>, never>;
|
|
765
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectOption<any>, "[forSelectOption]", ["forSelectOption"], { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "posInSet": { "alias": "posInSet"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Visibility helper inside a `[forSelectOption]`. The directive flips a
|
|
770
|
+
* `[hidden]` host binding so the consumer can keep the checkmark / icon
|
|
771
|
+
* inline without extra `@if` glue:
|
|
772
|
+
*
|
|
773
|
+
* ```html
|
|
774
|
+
* <button forSelectOption value="apple">
|
|
775
|
+
* <span forSelectIndicator>✓</span>
|
|
776
|
+
* Apple
|
|
777
|
+
* </button>
|
|
778
|
+
* ```
|
|
779
|
+
*
|
|
780
|
+
* Reflects the parent option's `data-state` (`"checked" | "unchecked"`) so
|
|
781
|
+
* the consumer can also style it from CSS. Visibility while unselected is
|
|
782
|
+
* enforced with an inline `display: none` (which beats any author `display`
|
|
783
|
+
* rule a consumer applies via a class) in addition to the `hidden` attribute
|
|
784
|
+
* that removes it from the a11y tree.
|
|
785
|
+
*/
|
|
786
|
+
declare class ForSelectIndicator {
|
|
787
|
+
protected readonly option: ForSelectOption<string>;
|
|
788
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectIndicator, never>;
|
|
789
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectIndicator, "[forSelectIndicator]", ["forSelectIndicator"], {}, {}, never, never, true, never>;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Optional grouping wrapper inside a `[forSelectContent]`. Renders
|
|
794
|
+
* `role="group"` and references the descendant `[forSelectGroupLabel]`
|
|
795
|
+
* (if any) via `aria-labelledby`. Options inside a group still register
|
|
796
|
+
* with the root listbox normally, so keyboard navigation traverses across
|
|
797
|
+
* groups in DOM order without special handling.
|
|
798
|
+
*/
|
|
799
|
+
declare class ForSelectGroup {
|
|
800
|
+
#private;
|
|
801
|
+
/** The id of the registered group label (or `null` if none). */
|
|
802
|
+
readonly labelId: _angular_core.Signal<string | null>;
|
|
803
|
+
/** Called by `ForSelectGroupLabel` on mount. */
|
|
804
|
+
registerLabel(id: string): void;
|
|
805
|
+
/** Called by `ForSelectGroupLabel` on destroy. Idempotent. */
|
|
806
|
+
unregisterLabel(id: string): void;
|
|
807
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectGroup, never>;
|
|
808
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectGroup, "[forSelectGroup]", ["forSelectGroup"], {}, {}, never, never, true, never>;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Visible label for a `[forSelectGroup]`. Generates a stable id and
|
|
813
|
+
* registers with its parent group so the group's `aria-labelledby` points
|
|
814
|
+
* at this element. Apply on whatever heading element fits the design
|
|
815
|
+
* (often `<div>` styled as a small caption).
|
|
816
|
+
*/
|
|
817
|
+
declare class ForSelectGroupLabel {
|
|
818
|
+
/** Stable host id used by the parent group's `aria-labelledby`. */
|
|
819
|
+
readonly id: Signal<string>;
|
|
820
|
+
constructor();
|
|
821
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectGroupLabel, never>;
|
|
822
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectGroupLabel, "[forSelectGroupLabel]", ["forSelectGroupLabel"], {}, {}, never, never, true, never>;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Decorative separator between options or groups inside a
|
|
827
|
+
* `[forSelectContent]`. Carries `role="separator"` and is intentionally not
|
|
828
|
+
* registered with the listbox's option collection, so keyboard navigation
|
|
829
|
+
* and typeahead skip it automatically.
|
|
830
|
+
*/
|
|
831
|
+
declare class ForSelectSeparator {
|
|
832
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ForSelectSeparator, never>;
|
|
833
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ForSelectSeparator, "[forSelectSeparator]", ["forSelectSeparator"], {}, {}, never, never, true, never>;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Defaults inherited by descendant selects in the surrounding injector
|
|
838
|
+
* scope. Configure with `provideForSelectDefaults` either at the
|
|
839
|
+
* application root or in any component's `providers` array; partial
|
|
840
|
+
* overrides merge with the parent scope.
|
|
841
|
+
*/
|
|
842
|
+
interface ForSelectDefaults {
|
|
843
|
+
/**
|
|
844
|
+
* Distance (px) between the select trigger and the floating content
|
|
845
|
+
* along the resolved `side` axis.
|
|
846
|
+
*/
|
|
847
|
+
sideOffset: number;
|
|
848
|
+
/**
|
|
849
|
+
* Padding (px) added to the viewport edges for collision-aware
|
|
850
|
+
* positioning. Higher values keep the floating content further from
|
|
851
|
+
* the edge when `flip` / `shift` runs.
|
|
852
|
+
*/
|
|
853
|
+
collisionPadding: number;
|
|
854
|
+
}
|
|
855
|
+
/** Token holding the resolved select defaults for the current scope. */
|
|
856
|
+
declare const FOR_SELECT_DEFAULTS: _angular_core.InjectionToken<ForSelectDefaults>;
|
|
857
|
+
/**
|
|
858
|
+
* Configures forty-cdk select defaults for this injector scope. Partial
|
|
859
|
+
* overrides inherit unspecified keys from the parent scope (or library
|
|
860
|
+
* defaults at the root).
|
|
861
|
+
*/
|
|
862
|
+
declare function provideForSelectDefaults(defaults?: Partial<ForSelectDefaults>): Provider[];
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Exact public names of every `ForSelect` input, its models included. Spread it into the
|
|
866
|
+
* `inputs` array of a `hostDirectives` entry so a wrapper component re-exposes the
|
|
867
|
+
* primitive's full surface — the Signal Forms members `[formField]` binds among them —
|
|
868
|
+
* without hand-maintaining the list. Always spread into an inline object literal as shown
|
|
869
|
+
* below: the literal is what keeps the entry statically analyzable for consumers compiling
|
|
870
|
+
* against the published package. An anti-drift spec fails when this list no longer matches
|
|
871
|
+
* the directive's actual API. See `docs/wrapping-form-primitives.md` for both supported
|
|
872
|
+
* wrapping patterns.
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* ```ts
|
|
876
|
+
* @Component({
|
|
877
|
+
* selector: 'div[mySelect]',
|
|
878
|
+
* template: '',
|
|
879
|
+
* hostDirectives: [
|
|
880
|
+
* {
|
|
881
|
+
* directive: ForSelect,
|
|
882
|
+
* inputs: [...FOR_SELECT_HOST_DIRECTIVE_INPUTS],
|
|
883
|
+
* outputs: [...FOR_SELECT_HOST_DIRECTIVE_OUTPUTS],
|
|
884
|
+
* },
|
|
885
|
+
* ],
|
|
886
|
+
* })
|
|
887
|
+
* export class MySelect {}
|
|
888
|
+
* ```
|
|
889
|
+
*/
|
|
890
|
+
declare const FOR_SELECT_HOST_DIRECTIVE_INPUTS: readonly ["value", "open", "align", "alignOffset", "ariaLabel", "arrowPadding", "avoidCollisions", "clipUntilPositioned", "collisionPadding", "dir", "dirty", "disabled", "dismissible", "errors", "hideWhenDetached", "invalid", "isItemEqualToValue", "itemToFormValue", "itemToLabel", "loop", "modal", "multiple", "name", "orientation", "pending", "placeholder", "position", "readonly", "required", "returnFocus", "selectionFollowsFocus", "side", "sideOffset", "sticky", "totalCount", "touched", "visibleRange"];
|
|
891
|
+
/**
|
|
892
|
+
* Exact public names of every `ForSelect` output, the Signal Forms `touch` output
|
|
893
|
+
* included. Spread it into the `outputs` array of the same `hostDirectives` entry as
|
|
894
|
+
* {@link FOR_SELECT_HOST_DIRECTIVE_INPUTS}.
|
|
895
|
+
*/
|
|
896
|
+
declare const FOR_SELECT_HOST_DIRECTIVE_OUTPUTS: readonly ["valueChange", "openChange", "escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "autoFocusOnOpen", "autoFocusOnClose", "scrollToIndex", "touchedChange", "touch"];
|
|
897
|
+
|
|
898
|
+
export { FOR_SELECT_CONTEXT, FOR_SELECT_DEFAULTS, FOR_SELECT_HOST_DIRECTIVE_INPUTS, FOR_SELECT_HOST_DIRECTIVE_OUTPUTS, FOR_SELECT_OPTION, ForSelect, ForSelectAnchor, ForSelectContent, ForSelectGroup, ForSelectGroupLabel, ForSelectIndicator, ForSelectOption, ForSelectSeparator, ForSelectTrigger, ForSelectValue, provideForSelectDefaults };
|
|
899
|
+
export type { ForSelectCloseReason, ForSelectContext, ForSelectDefaults, ForSelectInitialFocus, ForSelectOptionHandle };
|