forge-select 0.3.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 +24 -15
- package/dist/index.cjs +337 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +125 -7
- package/dist/index.d.ts +125 -7
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +337 -43
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/styles/forge-select.css +25 -1
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;
|
|
@@ -62,12 +68,55 @@ interface ForgeSelectOptions {
|
|
|
62
68
|
* behavior and tag markup are unchanged when this is left off.
|
|
63
69
|
*/
|
|
64
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;
|
|
65
84
|
theme?: string;
|
|
66
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;
|
|
67
94
|
data?: DataItem[];
|
|
68
95
|
ajax?: AjaxConfig;
|
|
69
96
|
templateResult?: TemplateFn;
|
|
70
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;
|
|
71
120
|
/**
|
|
72
121
|
* false = never virtualize. true or unset = virtualize automatically
|
|
73
122
|
* once the list exceeds ~100 rows.
|
|
@@ -77,13 +126,42 @@ interface ForgeSelectOptions {
|
|
|
77
126
|
itemHeight?: number;
|
|
78
127
|
language?: string | Record<string, string>;
|
|
79
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;
|
|
80
140
|
}
|
|
81
141
|
type ForgeSelectValue = string | string[] | null;
|
|
82
142
|
interface SetValueOptions {
|
|
83
143
|
/** Emit Forge Select's `change` event after updating. Default true. */
|
|
84
144
|
emitChange?: boolean;
|
|
85
145
|
}
|
|
86
|
-
|
|
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;
|
|
87
165
|
|
|
88
166
|
declare class ForgeSelect {
|
|
89
167
|
/** The original element ForgeSelect was mounted on. */
|
|
@@ -105,6 +183,7 @@ declare class ForgeSelect {
|
|
|
105
183
|
private searchInput;
|
|
106
184
|
private list;
|
|
107
185
|
private liveRegion;
|
|
186
|
+
private portalHost;
|
|
108
187
|
private isOpen;
|
|
109
188
|
private isDisabled;
|
|
110
189
|
private destroyed;
|
|
@@ -128,20 +207,50 @@ declare class ForgeSelect {
|
|
|
128
207
|
private nativeSelect;
|
|
129
208
|
private nativeForm;
|
|
130
209
|
private syncingNative;
|
|
210
|
+
/** Combines the static `disabled` field with the dynamic `isOptionDisabled` callback. */
|
|
211
|
+
private isOptionDisabled;
|
|
212
|
+
private pointerDownOnControl;
|
|
131
213
|
private onDocumentMouseDown;
|
|
214
|
+
private onWindowResize;
|
|
215
|
+
private onAncestorScroll;
|
|
216
|
+
private onNativeInvalid;
|
|
132
217
|
private onNativeChange;
|
|
133
218
|
private applyNativeValues;
|
|
134
219
|
private onFormReset;
|
|
135
220
|
constructor(target: string | HTMLElement, options?: ForgeSelectOptions);
|
|
136
221
|
open(): void;
|
|
137
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;
|
|
138
231
|
destroy(): void;
|
|
139
232
|
getValue(): ForgeSelectValue;
|
|
140
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;
|
|
141
250
|
enable(): void;
|
|
142
251
|
disable(): void;
|
|
143
|
-
on(event:
|
|
144
|
-
off(event:
|
|
252
|
+
on<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
253
|
+
off<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
145
254
|
/**
|
|
146
255
|
* The original target (a hidden native <select> or a plain mount div) can
|
|
147
256
|
* carry an accessible name via aria-label/aria-labelledby, or via a
|
|
@@ -151,9 +260,14 @@ declare class ForgeSelect {
|
|
|
151
260
|
* interactive `this.control` ourselves.
|
|
152
261
|
*/
|
|
153
262
|
private applyAccessibleName;
|
|
263
|
+
private shouldShowSearch;
|
|
264
|
+
private updateSearchVisibility;
|
|
154
265
|
private buildDom;
|
|
155
266
|
private bindEvents;
|
|
156
267
|
private handleKeydown;
|
|
268
|
+
private canSelectOption;
|
|
269
|
+
private hasReachedMaximum;
|
|
270
|
+
private announceMaximum;
|
|
157
271
|
private selectValue;
|
|
158
272
|
private deselectValue;
|
|
159
273
|
/**
|
|
@@ -164,9 +278,13 @@ declare class ForgeSelect {
|
|
|
164
278
|
*/
|
|
165
279
|
private syncTreeAncestors;
|
|
166
280
|
private clearSelection;
|
|
281
|
+
private allSelectableValues;
|
|
167
282
|
private afterSelectionChange;
|
|
168
283
|
private syncNativeSelect;
|
|
169
284
|
private findOption;
|
|
285
|
+
private findOptionByLabel;
|
|
286
|
+
/** Selects an existing option matching `label` exactly, or creates and selects a new one. */
|
|
287
|
+
private createTag;
|
|
170
288
|
private createFromQuery;
|
|
171
289
|
private activateNavItem;
|
|
172
290
|
private renderValue;
|
|
@@ -212,4 +330,4 @@ declare class ForgeSelect {
|
|
|
212
330
|
private loadRemote;
|
|
213
331
|
}
|
|
214
332
|
|
|
215
|
-
export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type Option, type OptionGroup, type SetValueOptions, 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;
|
|
@@ -62,12 +68,55 @@ interface ForgeSelectOptions {
|
|
|
62
68
|
* behavior and tag markup are unchanged when this is left off.
|
|
63
69
|
*/
|
|
64
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;
|
|
65
84
|
theme?: string;
|
|
66
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;
|
|
67
94
|
data?: DataItem[];
|
|
68
95
|
ajax?: AjaxConfig;
|
|
69
96
|
templateResult?: TemplateFn;
|
|
70
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;
|
|
71
120
|
/**
|
|
72
121
|
* false = never virtualize. true or unset = virtualize automatically
|
|
73
122
|
* once the list exceeds ~100 rows.
|
|
@@ -77,13 +126,42 @@ interface ForgeSelectOptions {
|
|
|
77
126
|
itemHeight?: number;
|
|
78
127
|
language?: string | Record<string, string>;
|
|
79
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;
|
|
80
140
|
}
|
|
81
141
|
type ForgeSelectValue = string | string[] | null;
|
|
82
142
|
interface SetValueOptions {
|
|
83
143
|
/** Emit Forge Select's `change` event after updating. Default true. */
|
|
84
144
|
emitChange?: boolean;
|
|
85
145
|
}
|
|
86
|
-
|
|
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;
|
|
87
165
|
|
|
88
166
|
declare class ForgeSelect {
|
|
89
167
|
/** The original element ForgeSelect was mounted on. */
|
|
@@ -105,6 +183,7 @@ declare class ForgeSelect {
|
|
|
105
183
|
private searchInput;
|
|
106
184
|
private list;
|
|
107
185
|
private liveRegion;
|
|
186
|
+
private portalHost;
|
|
108
187
|
private isOpen;
|
|
109
188
|
private isDisabled;
|
|
110
189
|
private destroyed;
|
|
@@ -128,20 +207,50 @@ declare class ForgeSelect {
|
|
|
128
207
|
private nativeSelect;
|
|
129
208
|
private nativeForm;
|
|
130
209
|
private syncingNative;
|
|
210
|
+
/** Combines the static `disabled` field with the dynamic `isOptionDisabled` callback. */
|
|
211
|
+
private isOptionDisabled;
|
|
212
|
+
private pointerDownOnControl;
|
|
131
213
|
private onDocumentMouseDown;
|
|
214
|
+
private onWindowResize;
|
|
215
|
+
private onAncestorScroll;
|
|
216
|
+
private onNativeInvalid;
|
|
132
217
|
private onNativeChange;
|
|
133
218
|
private applyNativeValues;
|
|
134
219
|
private onFormReset;
|
|
135
220
|
constructor(target: string | HTMLElement, options?: ForgeSelectOptions);
|
|
136
221
|
open(): void;
|
|
137
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;
|
|
138
231
|
destroy(): void;
|
|
139
232
|
getValue(): ForgeSelectValue;
|
|
140
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;
|
|
141
250
|
enable(): void;
|
|
142
251
|
disable(): void;
|
|
143
|
-
on(event:
|
|
144
|
-
off(event:
|
|
252
|
+
on<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
253
|
+
off<E extends ForgeSelectEvent>(event: E, handler: ForgeSelectEventHandler<E>): void;
|
|
145
254
|
/**
|
|
146
255
|
* The original target (a hidden native <select> or a plain mount div) can
|
|
147
256
|
* carry an accessible name via aria-label/aria-labelledby, or via a
|
|
@@ -151,9 +260,14 @@ declare class ForgeSelect {
|
|
|
151
260
|
* interactive `this.control` ourselves.
|
|
152
261
|
*/
|
|
153
262
|
private applyAccessibleName;
|
|
263
|
+
private shouldShowSearch;
|
|
264
|
+
private updateSearchVisibility;
|
|
154
265
|
private buildDom;
|
|
155
266
|
private bindEvents;
|
|
156
267
|
private handleKeydown;
|
|
268
|
+
private canSelectOption;
|
|
269
|
+
private hasReachedMaximum;
|
|
270
|
+
private announceMaximum;
|
|
157
271
|
private selectValue;
|
|
158
272
|
private deselectValue;
|
|
159
273
|
/**
|
|
@@ -164,9 +278,13 @@ declare class ForgeSelect {
|
|
|
164
278
|
*/
|
|
165
279
|
private syncTreeAncestors;
|
|
166
280
|
private clearSelection;
|
|
281
|
+
private allSelectableValues;
|
|
167
282
|
private afterSelectionChange;
|
|
168
283
|
private syncNativeSelect;
|
|
169
284
|
private findOption;
|
|
285
|
+
private findOptionByLabel;
|
|
286
|
+
/** Selects an existing option matching `label` exactly, or creates and selects a new one. */
|
|
287
|
+
private createTag;
|
|
170
288
|
private createFromQuery;
|
|
171
289
|
private activateNavItem;
|
|
172
290
|
private renderValue;
|
|
@@ -212,4 +330,4 @@ declare class ForgeSelect {
|
|
|
212
330
|
private loadRemote;
|
|
213
331
|
}
|
|
214
332
|
|
|
215
|
-
export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type Option, type OptionGroup, type SetValueOptions, 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.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var ForgeSelectBundle=(()=>{var I=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var q=(r,e)=>{for(var t in e)I(r,t,{get:e[t],enumerable:!0})},P=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of F(e))!j.call(r,s)&&s!==t&&I(r,s,{get:()=>e[s],enumerable:!(i=V(e,s))||i.enumerable});return r};var B=r=>P(I({},"__esModule",{value:!0}),r);var X={};q(X,{ForgeSelect:()=>p,default:()=>p});var v=class{constructor(){this.handlers=new Map}on(e,t){let i=this.handlers.get(e);i||(i=new Set,this.handlers.set(e,i)),i.add(t)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,...t){let i=this.handlers.get(e);if(i)for(let s of[...i])s(...t)}clear(){this.handlers.clear()}};var L={en:{noResults:"No results found",loading:"Loading\u2026",loadingMore:"Loading more\u2026",errorLoading:"Could not load options",createOption:'Create "{query}"',clearSelection:"Clear selection",removeItem:"Remove {label}",search:"Search",reorderHint:"{label}. Press Alt+Left or Alt+Right to reorder."},vi:{noResults:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3",loading:"\u0110ang t\u1EA3i\u2026",loadingMore:"\u0110ang t\u1EA3i th\xEAm\u2026",errorLoading:"Kh\xF4ng th\u1EC3 t\u1EA3i t\xF9y ch\u1ECDn",createOption:'T\u1EA1o "{query}"',clearSelection:"X\xF3a l\u1EF1a ch\u1ECDn",removeItem:"X\xF3a {label}",search:"T\xECm ki\u1EBFm",reorderHint:"{label}. Nh\u1EA5n Alt+Tr\xE1i ho\u1EB7c Alt+Ph\u1EA3i \u0111\u1EC3 s\u1EAFp x\u1EBFp l\u1EA1i."}};function C(r){return typeof r=="string"?L[r]??L.en:{...L.en,...r}}function b(r,e){return r.replace(/\{(\w+)\}/g,(t,i)=>e[i]??t)}function T(r){let e=[];for(let t of Array.from(r.children))t instanceof HTMLOptGroupElement?e.push({label:t.label,options:Array.from(t.querySelectorAll("option")).map(O)}):t instanceof HTMLOptionElement&&e.push(O(t));return e}function O(r){let e=r.parentElement instanceof HTMLOptGroupElement&&r.parentElement.disabled;return{value:r.value,label:r.textContent?.trim()??r.value,disabled:r.disabled||e||void 0}}function x(r,e,t,i="row"){if(t){let s=t(e);typeof s=="string"?r.innerHTML=s:r.append(s);return}if(!e.avatar&&!e.description){r.textContent=e.label;return}if(e.avatar){let s=document.createElement("img");s.className=i==="row"?"forge-select__option-avatar":"forge-select__inline-avatar",s.src=e.avatar,s.alt="",s.setAttribute("loading","lazy"),s.setAttribute("decoding","async"),r.append(s)}if(i==="row"&&e.description){let s=document.createElement("span");s.className="forge-select__option-body";let n=document.createElement("span");n.className="forge-select__option-label",n.textContent=e.label;let a=document.createElement("span");a.className="forge-select__option-desc",a.textContent=e.description,s.append(n,a),r.append(s)}else{let s=document.createElement("span");s.className="forge-select__option-label",s.textContent=e.label,r.append(s)}}function _(r,e,t){if(typeof r.url=="function")return r.url(e,t);if(!r.params)return r.url;let i=new URLSearchParams;for(let[n,a]of Object.entries(r.params(e,t)))i.set(n,String(a));let s=r.url.includes("?")?"&":"?";return`${r.url}${s}${i.toString()}`}function R(r,e){let t=r.transform?r.transform(e):e;if(Array.isArray(t))return{options:t,hasMore:!1};if(!t||!Array.isArray(t.options))throw new Error("ForgeSelect: ajax.transform must return an array of options, or an object shaped like { options: Option[], hasMore?: boolean }.");return{options:t.options,hasMore:r.pagination?!!t.hasMore:!1}}function u(r){return r.options!==void 0}function y(r){if(!r.children)return[];let e=[];for(let t of r.children)t.disabled||e.push(t.value),e.push(...y(t));return e}function E(r,e){if(!r.children?.length)return e.includes(r.value)?"all":"none";let t=r.children.filter(i=>!i.disabled).map(i=>E(i,e));return t.length===0?"none":t.every(i=>i==="all")?"all":t.every(i=>i==="none")?"none":"some"}function k(r,e){let t=i=>{for(let s of i){if(s.value===e)return s;let n=s.children?t(s.children):void 0;if(n)return n}};for(let i of r){let s=t(u(i)?i.options:[i]);if(s)return s}}function M(r,e){let t=i=>{if(!i.children?.length)return;for(let a of i.children)t(a);let s=E(i,e),n=e.indexOf(i.value);s==="all"&&n===-1?e.push(i.value):s!=="all"&&n!==-1&&e.splice(n,1)};for(let i of r)(u(i)?i.options:[i]).forEach(t)}function N(r){let e=new Set,t=i=>{e.add(i.value),i.children?.forEach(t)};for(let i of r)(u(i)?i.options:[i]).forEach(t);return e}function H(r,e){return r.length===e.length&&r.every((t,i)=>t===e[i])}var $=36,D=5,G=100,K=2e3,U=0,p=class{constructor(e,t={}){this.selected=[];this.selectedOptions=new Map;this.suppressNextTagClick=!1;this.emitter=new v;this.uid=`forge-select-${++U}`;this.searchInput=null;this.isOpen=!1;this.isDisabled=!1;this.destroyed=!1;this.query="";this.rows=[];this.navItems=[];this.highlightedIndex=-1;this.rowContentCache=new Map;this.expandedValues=new Set;this.loading=!1;this.loadingMore=!1;this.page=0;this.hasMore=!0;this.ajaxTimer=null;this.ajaxRequestId=0;this.ajaxController=null;this.remoteLoaded=!1;this.loadError=null;this.originalDisplay="";this.originalDisabled=!1;this.nativeSelect=null;this.nativeForm=null;this.syncingNative=!1;this.onDocumentMouseDown=e=>{this.root.contains(e.target)||this.close()};this.onNativeChange=()=>{if(!this.nativeSelect||this.destroyed||this.syncingNative)return;let e=Array.from(this.nativeSelect.selectedOptions,t=>t.value);this.applyNativeValues(e)};this.onFormReset=()=>{if(!this.nativeSelect||this.destroyed)return;let e=Array.from(this.nativeSelect.options).filter(t=>t.defaultSelected).map(t=>t.value);this.applyNativeValues(e)};let i=typeof e=="string"?document.querySelector(e):e;if(!i)throw new Error(`ForgeSelect: target element not found: ${String(e)}`);this.el=i;let s=i instanceof HTMLSelectElement?i:null;if(this.nativeSelect=s,this.nativeForm=s?.form??null,this.originalDisplay=i.style.display,this.originalDisabled=s?.disabled??!1,this.opts={placeholder:t.placeholder??"",searchable:t.searchable??!0,multiple:t.multiple??s?.multiple??!1,clearable:t.clearable??!1,allowCreate:t.allowCreate??!1,sortable:t.sortable??!1,theme:t.theme??"default",disabled:t.disabled??s?.disabled??!1,data:t.data,ajax:t.ajax,templateResult:t.templateResult,templateSelection:t.templateSelection,virtualScroll:t.virtualScroll,itemHeight:t.itemHeight??$,language:t.language??"en",plugins:t.plugins??[]},this.strings=C(this.opts.language),this.plugins=this.opts.plugins,this.data=this.opts.data??(s?T(s):[]),s&&!this.opts.data){let n=Array.from(s.options),a=s.multiple||s.selectedIndex>0||n.some(o=>o.defaultSelected);for(let o of n)a&&o.selected&&this.selectValue(o.value,!1)}this.buildDom(),this.renderValue(),this.opts.disabled&&this.disable(),s?.addEventListener("change",this.onNativeChange),this.nativeForm?.addEventListener("reset",this.onFormReset);for(let n of this.plugins)n.onInit?.(this)}applyNativeValues(e){this.selected=[];for(let t of this.opts.multiple?e:e.slice(0,1))this.selectValue(t,!1);this.renderValue(),this.isOpen&&this.renderList(),this.emitter.emit("change",this.getValue())}open(){if(!(this.isOpen||this.isDisabled||this.destroyed)){this.isOpen=!0,this.dropdown.hidden=!1,this.root.classList.add("forge-select--open"),this.control.setAttribute("aria-expanded","true"),document.addEventListener("mousedown",this.onDocumentMouseDown),this.opts.ajax&&!this.remoteLoaded&&this.scheduleRemoteLoad(this.query,0),this.renderList(),this.searchInput&&this.searchInput.focus(),this.emitter.emit("open");for(let e of this.plugins)e.onOpen?.(this)}}close(){if(this.isOpen){this.isOpen=!1,this.dropdown.hidden=!0,this.root.classList.remove("forge-select--open"),this.control.setAttribute("aria-expanded","false"),document.removeEventListener("mousedown",this.onDocumentMouseDown),this.highlightedIndex=-1,this.searchInput&&(this.searchInput.value="",this.query=""),this.emitter.emit("close");for(let e of this.plugins)e.onClose?.(this)}}destroy(){if(!this.destroyed){this.close();for(let e of this.plugins)e.onDestroy?.(this);this.destroyed=!0,this.ajaxTimer&&clearTimeout(this.ajaxTimer),this.ajaxController?.abort(),this.nativeSelect?.removeEventListener("change",this.onNativeChange),this.nativeForm?.removeEventListener("reset",this.onFormReset),this.rowContentCache.clear(),this.root.remove(),this.el.style.display=this.originalDisplay,this.nativeSelect&&(this.nativeSelect.disabled=this.originalDisabled),this.emitter.clear()}}getValue(){return this.opts.multiple?[...this.selected]:this.selected[0]??null}setValue(e,t={}){let i=e==null?[]:Array.isArray(e)?e:[e],s=this.opts.multiple?i:i.slice(0,1);if(!H(s,this.selected)){this.selected=[];for(let n of s)this.selectValue(n,!1);this.afterSelectionChange(t.emitChange??!0)}}enable(){this.isDisabled=!1,this.root.classList.remove("forge-select--disabled"),this.control.tabIndex=0,this.control.setAttribute("aria-disabled","false"),this.nativeSelect&&(this.nativeSelect.disabled=!1)}disable(){this.close(),this.isDisabled=!0,this.root.classList.add("forge-select--disabled"),this.control.tabIndex=-1,this.control.setAttribute("aria-disabled","true"),this.nativeSelect&&(this.nativeSelect.disabled=!0)}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}applyAccessibleName(){let e=this.el.getAttribute("aria-labelledby"),t=this.el.getAttribute("aria-label");if(e)this.control.setAttribute("aria-labelledby",e);else if(t)this.control.setAttribute("aria-label",t);else if(this.el.id){let i=Array.from(document.getElementsByTagName("label")).find(s=>s.htmlFor===this.el.id);i&&(i.id||(i.id=`${this.uid}-label`),this.control.setAttribute("aria-labelledby",i.id))}}buildDom(){this.root=document.createElement("div"),this.root.className="forge-select",this.root.dataset.theme=this.opts.theme,this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.opts.sortable&&this.opts.multiple&&this.root.classList.add("forge-select--sortable"),this.control=document.createElement("div"),this.control.className="forge-select__control",this.control.setAttribute("role","combobox"),this.control.setAttribute("aria-haspopup","listbox"),this.control.setAttribute("aria-expanded","false"),this.control.setAttribute("aria-controls",`${this.uid}-list`),this.control.tabIndex=0,this.applyAccessibleName(),this.valueEl=document.createElement("div"),this.valueEl.className="forge-select__value",this.clearBtn=document.createElement("button"),this.clearBtn.type="button",this.clearBtn.className="forge-select__clear",this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.clearBtn.textContent="\xD7",this.clearBtn.hidden=!0;let e=document.createElement("span");e.className="forge-select__arrow",e.setAttribute("aria-hidden","true"),this.control.append(this.valueEl,this.clearBtn,e),this.dropdown=document.createElement("div"),this.dropdown.className="forge-select__dropdown",this.dropdown.hidden=!0,this.opts.searchable&&(this.searchInput=document.createElement("input"),this.searchInput.type="search",this.searchInput.className="forge-select__search",this.searchInput.setAttribute("aria-label",this.strings.search),this.searchInput.setAttribute("aria-autocomplete","list"),this.searchInput.setAttribute("aria-controls",`${this.uid}-list`),this.dropdown.append(this.searchInput)),this.list=document.createElement("ul"),this.list.className="forge-select__list",this.list.id=`${this.uid}-list`,this.list.setAttribute("role","listbox"),this.opts.multiple&&this.list.setAttribute("aria-multiselectable","true"),this.dropdown.append(this.list),this.liveRegion=document.createElement("div"),this.liveRegion.className="forge-select__sr-only",this.liveRegion.setAttribute("role","status"),this.liveRegion.setAttribute("aria-live","polite"),this.root.append(this.control,this.dropdown,this.liveRegion),this.el.style.display="none",this.el.insertAdjacentElement("afterend",this.root),this.bindEvents()}bindEvents(){this.control.addEventListener("click",e=>{if(e.target!==this.clearBtn){if(this.suppressNextTagClick){this.suppressNextTagClick=!1;return}this.isDisabled||(this.isOpen?this.close():this.open())}}),this.control.addEventListener("keydown",e=>this.handleKeydown(e)),this.clearBtn.addEventListener("click",e=>{e.stopPropagation(),this.clearSelection()}),this.searchInput&&(this.searchInput.addEventListener("input",()=>{this.query=this.searchInput.value,this.highlightedIndex=-1,this.list.scrollTop=0,this.emitter.emit("search",this.query),this.opts.ajax?this.scheduleRemoteLoad(this.query,this.opts.ajax.debounce??250):this.renderList()}),this.searchInput.addEventListener("keydown",e=>this.handleKeydown(e))),this.list.addEventListener("click",e=>{let t=e.target,i=t.closest("[data-twisty]");if(i){let a=i.dataset.twisty;this.expandedValues.has(a)?this.expandedValues.delete(a):this.expandedValues.add(a),this.renderList();return}let s=t.closest("li[data-nav-index]");if(!s)return;let n=Number(s.dataset.navIndex);this.activateNavItem(n)}),this.list.addEventListener("scroll",()=>{this.usesVirtualScroll()&&this.renderRows(),this.maybeLoadNextPage()})}handleKeydown(e){if(!this.isDisabled)switch(e.key){case"Enter":e.preventDefault(),this.isOpen?this.highlightedIndex>=0&&this.activateNavItem(this.highlightedIndex):this.open();break;case" ":e.target===this.control&&(e.preventDefault(),this.isOpen||this.open());break;case"ArrowDown":e.preventDefault(),this.isOpen?this.moveHighlight(1):this.open();break;case"ArrowUp":e.preventDefault(),this.isOpen&&this.moveHighlight(-1);break;case"Escape":this.isOpen&&(e.preventDefault(),this.close(),this.control.focus());break;case"ArrowRight":this.isOpen&&this.navigateTree("right")&&e.preventDefault();break;case"ArrowLeft":this.isOpen&&this.navigateTree("left")&&e.preventDefault();break;case"Tab":this.close();break}}selectValue(e,t){if(this.selected.includes(e))return;let i=this.findOption(e)??this.selectedOptions.get(e)??{value:e,label:e};if(this.selectedOptions.set(e,i),this.opts.multiple){this.selected.push(e);for(let s of y(i))this.selected.includes(s)||this.selected.push(s);this.syncTreeAncestors()}else this.selected=[e];t&&this.afterSelectionChange()}deselectValue(e,t){let i=this.selected.indexOf(e);if(i!==-1){if(this.selected.splice(i,1),this.opts.multiple){let s=this.findOption(e)??this.selectedOptions.get(e);if(s)for(let n of y(s)){let a=this.selected.indexOf(n);a!==-1&&this.selected.splice(a,1)}this.syncTreeAncestors()}t&&this.afterSelectionChange()}}syncTreeAncestors(){M(this.data,this.selected)}clearSelection(){this.selected.length!==0&&(this.selected=[],this.emitter.emit("clear"),this.afterSelectionChange())}afterSelectionChange(e=!0){this.renderValue(),this.syncNativeSelect(e),this.isOpen&&this.renderList(),e&&this.emitter.emit("change",this.getValue())}syncNativeSelect(e=!0){if(!(this.el instanceof HTMLSelectElement))return;let t=new Set;for(let i of Array.from(this.el.options))t.add(i.value),i.selected=this.selected.includes(i.value);for(let i of this.selected){if(t.has(i))continue;let s=document.createElement("option");s.value=i,s.textContent=this.selectedOptions.get(i)?.label??i,s.selected=!0,this.el.append(s)}if(this.opts.sortable&&this.opts.multiple)for(let i of this.selected){let s=Array.from(this.el.options).find(n=>n.value===i);s&&this.el.append(s)}if(e){this.syncingNative=!0;try{this.el.dispatchEvent(new Event("change",{bubbles:!0}))}finally{this.syncingNative=!1}}}findOption(e){return k(this.data,e)}createFromQuery(){let e=this.query.trim();if(!e)return;let t={value:e,label:e};this.data.push(t),this.searchInput&&(this.searchInput.value="",this.query=""),this.selectValue(t.value,!0),this.opts.multiple||this.close()}activateNavItem(e){let t=this.navItems[e];if(!t)return;if(t.kind==="create"){this.createFromQuery();return}let{value:i}=t.option;this.opts.multiple?this.selected.includes(i)?this.deselectValue(i,!0):this.selectValue(i,!0):(this.selectValue(i,!0),this.close(),this.control.focus())}renderValue(){this.valueEl.textContent="";let e=this.selected.length>0;if(this.clearBtn.hidden=!(this.opts.clearable&&e),!e){let t=document.createElement("span");t.className="forge-select__placeholder",t.textContent=this.opts.placeholder,this.valueEl.append(t);return}if(this.opts.multiple)for(let t of this.selected){let i=this.selectedOptions.get(t)??{value:t,label:t},s=document.createElement("span");s.className="forge-select__tag";let n=document.createElement("span");n.className="forge-select__tag-label",x(n,i,this.opts.templateSelection,"inline");let a=document.createElement("button");a.type="button",a.className="forge-select__tag-remove",a.setAttribute("aria-label",b(this.strings.removeItem,{label:i.label})),a.textContent="\xD7",a.addEventListener("click",o=>{o.stopPropagation(),this.isDisabled||this.deselectValue(t,!0)}),s.append(n,a),this.opts.sortable&&(s.dataset.value=t,s.tabIndex=0,s.setAttribute("aria-roledescription","draggable item"),s.setAttribute("aria-label",b(this.strings.reorderHint,{label:i.label})),s.addEventListener("keydown",o=>this.handleTagKeydown(o,t)),this.bindTagDrag(s,t)),this.valueEl.append(s)}else{let t=this.selectedOptions.get(this.selected[0])??{value:this.selected[0],label:this.selected[0]},i=document.createElement("span");i.className="forge-select__single-value",x(i,t,this.opts.templateSelection,"inline"),this.valueEl.append(i)}}bindTagDrag(e,t){let s=0,n=!1,a=[],o=h=>{if(!n){if(Math.abs(h.clientX-s)<4)return;n=!0,a=[...this.selected],typeof this.valueEl.setPointerCapture=="function"&&this.valueEl.setPointerCapture(h.pointerId),e.classList.add("forge-select__tag--dragging")}h.preventDefault();let f=a.indexOf(t),d=Array.from(this.valueEl.querySelectorAll(".forge-select__tag"));for(let c of d){if(c===e)continue;let m=c.dataset.value;if(!m)continue;let g=a.indexOf(m);if(g===-1)continue;let S=c.getBoundingClientRect(),w=S.left+S.width/2,A=f<g;if(A?h.clientX>w:h.clientX<w){a.splice(f,1),a.splice(g,0,t),A?this.valueEl.insertBefore(e,c.nextSibling):this.valueEl.insertBefore(e,c);break}}},l=h=>{this.valueEl.removeEventListener("pointermove",o),this.valueEl.removeEventListener("pointerup",l),this.valueEl.removeEventListener("pointercancel",l),n&&(typeof this.valueEl.releasePointerCapture=="function"&&this.valueEl.releasePointerCapture(h.pointerId),e.classList.remove("forge-select__tag--dragging"),this.selected=a,this.suppressNextTagClick=!0,this.afterSelectionChange())};e.addEventListener("pointerdown",h=>{this.isDisabled||h.button!==0||h.target.closest(".forge-select__tag-remove")||(s=h.clientX,n=!1,this.valueEl.addEventListener("pointermove",o),this.valueEl.addEventListener("pointerup",l),this.valueEl.addEventListener("pointercancel",l))})}handleTagKeydown(e,t){if(!e.altKey||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;let i=this.selected.indexOf(t),s=e.key==="ArrowLeft"?i-1:i+1;if(i===-1||s<0||s>=this.selected.length)return;e.preventDefault(),e.stopPropagation();let n=[...this.selected];[n[i],n[s]]=[n[s],n[i]],this.selected=n,this.afterSelectionChange(),this.focusTagByValue(t)}focusTagByValue(e){for(let t of Array.from(this.valueEl.querySelectorAll(".forge-select__tag")))if(t.dataset.value===e){t.focus();return}}buildRows(){this.rows=[],this.navItems=[];let e=this.query.trim().toLowerCase(),t=n=>e===""||n.label.toLowerCase().includes(e)||(n.description?.toLowerCase().includes(e)??!1),i=n=>e===""||t(n)||(n.children??[]).some(i),s=(n,a,o)=>{let l=-1;n.disabled||(l=this.navItems.length,this.navItems.push({kind:"option",option:n,parentValue:o}));let h=!!n.children&&n.children.length>0;if(this.rows.push({kind:"option",option:n,navIndex:l,depth:a,hasChildren:h}),h&&(e!==""||this.expandedValues.has(n.value)))for(let d of n.children)i(d)&&s(d,a+1,n.value)};if(this.loading){this.rows.push({kind:"loading"});return}if(this.loadError){this.rows.push({kind:"error"});return}for(let n of this.data)if(u(n)){let a=n.options.filter(i);if(a.length===0)continue;this.rows.push({kind:"group",label:n.label}),a.forEach(o=>s(o,0))}else i(n)&&s(n,0);if(this.opts.allowCreate&&e!==""&&!this.hasExactMatch(e)){let n=this.navItems.length;this.navItems.push({kind:"create"}),this.rows.push({kind:"create",navIndex:n})}this.rows.length===0?this.rows.push({kind:"empty"}):this.loadingMore&&this.rows.push({kind:"loading-more"})}hasExactMatch(e){let t=i=>i.label.toLowerCase()===e||(i.children??[]).some(t);for(let i of this.data)if((u(i)?i.options:[i]).some(t))return!0;return!1}usesVirtualScroll(){return this.opts.virtualScroll!==!1&&this.rows.length>G}renderList(){this.buildRows(),this.renderRows(),this.announceStatus()}announceStatus(){let e=this.rows[0],t=e?.kind==="loading"?this.strings.loading:e?.kind==="error"?this.strings.errorLoading:e?.kind==="empty"?this.strings.noResults:"";this.liveRegion.textContent!==t&&(this.liveRegion.textContent=t)}renderRows(){let e=this.list.scrollTop,t=this.list.clientHeight,i=this.usesVirtualScroll();this.list.textContent="";let s=this.opts.itemHeight,n=0,a=this.rows.length;if(i){let o=t||s*8;n=Math.max(0,Math.floor(e/s)-D),a=Math.min(this.rows.length,n+Math.ceil(o/s)+D*2);let l=document.createElement("li");l.className="forge-select__spacer",l.setAttribute("aria-hidden","true"),l.style.height=`${n*s}px`,this.list.append(l)}for(let o=n;o<a;o++)this.list.append(this.renderRow(this.rows[o]));if(i){let o=document.createElement("li");o.className="forge-select__spacer",o.setAttribute("aria-hidden","true"),o.style.height=`${(this.rows.length-a)*s}px`,this.list.append(o),this.list.scrollTop!==e&&(this.list.scrollTop=e)}this.updateActiveDescendant()}renderRow(e){let t=document.createElement("li");switch(e.kind){case"group":t.className="forge-select__group-label",t.setAttribute("role","presentation"),t.textContent=e.label;break;case"empty":t.className="forge-select__empty",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.noResults;break;case"error":t.className="forge-select__error",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.errorLoading;break;case"loading":t.className="forge-select__loading",t.setAttribute("role","option"),t.setAttribute("aria-disabled","true"),t.setAttribute("aria-selected","false"),t.textContent=this.strings.loading;break;case"loading-more":t.className="forge-select__loading-more",t.setAttribute("aria-hidden","true"),t.textContent=this.strings.loadingMore;break;case"create":t.className="forge-select__option forge-select__option--create",t.setAttribute("role","option"),t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),t.textContent=b(this.strings.createOption,{query:this.query.trim()}),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted");break;case"option":{t.className="forge-select__option",t.setAttribute("role","option");let i=this.selected.includes(e.option.value);if(t.setAttribute("aria-selected",String(i)),i&&t.classList.add("forge-select__option--selected"),this.opts.multiple&&e.hasChildren&&E(e.option,this.selected)==="some"&&t.classList.add("forge-select__option--indeterminate"),e.depth>0&&(t.style.paddingLeft=`calc(12px + ${e.depth} * var(--fs-tree-indent, 18px))`),e.option.disabled?(t.classList.add("forge-select__option--disabled"),t.setAttribute("aria-disabled","true")):(t.id=`${this.uid}-nav-${e.navIndex}`,t.dataset.navIndex=String(e.navIndex),e.navIndex===this.highlightedIndex&&t.classList.add("forge-select__option--highlighted")),e.hasChildren){let s=this.query!==""||this.expandedValues.has(e.option.value);t.setAttribute("aria-expanded",String(s));let n=document.createElement("span");n.className="forge-select__twisty",n.dataset.twisty=e.option.value,n.setAttribute("aria-hidden","true"),n.textContent=s?"\u25BC":"\u25B6",t.append(n)}t.append(this.optionContent(e.option));break}}return t}optionContent(e){let t=this.rowContentCache.get(e.value);if(!t){let i=document.createElement("span");if(i.className="forge-select__option-content",x(i,e,this.opts.templateResult),this.rowContentCache.size>=K){let s=this.rowContentCache.keys().next().value;this.rowContentCache.delete(s)}this.rowContentCache.set(e.value,i),t=i}return t.cloneNode(!0)}moveHighlight(e){if(this.navItems.length===0)return;let t=this.highlightedIndex===-1?e>0?0:this.navItems.length-1:(this.highlightedIndex+e+this.navItems.length)%this.navItems.length;this.focusNavIndex(t)}focusNavIndex(e){if(this.highlightedIndex=e,this.usesVirtualScroll()){let t=this.rows.findIndex(i=>(i.kind==="option"||i.kind==="create")&&i.navIndex===e);if(t>=0){let i=this.opts.itemHeight,s=t*i,n=this.list.clientHeight||i*8,a=this.list.scrollTop;s<a?a=s:s+i>a+n&&(a=s+i-n),a!==this.list.scrollTop&&(this.list.scrollTop=a)}this.renderRows()}else this.renderRows(),this.list.querySelector(".forge-select__option--highlighted")?.scrollIntoView?.({block:"nearest"})}navigateTree(e){let t=this.navItems[this.highlightedIndex];if(!t||t.kind!=="option")return!1;let{option:i,parentValue:s}=t,n=!!i.children?.length,a=this.query!==""||this.expandedValues.has(i.value);if(e==="right"){if(n&&!a)return this.expandedValues.add(i.value),this.renderList(),!0;if(n){let o=this.navItems.findIndex(l=>l.kind==="option"&&l.parentValue===i.value);if(o>=0)return this.focusNavIndex(o),!0}return!1}if(n&&a&&this.query==="")return this.expandedValues.delete(i.value),this.renderList(),!0;if(s){let o=this.navItems.findIndex(l=>l.kind==="option"&&l.option.value===s);if(o>=0)return this.focusNavIndex(o),!0}return!1}updateActiveDescendant(){let e=this.searchInput??this.control;this.highlightedIndex>=0?e.setAttribute("aria-activedescendant",`${this.uid}-nav-${this.highlightedIndex}`):e.removeAttribute("aria-activedescendant")}scheduleRemoteLoad(e,t){this.ajaxTimer&&clearTimeout(this.ajaxTimer);let i=++this.ajaxRequestId;this.ajaxController?.abort(),this.ajaxController=null,this.page=0,this.hasMore=!0,this.loading=!0,this.loadingMore=!1,this.loadError=null,this.renderList(),this.ajaxTimer=setTimeout(()=>{this.ajaxTimer=null,this.loadRemote(e,{requestId:i})},t)}maybeLoadNextPage(){if(!this.opts.ajax?.pagination||!this.hasMore||this.loading||this.loadingMore)return;let{scrollHeight:t,scrollTop:i,clientHeight:s}=this.list,n=this.opts.itemHeight*2;t-i-s>=n||(this.loadingMore=!0,this.renderList(),this.loadRemote(this.query,{append:!0}))}async loadRemote(e,{append:t=!1,requestId:i}={}){let s=this.opts.ajax,n=i??++this.ajaxRequestId;if(n!==this.ajaxRequestId)return;this.ajaxController?.abort();let a=new AbortController;this.ajaxController=a;let o=t?this.page+1:0;try{let l=_(s,e,o),h=await fetch(l,{signal:a.signal});if(h.ok===!1)throw new Error(`ForgeSelect: remote request failed with HTTP ${h.status}`);let f=await h.json();if(n!==this.ajaxRequestId||this.destroyed)return;let{options:d,hasMore:c}=R(s,f);if(t){let m=N(this.data);this.data=[...this.data,...d.filter(g=>!m.has(g.value))]}else this.data=d,this.rowContentCache.clear();this.page=o,this.hasMore=c,this.remoteLoaded=!0,this.loadError=null}catch(l){if(n!==this.ajaxRequestId||this.destroyed||a.signal.aborted)return;let h=l instanceof Error?l:new Error(String(l));t||(this.data=[],this.rowContentCache.clear()),this.hasMore=!1,this.loadError=h,this.emitter.emit("error",h)}finally{n===this.ajaxRequestId&&!this.destroyed&&(this.ajaxController=null,this.loading=!1,this.loadingMore=!1,this.isOpen&&this.renderList())}}};return B(X);})();
|
|
1
|
+
"use strict";var ForgeSelectBundle=(()=>{var E=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var B=(o,t)=>{for(var e in t)E(o,e,{get:t[e],enumerable:!0})},$=(o,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of j(t))!P.call(o,i)&&i!==e&&E(o,i,{get:()=>t[i],enumerable:!(s=F(t,i))||s.enumerable});return o};var U=o=>$(E({},"__esModule",{value:!0}),o);var W={};B(W,{ForgeSelect:()=>f,default:()=>f});var b=class{constructor(){this.handlers=new Map}on(t,e){let s=this.handlers.get(t);s||(s=new Set,this.handlers.set(t,s)),s.add(e)}off(t,e){this.handlers.get(t)?.delete(e)}emit(t,...e){let s=this.handlers.get(t);if(s)for(let i of[...s])i(...e)}clear(){this.handlers.clear()}};function D(o,t,e,s=4){let i=e-o.bottom,r=o.top,n=t>i&&r>i;return{dropUp:n,top:n?o.top-t-s:o.bottom+s}}var O={en:{noResults:"No results found",loading:"Loading\u2026",loadingMore:"Loading more\u2026",errorLoading:"Could not load options",createOption:'Create "{query}"',clearSelection:"Clear selection",removeItem:"Remove {label}",search:"Search",reorderHint:"{label}. Press Alt+Left or Alt+Right to reorder.",minSearchLength:"Type {count} or more characters to search",maximumSelected:"Maximum of {count} selections reached"},vi:{noResults:"Kh\xF4ng t\xECm th\u1EA5y k\u1EBFt qu\u1EA3",loading:"\u0110ang t\u1EA3i\u2026",loadingMore:"\u0110ang t\u1EA3i th\xEAm\u2026",errorLoading:"Kh\xF4ng th\u1EC3 t\u1EA3i t\xF9y ch\u1ECDn",createOption:'T\u1EA1o "{query}"',clearSelection:"X\xF3a l\u1EF1a ch\u1ECDn",removeItem:"X\xF3a {label}",search:"T\xECm ki\u1EBFm",reorderHint:"{label}. Nh\u1EA5n Alt+Tr\xE1i ho\u1EB7c Alt+Ph\u1EA3i \u0111\u1EC3 s\u1EAFp x\u1EBFp l\u1EA1i.",minSearchLength:"Nh\u1EADp th\xEAm {count} k\xFD t\u1EF1 \u0111\u1EC3 t\xECm ki\u1EBFm",maximumSelected:"\u0110\xE3 \u0111\u1EA1t t\u1ED1i \u0111a {count} l\u1EF1a ch\u1ECDn"}};function _(o){return typeof o=="string"?O[o]??O.en:{...O.en,...o}}function u(o,t){return o.replace(/\{(\w+)\}/g,(e,s)=>t[s]??e)}function H(o){let t=[];for(let e of Array.from(o.children))e instanceof HTMLOptGroupElement?t.push({label:e.label,options:Array.from(e.querySelectorAll("option")).map(M)}):e instanceof HTMLOptionElement&&t.push(M(e));return t}function M(o){let t=o.parentElement instanceof HTMLOptGroupElement&&o.parentElement.disabled;return{value:o.value,label:o.textContent?.trim()??o.value,disabled:o.disabled||t||void 0}}function x(o,t,e,s="row"){if(e){let i=e(t);typeof i=="string"?o.innerHTML=i:o.append(i);return}if(!t.avatar&&!t.description){o.textContent=t.label;return}if(t.avatar){let i=document.createElement("img");i.className=s==="row"?"forge-select__option-avatar":"forge-select__inline-avatar",i.src=t.avatar,i.alt="",i.setAttribute("loading","lazy"),i.setAttribute("decoding","async"),o.append(i)}if(s==="row"&&t.description){let i=document.createElement("span");i.className="forge-select__option-body";let r=document.createElement("span");r.className="forge-select__option-label",r.textContent=t.label;let n=document.createElement("span");n.className="forge-select__option-desc",n.textContent=t.description,i.append(r,n),o.append(i)}else{let i=document.createElement("span");i.className="forge-select__option-label",i.textContent=t.label,o.append(i)}}function R(o,t,e){if(!o.url)throw new Error("ForgeSelect: ajax requires either url or request.");if(typeof o.url=="function")return o.url(t,e);if(!o.params)return o.url;let s=new URLSearchParams;for(let[r,n]of Object.entries(o.params(t,e)))s.set(r,String(n));let i=o.url.includes("?")?"&":"?";return`${o.url}${i}${s.toString()}`}function k(o,t){let e=o.transform?o.transform(t):t;if(Array.isArray(e))return{options:e,hasMore:!1};if(!e||!Array.isArray(e.options))throw new Error("ForgeSelect: ajax.transform must return an array of options, or an object shaped like { options: Option[], hasMore?: boolean }.");return{options:e.options,hasMore:o.pagination?!!e.hasMore:!1}}function p(o){return o.options!==void 0}var w=o=>!!o.disabled;function v(o,t=w){if(!o.children)return[];let e=[];for(let s of o.children)t(s)||e.push(s.value),e.push(...v(s,t));return e}function y(o,t,e=w){if(!o.children?.length)return t.includes(o.value)?"all":"none";let s=o.children.filter(i=>!e(i)).map(i=>y(i,t,e));return s.length===0?"none":s.every(i=>i==="all")?"all":s.every(i=>i==="none")?"none":"some"}function N(o,t){let e=s=>{for(let i of s){if(i.value===t)return i;let r=i.children?e(i.children):void 0;if(r)return r}};for(let s of o){let i=e(p(s)?s.options:[s]);if(i)return i}}function L(o,t,e=w){let s=i=>{if(!i.children?.length)return;for(let a of i.children)s(a);let r=y(i,t,e),n=t.indexOf(i.value);r==="all"&&n===-1?t.push(i.value):r!=="all"&&n!==-1&&t.splice(n,1)};for(let i of o)(p(i)?i.options:[i]).forEach(s)}function I(o){let t=new Set,e=s=>{t.add(s.value),s.children?.forEach(e)};for(let s of o)(p(s)?s.options:[s]).forEach(e);return t}function V(o,t){return o.length===t.length&&o.every((e,s)=>e===t[s])}var G=36,q=5,z=100,K=2e3,X=0,f=class{constructor(t,e={}){this.selected=[];this.selectedOptions=new Map;this.suppressNextTagClick=!1;this.emitter=new b;this.uid=`forge-select-${++X}`;this.searchInput=null;this.portalHost=null;this.isOpen=!1;this.isDisabled=!1;this.destroyed=!1;this.query="";this.rows=[];this.navItems=[];this.highlightedIndex=-1;this.rowContentCache=new Map;this.expandedValues=new Set;this.loading=!1;this.loadingMore=!1;this.page=0;this.hasMore=!0;this.ajaxTimer=null;this.ajaxRequestId=0;this.ajaxController=null;this.remoteLoaded=!1;this.loadError=null;this.originalDisplay="";this.originalDisabled=!1;this.nativeSelect=null;this.nativeForm=null;this.syncingNative=!1;this.isOptionDisabled=t=>t.disabled===!0||(this.opts.isOptionDisabled?.(t)??!1);this.pointerDownOnControl=!1;this.onDocumentMouseDown=t=>{let e=t.target;!this.root.contains(e)&&!this.portalHost?.contains(e)&&this.close()};this.onWindowResize=()=>{this.positionDropdown()};this.onAncestorScroll=()=>{this.portalHost&&this.positionDropdown()};this.onNativeInvalid=t=>{t.preventDefault(),this.control.classList.add("forge-select__control--invalid"),this.control.setAttribute("aria-invalid","true"),this.isOpen||this.open(),this.control.focus()};this.onNativeChange=()=>{if(!this.nativeSelect||this.destroyed||this.syncingNative)return;let t=Array.from(this.nativeSelect.selectedOptions,e=>e.value);this.applyNativeValues(t)};this.onFormReset=()=>{if(!this.nativeSelect||this.destroyed)return;let t=Array.from(this.nativeSelect.options).filter(e=>e.defaultSelected).map(e=>e.value);this.applyNativeValues(t)};let s=typeof t=="string"?document.querySelector(t):t;if(!s)throw new Error(`ForgeSelect: target element not found: ${String(t)}`);this.el=s;let i=s instanceof HTMLSelectElement?s:null;if(this.nativeSelect=i,this.nativeForm=i?.form??null,this.originalDisplay=s.style.display,this.originalDisabled=i?.disabled??!1,this.opts={placeholder:e.placeholder??"",searchable:e.searchable??!0,multiple:e.multiple??i?.multiple??!1,clearable:e.clearable??!1,allowCreate:e.allowCreate??!1,sortable:e.sortable??!1,closeOnSelect:e.closeOnSelect??!1,maxSelections:e.maxSelections==null||!Number.isFinite(e.maxSelections)?void 0:Math.max(0,Math.floor(e.maxSelections)),theme:e.theme??"default",disabled:e.disabled??i?.disabled??!1,required:e.required??i?.required??!1,data:e.data,ajax:e.ajax,templateResult:e.templateResult,templateSelection:e.templateSelection,filterOption:e.filterOption,minSearchLength:Math.max(0,Math.floor(e.minSearchLength??0)),minResultsForSearch:Math.max(0,Math.floor(e.minResultsForSearch??0)),isOptionDisabled:e.isOptionDisabled,virtualScroll:e.virtualScroll,itemHeight:e.itemHeight??G,language:e.language??"en",plugins:e.plugins??[],openOnFocus:e.openOnFocus??!1,dropdownParent:e.dropdownParent},this.strings=_(this.opts.language),this.plugins=this.opts.plugins,i&&(i.required=this.opts.required),this.data=this.opts.data??(i?H(i):[]),i&&!this.opts.data){let r=Array.from(i.options),n=i.multiple||i.selectedIndex>0||r.some(a=>a.defaultSelected);for(let a of r)n&&a.selected&&this.selectValue(a.value,!1)}this.buildDom(),this.renderValue(),this.opts.disabled&&this.disable(),i?.addEventListener("change",this.onNativeChange),i?.addEventListener("invalid",this.onNativeInvalid),this.nativeForm?.addEventListener("reset",this.onFormReset);for(let r of this.plugins)r.onInit?.(this)}applyNativeValues(t){this.selected=[];for(let e of this.opts.multiple?t:t.slice(0,1))this.selectValue(e,!1);this.renderValue(),this.isOpen&&this.renderList(),this.emitter.emit("change",this.getValue())}open(){if(!(this.isOpen||this.isDisabled||this.destroyed)){this.isOpen=!0,this.dropdown.hidden=!1,this.root.classList.add("forge-select--open"),this.control.setAttribute("aria-expanded","true"),document.addEventListener("mousedown",this.onDocumentMouseDown),this.opts.ajax&&!this.remoteLoaded&&this.scheduleRemoteLoad(this.query,0),this.renderList(),this.positionDropdown(),window.addEventListener("resize",this.onWindowResize),document.addEventListener("scroll",this.onAncestorScroll,!0),this.searchInput&&!this.searchInput.hidden&&this.searchInput.focus(),this.emitter.emit("open");for(let t of this.plugins)t.onOpen?.(this)}}close(){if(this.isOpen){this.isOpen=!1,this.dropdown.hidden=!0,this.root.classList.remove("forge-select--open"),this.root.classList.remove("forge-select--drop-up"),this.control.setAttribute("aria-expanded","false"),document.removeEventListener("mousedown",this.onDocumentMouseDown),window.removeEventListener("resize",this.onWindowResize),document.removeEventListener("scroll",this.onAncestorScroll,!0),this.highlightedIndex=-1,this.searchInput&&(this.searchInput.value="",this.query=""),this.emitter.emit("close");for(let t of this.plugins)t.onClose?.(this)}}positionDropdown(){let t=this.control.getBoundingClientRect(),e=D(t,this.dropdown.offsetHeight,window.innerHeight);this.root.classList.toggle("forge-select--drop-up",e.dropUp),this.portalHost&&(this.portalHost.style.top=`${e.top}px`,this.portalHost.style.left=`${t.left}px`,this.portalHost.style.width=`${t.width}px`)}destroy(){if(!this.destroyed){this.close();for(let t of this.plugins)t.onDestroy?.(this);this.destroyed=!0,this.ajaxTimer&&clearTimeout(this.ajaxTimer),this.ajaxController?.abort(),this.nativeSelect?.removeEventListener("change",this.onNativeChange),this.nativeSelect?.removeEventListener("invalid",this.onNativeInvalid),this.nativeForm?.removeEventListener("reset",this.onFormReset),this.rowContentCache.clear(),this.portalHost?.remove(),this.root.remove(),this.el.style.display=this.originalDisplay,this.nativeSelect&&(this.nativeSelect.disabled=this.originalDisabled),this.emitter.clear()}}getValue(){return this.opts.multiple?[...this.selected]:this.selected[0]??null}setValue(t,e={}){let s=t==null?[]:Array.isArray(t)?t:[t],i=this.opts.multiple?s:s.slice(0,1);if(!V(i,this.selected)){this.selected=[];for(let r of i)this.selectValue(r,!1);this.afterSelectionChange(e.emitChange??!0)}}setData(t){this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.ajaxController=null,this.ajaxRequestId+=1,this.loading=!1,this.loadingMore=!1,this.loadError=null,this.remoteLoaded=!0,this.page=0,this.hasMore=!1,this.data=t,this.opts.data=t,this.updateSearchVisibility(),this.rowContentCache.clear(),this.highlightedIndex=-1,this.isOpen&&this.renderList()}selectAll(){if(this.opts.multiple){this.selected=[];for(let t of this.allSelectableValues()){let e=this.findOption(t);e&&this.canSelectOption(e)&&this.selectValue(t,!1)}this.afterSelectionChange()}}clearAll(){this.clearSelection()}enable(){this.isDisabled=!1,this.root.classList.remove("forge-select--disabled"),this.control.tabIndex=0,this.control.setAttribute("aria-disabled","false"),this.nativeSelect&&(this.nativeSelect.disabled=!1)}disable(){this.close(),this.isDisabled=!0,this.root.classList.add("forge-select--disabled"),this.control.tabIndex=-1,this.control.setAttribute("aria-disabled","true"),this.nativeSelect&&(this.nativeSelect.disabled=!0)}on(t,e){this.emitter.on(t,e)}off(t,e){this.emitter.off(t,e)}applyAccessibleName(){let t=this.el.getAttribute("aria-labelledby"),e=this.el.getAttribute("aria-label");if(t)this.control.setAttribute("aria-labelledby",t);else if(e)this.control.setAttribute("aria-label",e);else if(this.el.id){let s=Array.from(document.getElementsByTagName("label")).find(i=>i.htmlFor===this.el.id);s&&(s.id||(s.id=`${this.uid}-label`),this.control.setAttribute("aria-labelledby",s.id))}}shouldShowSearch(){return this.opts.searchable&&(this.opts.ajax!=null||I(this.data).size>=this.opts.minResultsForSearch)}updateSearchVisibility(){this.searchInput&&(this.searchInput.hidden=!this.shouldShowSearch(),this.searchInput.hidden&&(this.searchInput.value="",this.query=""))}buildDom(){let t=typeof this.opts.dropdownParent=="string"?document.querySelector(this.opts.dropdownParent):this.opts.dropdownParent;if(this.opts.dropdownParent&&!t)throw new Error(`ForgeSelect: dropdown parent not found: ${String(this.opts.dropdownParent)}`);this.root=document.createElement("div"),this.root.className="forge-select",this.root.dataset.theme=this.opts.theme,this.root.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.opts.sortable&&this.opts.multiple&&this.root.classList.add("forge-select--sortable"),this.control=document.createElement("div"),this.control.className="forge-select__control",this.control.setAttribute("role","combobox"),this.control.setAttribute("aria-haspopup","listbox"),this.control.setAttribute("aria-expanded","false"),this.control.setAttribute("aria-controls",`${this.uid}-list`),this.opts.required&&this.control.setAttribute("aria-required","true"),this.control.tabIndex=0,this.applyAccessibleName(),this.valueEl=document.createElement("div"),this.valueEl.className="forge-select__value",this.clearBtn=document.createElement("button"),this.clearBtn.type="button",this.clearBtn.className="forge-select__clear",this.clearBtn.setAttribute("aria-label",this.strings.clearSelection),this.clearBtn.textContent="\xD7",this.clearBtn.hidden=!0;let e=document.createElement("span");e.className="forge-select__arrow",e.setAttribute("aria-hidden","true"),this.control.append(this.valueEl,this.clearBtn,e),this.dropdown=document.createElement("div"),this.dropdown.className="forge-select__dropdown",this.dropdown.hidden=!0,this.opts.searchable&&(this.searchInput=document.createElement("input"),this.searchInput.type="search",this.searchInput.className="forge-select__search",this.searchInput.setAttribute("aria-label",this.strings.search),this.searchInput.setAttribute("aria-autocomplete","list"),this.searchInput.setAttribute("aria-controls",`${this.uid}-list`),this.searchInput.hidden=!this.shouldShowSearch(),this.dropdown.append(this.searchInput)),this.list=document.createElement("ul"),this.list.className="forge-select__list",this.list.id=`${this.uid}-list`,this.list.setAttribute("role","listbox"),this.opts.multiple&&this.list.setAttribute("aria-multiselectable","true"),this.dropdown.append(this.list),this.liveRegion=document.createElement("div"),this.liveRegion.className="forge-select__sr-only",this.liveRegion.setAttribute("role","status"),this.liveRegion.setAttribute("aria-live","polite"),this.root.append(this.control,this.liveRegion),t||this.root.append(this.dropdown),this.el.style.display="none",this.el.insertAdjacentElement("afterend",this.root),t&&(this.portalHost=document.createElement("div"),this.portalHost.className="forge-select forge-select--portal-host",this.portalHost.dataset.theme=this.opts.theme,this.portalHost.style.setProperty("--fs-item-height",`${this.opts.itemHeight}px`),this.portalHost.append(this.dropdown),t.append(this.portalHost)),this.bindEvents()}bindEvents(){this.control.addEventListener("click",t=>{if(t.target!==this.clearBtn){if(this.suppressNextTagClick){this.suppressNextTagClick=!1;return}this.isDisabled||(this.isOpen?this.close():this.open())}}),this.control.addEventListener("keydown",t=>this.handleKeydown(t)),this.control.addEventListener("mousedown",()=>{this.pointerDownOnControl=!0}),this.control.addEventListener("focus",()=>{this.opts.openOnFocus&&!this.pointerDownOnControl&&!this.isOpen&&!this.isDisabled&&this.open(),this.pointerDownOnControl=!1}),this.clearBtn.addEventListener("click",t=>{t.stopPropagation(),this.clearSelection()}),this.searchInput&&(this.searchInput.addEventListener("input",()=>{this.query=this.searchInput.value,this.highlightedIndex=-1,this.list.scrollTop=0,this.emitter.emit("search",this.query);let t=this.query.trim(),e=t!==""&&t.length<this.opts.minSearchLength;this.opts.ajax&&!e?this.scheduleRemoteLoad(this.query,this.opts.ajax.debounce??250):(e&&(this.ajaxTimer&&(clearTimeout(this.ajaxTimer),this.ajaxTimer=null),this.ajaxController?.abort(),this.loading=!1),this.renderList())}),this.searchInput.addEventListener("keydown",t=>this.handleKeydown(t)),this.searchInput.addEventListener("paste",t=>{if(!this.opts.multiple||!this.opts.allowCreate)return;let s=(t.clipboardData?.getData("text")??"").split(/[,\n]+/).map(r=>r.trim()).filter(Boolean);if(s.length<2)return;t.preventDefault();let i=[];for(let r of s){let n=this.createTag(r);n&&i.push(n)}if(i.length!==0){this.searchInput.value="",this.query="",this.afterSelectionChange();for(let r of i)r.created&&this.emitter.emit("create",r.option),this.emitter.emit("select",r.option);this.opts.closeOnSelect?this.close():this.renderList()}})),this.list.addEventListener("click",t=>{let e=t.target,s=e.closest("[data-twisty]");if(s){let n=s.dataset.twisty;this.expandedValues.has(n)?this.expandedValues.delete(n):this.expandedValues.add(n),this.renderList();return}let i=e.closest("li[data-nav-index]");if(!i){let n=e.closest("li[data-option-value]"),a=n?this.findOption(n.dataset.optionValue):void 0;a&&this.hasReachedMaximum()&&!this.selected.includes(a.value)&&this.announceMaximum(a);return}let r=Number(i.dataset.navIndex);this.activateNavItem(r)}),this.list.addEventListener("scroll",()=>{this.usesVirtualScroll()&&this.renderRows(),this.maybeLoadNextPage()})}handleKeydown(t){if(!this.isDisabled)switch(t.key){case"Enter":t.preventDefault(),this.isOpen?this.highlightedIndex>=0&&this.activateNavItem(this.highlightedIndex):this.open();break;case" ":t.target===this.control&&(t.preventDefault(),this.isOpen||this.open());break;case"ArrowDown":t.preventDefault(),this.isOpen?this.moveHighlight(1):this.open();break;case"ArrowUp":t.preventDefault(),this.isOpen&&this.moveHighlight(-1);break;case"Escape":this.isOpen&&(t.preventDefault(),this.close(),this.control.focus());break;case"ArrowRight":this.isOpen&&this.navigateTree("right")&&t.preventDefault();break;case"ArrowLeft":this.isOpen&&this.navigateTree("left")&&t.preventDefault();break;case"Tab":this.close();break}}canSelectOption(t){if(this.opts.maxSelections==null)return!0;let e=[...this.selected];e.includes(t.value)||e.push(t.value);for(let s of v(t,this.isOptionDisabled))e.includes(s)||e.push(s);return L(this.data,e,this.isOptionDisabled),e.length<=this.opts.maxSelections}hasReachedMaximum(){return this.opts.maxSelections!=null&&this.selected.length>=this.opts.maxSelections}announceMaximum(t){let e=this.opts.maxSelections;e!=null&&(this.liveRegion.textContent=u(this.strings.maximumSelected,{count:String(e)}),this.emitter.emit("maximum",{limit:e,option:t}))}selectValue(t,e){if(this.selected.includes(t))return;let s=this.findOption(t)??this.selectedOptions.get(t)??{value:t,label:t};if(this.selectedOptions.set(t,s),this.opts.multiple){this.selected.push(t);for(let i of v(s,this.isOptionDisabled))this.selected.includes(i)||this.selected.push(i);this.syncTreeAncestors()}else this.selected=[t];e&&(this.afterSelectionChange(),this.emitter.emit("select",s))}deselectValue(t,e){let s=this.selected.indexOf(t);if(s===-1)return;let i=this.findOption(t)??this.selectedOptions.get(t);if(this.selected.splice(s,1),this.opts.multiple){if(i)for(let r of v(i,this.isOptionDisabled)){let n=this.selected.indexOf(r);n!==-1&&this.selected.splice(n,1)}this.syncTreeAncestors()}e&&(this.afterSelectionChange(),this.emitter.emit("unselect",i??{value:t,label:t}))}syncTreeAncestors(){L(this.data,this.selected,this.isOptionDisabled)}clearSelection(){this.selected.length!==0&&(this.selected=[],this.emitter.emit("clear"),this.afterSelectionChange())}allSelectableValues(){let t=[],e=s=>{this.isOptionDisabled(s)||t.push(s.value),s.children?.forEach(e)};for(let s of this.data)(p(s)?s.options:[s]).forEach(e);return t}afterSelectionChange(t=!0){this.renderValue(),this.syncNativeSelect(t),(!this.opts.required||this.selected.length>0)&&(this.control.classList.remove("forge-select__control--invalid"),this.control.removeAttribute("aria-invalid")),this.isOpen&&this.renderList(),t&&this.emitter.emit("change",this.getValue())}syncNativeSelect(t=!0){if(!(this.el instanceof HTMLSelectElement))return;let e=new Set;for(let s of Array.from(this.el.options))e.add(s.value),s.selected=this.selected.includes(s.value);for(let s of this.selected){if(e.has(s))continue;let i=document.createElement("option");i.value=s,i.textContent=this.selectedOptions.get(s)?.label??s,i.selected=!0,this.el.append(i)}if(this.opts.sortable&&this.opts.multiple)for(let s of this.selected){let i=Array.from(this.el.options).find(r=>r.value===s);i&&this.el.append(i)}if(t){this.syncingNative=!0;try{this.el.dispatchEvent(new Event("change",{bubbles:!0}))}finally{this.syncingNative=!1}}}findOption(t){return N(this.data,t)}findOptionByLabel(t){let e=t.toLowerCase(),s=i=>{for(let r of i){if(r.label.toLowerCase()===e)return r;let n=r.children?s(r.children):void 0;if(n)return n}};for(let i of this.data){let r=s(p(i)?i.options:[i]);if(r)return r}}createTag(t){let e=t.trim();if(!e)return;let s=this.findOptionByLabel(e);if(s){if(this.selected.includes(s.value))return;if(this.opts.multiple&&!this.canSelectOption(s)){this.announceMaximum(s);return}return this.selectValue(s.value,!1),{option:s,created:!1}}let i={value:e,label:e};if(this.opts.multiple&&!this.canSelectOption(i)){this.announceMaximum(i);return}return this.data.push(i),this.selectValue(i.value,!1),{option:i,created:!0}}createFromQuery(){let t=this.query.trim();if(!t)return;let e=this.createTag(t);e&&(this.searchInput&&(this.searchInput.value="",this.query=""),this.afterSelectionChange(),e.created&&this.emitter.emit("create",e.option),this.emitter.emit("select",e.option),(!this.opts.multiple||this.opts.closeOnSelect)&&this.close())}activateNavItem(t){let e=this.navItems[t];if(!e)return;if(e.kind==="create"){this.createFromQuery();return}let{value:s}=e.option;if(this.opts.multiple){let i=!1;this.selected.includes(s)?(this.deselectValue(s,!0),i=!0):this.canSelectOption(e.option)?(this.selectValue(s,!0),i=!0):this.announceMaximum(e.option),i&&this.opts.closeOnSelect&&this.close()}else this.selectValue(s,!0),this.close(),this.control.focus()}renderValue(){this.valueEl.textContent="";let t=this.selected.length>0;if(this.clearBtn.hidden=!(this.opts.clearable&&t),!t){let e=document.createElement("span");e.className="forge-select__placeholder",e.textContent=this.opts.placeholder,this.valueEl.append(e);return}if(this.opts.multiple)for(let e of this.selected){let s=this.selectedOptions.get(e)??{value:e,label:e},i=document.createElement("span");i.className="forge-select__tag";let r=document.createElement("span");r.className="forge-select__tag-label",x(r,s,this.opts.templateSelection,"inline");let n=document.createElement("button");n.type="button",n.className="forge-select__tag-remove",n.setAttribute("aria-label",u(this.strings.removeItem,{label:s.label})),n.textContent="\xD7",n.addEventListener("click",a=>{a.stopPropagation(),this.isDisabled||this.deselectValue(e,!0)}),i.append(r,n),this.opts.sortable&&(i.dataset.value=e,i.tabIndex=0,i.setAttribute("aria-roledescription","draggable item"),i.setAttribute("aria-label",u(this.strings.reorderHint,{label:s.label})),i.addEventListener("keydown",a=>this.handleTagKeydown(a,e)),this.bindTagDrag(i,e)),this.valueEl.append(i)}else{let e=this.selectedOptions.get(this.selected[0])??{value:this.selected[0],label:this.selected[0]},s=document.createElement("span");s.className="forge-select__single-value",x(s,e,this.opts.templateSelection,"inline"),this.valueEl.append(s)}}bindTagDrag(t,e){let i=0,r=!1,n=[],a=h=>{if(!r){if(Math.abs(h.clientX-i)<4)return;r=!0,n=[...this.selected],typeof this.valueEl.setPointerCapture=="function"&&this.valueEl.setPointerCapture(h.pointerId),t.classList.add("forge-select__tag--dragging")}h.preventDefault();let m=n.indexOf(e),d=Array.from(this.valueEl.querySelectorAll(".forge-select__tag"));for(let c of d){if(c===t)continue;let g=c.dataset.value;if(!g)continue;let S=n.indexOf(g);if(S===-1)continue;let C=c.getBoundingClientRect(),A=C.left+C.width/2,T=m<S;if(T?h.clientX>A:h.clientX<A){n.splice(m,1),n.splice(S,0,e),T?this.valueEl.insertBefore(t,c.nextSibling):this.valueEl.insertBefore(t,c);break}}},l=h=>{this.valueEl.removeEventListener("pointermove",a),this.valueEl.removeEventListener("pointerup",l),this.valueEl.removeEventListener("pointercancel",l),r&&(typeof this.valueEl.releasePointerCapture=="function"&&this.valueEl.releasePointerCapture(h.pointerId),t.classList.remove("forge-select__tag--dragging"),this.selected=n,this.suppressNextTagClick=!0,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]))};t.addEventListener("pointerdown",h=>{this.isDisabled||h.button!==0||h.target.closest(".forge-select__tag-remove")||(i=h.clientX,r=!1,this.valueEl.addEventListener("pointermove",a),this.valueEl.addEventListener("pointerup",l),this.valueEl.addEventListener("pointercancel",l))})}handleTagKeydown(t,e){if(!t.altKey||t.key!=="ArrowLeft"&&t.key!=="ArrowRight")return;let s=this.selected.indexOf(e),i=t.key==="ArrowLeft"?s-1:s+1;if(s===-1||i<0||i>=this.selected.length)return;t.preventDefault(),t.stopPropagation();let r=[...this.selected];[r[s],r[i]]=[r[i],r[s]],this.selected=r,this.afterSelectionChange(),this.emitter.emit("reorder",[...this.selected]),this.focusTagByValue(e)}focusTagByValue(t){for(let e of Array.from(this.valueEl.querySelectorAll(".forge-select__tag")))if(e.dataset.value===t){e.focus();return}}buildRows(){this.rows=[],this.navItems=[];let t=this.query.trim(),e=t.toLowerCase(),s=n=>e===""||(this.opts.filterOption?this.opts.filterOption(n,t):n.label.toLowerCase().includes(e)||(n.description?.toLowerCase().includes(e)??!1)),i=n=>e===""||s(n)||(n.children??[]).some(i),r=(n,a,l)=>{let h=-1;this.isOptionDisabled(n)||this.hasReachedMaximum()&&!this.selected.includes(n.value)||(h=this.navItems.length,this.navItems.push({kind:"option",option:n,parentValue:l}));let d=!!n.children&&n.children.length>0;if(this.rows.push({kind:"option",option:n,navIndex:h,depth:a,hasChildren:d}),d&&(e!==""||this.expandedValues.has(n.value)))for(let g of n.children)i(g)&&r(g,a+1,n.value)};if(t!==""&&t.length<this.opts.minSearchLength){this.rows.push({kind:"min-length"});return}if(this.loading){this.rows.push({kind:"loading"});return}if(this.loadError){this.rows.push({kind:"error"});return}for(let n of this.data)if(p(n)){let a=n.options.filter(i);if(a.length===0)continue;this.rows.push({kind:"group",label:n.label}),a.forEach(l=>r(l,0))}else i(n)&&r(n,0);if(this.opts.allowCreate&&e!==""&&!this.hasExactMatch(e)){let n=this.navItems.length;this.navItems.push({kind:"create"}),this.rows.push({kind:"create",navIndex:n})}this.rows.length===0?this.rows.push({kind:"empty"}):this.loadingMore&&this.rows.push({kind:"loading-more"})}hasExactMatch(t){return!!this.findOptionByLabel(t)}usesVirtualScroll(){return this.opts.virtualScroll!==!1&&this.rows.length>z}renderList(){this.buildRows(),this.renderRows(),this.announceStatus()}announceStatus(){let t=this.rows[0],e=this.hasReachedMaximum()?u(this.strings.maximumSelected,{count:String(this.opts.maxSelections)}):t?.kind==="loading"?this.strings.loading:t?.kind==="error"?this.strings.errorLoading:t?.kind==="empty"?this.strings.noResults:t?.kind==="min-length"?u(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)}):"";this.liveRegion.textContent!==e&&(this.liveRegion.textContent=e)}renderRows(){let t=this.list.scrollTop,e=this.list.clientHeight,s=this.usesVirtualScroll();this.list.textContent="";let i=this.opts.itemHeight,r=0,n=this.rows.length;if(s){let a=e||i*8;r=Math.max(0,Math.floor(t/i)-q),n=Math.min(this.rows.length,r+Math.ceil(a/i)+q*2);let l=document.createElement("li");l.className="forge-select__spacer",l.setAttribute("aria-hidden","true"),l.style.height=`${r*i}px`,this.list.append(l)}for(let a=r;a<n;a++)this.list.append(this.renderRow(this.rows[a]));if(s){let a=document.createElement("li");a.className="forge-select__spacer",a.setAttribute("aria-hidden","true"),a.style.height=`${(this.rows.length-n)*i}px`,this.list.append(a),this.list.scrollTop!==t&&(this.list.scrollTop=t)}this.updateActiveDescendant()}renderRow(t){let e=document.createElement("li");switch(t.kind){case"group":e.className="forge-select__group-label",e.setAttribute("role","presentation"),e.textContent=t.label;break;case"empty":e.className="forge-select__empty",e.setAttribute("role","option"),e.setAttribute("aria-disabled","true"),e.setAttribute("aria-selected","false"),e.textContent=this.strings.noResults;break;case"min-length":e.className="forge-select__min-length",e.setAttribute("role","option"),e.setAttribute("aria-disabled","true"),e.setAttribute("aria-selected","false"),e.textContent=u(this.strings.minSearchLength,{count:String(this.opts.minSearchLength)});break;case"error":e.className="forge-select__error",e.setAttribute("role","option"),e.setAttribute("aria-disabled","true"),e.setAttribute("aria-selected","false"),e.textContent=this.strings.errorLoading;break;case"loading":e.className="forge-select__loading",e.setAttribute("role","option"),e.setAttribute("aria-disabled","true"),e.setAttribute("aria-selected","false"),e.textContent=this.strings.loading;break;case"loading-more":e.className="forge-select__loading-more",e.setAttribute("aria-hidden","true"),e.textContent=this.strings.loadingMore;break;case"create":e.className="forge-select__option forge-select__option--create",e.setAttribute("role","option"),e.id=`${this.uid}-nav-${t.navIndex}`,e.dataset.navIndex=String(t.navIndex),e.textContent=u(this.strings.createOption,{query:this.query.trim()}),t.navIndex===this.highlightedIndex&&e.classList.add("forge-select__option--highlighted");break;case"option":{e.className="forge-select__option",e.dataset.optionValue=t.option.value,t.option.className&&e.classList.add(...t.option.className.trim().split(/\s+/).filter(Boolean)),e.setAttribute("role","option");let s=this.selected.includes(t.option.value);if(e.setAttribute("aria-selected",String(s)),s&&e.classList.add("forge-select__option--selected"),this.opts.multiple&&t.hasChildren&&y(t.option,this.selected,this.isOptionDisabled)==="some"&&e.classList.add("forge-select__option--indeterminate"),t.depth>0&&(e.style.paddingLeft=`calc(12px + ${t.depth} * var(--fs-tree-indent, 18px))`),this.isOptionDisabled(t.option)||this.hasReachedMaximum()&&!this.selected.includes(t.option.value)?(e.classList.add("forge-select__option--disabled"),e.setAttribute("aria-disabled","true")):(e.id=`${this.uid}-nav-${t.navIndex}`,e.dataset.navIndex=String(t.navIndex),t.navIndex===this.highlightedIndex&&e.classList.add("forge-select__option--highlighted")),t.hasChildren){let i=this.query!==""||this.expandedValues.has(t.option.value);e.setAttribute("aria-expanded",String(i));let r=document.createElement("span");r.className="forge-select__twisty",r.dataset.twisty=t.option.value,r.setAttribute("aria-hidden","true"),r.textContent=i?"\u25BC":"\u25B6",e.append(r)}e.append(this.optionContent(t.option));break}}return e}optionContent(t){let e=this.rowContentCache.get(t.value);if(!e){let s=document.createElement("span");if(s.className="forge-select__option-content",x(s,t,this.opts.templateResult),this.rowContentCache.size>=K){let i=this.rowContentCache.keys().next().value;this.rowContentCache.delete(i)}this.rowContentCache.set(t.value,s),e=s}return e.cloneNode(!0)}moveHighlight(t){if(this.navItems.length===0)return;let e=this.highlightedIndex===-1?t>0?0:this.navItems.length-1:(this.highlightedIndex+t+this.navItems.length)%this.navItems.length;this.focusNavIndex(e)}focusNavIndex(t){if(this.highlightedIndex=t,this.usesVirtualScroll()){let e=this.rows.findIndex(s=>(s.kind==="option"||s.kind==="create")&&s.navIndex===t);if(e>=0){let s=this.opts.itemHeight,i=e*s,r=this.list.clientHeight||s*8,n=this.list.scrollTop;i<n?n=i:i+s>n+r&&(n=i+s-r),n!==this.list.scrollTop&&(this.list.scrollTop=n)}this.renderRows()}else this.renderRows(),this.list.querySelector(".forge-select__option--highlighted")?.scrollIntoView?.({block:"nearest"})}navigateTree(t){let e=this.navItems[this.highlightedIndex];if(!e||e.kind!=="option")return!1;let{option:s,parentValue:i}=e,r=!!s.children?.length,n=this.query!==""||this.expandedValues.has(s.value);if(t==="right"){if(r&&!n)return this.expandedValues.add(s.value),this.renderList(),!0;if(r){let a=this.navItems.findIndex(l=>l.kind==="option"&&l.parentValue===s.value);if(a>=0)return this.focusNavIndex(a),!0}return!1}if(r&&n&&this.query==="")return this.expandedValues.delete(s.value),this.renderList(),!0;if(i){let a=this.navItems.findIndex(l=>l.kind==="option"&&l.option.value===i);if(a>=0)return this.focusNavIndex(a),!0}return!1}updateActiveDescendant(){let t=this.searchInput??this.control;this.highlightedIndex>=0?t.setAttribute("aria-activedescendant",`${this.uid}-nav-${this.highlightedIndex}`):t.removeAttribute("aria-activedescendant")}scheduleRemoteLoad(t,e){this.ajaxTimer&&clearTimeout(this.ajaxTimer);let s=++this.ajaxRequestId;this.ajaxController?.abort(),this.ajaxController=null,this.page=0,this.hasMore=!0,this.loading=!0,this.loadingMore=!1,this.loadError=null,this.renderList(),this.ajaxTimer=setTimeout(()=>{this.ajaxTimer=null,this.loadRemote(t,{requestId:s})},e)}maybeLoadNextPage(){if(!this.opts.ajax?.pagination||!this.hasMore||this.loading||this.loadingMore)return;let{scrollHeight:e,scrollTop:s,clientHeight:i}=this.list,r=this.opts.itemHeight*2;e-s-i>=r||(this.loadingMore=!0,this.renderList(),this.loadRemote(this.query,{append:!0}))}async loadRemote(t,{append:e=!1,requestId:s}={}){let i=this.opts.ajax,r=s??++this.ajaxRequestId;if(r!==this.ajaxRequestId)return;this.ajaxController?.abort();let n=new AbortController;this.ajaxController=n;let a=e?this.page+1:0;try{let l;if(i.request)l=await i.request(t,a,n.signal);else{let d=R(i,t,a),c=await fetch(d,{signal:n.signal});if(c.ok===!1)throw new Error(`ForgeSelect: remote request failed with HTTP ${c.status}`);l=await c.json()}if(r!==this.ajaxRequestId||this.destroyed)return;let{options:h,hasMore:m}=k(i,l);if(e){let d=I(this.data);this.data=[...this.data,...h.filter(c=>!d.has(c.value))]}else this.data=h,this.rowContentCache.clear();this.page=a,this.hasMore=m,this.remoteLoaded=!0,this.loadError=null}catch(l){if(r!==this.ajaxRequestId||this.destroyed||n.signal.aborted)return;let h=l instanceof Error?l:new Error(String(l));e||(this.data=[],this.rowContentCache.clear()),this.hasMore=!1,this.loadError=h,this.emitter.emit("error",h)}finally{r===this.ajaxRequestId&&!this.destroyed&&(this.ajaxController=null,this.loading=!1,this.loadingMore=!1,this.isOpen&&this.renderList())}}};return U(W);})();
|
|
2
2
|
//# sourceMappingURL=index.global.js.map
|