forge-select 0.2.0 → 0.4.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/README.md +62 -40
- package/dist/index.cjs +754 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +175 -9
- package/dist/index.d.ts +175 -9
- package/dist/index.global.js +1 -900
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +754 -174
- package/dist/index.js.map +1 -1
- package/package.json +32 -7
- package/styles/forge-select.css +50 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
type Handler = (...args: unknown[]) => void;
|
|
2
|
-
|
|
3
1
|
interface Option {
|
|
4
2
|
value: string;
|
|
5
3
|
label: string;
|
|
@@ -10,6 +8,8 @@ interface Option {
|
|
|
10
8
|
description?: string;
|
|
11
9
|
/** Arbitrary payload for custom templates; ForgeSelect never reads it. */
|
|
12
10
|
meta?: Record<string, unknown>;
|
|
11
|
+
/** Extra CSS class(es) applied to this option's rendered <li>. */
|
|
12
|
+
className?: string;
|
|
13
13
|
/**
|
|
14
14
|
* Nested options, making this a tree node. Purely additive: lists where
|
|
15
15
|
* no option has `children` render and behave exactly as a flat list.
|
|
@@ -22,7 +22,13 @@ interface OptionGroup {
|
|
|
22
22
|
}
|
|
23
23
|
type DataItem = Option | OptionGroup;
|
|
24
24
|
interface AjaxConfig {
|
|
25
|
-
|
|
25
|
+
/** GET endpoint. Optional when `request` supplies a custom transport. */
|
|
26
|
+
url?: string | ((query: string, page: number) => string);
|
|
27
|
+
/**
|
|
28
|
+
* Custom transport for POST/authenticated/GraphQL requests. Takes precedence
|
|
29
|
+
* over `url`; the returned payload is passed through `transform`.
|
|
30
|
+
*/
|
|
31
|
+
request?: (query: string, page: number, signal: AbortSignal) => Promise<unknown>;
|
|
26
32
|
params?: (query: string, page: number) => Record<string, unknown>;
|
|
27
33
|
/** Debounce in milliseconds. Default 250. */
|
|
28
34
|
debounce?: number;
|
|
@@ -55,12 +61,62 @@ interface ForgeSelectOptions {
|
|
|
55
61
|
multiple?: boolean;
|
|
56
62
|
clearable?: boolean;
|
|
57
63
|
allowCreate?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Let the user reorder selected tags by dragging them (mouse/touch/pen via
|
|
66
|
+
* Pointer Events), or via Alt+Left/Alt+Right when a tag has focus. Only
|
|
67
|
+
* meaningful when `multiple` is true. Default false — existing multi-select
|
|
68
|
+
* behavior and tag markup are unchanged when this is left off.
|
|
69
|
+
*/
|
|
70
|
+
sortable?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Multi-select only: close the dropdown immediately after each pick
|
|
73
|
+
* instead of staying open for further selections. Default false —
|
|
74
|
+
* existing multi-select behavior (stays open) is unchanged.
|
|
75
|
+
*/
|
|
76
|
+
closeOnSelect?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Multi-select only: caps the number of selected values. Once reached,
|
|
79
|
+
* further picks (including via allowCreate) are ignored until one is
|
|
80
|
+
* removed. Only gates interactive selection — setValue() is not clamped.
|
|
81
|
+
* Default undefined (no limit).
|
|
82
|
+
*/
|
|
83
|
+
maxSelections?: number;
|
|
58
84
|
theme?: string;
|
|
59
85
|
disabled?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Marks the field as required for native form validation. When mounted on
|
|
88
|
+
* a real <select>, an empty selection blocks form submission and shows
|
|
89
|
+
* inline invalid styling, mirroring native <select required> behavior.
|
|
90
|
+
* On a plain-element mount this only sets aria-required (no native form
|
|
91
|
+
* to hook into). Default false.
|
|
92
|
+
*/
|
|
93
|
+
required?: boolean;
|
|
60
94
|
data?: DataItem[];
|
|
61
95
|
ajax?: AjaxConfig;
|
|
62
96
|
templateResult?: TemplateFn;
|
|
63
97
|
templateSelection?: TemplateFn;
|
|
98
|
+
/**
|
|
99
|
+
* Custom match predicate, replacing the built-in label/description
|
|
100
|
+
* substring match. Receives the trimmed (not lowercased) query.
|
|
101
|
+
*/
|
|
102
|
+
filterOption?: (option: Option, query: string) => boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Hides results (showing a hint row instead) until the trimmed search
|
|
105
|
+
* query reaches this length. Also delays ajax requests until the
|
|
106
|
+
* threshold is met. Default 0 (no gate).
|
|
107
|
+
*/
|
|
108
|
+
minSearchLength?: number;
|
|
109
|
+
/**
|
|
110
|
+
* Hides the search field when a local list contains fewer options than
|
|
111
|
+
* this threshold. AJAX-backed lists always keep search visible. Default 0.
|
|
112
|
+
*/
|
|
113
|
+
minResultsForSearch?: number;
|
|
114
|
+
/**
|
|
115
|
+
* Dynamically disables an option, in addition to its static `disabled`
|
|
116
|
+
* field. Re-evaluated on every render, so it can react to external state
|
|
117
|
+
* (e.g. a quota) without rebuilding `data` via setData().
|
|
118
|
+
*/
|
|
119
|
+
isOptionDisabled?: (option: Option) => boolean;
|
|
64
120
|
/**
|
|
65
121
|
* false = never virtualize. true or unset = virtualize automatically
|
|
66
122
|
* once the list exceeds ~100 rows.
|
|
@@ -70,9 +126,42 @@ interface ForgeSelectOptions {
|
|
|
70
126
|
itemHeight?: number;
|
|
71
127
|
language?: string | Record<string, string>;
|
|
72
128
|
plugins?: ForgeSelectPlugin[];
|
|
129
|
+
/**
|
|
130
|
+
* Opens the dropdown when the control receives keyboard focus (e.g. via
|
|
131
|
+
* Tab). Default false — focusing alone still requires Enter/Space/ArrowDown
|
|
132
|
+
* to open, matching existing behavior.
|
|
133
|
+
*/
|
|
134
|
+
openOnFocus?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Optional portal container for the dropdown, useful inside overflow-hidden
|
|
137
|
+
* modals and drawers. Accepts an element or selector. Default: the root.
|
|
138
|
+
*/
|
|
139
|
+
dropdownParent?: HTMLElement | string;
|
|
73
140
|
}
|
|
74
141
|
type ForgeSelectValue = string | string[] | null;
|
|
75
|
-
|
|
142
|
+
interface SetValueOptions {
|
|
143
|
+
/** Emit Forge Select's `change` event after updating. Default true. */
|
|
144
|
+
emitChange?: boolean;
|
|
145
|
+
}
|
|
146
|
+
interface MaximumSelectionEvent {
|
|
147
|
+
limit: number;
|
|
148
|
+
option: Option;
|
|
149
|
+
}
|
|
150
|
+
interface ForgeSelectEventMap {
|
|
151
|
+
change: ForgeSelectValue;
|
|
152
|
+
open: void;
|
|
153
|
+
close: void;
|
|
154
|
+
search: string;
|
|
155
|
+
clear: void;
|
|
156
|
+
error: Error;
|
|
157
|
+
select: Option;
|
|
158
|
+
unselect: Option;
|
|
159
|
+
create: Option;
|
|
160
|
+
reorder: string[];
|
|
161
|
+
maximum: MaximumSelectionEvent;
|
|
162
|
+
}
|
|
163
|
+
type ForgeSelectEvent = keyof ForgeSelectEventMap;
|
|
164
|
+
type ForgeSelectEventHandler<E extends ForgeSelectEvent> = ForgeSelectEventMap[E] extends void ? () => void : (payload: ForgeSelectEventMap[E]) => void;
|
|
76
165
|
|
|
77
166
|
declare class ForgeSelect {
|
|
78
167
|
/** The original element ForgeSelect was mounted on. */
|
|
@@ -82,6 +171,7 @@ declare class ForgeSelect {
|
|
|
82
171
|
private data;
|
|
83
172
|
private selected;
|
|
84
173
|
private selectedOptions;
|
|
174
|
+
private suppressNextTagClick;
|
|
85
175
|
private emitter;
|
|
86
176
|
private plugins;
|
|
87
177
|
private uid;
|
|
@@ -92,6 +182,8 @@ declare class ForgeSelect {
|
|
|
92
182
|
private dropdown;
|
|
93
183
|
private searchInput;
|
|
94
184
|
private list;
|
|
185
|
+
private liveRegion;
|
|
186
|
+
private portalHost;
|
|
95
187
|
private isOpen;
|
|
96
188
|
private isDisabled;
|
|
97
189
|
private destroyed;
|
|
@@ -107,21 +199,75 @@ declare class ForgeSelect {
|
|
|
107
199
|
private hasMore;
|
|
108
200
|
private ajaxTimer;
|
|
109
201
|
private ajaxRequestId;
|
|
202
|
+
private ajaxController;
|
|
110
203
|
private remoteLoaded;
|
|
204
|
+
private loadError;
|
|
205
|
+
private originalDisplay;
|
|
206
|
+
private originalDisabled;
|
|
207
|
+
private nativeSelect;
|
|
208
|
+
private nativeForm;
|
|
209
|
+
private syncingNative;
|
|
210
|
+
/** Combines the static `disabled` field with the dynamic `isOptionDisabled` callback. */
|
|
211
|
+
private isOptionDisabled;
|
|
212
|
+
private pointerDownOnControl;
|
|
111
213
|
private onDocumentMouseDown;
|
|
214
|
+
private onWindowResize;
|
|
215
|
+
private onAncestorScroll;
|
|
216
|
+
private onNativeInvalid;
|
|
217
|
+
private onNativeChange;
|
|
218
|
+
private applyNativeValues;
|
|
219
|
+
private onFormReset;
|
|
112
220
|
constructor(target: string | HTMLElement, options?: ForgeSelectOptions);
|
|
113
221
|
open(): void;
|
|
114
222
|
close(): void;
|
|
223
|
+
/**
|
|
224
|
+
* Flips the dropdown above the control when there isn't enough room below
|
|
225
|
+
* but there is above. Recomputed on open() and on window resize — the
|
|
226
|
+
* dropdown is positioned absolutely inside the relatively-positioned root,
|
|
227
|
+
* so it already tracks the control correctly on page scroll without
|
|
228
|
+
* needing a scroll listener.
|
|
229
|
+
*/
|
|
230
|
+
private positionDropdown;
|
|
115
231
|
destroy(): void;
|
|
116
232
|
getValue(): ForgeSelectValue;
|
|
117
|
-
setValue(value: ForgeSelectValue): void;
|
|
233
|
+
setValue(value: ForgeSelectValue, options?: SetValueOptions): void;
|
|
234
|
+
/**
|
|
235
|
+
* Replaces the option list after construction. An open dropdown re-renders
|
|
236
|
+
* immediately; a selection whose value isn't in the new data stays
|
|
237
|
+
* selected (rendered via the already-selected option's own label/avatar,
|
|
238
|
+
* the same fallback used for values selected from a stale ajax page).
|
|
239
|
+
*/
|
|
240
|
+
setData(data: DataItem[]): void;
|
|
241
|
+
/**
|
|
242
|
+
* Multi-select only: selects every currently non-disabled option, including
|
|
243
|
+
* nested tree descendants and options inside groups. If `maxSelections` is
|
|
244
|
+
* set, stops once the cap is reached rather than exceeding it. A no-op for
|
|
245
|
+
* single-select.
|
|
246
|
+
*/
|
|
247
|
+
selectAll(): void;
|
|
248
|
+
/** Clears every selection. Equivalent to `setValue(null)`. */
|
|
249
|
+
clearAll(): void;
|
|
118
250
|
enable(): void;
|
|
119
251
|
disable(): void;
|
|
120
|
-
on(event:
|
|
121
|
-
off(event:
|
|
252
|
+
on<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
253
|
+
off<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
254
|
+
/**
|
|
255
|
+
* The original target (a hidden native <select> or a plain mount div) can
|
|
256
|
+
* carry an accessible name via aria-label/aria-labelledby, or via a
|
|
257
|
+
* <label for> pointing at its id — but once `this.el` is display:none it
|
|
258
|
+
* drops out of the accessibility tree, so any such association silently
|
|
259
|
+
* stops reaching assistive tech unless we forward it onto the visible,
|
|
260
|
+
* interactive `this.control` ourselves.
|
|
261
|
+
*/
|
|
262
|
+
private applyAccessibleName;
|
|
263
|
+
private shouldShowSearch;
|
|
264
|
+
private updateSearchVisibility;
|
|
122
265
|
private buildDom;
|
|
123
266
|
private bindEvents;
|
|
124
267
|
private handleKeydown;
|
|
268
|
+
private canSelectOption;
|
|
269
|
+
private hasReachedMaximum;
|
|
270
|
+
private announceMaximum;
|
|
125
271
|
private selectValue;
|
|
126
272
|
private deselectValue;
|
|
127
273
|
/**
|
|
@@ -132,17 +278,35 @@ declare class ForgeSelect {
|
|
|
132
278
|
*/
|
|
133
279
|
private syncTreeAncestors;
|
|
134
280
|
private clearSelection;
|
|
281
|
+
private allSelectableValues;
|
|
135
282
|
private afterSelectionChange;
|
|
136
283
|
private syncNativeSelect;
|
|
137
284
|
private findOption;
|
|
285
|
+
private findOptionByLabel;
|
|
286
|
+
/** Selects an existing option matching `label` exactly, or creates and selects a new one. */
|
|
287
|
+
private createTag;
|
|
138
288
|
private createFromQuery;
|
|
139
289
|
private activateNavItem;
|
|
140
290
|
private renderValue;
|
|
141
|
-
|
|
291
|
+
/**
|
|
292
|
+
* Pointer-based (mouse/touch/pen) reorder for a single tag. Only the real
|
|
293
|
+
* dragged DOM node is moved during the gesture — a full renderValue()
|
|
294
|
+
* mid-drag would destroy it — so the reordered `this.selected` is only
|
|
295
|
+
* committed on release. The move/up listeners and pointer capture live on
|
|
296
|
+
* the stable `this.valueEl` container rather than the tag itself: `tag`
|
|
297
|
+
* gets repositioned via `insertBefore` during the drag, and browsers treat
|
|
298
|
+
* that reparenting as detaching the node, which silently drops pointer
|
|
299
|
+
* capture (and further move events) if it were captured on `tag`.
|
|
300
|
+
*/
|
|
301
|
+
private bindTagDrag;
|
|
302
|
+
/** Alt+Left/Alt+Right on a focused tag: the keyboard-operable equivalent of dragging. */
|
|
303
|
+
private handleTagKeydown;
|
|
304
|
+
private focusTagByValue;
|
|
142
305
|
private buildRows;
|
|
143
306
|
private hasExactMatch;
|
|
144
307
|
private usesVirtualScroll;
|
|
145
308
|
private renderList;
|
|
309
|
+
private announceStatus;
|
|
146
310
|
private renderRows;
|
|
147
311
|
private renderRow;
|
|
148
312
|
/**
|
|
@@ -153,6 +317,8 @@ declare class ForgeSelect {
|
|
|
153
317
|
*/
|
|
154
318
|
private optionContent;
|
|
155
319
|
private moveHighlight;
|
|
320
|
+
private focusNavIndex;
|
|
321
|
+
private navigateTree;
|
|
156
322
|
private updateActiveDescendant;
|
|
157
323
|
private scheduleRemoteLoad;
|
|
158
324
|
/**
|
|
@@ -164,4 +330,4 @@ declare class ForgeSelect {
|
|
|
164
330
|
private loadRemote;
|
|
165
331
|
}
|
|
166
332
|
|
|
167
|
-
export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type Option, type OptionGroup, type TemplateFn, ForgeSelect as default };
|
|
333
|
+
export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectEventHandler, type ForgeSelectEventMap, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type MaximumSelectionEvent, type Option, type OptionGroup, type SetValueOptions, type TemplateFn, ForgeSelect as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
type Handler = (...args: unknown[]) => void;
|
|
2
|
-
|
|
3
1
|
interface Option {
|
|
4
2
|
value: string;
|
|
5
3
|
label: string;
|
|
@@ -10,6 +8,8 @@ interface Option {
|
|
|
10
8
|
description?: string;
|
|
11
9
|
/** Arbitrary payload for custom templates; ForgeSelect never reads it. */
|
|
12
10
|
meta?: Record<string, unknown>;
|
|
11
|
+
/** Extra CSS class(es) applied to this option's rendered <li>. */
|
|
12
|
+
className?: string;
|
|
13
13
|
/**
|
|
14
14
|
* Nested options, making this a tree node. Purely additive: lists where
|
|
15
15
|
* no option has `children` render and behave exactly as a flat list.
|
|
@@ -22,7 +22,13 @@ interface OptionGroup {
|
|
|
22
22
|
}
|
|
23
23
|
type DataItem = Option | OptionGroup;
|
|
24
24
|
interface AjaxConfig {
|
|
25
|
-
|
|
25
|
+
/** GET endpoint. Optional when `request` supplies a custom transport. */
|
|
26
|
+
url?: string | ((query: string, page: number) => string);
|
|
27
|
+
/**
|
|
28
|
+
* Custom transport for POST/authenticated/GraphQL requests. Takes precedence
|
|
29
|
+
* over `url`; the returned payload is passed through `transform`.
|
|
30
|
+
*/
|
|
31
|
+
request?: (query: string, page: number, signal: AbortSignal) => Promise<unknown>;
|
|
26
32
|
params?: (query: string, page: number) => Record<string, unknown>;
|
|
27
33
|
/** Debounce in milliseconds. Default 250. */
|
|
28
34
|
debounce?: number;
|
|
@@ -55,12 +61,62 @@ interface ForgeSelectOptions {
|
|
|
55
61
|
multiple?: boolean;
|
|
56
62
|
clearable?: boolean;
|
|
57
63
|
allowCreate?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Let the user reorder selected tags by dragging them (mouse/touch/pen via
|
|
66
|
+
* Pointer Events), or via Alt+Left/Alt+Right when a tag has focus. Only
|
|
67
|
+
* meaningful when `multiple` is true. Default false — existing multi-select
|
|
68
|
+
* behavior and tag markup are unchanged when this is left off.
|
|
69
|
+
*/
|
|
70
|
+
sortable?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Multi-select only: close the dropdown immediately after each pick
|
|
73
|
+
* instead of staying open for further selections. Default false —
|
|
74
|
+
* existing multi-select behavior (stays open) is unchanged.
|
|
75
|
+
*/
|
|
76
|
+
closeOnSelect?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Multi-select only: caps the number of selected values. Once reached,
|
|
79
|
+
* further picks (including via allowCreate) are ignored until one is
|
|
80
|
+
* removed. Only gates interactive selection — setValue() is not clamped.
|
|
81
|
+
* Default undefined (no limit).
|
|
82
|
+
*/
|
|
83
|
+
maxSelections?: number;
|
|
58
84
|
theme?: string;
|
|
59
85
|
disabled?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Marks the field as required for native form validation. When mounted on
|
|
88
|
+
* a real <select>, an empty selection blocks form submission and shows
|
|
89
|
+
* inline invalid styling, mirroring native <select required> behavior.
|
|
90
|
+
* On a plain-element mount this only sets aria-required (no native form
|
|
91
|
+
* to hook into). Default false.
|
|
92
|
+
*/
|
|
93
|
+
required?: boolean;
|
|
60
94
|
data?: DataItem[];
|
|
61
95
|
ajax?: AjaxConfig;
|
|
62
96
|
templateResult?: TemplateFn;
|
|
63
97
|
templateSelection?: TemplateFn;
|
|
98
|
+
/**
|
|
99
|
+
* Custom match predicate, replacing the built-in label/description
|
|
100
|
+
* substring match. Receives the trimmed (not lowercased) query.
|
|
101
|
+
*/
|
|
102
|
+
filterOption?: (option: Option, query: string) => boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Hides results (showing a hint row instead) until the trimmed search
|
|
105
|
+
* query reaches this length. Also delays ajax requests until the
|
|
106
|
+
* threshold is met. Default 0 (no gate).
|
|
107
|
+
*/
|
|
108
|
+
minSearchLength?: number;
|
|
109
|
+
/**
|
|
110
|
+
* Hides the search field when a local list contains fewer options than
|
|
111
|
+
* this threshold. AJAX-backed lists always keep search visible. Default 0.
|
|
112
|
+
*/
|
|
113
|
+
minResultsForSearch?: number;
|
|
114
|
+
/**
|
|
115
|
+
* Dynamically disables an option, in addition to its static `disabled`
|
|
116
|
+
* field. Re-evaluated on every render, so it can react to external state
|
|
117
|
+
* (e.g. a quota) without rebuilding `data` via setData().
|
|
118
|
+
*/
|
|
119
|
+
isOptionDisabled?: (option: Option) => boolean;
|
|
64
120
|
/**
|
|
65
121
|
* false = never virtualize. true or unset = virtualize automatically
|
|
66
122
|
* once the list exceeds ~100 rows.
|
|
@@ -70,9 +126,42 @@ interface ForgeSelectOptions {
|
|
|
70
126
|
itemHeight?: number;
|
|
71
127
|
language?: string | Record<string, string>;
|
|
72
128
|
plugins?: ForgeSelectPlugin[];
|
|
129
|
+
/**
|
|
130
|
+
* Opens the dropdown when the control receives keyboard focus (e.g. via
|
|
131
|
+
* Tab). Default false — focusing alone still requires Enter/Space/ArrowDown
|
|
132
|
+
* to open, matching existing behavior.
|
|
133
|
+
*/
|
|
134
|
+
openOnFocus?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Optional portal container for the dropdown, useful inside overflow-hidden
|
|
137
|
+
* modals and drawers. Accepts an element or selector. Default: the root.
|
|
138
|
+
*/
|
|
139
|
+
dropdownParent?: HTMLElement | string;
|
|
73
140
|
}
|
|
74
141
|
type ForgeSelectValue = string | string[] | null;
|
|
75
|
-
|
|
142
|
+
interface SetValueOptions {
|
|
143
|
+
/** Emit Forge Select's `change` event after updating. Default true. */
|
|
144
|
+
emitChange?: boolean;
|
|
145
|
+
}
|
|
146
|
+
interface MaximumSelectionEvent {
|
|
147
|
+
limit: number;
|
|
148
|
+
option: Option;
|
|
149
|
+
}
|
|
150
|
+
interface ForgeSelectEventMap {
|
|
151
|
+
change: ForgeSelectValue;
|
|
152
|
+
open: void;
|
|
153
|
+
close: void;
|
|
154
|
+
search: string;
|
|
155
|
+
clear: void;
|
|
156
|
+
error: Error;
|
|
157
|
+
select: Option;
|
|
158
|
+
unselect: Option;
|
|
159
|
+
create: Option;
|
|
160
|
+
reorder: string[];
|
|
161
|
+
maximum: MaximumSelectionEvent;
|
|
162
|
+
}
|
|
163
|
+
type ForgeSelectEvent = keyof ForgeSelectEventMap;
|
|
164
|
+
type ForgeSelectEventHandler<E extends ForgeSelectEvent> = ForgeSelectEventMap[E] extends void ? () => void : (payload: ForgeSelectEventMap[E]) => void;
|
|
76
165
|
|
|
77
166
|
declare class ForgeSelect {
|
|
78
167
|
/** The original element ForgeSelect was mounted on. */
|
|
@@ -82,6 +171,7 @@ declare class ForgeSelect {
|
|
|
82
171
|
private data;
|
|
83
172
|
private selected;
|
|
84
173
|
private selectedOptions;
|
|
174
|
+
private suppressNextTagClick;
|
|
85
175
|
private emitter;
|
|
86
176
|
private plugins;
|
|
87
177
|
private uid;
|
|
@@ -92,6 +182,8 @@ declare class ForgeSelect {
|
|
|
92
182
|
private dropdown;
|
|
93
183
|
private searchInput;
|
|
94
184
|
private list;
|
|
185
|
+
private liveRegion;
|
|
186
|
+
private portalHost;
|
|
95
187
|
private isOpen;
|
|
96
188
|
private isDisabled;
|
|
97
189
|
private destroyed;
|
|
@@ -107,21 +199,75 @@ declare class ForgeSelect {
|
|
|
107
199
|
private hasMore;
|
|
108
200
|
private ajaxTimer;
|
|
109
201
|
private ajaxRequestId;
|
|
202
|
+
private ajaxController;
|
|
110
203
|
private remoteLoaded;
|
|
204
|
+
private loadError;
|
|
205
|
+
private originalDisplay;
|
|
206
|
+
private originalDisabled;
|
|
207
|
+
private nativeSelect;
|
|
208
|
+
private nativeForm;
|
|
209
|
+
private syncingNative;
|
|
210
|
+
/** Combines the static `disabled` field with the dynamic `isOptionDisabled` callback. */
|
|
211
|
+
private isOptionDisabled;
|
|
212
|
+
private pointerDownOnControl;
|
|
111
213
|
private onDocumentMouseDown;
|
|
214
|
+
private onWindowResize;
|
|
215
|
+
private onAncestorScroll;
|
|
216
|
+
private onNativeInvalid;
|
|
217
|
+
private onNativeChange;
|
|
218
|
+
private applyNativeValues;
|
|
219
|
+
private onFormReset;
|
|
112
220
|
constructor(target: string | HTMLElement, options?: ForgeSelectOptions);
|
|
113
221
|
open(): void;
|
|
114
222
|
close(): void;
|
|
223
|
+
/**
|
|
224
|
+
* Flips the dropdown above the control when there isn't enough room below
|
|
225
|
+
* but there is above. Recomputed on open() and on window resize — the
|
|
226
|
+
* dropdown is positioned absolutely inside the relatively-positioned root,
|
|
227
|
+
* so it already tracks the control correctly on page scroll without
|
|
228
|
+
* needing a scroll listener.
|
|
229
|
+
*/
|
|
230
|
+
private positionDropdown;
|
|
115
231
|
destroy(): void;
|
|
116
232
|
getValue(): ForgeSelectValue;
|
|
117
|
-
setValue(value: ForgeSelectValue): void;
|
|
233
|
+
setValue(value: ForgeSelectValue, options?: SetValueOptions): void;
|
|
234
|
+
/**
|
|
235
|
+
* Replaces the option list after construction. An open dropdown re-renders
|
|
236
|
+
* immediately; a selection whose value isn't in the new data stays
|
|
237
|
+
* selected (rendered via the already-selected option's own label/avatar,
|
|
238
|
+
* the same fallback used for values selected from a stale ajax page).
|
|
239
|
+
*/
|
|
240
|
+
setData(data: DataItem[]): void;
|
|
241
|
+
/**
|
|
242
|
+
* Multi-select only: selects every currently non-disabled option, including
|
|
243
|
+
* nested tree descendants and options inside groups. If `maxSelections` is
|
|
244
|
+
* set, stops once the cap is reached rather than exceeding it. A no-op for
|
|
245
|
+
* single-select.
|
|
246
|
+
*/
|
|
247
|
+
selectAll(): void;
|
|
248
|
+
/** Clears every selection. Equivalent to `setValue(null)`. */
|
|
249
|
+
clearAll(): void;
|
|
118
250
|
enable(): void;
|
|
119
251
|
disable(): void;
|
|
120
|
-
on(event:
|
|
121
|
-
off(event:
|
|
252
|
+
on<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
253
|
+
off<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
254
|
+
/**
|
|
255
|
+
* The original target (a hidden native <select> or a plain mount div) can
|
|
256
|
+
* carry an accessible name via aria-label/aria-labelledby, or via a
|
|
257
|
+
* <label for> pointing at its id — but once `this.el` is display:none it
|
|
258
|
+
* drops out of the accessibility tree, so any such association silently
|
|
259
|
+
* stops reaching assistive tech unless we forward it onto the visible,
|
|
260
|
+
* interactive `this.control` ourselves.
|
|
261
|
+
*/
|
|
262
|
+
private applyAccessibleName;
|
|
263
|
+
private shouldShowSearch;
|
|
264
|
+
private updateSearchVisibility;
|
|
122
265
|
private buildDom;
|
|
123
266
|
private bindEvents;
|
|
124
267
|
private handleKeydown;
|
|
268
|
+
private canSelectOption;
|
|
269
|
+
private hasReachedMaximum;
|
|
270
|
+
private announceMaximum;
|
|
125
271
|
private selectValue;
|
|
126
272
|
private deselectValue;
|
|
127
273
|
/**
|
|
@@ -132,17 +278,35 @@ declare class ForgeSelect {
|
|
|
132
278
|
*/
|
|
133
279
|
private syncTreeAncestors;
|
|
134
280
|
private clearSelection;
|
|
281
|
+
private allSelectableValues;
|
|
135
282
|
private afterSelectionChange;
|
|
136
283
|
private syncNativeSelect;
|
|
137
284
|
private findOption;
|
|
285
|
+
private findOptionByLabel;
|
|
286
|
+
/** Selects an existing option matching `label` exactly, or creates and selects a new one. */
|
|
287
|
+
private createTag;
|
|
138
288
|
private createFromQuery;
|
|
139
289
|
private activateNavItem;
|
|
140
290
|
private renderValue;
|
|
141
|
-
|
|
291
|
+
/**
|
|
292
|
+
* Pointer-based (mouse/touch/pen) reorder for a single tag. Only the real
|
|
293
|
+
* dragged DOM node is moved during the gesture — a full renderValue()
|
|
294
|
+
* mid-drag would destroy it — so the reordered `this.selected` is only
|
|
295
|
+
* committed on release. The move/up listeners and pointer capture live on
|
|
296
|
+
* the stable `this.valueEl` container rather than the tag itself: `tag`
|
|
297
|
+
* gets repositioned via `insertBefore` during the drag, and browsers treat
|
|
298
|
+
* that reparenting as detaching the node, which silently drops pointer
|
|
299
|
+
* capture (and further move events) if it were captured on `tag`.
|
|
300
|
+
*/
|
|
301
|
+
private bindTagDrag;
|
|
302
|
+
/** Alt+Left/Alt+Right on a focused tag: the keyboard-operable equivalent of dragging. */
|
|
303
|
+
private handleTagKeydown;
|
|
304
|
+
private focusTagByValue;
|
|
142
305
|
private buildRows;
|
|
143
306
|
private hasExactMatch;
|
|
144
307
|
private usesVirtualScroll;
|
|
145
308
|
private renderList;
|
|
309
|
+
private announceStatus;
|
|
146
310
|
private renderRows;
|
|
147
311
|
private renderRow;
|
|
148
312
|
/**
|
|
@@ -153,6 +317,8 @@ declare class ForgeSelect {
|
|
|
153
317
|
*/
|
|
154
318
|
private optionContent;
|
|
155
319
|
private moveHighlight;
|
|
320
|
+
private focusNavIndex;
|
|
321
|
+
private navigateTree;
|
|
156
322
|
private updateActiveDescendant;
|
|
157
323
|
private scheduleRemoteLoad;
|
|
158
324
|
/**
|
|
@@ -164,4 +330,4 @@ declare class ForgeSelect {
|
|
|
164
330
|
private loadRemote;
|
|
165
331
|
}
|
|
166
332
|
|
|
167
|
-
export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type Option, type OptionGroup, type TemplateFn, ForgeSelect as default };
|
|
333
|
+
export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectEventHandler, type ForgeSelectEventMap, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type MaximumSelectionEvent, type Option, type OptionGroup, type SetValueOptions, type TemplateFn, ForgeSelect as default };
|