@destyler/combobox 0.0.7-beta.7 → 0.0.7-beta.9

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/dist/index.js ADDED
@@ -0,0 +1,1401 @@
1
+ import { createAnatomy } from "@destyler/anatomy";
2
+ import { ListCollection } from "@destyler/collection";
3
+ import { createMachine, guards, ref } from "@destyler/xstate";
4
+ import { ariaAttr, clickIfLink, createScope, dataAttr, getEventKey, isAnchorElement, isComposingEvent, isContextMenuEvent, isDownloadingEvent, isLeftClick, isOpeningInNewTab, observeAttributes, observeChildren, query, raf, scrollIntoView } from "@destyler/dom";
5
+ import { getPlacement, getPlacementStyles } from "@destyler/popper";
6
+ import { ariaHidden } from "@destyler/aria-hidden";
7
+ import { trackDismissableElement } from "@destyler/dismissable";
8
+ import { addOrRemove, compact, isArray, isBoolean, isEqual, match } from "@destyler/utils";
9
+
10
+ //#region src/anatomy.ts
11
+ const anatomy = createAnatomy("combobox").parts("root", "clearTrigger", "content", "control", "input", "item", "itemGroup", "itemGroupLabel", "itemIndicator", "itemText", "label", "list", "positioner", "trigger");
12
+ const parts = anatomy.build();
13
+
14
+ //#endregion
15
+ //#region src/collection.ts
16
+ function collection(options) {
17
+ return ref(new ListCollection(options));
18
+ }
19
+ collection.empty = () => {
20
+ return ref(new ListCollection({ items: [] }));
21
+ };
22
+
23
+ //#endregion
24
+ //#region src/dom.ts
25
+ const dom = createScope({
26
+ getRootId: (ctx) => ctx.ids?.root ?? `combobox:${ctx.id}`,
27
+ getLabelId: (ctx) => ctx.ids?.label ?? `combobox:${ctx.id}:label`,
28
+ getControlId: (ctx) => ctx.ids?.control ?? `combobox:${ctx.id}:control`,
29
+ getInputId: (ctx) => ctx.ids?.input ?? `combobox:${ctx.id}:input`,
30
+ getContentId: (ctx) => ctx.ids?.content ?? `combobox:${ctx.id}:content`,
31
+ getPositionerId: (ctx) => ctx.ids?.positioner ?? `combobox:${ctx.id}:popper`,
32
+ getTriggerId: (ctx) => ctx.ids?.trigger ?? `combobox:${ctx.id}:toggle-btn`,
33
+ getClearTriggerId: (ctx) => ctx.ids?.clearTrigger ?? `combobox:${ctx.id}:clear-btn`,
34
+ getItemGroupId: (ctx, id) => ctx.ids?.itemGroup?.(id) ?? `combobox:${ctx.id}:optgroup:${id}`,
35
+ getItemGroupLabelId: (ctx, id) => ctx.ids?.itemGroupLabel?.(id) ?? `combobox:${ctx.id}:optgroup-label:${id}`,
36
+ getItemId: (ctx, id) => ctx.ids?.item?.(id) ?? `combobox:${ctx.id}:option:${id}`,
37
+ getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
38
+ getInputEl: (ctx) => dom.getById(ctx, dom.getInputId(ctx)),
39
+ getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
40
+ getControlEl: (ctx) => dom.getById(ctx, dom.getControlId(ctx)),
41
+ getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
42
+ getClearTriggerEl: (ctx) => dom.getById(ctx, dom.getClearTriggerId(ctx)),
43
+ getHighlightedItemEl: (ctx) => {
44
+ const value = ctx.highlightedValue;
45
+ if (value == null) return;
46
+ const selector = `[role=option][data-value="${CSS.escape(value)}"`;
47
+ return query(dom.getContentEl(ctx), selector);
48
+ },
49
+ focusInputEl: (ctx) => {
50
+ const inputEl = dom.getInputEl(ctx);
51
+ if (dom.isActiveElement(ctx, inputEl)) return;
52
+ inputEl?.focus({ preventScroll: true });
53
+ },
54
+ focusTriggerEl: (ctx) => {
55
+ const triggerEl = dom.getTriggerEl(ctx);
56
+ if (dom.isActiveElement(ctx, triggerEl)) return;
57
+ triggerEl?.focus({ preventScroll: true });
58
+ }
59
+ });
60
+
61
+ //#endregion
62
+ //#region src/connect.ts
63
+ function connect(state, send, normalize) {
64
+ const translations = state.context.translations;
65
+ const collection$1 = state.context.collection;
66
+ const disabled = state.context.disabled;
67
+ const interactive = state.context.isInteractive;
68
+ const invalid = state.context.invalid;
69
+ const readOnly = state.context.readOnly;
70
+ const open = state.hasTag("open");
71
+ const focused = state.hasTag("focused");
72
+ const composite = state.context.composite;
73
+ const highlightedValue = state.context.highlightedValue;
74
+ const popperStyles = getPlacementStyles({
75
+ ...state.context.positioning,
76
+ placement: state.context.currentPlacement
77
+ });
78
+ function getItemState(props) {
79
+ const disabled$1 = collection$1.getItemDisabled(props.item);
80
+ const value = collection$1.getItemValue(props.item);
81
+ return {
82
+ value,
83
+ disabled: Boolean(disabled$1 || disabled$1),
84
+ highlighted: highlightedValue === value,
85
+ selected: state.context.value.includes(value)
86
+ };
87
+ }
88
+ return {
89
+ focused,
90
+ open,
91
+ inputValue: state.context.inputValue,
92
+ highlightedValue,
93
+ highlightedItem: state.context.highlightedItem,
94
+ value: state.context.value,
95
+ valueAsString: state.context.valueAsString,
96
+ hasSelectedItems: state.context.hasSelectedItems,
97
+ selectedItems: state.context.selectedItems,
98
+ collection: state.context.collection,
99
+ multiple: !!state.context.multiple,
100
+ disabled: !!disabled,
101
+ syncSelectedItems() {
102
+ send({ type: "SELECTED_ITEMS.SYNC" });
103
+ },
104
+ reposition(options = {}) {
105
+ send({
106
+ type: "POSITIONING.SET",
107
+ options
108
+ });
109
+ },
110
+ setCollection(collection$2) {
111
+ send({
112
+ type: "COLLECTION.SET",
113
+ value: collection$2
114
+ });
115
+ },
116
+ setHighlightValue(value) {
117
+ send({
118
+ type: "HIGHLIGHTED_VALUE.SET",
119
+ value
120
+ });
121
+ },
122
+ selectValue(value) {
123
+ send({
124
+ type: "ITEM.SELECT",
125
+ value
126
+ });
127
+ },
128
+ setValue(value) {
129
+ send({
130
+ type: "VALUE.SET",
131
+ value
132
+ });
133
+ },
134
+ setInputValue(value) {
135
+ send({
136
+ type: "INPUT_VALUE.SET",
137
+ value
138
+ });
139
+ },
140
+ clearValue(value) {
141
+ if (value != null) send({
142
+ type: "ITEM.CLEAR",
143
+ value
144
+ });
145
+ else send("VALUE.CLEAR");
146
+ },
147
+ focus() {
148
+ dom.getInputEl(state.context)?.focus();
149
+ },
150
+ setOpen(nextOpen) {
151
+ if (nextOpen === open) return;
152
+ send(nextOpen ? "OPEN" : "CLOSE");
153
+ },
154
+ getRootProps() {
155
+ return normalize.element({
156
+ ...parts.root.attrs,
157
+ "dir": state.context.dir,
158
+ "id": dom.getRootId(state.context),
159
+ "data-invalid": dataAttr(invalid),
160
+ "data-readonly": dataAttr(readOnly)
161
+ });
162
+ },
163
+ getLabelProps() {
164
+ return normalize.label({
165
+ ...parts.label.attrs,
166
+ "dir": state.context.dir,
167
+ "htmlFor": dom.getInputId(state.context),
168
+ "id": dom.getLabelId(state.context),
169
+ "data-readonly": dataAttr(readOnly),
170
+ "data-disabled": dataAttr(disabled),
171
+ "data-invalid": dataAttr(invalid),
172
+ "data-focus": dataAttr(focused),
173
+ onClick(event) {
174
+ if (composite) return;
175
+ event.preventDefault();
176
+ dom.getTriggerEl(state.context)?.focus({ preventScroll: true });
177
+ }
178
+ });
179
+ },
180
+ getControlProps() {
181
+ return normalize.element({
182
+ ...parts.control.attrs,
183
+ "dir": state.context.dir,
184
+ "id": dom.getControlId(state.context),
185
+ "data-state": open ? "open" : "closed",
186
+ "data-focus": dataAttr(focused),
187
+ "data-disabled": dataAttr(disabled),
188
+ "data-invalid": dataAttr(invalid)
189
+ });
190
+ },
191
+ getPositionerProps() {
192
+ return normalize.element({
193
+ ...parts.positioner.attrs,
194
+ dir: state.context.dir,
195
+ id: dom.getPositionerId(state.context),
196
+ style: popperStyles.floating
197
+ });
198
+ },
199
+ getInputProps() {
200
+ return normalize.input({
201
+ ...parts.input.attrs,
202
+ "dir": state.context.dir,
203
+ "aria-invalid": ariaAttr(invalid),
204
+ "data-invalid": dataAttr(invalid),
205
+ "name": state.context.name,
206
+ "form": state.context.form,
207
+ "disabled": disabled,
208
+ "autoFocus": state.context.autoFocus,
209
+ "required": state.context.required,
210
+ "autoComplete": "off",
211
+ "autoCorrect": "off",
212
+ "autoCapitalize": "none",
213
+ "spellCheck": "false",
214
+ "readOnly": readOnly,
215
+ "placeholder": state.context.placeholder,
216
+ "id": dom.getInputId(state.context),
217
+ "type": "text",
218
+ "role": "combobox",
219
+ "defaultValue": state.context.inputValue,
220
+ "aria-autocomplete": state.context.autoComplete ? "both" : "list",
221
+ "aria-controls": dom.getContentId(state.context),
222
+ "aria-expanded": open,
223
+ "data-state": open ? "open" : "closed",
224
+ "aria-activedescendant": highlightedValue ? dom.getItemId(state.context, highlightedValue) : void 0,
225
+ onClick(event) {
226
+ if (event.defaultPrevented) return;
227
+ if (!state.context.openOnClick) return;
228
+ if (!interactive) return;
229
+ send("INPUT.CLICK");
230
+ },
231
+ onFocus() {
232
+ if (disabled) return;
233
+ send("INPUT.FOCUS");
234
+ },
235
+ onBlur() {
236
+ if (disabled) return;
237
+ send("INPUT.BLUR");
238
+ },
239
+ onChange(event) {
240
+ send({
241
+ type: "INPUT.CHANGE",
242
+ value: event.currentTarget.value
243
+ });
244
+ },
245
+ onKeyDown(event) {
246
+ if (event.defaultPrevented) return;
247
+ if (!interactive) return;
248
+ if (event.ctrlKey || event.shiftKey || isComposingEvent(event)) return;
249
+ const openOnKeyPress = state.context.openOnKeyPress;
250
+ const isModifierKey = event.ctrlKey || event.metaKey || event.shiftKey;
251
+ const keypress = true;
252
+ const keymap = {
253
+ ArrowDown(event$1) {
254
+ if (!openOnKeyPress && !open) return;
255
+ send({
256
+ type: event$1.altKey ? "OPEN" : "INPUT.ARROW_DOWN",
257
+ keypress
258
+ });
259
+ event$1.preventDefault();
260
+ },
261
+ ArrowUp() {
262
+ if (!openOnKeyPress && !open) return;
263
+ send({
264
+ type: event.altKey ? "CLOSE" : "INPUT.ARROW_UP",
265
+ keypress
266
+ });
267
+ event.preventDefault();
268
+ },
269
+ Home(event$1) {
270
+ if (isModifierKey) return;
271
+ send({
272
+ type: "INPUT.HOME",
273
+ keypress
274
+ });
275
+ if (open) event$1.preventDefault();
276
+ },
277
+ End(event$1) {
278
+ if (isModifierKey) return;
279
+ send({
280
+ type: "INPUT.END",
281
+ keypress
282
+ });
283
+ if (open) event$1.preventDefault();
284
+ },
285
+ Enter(event$1) {
286
+ send({
287
+ type: "INPUT.ENTER",
288
+ keypress
289
+ });
290
+ if (open) event$1.preventDefault();
291
+ const itemEl = dom.getHighlightedItemEl(state.context);
292
+ if (isAnchorElement(itemEl)) state.context.navigate({
293
+ value: state.context.highlightedValue,
294
+ node: itemEl
295
+ });
296
+ },
297
+ Escape() {
298
+ send({
299
+ type: "INPUT.ESCAPE",
300
+ keypress
301
+ });
302
+ event.preventDefault();
303
+ }
304
+ };
305
+ const key = getEventKey(event, state.context);
306
+ const exec = keymap[key];
307
+ exec?.(event);
308
+ }
309
+ });
310
+ },
311
+ getTriggerProps(props = {}) {
312
+ return normalize.button({
313
+ ...parts.trigger.attrs,
314
+ "dir": state.context.dir,
315
+ "id": dom.getTriggerId(state.context),
316
+ "aria-haspopup": composite ? "listbox" : "dialog",
317
+ "type": "button",
318
+ "tabIndex": props.focusable ? void 0 : -1,
319
+ "aria-label": translations.triggerLabel,
320
+ "aria-expanded": open,
321
+ "data-state": open ? "open" : "closed",
322
+ "aria-controls": open ? dom.getContentId(state.context) : void 0,
323
+ disabled,
324
+ "data-invalid": dataAttr(invalid),
325
+ "data-focusable": dataAttr(props.focusable),
326
+ "data-readonly": dataAttr(readOnly),
327
+ "data-disabled": dataAttr(disabled),
328
+ onFocus() {
329
+ if (!props.focusable) return;
330
+ send({
331
+ type: "INPUT.FOCUS",
332
+ src: "trigger"
333
+ });
334
+ },
335
+ onClick(event) {
336
+ if (event.defaultPrevented) return;
337
+ if (!interactive) return;
338
+ if (!isLeftClick(event)) return;
339
+ send("TRIGGER.CLICK");
340
+ },
341
+ onPointerDown(event) {
342
+ if (!interactive) return;
343
+ if (event.pointerType === "touch") return;
344
+ event.preventDefault();
345
+ queueMicrotask(() => {
346
+ dom.getInputEl(state.context)?.focus({ preventScroll: true });
347
+ });
348
+ },
349
+ onKeyDown(event) {
350
+ if (event.defaultPrevented) return;
351
+ if (composite) return;
352
+ const keyMap = {
353
+ ArrowDown() {
354
+ send({
355
+ type: "INPUT.ARROW_DOWN",
356
+ src: "trigger"
357
+ });
358
+ },
359
+ ArrowUp() {
360
+ send({
361
+ type: "INPUT.ARROW_UP",
362
+ src: "trigger"
363
+ });
364
+ }
365
+ };
366
+ const key = getEventKey(event, state.context);
367
+ const exec = keyMap[key];
368
+ if (exec) {
369
+ exec(event);
370
+ event.preventDefault();
371
+ }
372
+ }
373
+ });
374
+ },
375
+ getContentProps() {
376
+ return normalize.element({
377
+ ...parts.content.attrs,
378
+ "dir": state.context.dir,
379
+ "id": dom.getContentId(state.context),
380
+ "role": !composite ? "dialog" : "listbox",
381
+ "tabIndex": -1,
382
+ "hidden": !open,
383
+ "data-state": open ? "open" : "closed",
384
+ "data-placement": state.context.currentPlacement,
385
+ "aria-labelledby": dom.getLabelId(state.context),
386
+ "aria-multiselectable": state.context.multiple && composite ? true : void 0,
387
+ onPointerDown(event) {
388
+ event.preventDefault();
389
+ }
390
+ });
391
+ },
392
+ getListProps() {
393
+ return normalize.element({
394
+ ...parts.list.attrs,
395
+ "role": !composite ? "listbox" : void 0,
396
+ "aria-labelledby": dom.getLabelId(state.context),
397
+ "aria-multiselectable": state.context.multiple && !composite ? true : void 0
398
+ });
399
+ },
400
+ getClearTriggerProps() {
401
+ return normalize.button({
402
+ ...parts.clearTrigger.attrs,
403
+ "dir": state.context.dir,
404
+ "id": dom.getClearTriggerId(state.context),
405
+ "type": "button",
406
+ "tabIndex": -1,
407
+ "disabled": disabled,
408
+ "data-invalid": dataAttr(invalid),
409
+ "aria-label": translations.clearTriggerLabel,
410
+ "aria-controls": dom.getInputId(state.context),
411
+ "hidden": !state.context.value.length,
412
+ onPointerDown(event) {
413
+ event.preventDefault();
414
+ },
415
+ onClick(event) {
416
+ if (event.defaultPrevented) return;
417
+ if (!interactive) return;
418
+ send({
419
+ type: "VALUE.CLEAR",
420
+ src: "clear-trigger"
421
+ });
422
+ }
423
+ });
424
+ },
425
+ getItemState,
426
+ getItemProps(props) {
427
+ const itemState = getItemState(props);
428
+ const value = itemState.value;
429
+ return normalize.element({
430
+ ...parts.item.attrs,
431
+ "dir": state.context.dir,
432
+ "id": dom.getItemId(state.context, value),
433
+ "role": "option",
434
+ "tabIndex": -1,
435
+ "data-highlighted": dataAttr(itemState.highlighted),
436
+ "data-state": itemState.selected ? "checked" : "unchecked",
437
+ "aria-selected": ariaAttr(itemState.highlighted),
438
+ "aria-disabled": ariaAttr(itemState.disabled),
439
+ "data-disabled": dataAttr(itemState.disabled),
440
+ "data-value": itemState.value,
441
+ onPointerMove() {
442
+ if (itemState.disabled) return;
443
+ if (itemState.highlighted) return;
444
+ send({
445
+ type: "ITEM.POINTER_MOVE",
446
+ value
447
+ });
448
+ },
449
+ onPointerLeave() {
450
+ if (props.persistFocus) return;
451
+ if (itemState.disabled) return;
452
+ const mouseMoved = state.previousEvent.type.includes("POINTER");
453
+ if (!mouseMoved) return;
454
+ send({
455
+ type: "ITEM.POINTER_LEAVE",
456
+ value
457
+ });
458
+ },
459
+ onClick(event) {
460
+ if (isDownloadingEvent(event)) return;
461
+ if (isOpeningInNewTab(event)) return;
462
+ if (isContextMenuEvent(event)) return;
463
+ if (itemState.disabled) return;
464
+ send({
465
+ type: "ITEM.CLICK",
466
+ src: "click",
467
+ value
468
+ });
469
+ }
470
+ });
471
+ },
472
+ getItemTextProps(props) {
473
+ const itemState = getItemState(props);
474
+ return normalize.element({
475
+ ...parts.itemText.attrs,
476
+ "dir": state.context.dir,
477
+ "data-state": itemState.selected ? "checked" : "unchecked",
478
+ "data-disabled": dataAttr(itemState.disabled),
479
+ "data-highlighted": dataAttr(itemState.highlighted)
480
+ });
481
+ },
482
+ getItemIndicatorProps(props) {
483
+ const itemState = getItemState(props);
484
+ return normalize.element({
485
+ "aria-hidden": true,
486
+ ...parts.itemIndicator.attrs,
487
+ "dir": state.context.dir,
488
+ "data-state": itemState.selected ? "checked" : "unchecked",
489
+ "hidden": !itemState.selected
490
+ });
491
+ },
492
+ getItemGroupProps(props) {
493
+ const { id } = props;
494
+ return normalize.element({
495
+ ...parts.itemGroup.attrs,
496
+ "dir": state.context.dir,
497
+ "id": dom.getItemGroupId(state.context, id),
498
+ "aria-labelledby": dom.getItemGroupLabelId(state.context, id)
499
+ });
500
+ },
501
+ getItemGroupLabelProps(props) {
502
+ const { htmlFor } = props;
503
+ return normalize.element({
504
+ ...parts.itemGroupLabel.attrs,
505
+ dir: state.context.dir,
506
+ id: dom.getItemGroupLabelId(state.context, htmlFor),
507
+ role: "group"
508
+ });
509
+ }
510
+ };
511
+ }
512
+
513
+ //#endregion
514
+ //#region src/machine.ts
515
+ const { and, not } = guards;
516
+ function getInputValue(ctx) {
517
+ return match(ctx.selectionBehavior, {
518
+ preserve: ctx.inputValue,
519
+ replace: ctx.valueAsString,
520
+ clear: ""
521
+ });
522
+ }
523
+ const sync = {
524
+ valueChange: (ctx) => {
525
+ const prevSelectedItems = ctx.selectedItems;
526
+ ctx.selectedItems = ctx.value.map((v) => {
527
+ const foundItem = prevSelectedItems.find((item) => ctx.collection.getItemValue(item) === v);
528
+ if (foundItem) return foundItem;
529
+ return ctx.collection.find(v);
530
+ });
531
+ ctx.valueAsString = ctx.collection.stringifyItems(ctx.selectedItems);
532
+ },
533
+ highlightChange: (ctx) => {
534
+ ctx.highlightedItem = ctx.collection.find(ctx.highlightedValue);
535
+ }
536
+ };
537
+ const invoke = {
538
+ valueChange: (ctx) => {
539
+ sync.valueChange(ctx);
540
+ ctx.onValueChange?.({
541
+ value: Array.from(ctx.value),
542
+ items: Array.from(ctx.selectedItems)
543
+ });
544
+ },
545
+ highlightChange: (ctx) => {
546
+ sync.highlightChange(ctx);
547
+ ctx.onHighlightChange?.({
548
+ highlightedValue: ctx.highlightedValue,
549
+ highlightedItem: ctx.highlightedItem
550
+ });
551
+ },
552
+ inputChange: (ctx) => {
553
+ ctx.onInputValueChange?.({ inputValue: ctx.inputValue });
554
+ }
555
+ };
556
+ const set = {
557
+ value: (ctx, value, force = false) => {
558
+ if (isEqual(ctx.value, value)) return;
559
+ if (value == null && !force) return;
560
+ if (value == null && force) {
561
+ ctx.value = [];
562
+ invoke.valueChange(ctx);
563
+ return;
564
+ }
565
+ if (isArray(value)) ctx.value = value;
566
+ else if (value != null) ctx.value = ctx.multiple ? addOrRemove(ctx.value, value) : [value];
567
+ invoke.valueChange(ctx);
568
+ },
569
+ highlightedValue: (ctx, value, force = false) => {
570
+ if (isEqual(ctx.highlightedValue, value)) return;
571
+ if (!value && !force) return;
572
+ ctx.highlightedValue = value || null;
573
+ invoke.highlightChange(ctx);
574
+ },
575
+ inputValue: (ctx, value) => {
576
+ if (isEqual(ctx.inputValue, value)) return;
577
+ ctx.inputValue = value;
578
+ invoke.inputChange(ctx);
579
+ }
580
+ };
581
+ function machine(userContext) {
582
+ const ctx = compact(userContext);
583
+ return createMachine({
584
+ id: "combobox",
585
+ initial: ctx.open ? "suggesting" : "idle",
586
+ context: {
587
+ loopFocus: true,
588
+ openOnClick: false,
589
+ value: [],
590
+ highlightedValue: null,
591
+ inputValue: "",
592
+ allowCustomValue: false,
593
+ closeOnSelect: !ctx.multiple,
594
+ inputBehavior: "none",
595
+ selectionBehavior: "replace",
596
+ openOnKeyPress: true,
597
+ openOnChange: true,
598
+ composite: true,
599
+ readOnly: false,
600
+ disabled: false,
601
+ navigate({ node }) {
602
+ clickIfLink(node);
603
+ },
604
+ ...ctx,
605
+ highlightedItem: null,
606
+ selectedItems: [],
607
+ valueAsString: "",
608
+ collection: ctx.collection ?? collection.empty(),
609
+ positioning: {
610
+ placement: "bottom",
611
+ sameWidth: true,
612
+ ...ctx.positioning
613
+ },
614
+ translations: {
615
+ triggerLabel: "Toggle suggestions",
616
+ clearTriggerLabel: "Clear value",
617
+ ...ctx.translations
618
+ }
619
+ },
620
+ created: ["syncInitialValues", "syncSelectionBehavior"],
621
+ computed: {
622
+ isInputValueEmpty: (ctx$1) => ctx$1.inputValue.length === 0,
623
+ isInteractive: (ctx$1) => !(ctx$1.readOnly || ctx$1.disabled),
624
+ autoComplete: (ctx$1) => ctx$1.inputBehavior === "autocomplete",
625
+ autoHighlight: (ctx$1) => ctx$1.inputBehavior === "autohighlight",
626
+ hasSelectedItems: (ctx$1) => ctx$1.value.length > 0
627
+ },
628
+ watch: {
629
+ value: ["syncSelectedItems"],
630
+ inputValue: ["syncInputValue"],
631
+ highlightedValue: ["syncHighlightedItem", "autofillInputValue"],
632
+ multiple: ["syncSelectionBehavior"],
633
+ open: ["toggleVisibility"]
634
+ },
635
+ on: {
636
+ "SELECTED_ITEMS.SYNC": { actions: ["syncSelectedItems"] },
637
+ "HIGHLIGHTED_VALUE.SET": { actions: ["setHighlightedItem"] },
638
+ "ITEM.SELECT": { actions: ["selectItem"] },
639
+ "ITEM.CLEAR": { actions: ["clearItem"] },
640
+ "VALUE.SET": { actions: ["setSelectedItems"] },
641
+ "INPUT_VALUE.SET": { actions: "setInputValue" },
642
+ "COLLECTION.SET": { actions: ["setCollection"] },
643
+ "POSITIONING.SET": { actions: ["reposition"] }
644
+ },
645
+ states: {
646
+ idle: {
647
+ tags: ["idle", "closed"],
648
+ entry: ["scrollContentToTop", "clearHighlightedItem"],
649
+ on: {
650
+ "CONTROLLED.OPEN": { target: "interacting" },
651
+ "TRIGGER.CLICK": [{
652
+ guard: "isOpenControlled",
653
+ actions: [
654
+ "setInitialFocus",
655
+ "highlightFirstSelectedItem",
656
+ "invokeOnOpen"
657
+ ]
658
+ }, {
659
+ target: "interacting",
660
+ actions: [
661
+ "setInitialFocus",
662
+ "highlightFirstSelectedItem",
663
+ "invokeOnOpen"
664
+ ]
665
+ }],
666
+ "INPUT.CLICK": [{
667
+ guard: "isOpenControlled",
668
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
669
+ }, {
670
+ target: "interacting",
671
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
672
+ }],
673
+ "INPUT.FOCUS": { target: "focused" },
674
+ "OPEN": [{
675
+ guard: "isOpenControlled",
676
+ actions: ["invokeOnOpen"]
677
+ }, {
678
+ target: "interacting",
679
+ actions: ["invokeOnOpen"]
680
+ }],
681
+ "VALUE.CLEAR": {
682
+ target: "focused",
683
+ actions: [
684
+ "clearInputValue",
685
+ "clearSelectedItems",
686
+ "setInitialFocus"
687
+ ]
688
+ }
689
+ }
690
+ },
691
+ focused: {
692
+ tags: ["focused", "closed"],
693
+ entry: ["scrollContentToTop", "clearHighlightedItem"],
694
+ on: {
695
+ "CONTROLLED.OPEN": [{
696
+ guard: "isChangeEvent",
697
+ target: "suggesting"
698
+ }, { target: "interacting" }],
699
+ "INPUT.CHANGE": [
700
+ {
701
+ guard: and("isOpenControlled", "openOnChange"),
702
+ actions: [
703
+ "setInputValue",
704
+ "invokeOnOpen",
705
+ "highlightFirstItemIfNeeded"
706
+ ]
707
+ },
708
+ {
709
+ guard: "openOnChange",
710
+ target: "suggesting",
711
+ actions: [
712
+ "setInputValue",
713
+ "invokeOnOpen",
714
+ "highlightFirstItemIfNeeded"
715
+ ]
716
+ },
717
+ { actions: "setInputValue" }
718
+ ],
719
+ "LAYER.INTERACT_OUTSIDE": { target: "idle" },
720
+ "INPUT.ESCAPE": {
721
+ guard: and("isCustomValue", not("allowCustomValue")),
722
+ actions: "revertInputValue"
723
+ },
724
+ "INPUT.BLUR": { target: "idle" },
725
+ "INPUT.CLICK": [{
726
+ guard: "isOpenControlled",
727
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
728
+ }, {
729
+ target: "interacting",
730
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
731
+ }],
732
+ "TRIGGER.CLICK": [{
733
+ guard: "isOpenControlled",
734
+ actions: [
735
+ "setInitialFocus",
736
+ "highlightFirstSelectedItem",
737
+ "invokeOnOpen"
738
+ ]
739
+ }, {
740
+ target: "interacting",
741
+ actions: [
742
+ "setInitialFocus",
743
+ "highlightFirstSelectedItem",
744
+ "invokeOnOpen"
745
+ ]
746
+ }],
747
+ "INPUT.ARROW_DOWN": [
748
+ {
749
+ guard: and("isOpenControlled", "autoComplete"),
750
+ actions: ["invokeOnOpen"]
751
+ },
752
+ {
753
+ guard: "autoComplete",
754
+ target: "interacting",
755
+ actions: ["invokeOnOpen"]
756
+ },
757
+ {
758
+ guard: "isOpenControlled",
759
+ actions: ["highlightFirstOrSelectedItem", "invokeOnOpen"]
760
+ },
761
+ {
762
+ target: "interacting",
763
+ actions: ["highlightFirstOrSelectedItem", "invokeOnOpen"]
764
+ }
765
+ ],
766
+ "INPUT.ARROW_UP": [
767
+ {
768
+ guard: "autoComplete",
769
+ target: "interacting",
770
+ actions: "invokeOnOpen"
771
+ },
772
+ {
773
+ guard: "autoComplete",
774
+ target: "interacting",
775
+ actions: "invokeOnOpen"
776
+ },
777
+ {
778
+ target: "interacting",
779
+ actions: ["highlightLastOrSelectedItem", "invokeOnOpen"]
780
+ },
781
+ {
782
+ target: "interacting",
783
+ actions: ["highlightLastOrSelectedItem", "invokeOnOpen"]
784
+ }
785
+ ],
786
+ "OPEN": [{
787
+ guard: "isOpenControlled",
788
+ actions: ["invokeOnOpen"]
789
+ }, {
790
+ target: "interacting",
791
+ actions: ["invokeOnOpen"]
792
+ }],
793
+ "VALUE.CLEAR": { actions: ["clearInputValue", "clearSelectedItems"] }
794
+ }
795
+ },
796
+ interacting: {
797
+ tags: ["open", "focused"],
798
+ entry: ["setInitialFocus"],
799
+ activities: [
800
+ "scrollToHighlightedItem",
801
+ "trackDismissableLayer",
802
+ "computePlacement",
803
+ "hideOtherElements"
804
+ ],
805
+ on: {
806
+ "CONTROLLED.CLOSE": [{
807
+ guard: "restoreFocus",
808
+ target: "focused",
809
+ actions: ["setFinalFocus"]
810
+ }, { target: "idle" }],
811
+ "INPUT.HOME": { actions: ["highlightFirstItem"] },
812
+ "INPUT.END": { actions: ["highlightLastItem"] },
813
+ "INPUT.ARROW_DOWN": [{
814
+ guard: and("autoComplete", "isLastItemHighlighted"),
815
+ actions: ["clearHighlightedItem", "scrollContentToTop"]
816
+ }, { actions: ["highlightNextItem"] }],
817
+ "INPUT.ARROW_UP": [{
818
+ guard: and("autoComplete", "isFirstItemHighlighted"),
819
+ actions: "clearHighlightedItem"
820
+ }, { actions: "highlightPrevItem" }],
821
+ "INPUT.ENTER": [
822
+ {
823
+ guard: and("isOpenControlled", "isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
824
+ actions: ["revertInputValue", "invokeOnClose"]
825
+ },
826
+ {
827
+ guard: and("isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
828
+ target: "focused",
829
+ actions: ["revertInputValue", "invokeOnClose"]
830
+ },
831
+ {
832
+ guard: and("isOpenControlled", "closeOnSelect"),
833
+ actions: ["selectHighlightedItem", "invokeOnClose"]
834
+ },
835
+ {
836
+ guard: "closeOnSelect",
837
+ target: "focused",
838
+ actions: [
839
+ "selectHighlightedItem",
840
+ "invokeOnClose",
841
+ "setFinalFocus"
842
+ ]
843
+ },
844
+ { actions: ["selectHighlightedItem"] }
845
+ ],
846
+ "INPUT.CHANGE": [{
847
+ guard: "autoComplete",
848
+ target: "suggesting",
849
+ actions: ["setInputValue", "invokeOnOpen"]
850
+ }, {
851
+ target: "suggesting",
852
+ actions: [
853
+ "clearHighlightedItem",
854
+ "setInputValue",
855
+ "invokeOnOpen"
856
+ ]
857
+ }],
858
+ "ITEM.POINTER_MOVE": { actions: ["setHighlightedItem"] },
859
+ "ITEM.POINTER_LEAVE": { actions: ["clearHighlightedItem"] },
860
+ "ITEM.CLICK": [
861
+ {
862
+ guard: and("isOpenControlled", "closeOnSelect"),
863
+ actions: ["selectItem", "invokeOnClose"]
864
+ },
865
+ {
866
+ guard: "closeOnSelect",
867
+ target: "focused",
868
+ actions: [
869
+ "selectItem",
870
+ "invokeOnClose",
871
+ "setFinalFocus"
872
+ ]
873
+ },
874
+ { actions: ["selectItem"] }
875
+ ],
876
+ "LAYER.ESCAPE": [
877
+ {
878
+ guard: and("isOpenControlled", "autoComplete"),
879
+ actions: ["syncInputValue", "invokeOnClose"]
880
+ },
881
+ {
882
+ guard: "autoComplete",
883
+ target: "focused",
884
+ actions: ["syncInputValue", "invokeOnClose"]
885
+ },
886
+ {
887
+ guard: "isOpenControlled",
888
+ actions: "invokeOnClose"
889
+ },
890
+ {
891
+ target: "focused",
892
+ actions: ["invokeOnClose", "setFinalFocus"]
893
+ }
894
+ ],
895
+ "TRIGGER.CLICK": [{
896
+ guard: "isOpenControlled",
897
+ actions: "invokeOnClose"
898
+ }, {
899
+ target: "focused",
900
+ actions: "invokeOnClose"
901
+ }],
902
+ "LAYER.INTERACT_OUTSIDE": [
903
+ {
904
+ guard: and("isOpenControlled", "isCustomValue", not("allowCustomValue")),
905
+ actions: ["revertInputValue", "invokeOnClose"]
906
+ },
907
+ {
908
+ guard: and("isCustomValue", not("allowCustomValue")),
909
+ target: "idle",
910
+ actions: ["revertInputValue", "invokeOnClose"]
911
+ },
912
+ {
913
+ guard: "isOpenControlled",
914
+ actions: "invokeOnClose"
915
+ },
916
+ {
917
+ target: "idle",
918
+ actions: "invokeOnClose"
919
+ }
920
+ ],
921
+ "CLOSE": [{
922
+ guard: "isOpenControlled",
923
+ actions: ["invokeOnClose"]
924
+ }, {
925
+ target: "focused",
926
+ actions: ["invokeOnClose", "setFinalFocus"]
927
+ }],
928
+ "VALUE.CLEAR": [{
929
+ guard: "isOpenControlled",
930
+ actions: [
931
+ "clearInputValue",
932
+ "clearSelectedItems",
933
+ "invokeOnClose"
934
+ ]
935
+ }, {
936
+ target: "focused",
937
+ actions: [
938
+ "clearInputValue",
939
+ "clearSelectedItems",
940
+ "invokeOnClose",
941
+ "setFinalFocus"
942
+ ]
943
+ }]
944
+ }
945
+ },
946
+ suggesting: {
947
+ tags: ["open", "focused"],
948
+ activities: [
949
+ "trackDismissableLayer",
950
+ "scrollToHighlightedItem",
951
+ "computePlacement",
952
+ "trackChildNodes",
953
+ "hideOtherElements"
954
+ ],
955
+ entry: ["setInitialFocus"],
956
+ on: {
957
+ "CONTROLLED.CLOSE": [{
958
+ guard: "restoreFocus",
959
+ target: "focused",
960
+ actions: ["setFinalFocus"]
961
+ }, { target: "idle" }],
962
+ "CHILDREN_CHANGE": { actions: ["highlightFirstItem"] },
963
+ "INPUT.ARROW_DOWN": {
964
+ target: "interacting",
965
+ actions: ["highlightNextItem"]
966
+ },
967
+ "INPUT.ARROW_UP": {
968
+ target: "interacting",
969
+ actions: ["highlightPrevItem"]
970
+ },
971
+ "INPUT.HOME": {
972
+ target: "interacting",
973
+ actions: ["highlightFirstItem"]
974
+ },
975
+ "INPUT.END": {
976
+ target: "interacting",
977
+ actions: ["highlightLastItem"]
978
+ },
979
+ "INPUT.ENTER": [
980
+ {
981
+ guard: and("isOpenControlled", "isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
982
+ actions: ["revertInputValue", "invokeOnClose"]
983
+ },
984
+ {
985
+ guard: and("isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
986
+ target: "focused",
987
+ actions: ["revertInputValue", "invokeOnClose"]
988
+ },
989
+ {
990
+ guard: and("isOpenControlled", "closeOnSelect"),
991
+ actions: ["selectHighlightedItem", "invokeOnClose"]
992
+ },
993
+ {
994
+ guard: "closeOnSelect",
995
+ target: "focused",
996
+ actions: [
997
+ "selectHighlightedItem",
998
+ "invokeOnClose",
999
+ "setFinalFocus"
1000
+ ]
1001
+ },
1002
+ { actions: ["selectHighlightedItem"] }
1003
+ ],
1004
+ "INPUT.CHANGE": [{
1005
+ guard: "autoHighlight",
1006
+ actions: ["setInputValue"]
1007
+ }, { actions: ["setInputValue"] }],
1008
+ "LAYER.ESCAPE": [{
1009
+ guard: "isOpenControlled",
1010
+ actions: ["invokeOnClose"]
1011
+ }, {
1012
+ target: "focused",
1013
+ actions: ["invokeOnClose"]
1014
+ }],
1015
+ "ITEM.POINTER_MOVE": {
1016
+ target: "interacting",
1017
+ actions: ["setHighlightedItem"]
1018
+ },
1019
+ "ITEM.POINTER_LEAVE": { actions: ["clearHighlightedItem"] },
1020
+ "LAYER.INTERACT_OUTSIDE": [
1021
+ {
1022
+ guard: and("isOpenControlled", "isCustomValue", not("allowCustomValue")),
1023
+ actions: ["revertInputValue", "invokeOnClose"]
1024
+ },
1025
+ {
1026
+ guard: and("isCustomValue", not("allowCustomValue")),
1027
+ target: "idle",
1028
+ actions: ["revertInputValue", "invokeOnClose"]
1029
+ },
1030
+ {
1031
+ guard: "isOpenControlled",
1032
+ actions: ["invokeOnClose"]
1033
+ },
1034
+ {
1035
+ target: "idle",
1036
+ actions: ["invokeOnClose"]
1037
+ }
1038
+ ],
1039
+ "TRIGGER.CLICK": [{
1040
+ guard: "isOpenControlled",
1041
+ actions: ["invokeOnClose"]
1042
+ }, {
1043
+ target: "focused",
1044
+ actions: ["invokeOnClose"]
1045
+ }],
1046
+ "ITEM.CLICK": [
1047
+ {
1048
+ guard: and("isOpenControlled", "closeOnSelect"),
1049
+ actions: ["selectItem", "invokeOnClose"]
1050
+ },
1051
+ {
1052
+ guard: "closeOnSelect",
1053
+ target: "focused",
1054
+ actions: [
1055
+ "selectItem",
1056
+ "invokeOnClose",
1057
+ "setFinalFocus"
1058
+ ]
1059
+ },
1060
+ { actions: ["selectItem"] }
1061
+ ],
1062
+ "CLOSE": [{
1063
+ guard: "isOpenControlled",
1064
+ actions: ["invokeOnClose"]
1065
+ }, {
1066
+ target: "focused",
1067
+ actions: ["invokeOnClose", "setFinalFocus"]
1068
+ }],
1069
+ "VALUE.CLEAR": [{
1070
+ guard: "isOpenControlled",
1071
+ actions: [
1072
+ "clearInputValue",
1073
+ "clearSelectedItems",
1074
+ "invokeOnClose"
1075
+ ]
1076
+ }, {
1077
+ target: "focused",
1078
+ actions: [
1079
+ "clearInputValue",
1080
+ "clearSelectedItems",
1081
+ "invokeOnClose",
1082
+ "setFinalFocus"
1083
+ ]
1084
+ }]
1085
+ }
1086
+ }
1087
+ }
1088
+ }, {
1089
+ guards: {
1090
+ isInputValueEmpty: (ctx$1) => ctx$1.isInputValueEmpty,
1091
+ autoComplete: (ctx$1) => ctx$1.autoComplete && !ctx$1.multiple,
1092
+ autoHighlight: (ctx$1) => ctx$1.autoHighlight,
1093
+ isFirstItemHighlighted: (ctx$1) => ctx$1.collection.firstValue === ctx$1.highlightedValue,
1094
+ isLastItemHighlighted: (ctx$1) => ctx$1.collection.lastValue === ctx$1.highlightedValue,
1095
+ isCustomValue: (ctx$1) => ctx$1.inputValue !== ctx$1.valueAsString,
1096
+ allowCustomValue: (ctx$1) => !!ctx$1.allowCustomValue,
1097
+ hasHighlightedItem: (ctx$1) => ctx$1.highlightedValue != null,
1098
+ closeOnSelect: (ctx$1) => !!ctx$1.closeOnSelect,
1099
+ isOpenControlled: (ctx$1) => !!ctx$1["open.controlled"],
1100
+ openOnChange: (ctx$1, evt) => {
1101
+ if (isBoolean(ctx$1.openOnChange)) return ctx$1.openOnChange;
1102
+ return !!ctx$1.openOnChange?.({ inputValue: evt.value });
1103
+ },
1104
+ restoreFocus: (_ctx, evt) => evt.restoreFocus == null ? true : !!evt.restoreFocus,
1105
+ isChangeEvent: (_ctx, evt) => evt.previousEvent?.type === "INPUT.CHANGE"
1106
+ },
1107
+ activities: {
1108
+ trackDismissableLayer(ctx$1, _evt, { send }) {
1109
+ if (ctx$1.disableLayer) return;
1110
+ const contentEl = () => dom.getContentEl(ctx$1);
1111
+ return trackDismissableElement(contentEl, {
1112
+ defer: true,
1113
+ exclude: () => [
1114
+ dom.getInputEl(ctx$1),
1115
+ dom.getTriggerEl(ctx$1),
1116
+ dom.getClearTriggerEl(ctx$1)
1117
+ ],
1118
+ onFocusOutside: ctx$1.onFocusOutside,
1119
+ onPointerDownOutside: ctx$1.onPointerDownOutside,
1120
+ onInteractOutside: ctx$1.onInteractOutside,
1121
+ onEscapeKeyDown(event) {
1122
+ event.preventDefault();
1123
+ event.stopPropagation();
1124
+ send("LAYER.ESCAPE");
1125
+ },
1126
+ onDismiss() {
1127
+ send({
1128
+ type: "LAYER.INTERACT_OUTSIDE",
1129
+ restoreFocus: false
1130
+ });
1131
+ }
1132
+ });
1133
+ },
1134
+ hideOtherElements(ctx$1) {
1135
+ return ariaHidden([
1136
+ dom.getInputEl(ctx$1),
1137
+ dom.getContentEl(ctx$1),
1138
+ dom.getTriggerEl(ctx$1),
1139
+ dom.getClearTriggerEl(ctx$1)
1140
+ ]);
1141
+ },
1142
+ computePlacement(ctx$1) {
1143
+ const controlEl = () => dom.getControlEl(ctx$1);
1144
+ const positionerEl = () => dom.getPositionerEl(ctx$1);
1145
+ ctx$1.currentPlacement = ctx$1.positioning.placement;
1146
+ return getPlacement(controlEl, positionerEl, {
1147
+ ...ctx$1.positioning,
1148
+ defer: true,
1149
+ onComplete(data) {
1150
+ ctx$1.currentPlacement = data.placement;
1151
+ }
1152
+ });
1153
+ },
1154
+ trackChildNodes(ctx$1, _evt, { send }) {
1155
+ if (!ctx$1.autoHighlight) return;
1156
+ const exec = () => send("CHILDREN_CHANGE");
1157
+ const contentEl = () => dom.getContentEl(ctx$1);
1158
+ return observeChildren(contentEl, {
1159
+ callback: exec,
1160
+ defer: true
1161
+ });
1162
+ },
1163
+ scrollToHighlightedItem(ctx$1, _evt, { getState }) {
1164
+ const inputEl = dom.getInputEl(ctx$1);
1165
+ const cleanups = [];
1166
+ const exec = (immediate) => {
1167
+ const state = getState();
1168
+ const pointer = state.event.type.includes("POINTER");
1169
+ if (pointer || !ctx$1.highlightedValue) return;
1170
+ const itemEl = dom.getHighlightedItemEl(ctx$1);
1171
+ const contentEl = dom.getContentEl(ctx$1);
1172
+ if (ctx$1.scrollToIndexFn) {
1173
+ const highlightedIndex = ctx$1.collection.indexOf(ctx$1.highlightedValue);
1174
+ ctx$1.scrollToIndexFn({
1175
+ index: highlightedIndex,
1176
+ immediate
1177
+ });
1178
+ return;
1179
+ }
1180
+ const rafCleanup$1 = raf(() => {
1181
+ scrollIntoView(itemEl, {
1182
+ rootEl: contentEl,
1183
+ block: "nearest"
1184
+ });
1185
+ });
1186
+ cleanups.push(rafCleanup$1);
1187
+ };
1188
+ const rafCleanup = raf(() => exec(true));
1189
+ cleanups.push(rafCleanup);
1190
+ const observerCleanup = observeAttributes(inputEl, {
1191
+ attributes: ["aria-activedescendant"],
1192
+ callback: () => exec(false)
1193
+ });
1194
+ cleanups.push(observerCleanup);
1195
+ return () => {
1196
+ cleanups.forEach((cleanup) => cleanup());
1197
+ };
1198
+ }
1199
+ },
1200
+ actions: {
1201
+ reposition(ctx$1, evt) {
1202
+ const controlEl = () => dom.getControlEl(ctx$1);
1203
+ const positionerEl = () => dom.getPositionerEl(ctx$1);
1204
+ getPlacement(controlEl, positionerEl, {
1205
+ ...ctx$1.positioning,
1206
+ ...evt.options,
1207
+ defer: true,
1208
+ listeners: false,
1209
+ onComplete(data) {
1210
+ ctx$1.currentPlacement = data.placement;
1211
+ }
1212
+ });
1213
+ },
1214
+ setHighlightedItem(ctx$1, evt) {
1215
+ if (evt.value == null) return;
1216
+ set.highlightedValue(ctx$1, evt.value);
1217
+ },
1218
+ clearHighlightedItem(ctx$1) {
1219
+ set.highlightedValue(ctx$1, null, true);
1220
+ },
1221
+ selectHighlightedItem(ctx$1) {
1222
+ set.value(ctx$1, ctx$1.highlightedValue);
1223
+ set.inputValue(ctx$1, getInputValue(ctx$1));
1224
+ },
1225
+ selectItem(ctx$1, evt) {
1226
+ if (evt.value == null) return;
1227
+ set.value(ctx$1, evt.value);
1228
+ set.inputValue(ctx$1, getInputValue(ctx$1));
1229
+ },
1230
+ clearItem(ctx$1, evt) {
1231
+ if (evt.value == null) return;
1232
+ const value = ctx$1.value.filter((v) => v !== evt.value);
1233
+ set.value(ctx$1, value);
1234
+ set.inputValue(ctx$1, getInputValue(ctx$1));
1235
+ },
1236
+ setInitialFocus(ctx$1) {
1237
+ raf(() => {
1238
+ dom.focusInputEl(ctx$1);
1239
+ });
1240
+ },
1241
+ setFinalFocus(ctx$1) {
1242
+ raf(() => {
1243
+ const triggerEl = dom.getTriggerEl(ctx$1);
1244
+ if (triggerEl?.dataset.focusable == null) dom.focusInputEl(ctx$1);
1245
+ else dom.focusTriggerEl(ctx$1);
1246
+ });
1247
+ },
1248
+ syncInputValue(ctx$1) {
1249
+ const inputEl = dom.getInputEl(ctx$1);
1250
+ if (!inputEl) return;
1251
+ inputEl.value = ctx$1.inputValue;
1252
+ queueMicrotask(() => {
1253
+ const { selectionStart, selectionEnd } = inputEl;
1254
+ if (Math.abs((selectionEnd ?? 0) - (selectionStart ?? 0)) !== 0) return;
1255
+ if (selectionStart !== 0) return;
1256
+ inputEl.setSelectionRange(inputEl.value.length, inputEl.value.length);
1257
+ });
1258
+ },
1259
+ setInputValue(ctx$1, evt) {
1260
+ set.inputValue(ctx$1, evt.value);
1261
+ },
1262
+ clearInputValue(ctx$1) {
1263
+ set.inputValue(ctx$1, "");
1264
+ },
1265
+ revertInputValue(ctx$1) {
1266
+ const inputValue = match(ctx$1.selectionBehavior, {
1267
+ replace: ctx$1.hasSelectedItems ? ctx$1.valueAsString : "",
1268
+ preserve: ctx$1.inputValue,
1269
+ clear: ""
1270
+ });
1271
+ set.inputValue(ctx$1, inputValue);
1272
+ },
1273
+ syncInitialValues(ctx$1) {
1274
+ const selectedItems = ctx$1.collection.findMany(ctx$1.value);
1275
+ const valueAsString = ctx$1.collection.stringifyMany(ctx$1.value);
1276
+ ctx$1.highlightedItem = ctx$1.collection.find(ctx$1.highlightedValue);
1277
+ ctx$1.selectedItems = selectedItems;
1278
+ ctx$1.valueAsString = valueAsString;
1279
+ if (ctx$1.inputValue.trim() || ctx$1.multiple) return;
1280
+ ctx$1.inputValue = match(ctx$1.selectionBehavior, {
1281
+ preserve: ctx$1.inputValue || valueAsString,
1282
+ replace: valueAsString,
1283
+ clear: ""
1284
+ });
1285
+ },
1286
+ syncSelectionBehavior(ctx$1) {
1287
+ if (ctx$1.multiple) ctx$1.selectionBehavior = "clear";
1288
+ },
1289
+ setSelectedItems(ctx$1, evt) {
1290
+ if (!isArray(evt.value)) return;
1291
+ set.value(ctx$1, evt.value);
1292
+ set.inputValue(ctx$1, getInputValue(ctx$1));
1293
+ },
1294
+ clearSelectedItems(ctx$1) {
1295
+ set.value(ctx$1, []);
1296
+ set.inputValue(ctx$1, getInputValue(ctx$1));
1297
+ },
1298
+ scrollContentToTop(ctx$1) {
1299
+ if (ctx$1.scrollToIndexFn) ctx$1.scrollToIndexFn({
1300
+ index: 0,
1301
+ immediate: true
1302
+ });
1303
+ else {
1304
+ const contentEl = dom.getContentEl(ctx$1);
1305
+ if (!contentEl) return;
1306
+ contentEl.scrollTop = 0;
1307
+ }
1308
+ },
1309
+ invokeOnOpen(ctx$1) {
1310
+ ctx$1.onOpenChange?.({ open: true });
1311
+ },
1312
+ invokeOnClose(ctx$1) {
1313
+ ctx$1.onOpenChange?.({ open: false });
1314
+ },
1315
+ highlightFirstItem(ctx$1) {
1316
+ raf(() => {
1317
+ const value = ctx$1.collection.firstValue;
1318
+ set.highlightedValue(ctx$1, value, true);
1319
+ });
1320
+ },
1321
+ highlightFirstItemIfNeeded(ctx$1) {
1322
+ if (!ctx$1.autoHighlight) return;
1323
+ raf(() => {
1324
+ const value = ctx$1.collection.firstValue;
1325
+ set.highlightedValue(ctx$1, value);
1326
+ });
1327
+ },
1328
+ highlightLastItem(ctx$1) {
1329
+ raf(() => {
1330
+ const value = ctx$1.collection.lastValue;
1331
+ set.highlightedValue(ctx$1, value);
1332
+ });
1333
+ },
1334
+ highlightNextItem(ctx$1) {
1335
+ let value = null;
1336
+ if (ctx$1.highlightedValue) {
1337
+ value = ctx$1.collection.getNextValue(ctx$1.highlightedValue);
1338
+ if (!value && ctx$1.loopFocus) value = ctx$1.collection.firstValue;
1339
+ } else value = ctx$1.collection.firstValue;
1340
+ set.highlightedValue(ctx$1, value);
1341
+ },
1342
+ highlightPrevItem(ctx$1) {
1343
+ let value = null;
1344
+ if (ctx$1.highlightedValue) {
1345
+ value = ctx$1.collection.getPreviousValue(ctx$1.highlightedValue);
1346
+ if (!value && ctx$1.loopFocus) value = ctx$1.collection.lastValue;
1347
+ } else value = ctx$1.collection.lastValue;
1348
+ set.highlightedValue(ctx$1, value);
1349
+ },
1350
+ highlightFirstSelectedItem(ctx$1) {
1351
+ raf(() => {
1352
+ const [value] = ctx$1.collection.sort(ctx$1.value);
1353
+ set.highlightedValue(ctx$1, value);
1354
+ });
1355
+ },
1356
+ highlightFirstOrSelectedItem(ctx$1) {
1357
+ raf(() => {
1358
+ let value = null;
1359
+ if (ctx$1.hasSelectedItems) value = ctx$1.collection.sort(ctx$1.value)[0];
1360
+ else value = ctx$1.collection.firstValue;
1361
+ set.highlightedValue(ctx$1, value);
1362
+ });
1363
+ },
1364
+ highlightLastOrSelectedItem(ctx$1) {
1365
+ raf(() => {
1366
+ let value = null;
1367
+ if (ctx$1.hasSelectedItems) value = ctx$1.collection.sort(ctx$1.value)[0];
1368
+ else value = ctx$1.collection.lastValue;
1369
+ set.highlightedValue(ctx$1, value);
1370
+ });
1371
+ },
1372
+ autofillInputValue(ctx$1, evt) {
1373
+ const inputEl = dom.getInputEl(ctx$1);
1374
+ if (!ctx$1.autoComplete || !inputEl || !evt.keypress) return;
1375
+ const valueText = ctx$1.collection.stringify(ctx$1.highlightedValue);
1376
+ raf(() => {
1377
+ inputEl.value = valueText || ctx$1.inputValue;
1378
+ });
1379
+ },
1380
+ setCollection(ctx$1, evt) {
1381
+ ctx$1.collection = evt.value;
1382
+ },
1383
+ syncSelectedItems(ctx$1) {
1384
+ sync.valueChange(ctx$1);
1385
+ set.inputValue(ctx$1, getInputValue(ctx$1));
1386
+ },
1387
+ syncHighlightedItem(ctx$1) {
1388
+ sync.highlightChange(ctx$1);
1389
+ },
1390
+ toggleVisibility(ctx$1, evt, { send }) {
1391
+ send({
1392
+ type: ctx$1.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE",
1393
+ previousEvent: evt
1394
+ });
1395
+ }
1396
+ }
1397
+ });
1398
+ }
1399
+
1400
+ //#endregion
1401
+ export { anatomy, collection, connect, machine };