@zag-js/combobox 1.34.1 → 1.35.1

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.
@@ -0,0 +1,1085 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/combobox.machine.ts
31
+ var combobox_machine_exports = {};
32
+ __export(combobox_machine_exports, {
33
+ machine: () => machine
34
+ });
35
+ module.exports = __toCommonJS(combobox_machine_exports);
36
+ var import_core = require("@zag-js/core");
37
+ var import_dismissable = require("@zag-js/dismissable");
38
+ var import_dom_query = require("@zag-js/dom-query");
39
+ var import_focus_visible = require("@zag-js/focus-visible");
40
+ var import_popper = require("@zag-js/popper");
41
+ var import_utils = require("@zag-js/utils");
42
+ var import_combobox = require("./combobox.collection.cjs");
43
+ var dom = __toESM(require("./combobox.dom.cjs"));
44
+ var { guards, createMachine, choose } = (0, import_core.setup)();
45
+ var { and, not } = guards;
46
+ var machine = createMachine({
47
+ props({ props }) {
48
+ return {
49
+ loopFocus: true,
50
+ openOnClick: false,
51
+ defaultValue: [],
52
+ defaultInputValue: "",
53
+ closeOnSelect: !props.multiple,
54
+ allowCustomValue: false,
55
+ alwaysSubmitOnEnter: false,
56
+ inputBehavior: "none",
57
+ selectionBehavior: props.multiple ? "clear" : "replace",
58
+ openOnKeyPress: true,
59
+ openOnChange: true,
60
+ composite: true,
61
+ navigate({ node }) {
62
+ (0, import_dom_query.clickIfLink)(node);
63
+ },
64
+ collection: import_combobox.collection.empty(),
65
+ ...props,
66
+ positioning: {
67
+ placement: "bottom",
68
+ sameWidth: true,
69
+ ...props.positioning
70
+ },
71
+ translations: {
72
+ triggerLabel: "Toggle suggestions",
73
+ clearTriggerLabel: "Clear value",
74
+ ...props.translations
75
+ }
76
+ };
77
+ },
78
+ initialState({ prop }) {
79
+ const open = prop("open") || prop("defaultOpen");
80
+ return open ? "suggesting" : "idle";
81
+ },
82
+ context({ prop, bindable, getContext, getEvent }) {
83
+ return {
84
+ currentPlacement: bindable(() => ({
85
+ defaultValue: void 0
86
+ })),
87
+ value: bindable(() => ({
88
+ defaultValue: prop("defaultValue"),
89
+ value: prop("value"),
90
+ isEqual: import_utils.isEqual,
91
+ hash(value) {
92
+ return value.join(",");
93
+ },
94
+ onChange(value) {
95
+ const context = getContext();
96
+ const prevSelectedItems = context.get("selectedItems");
97
+ const collection2 = prop("collection");
98
+ const findItems = (vals) => vals.map((v) => prevSelectedItems.find((item) => collection2.getItemValue(item) === v) || collection2.find(v));
99
+ const nextItems = findItems(value);
100
+ const effectiveValue = prop("value") || value;
101
+ context.set("selectedItems", findItems(effectiveValue));
102
+ prop("onValueChange")?.({ value, items: nextItems });
103
+ }
104
+ })),
105
+ highlightedValue: bindable(() => ({
106
+ defaultValue: prop("defaultHighlightedValue") || null,
107
+ value: prop("highlightedValue"),
108
+ onChange(value) {
109
+ const item = prop("collection").find(value);
110
+ prop("onHighlightChange")?.({ highlightedValue: value, highlightedItem: item });
111
+ }
112
+ })),
113
+ inputValue: bindable(() => {
114
+ let inputValue = prop("inputValue") || prop("defaultInputValue");
115
+ const value = prop("value") || prop("defaultValue");
116
+ if (!inputValue.trim() && !prop("multiple")) {
117
+ const valueAsString = prop("collection").stringifyMany(value);
118
+ inputValue = (0, import_utils.match)(prop("selectionBehavior"), {
119
+ preserve: inputValue || valueAsString,
120
+ replace: valueAsString,
121
+ clear: ""
122
+ });
123
+ }
124
+ return {
125
+ defaultValue: inputValue,
126
+ value: prop("inputValue"),
127
+ onChange(value2) {
128
+ const event = getEvent();
129
+ const reason = (event.previousEvent || event).src;
130
+ prop("onInputValueChange")?.({ inputValue: value2, reason });
131
+ }
132
+ };
133
+ }),
134
+ highlightedItem: bindable(() => {
135
+ const highlightedValue = prop("highlightedValue");
136
+ const highlightedItem = prop("collection").find(highlightedValue);
137
+ return { defaultValue: highlightedItem };
138
+ }),
139
+ selectedItems: bindable(() => {
140
+ const value = prop("value") || prop("defaultValue") || [];
141
+ const selectedItems = prop("collection").findMany(value);
142
+ return { defaultValue: selectedItems };
143
+ })
144
+ };
145
+ },
146
+ computed: {
147
+ isInputValueEmpty: ({ context }) => context.get("inputValue").length === 0,
148
+ isInteractive: ({ prop }) => !(prop("readOnly") || prop("disabled")),
149
+ autoComplete: ({ prop }) => prop("inputBehavior") === "autocomplete",
150
+ autoHighlight: ({ prop }) => prop("inputBehavior") === "autohighlight",
151
+ hasSelectedItems: ({ context }) => context.get("value").length > 0,
152
+ valueAsString: ({ context, prop }) => prop("collection").stringifyItems(context.get("selectedItems")),
153
+ isCustomValue: ({ context, computed }) => context.get("inputValue") !== computed("valueAsString")
154
+ },
155
+ watch({ context, prop, track, action, send }) {
156
+ track([() => context.hash("value")], () => {
157
+ action(["syncSelectedItems"]);
158
+ });
159
+ track([() => context.get("inputValue")], () => {
160
+ action(["syncInputValue"]);
161
+ });
162
+ track([() => context.get("highlightedValue")], () => {
163
+ action(["syncHighlightedItem", "autofillInputValue"]);
164
+ });
165
+ track([() => prop("open")], () => {
166
+ action(["toggleVisibility"]);
167
+ });
168
+ track([() => prop("collection").toString()], () => {
169
+ send({ type: "CHILDREN_CHANGE" });
170
+ });
171
+ },
172
+ on: {
173
+ "SELECTED_ITEMS.SYNC": {
174
+ actions: ["syncSelectedItems"]
175
+ },
176
+ "HIGHLIGHTED_VALUE.SET": {
177
+ actions: ["setHighlightedValue"]
178
+ },
179
+ "HIGHLIGHTED_VALUE.CLEAR": {
180
+ actions: ["clearHighlightedValue"]
181
+ },
182
+ "ITEM.SELECT": {
183
+ actions: ["selectItem"]
184
+ },
185
+ "ITEM.CLEAR": {
186
+ actions: ["clearItem"]
187
+ },
188
+ "VALUE.SET": {
189
+ actions: ["setValue"]
190
+ },
191
+ "INPUT_VALUE.SET": {
192
+ actions: ["setInputValue"]
193
+ },
194
+ "POSITIONING.SET": {
195
+ actions: ["reposition"]
196
+ }
197
+ },
198
+ entry: choose([
199
+ {
200
+ guard: "autoFocus",
201
+ actions: ["setInitialFocus"]
202
+ }
203
+ ]),
204
+ states: {
205
+ idle: {
206
+ tags: ["idle", "closed"],
207
+ entry: ["scrollContentToTop", "clearHighlightedValue"],
208
+ on: {
209
+ "CONTROLLED.OPEN": {
210
+ target: "interacting"
211
+ },
212
+ "TRIGGER.CLICK": [
213
+ {
214
+ guard: "isOpenControlled",
215
+ actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"]
216
+ },
217
+ {
218
+ target: "interacting",
219
+ actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"]
220
+ }
221
+ ],
222
+ "INPUT.CLICK": [
223
+ {
224
+ guard: "isOpenControlled",
225
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
226
+ },
227
+ {
228
+ target: "interacting",
229
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
230
+ }
231
+ ],
232
+ "INPUT.FOCUS": {
233
+ target: "focused"
234
+ },
235
+ OPEN: [
236
+ {
237
+ guard: "isOpenControlled",
238
+ actions: ["invokeOnOpen"]
239
+ },
240
+ {
241
+ target: "interacting",
242
+ actions: ["invokeOnOpen"]
243
+ }
244
+ ],
245
+ "VALUE.CLEAR": {
246
+ target: "focused",
247
+ actions: ["clearInputValue", "clearSelectedItems", "setInitialFocus"]
248
+ }
249
+ }
250
+ },
251
+ focused: {
252
+ tags: ["focused", "closed"],
253
+ entry: ["scrollContentToTop", "clearHighlightedValue"],
254
+ on: {
255
+ "CONTROLLED.OPEN": [
256
+ {
257
+ guard: "isChangeEvent",
258
+ target: "suggesting"
259
+ },
260
+ {
261
+ target: "interacting"
262
+ }
263
+ ],
264
+ "INPUT.CHANGE": [
265
+ {
266
+ guard: and("isOpenControlled", "openOnChange"),
267
+ actions: ["setInputValue", "invokeOnOpen", "highlightFirstItemIfNeeded"]
268
+ },
269
+ {
270
+ guard: "openOnChange",
271
+ target: "suggesting",
272
+ actions: ["setInputValue", "invokeOnOpen", "highlightFirstItemIfNeeded"]
273
+ },
274
+ {
275
+ actions: ["setInputValue"]
276
+ }
277
+ ],
278
+ "LAYER.INTERACT_OUTSIDE": {
279
+ target: "idle"
280
+ },
281
+ "INPUT.ESCAPE": {
282
+ guard: and("isCustomValue", not("allowCustomValue")),
283
+ actions: ["revertInputValue"]
284
+ },
285
+ "INPUT.BLUR": {
286
+ target: "idle"
287
+ },
288
+ "INPUT.CLICK": [
289
+ {
290
+ guard: "isOpenControlled",
291
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
292
+ },
293
+ {
294
+ target: "interacting",
295
+ actions: ["highlightFirstSelectedItem", "invokeOnOpen"]
296
+ }
297
+ ],
298
+ "TRIGGER.CLICK": [
299
+ {
300
+ guard: "isOpenControlled",
301
+ actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"]
302
+ },
303
+ {
304
+ target: "interacting",
305
+ actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"]
306
+ }
307
+ ],
308
+ "INPUT.ARROW_DOWN": [
309
+ // == group 1 ==
310
+ {
311
+ guard: and("isOpenControlled", "autoComplete"),
312
+ actions: ["invokeOnOpen"]
313
+ },
314
+ {
315
+ guard: "autoComplete",
316
+ target: "interacting",
317
+ actions: ["invokeOnOpen"]
318
+ },
319
+ // == group 2 ==
320
+ {
321
+ guard: "isOpenControlled",
322
+ actions: ["highlightFirstOrSelectedItem", "invokeOnOpen"]
323
+ },
324
+ {
325
+ target: "interacting",
326
+ actions: ["highlightFirstOrSelectedItem", "invokeOnOpen"]
327
+ }
328
+ ],
329
+ "INPUT.ARROW_UP": [
330
+ // == group 1 ==
331
+ {
332
+ guard: and("isOpenControlled", "autoComplete"),
333
+ actions: ["invokeOnOpen"]
334
+ },
335
+ {
336
+ guard: "autoComplete",
337
+ target: "interacting",
338
+ actions: ["invokeOnOpen"]
339
+ },
340
+ // == group 2 ==
341
+ {
342
+ guard: "isOpenControlled",
343
+ actions: ["highlightLastOrSelectedItem", "invokeOnOpen"]
344
+ },
345
+ {
346
+ target: "interacting",
347
+ actions: ["highlightLastOrSelectedItem", "invokeOnOpen"]
348
+ }
349
+ ],
350
+ OPEN: [
351
+ {
352
+ guard: "isOpenControlled",
353
+ actions: ["invokeOnOpen"]
354
+ },
355
+ {
356
+ target: "interacting",
357
+ actions: ["invokeOnOpen"]
358
+ }
359
+ ],
360
+ "VALUE.CLEAR": {
361
+ actions: ["clearInputValue", "clearSelectedItems"]
362
+ }
363
+ }
364
+ },
365
+ interacting: {
366
+ tags: ["open", "focused"],
367
+ entry: ["setInitialFocus"],
368
+ effects: ["trackFocusVisible", "scrollToHighlightedItem", "trackDismissableLayer", "trackPlacement"],
369
+ on: {
370
+ "CONTROLLED.CLOSE": [
371
+ {
372
+ guard: "restoreFocus",
373
+ target: "focused",
374
+ actions: ["setFinalFocus"]
375
+ },
376
+ {
377
+ target: "idle"
378
+ }
379
+ ],
380
+ CHILDREN_CHANGE: [
381
+ {
382
+ guard: "isHighlightedItemRemoved",
383
+ actions: ["clearHighlightedValue"]
384
+ },
385
+ {
386
+ actions: ["scrollToHighlightedItem"]
387
+ }
388
+ ],
389
+ "INPUT.HOME": {
390
+ actions: ["highlightFirstItem"]
391
+ },
392
+ "INPUT.END": {
393
+ actions: ["highlightLastItem"]
394
+ },
395
+ "INPUT.ARROW_DOWN": [
396
+ {
397
+ guard: and("autoComplete", "isLastItemHighlighted"),
398
+ actions: ["clearHighlightedValue", "scrollContentToTop"]
399
+ },
400
+ {
401
+ actions: ["highlightNextItem"]
402
+ }
403
+ ],
404
+ "INPUT.ARROW_UP": [
405
+ {
406
+ guard: and("autoComplete", "isFirstItemHighlighted"),
407
+ actions: ["clearHighlightedValue"]
408
+ },
409
+ {
410
+ actions: ["highlightPrevItem"]
411
+ }
412
+ ],
413
+ "INPUT.ENTER": [
414
+ // == group 1 ==
415
+ {
416
+ guard: and("isOpenControlled", "isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
417
+ actions: ["revertInputValue", "invokeOnClose"]
418
+ },
419
+ {
420
+ guard: and("isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
421
+ target: "focused",
422
+ actions: ["revertInputValue", "invokeOnClose"]
423
+ },
424
+ // == group 2 ==
425
+ {
426
+ guard: and("isOpenControlled", "closeOnSelect"),
427
+ actions: ["selectHighlightedItem", "invokeOnClose"]
428
+ },
429
+ {
430
+ guard: "closeOnSelect",
431
+ target: "focused",
432
+ actions: ["selectHighlightedItem", "invokeOnClose", "setFinalFocus"]
433
+ },
434
+ {
435
+ actions: ["selectHighlightedItem"]
436
+ }
437
+ ],
438
+ "INPUT.CHANGE": [
439
+ {
440
+ guard: "autoComplete",
441
+ target: "suggesting",
442
+ actions: ["setInputValue"]
443
+ },
444
+ {
445
+ target: "suggesting",
446
+ actions: ["clearHighlightedValue", "setInputValue"]
447
+ }
448
+ ],
449
+ "ITEM.POINTER_MOVE": {
450
+ actions: ["setHighlightedValue"]
451
+ },
452
+ "ITEM.POINTER_LEAVE": {
453
+ actions: ["clearHighlightedValue"]
454
+ },
455
+ "ITEM.CLICK": [
456
+ {
457
+ guard: and("isOpenControlled", "closeOnSelect"),
458
+ actions: ["selectItem", "invokeOnClose"]
459
+ },
460
+ {
461
+ guard: "closeOnSelect",
462
+ target: "focused",
463
+ actions: ["selectItem", "invokeOnClose", "setFinalFocus"]
464
+ },
465
+ {
466
+ actions: ["selectItem"]
467
+ }
468
+ ],
469
+ "LAYER.ESCAPE": [
470
+ {
471
+ guard: and("isOpenControlled", "autoComplete"),
472
+ actions: ["syncInputValue", "invokeOnClose"]
473
+ },
474
+ {
475
+ guard: "autoComplete",
476
+ target: "focused",
477
+ actions: ["syncInputValue", "invokeOnClose"]
478
+ },
479
+ {
480
+ guard: "isOpenControlled",
481
+ actions: ["invokeOnClose"]
482
+ },
483
+ {
484
+ target: "focused",
485
+ actions: ["invokeOnClose", "setFinalFocus"]
486
+ }
487
+ ],
488
+ "TRIGGER.CLICK": [
489
+ {
490
+ guard: "isOpenControlled",
491
+ actions: ["invokeOnClose"]
492
+ },
493
+ {
494
+ target: "focused",
495
+ actions: ["invokeOnClose"]
496
+ }
497
+ ],
498
+ "LAYER.INTERACT_OUTSIDE": [
499
+ // == group 1 ==
500
+ {
501
+ guard: and("isOpenControlled", "isCustomValue", not("allowCustomValue")),
502
+ actions: ["revertInputValue", "invokeOnClose"]
503
+ },
504
+ {
505
+ guard: and("isCustomValue", not("allowCustomValue")),
506
+ target: "idle",
507
+ actions: ["revertInputValue", "invokeOnClose"]
508
+ },
509
+ // == group 2 ==
510
+ {
511
+ guard: "isOpenControlled",
512
+ actions: ["invokeOnClose"]
513
+ },
514
+ {
515
+ target: "idle",
516
+ actions: ["invokeOnClose"]
517
+ }
518
+ ],
519
+ CLOSE: [
520
+ {
521
+ guard: "isOpenControlled",
522
+ actions: ["invokeOnClose"]
523
+ },
524
+ {
525
+ target: "focused",
526
+ actions: ["invokeOnClose", "setFinalFocus"]
527
+ }
528
+ ],
529
+ "VALUE.CLEAR": [
530
+ {
531
+ guard: "isOpenControlled",
532
+ actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"]
533
+ },
534
+ {
535
+ target: "focused",
536
+ actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose", "setFinalFocus"]
537
+ }
538
+ ]
539
+ }
540
+ },
541
+ suggesting: {
542
+ tags: ["open", "focused"],
543
+ effects: ["trackFocusVisible", "trackDismissableLayer", "scrollToHighlightedItem", "trackPlacement"],
544
+ entry: ["setInitialFocus"],
545
+ on: {
546
+ "CONTROLLED.CLOSE": [
547
+ {
548
+ guard: "restoreFocus",
549
+ target: "focused",
550
+ actions: ["setFinalFocus"]
551
+ },
552
+ {
553
+ target: "idle"
554
+ }
555
+ ],
556
+ CHILDREN_CHANGE: [
557
+ {
558
+ guard: and("isHighlightedItemRemoved", "hasCollectionItems", "autoHighlight"),
559
+ actions: ["clearHighlightedValue", "highlightFirstItem"]
560
+ },
561
+ {
562
+ guard: "isHighlightedItemRemoved",
563
+ actions: ["clearHighlightedValue"]
564
+ },
565
+ {
566
+ guard: "autoHighlight",
567
+ actions: ["highlightFirstItem"]
568
+ }
569
+ ],
570
+ "INPUT.ARROW_DOWN": {
571
+ target: "interacting",
572
+ actions: ["highlightNextItem"]
573
+ },
574
+ "INPUT.ARROW_UP": {
575
+ target: "interacting",
576
+ actions: ["highlightPrevItem"]
577
+ },
578
+ "INPUT.HOME": {
579
+ target: "interacting",
580
+ actions: ["highlightFirstItem"]
581
+ },
582
+ "INPUT.END": {
583
+ target: "interacting",
584
+ actions: ["highlightLastItem"]
585
+ },
586
+ "INPUT.ENTER": [
587
+ // == group 1 ==
588
+ {
589
+ guard: and("isOpenControlled", "isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
590
+ actions: ["revertInputValue", "invokeOnClose"]
591
+ },
592
+ {
593
+ guard: and("isCustomValue", not("hasHighlightedItem"), not("allowCustomValue")),
594
+ target: "focused",
595
+ actions: ["revertInputValue", "invokeOnClose"]
596
+ },
597
+ // == group 2 ==
598
+ {
599
+ guard: and("isOpenControlled", "closeOnSelect"),
600
+ actions: ["selectHighlightedItem", "invokeOnClose"]
601
+ },
602
+ {
603
+ guard: "closeOnSelect",
604
+ target: "focused",
605
+ actions: ["selectHighlightedItem", "invokeOnClose", "setFinalFocus"]
606
+ },
607
+ {
608
+ actions: ["selectHighlightedItem"]
609
+ }
610
+ ],
611
+ "INPUT.CHANGE": {
612
+ actions: ["setInputValue"]
613
+ },
614
+ "LAYER.ESCAPE": [
615
+ {
616
+ guard: "isOpenControlled",
617
+ actions: ["invokeOnClose"]
618
+ },
619
+ {
620
+ target: "focused",
621
+ actions: ["invokeOnClose"]
622
+ }
623
+ ],
624
+ "ITEM.POINTER_MOVE": {
625
+ target: "interacting",
626
+ actions: ["setHighlightedValue"]
627
+ },
628
+ "ITEM.POINTER_LEAVE": {
629
+ actions: ["clearHighlightedValue"]
630
+ },
631
+ "LAYER.INTERACT_OUTSIDE": [
632
+ // == group 1 ==
633
+ {
634
+ guard: and("isOpenControlled", "isCustomValue", not("allowCustomValue")),
635
+ actions: ["revertInputValue", "invokeOnClose"]
636
+ },
637
+ {
638
+ guard: and("isCustomValue", not("allowCustomValue")),
639
+ target: "idle",
640
+ actions: ["revertInputValue", "invokeOnClose"]
641
+ },
642
+ // == group 2 ==
643
+ {
644
+ guard: "isOpenControlled",
645
+ actions: ["invokeOnClose"]
646
+ },
647
+ {
648
+ target: "idle",
649
+ actions: ["invokeOnClose"]
650
+ }
651
+ ],
652
+ "TRIGGER.CLICK": [
653
+ {
654
+ guard: "isOpenControlled",
655
+ actions: ["invokeOnClose"]
656
+ },
657
+ {
658
+ target: "focused",
659
+ actions: ["invokeOnClose"]
660
+ }
661
+ ],
662
+ "ITEM.CLICK": [
663
+ {
664
+ guard: and("isOpenControlled", "closeOnSelect"),
665
+ actions: ["selectItem", "invokeOnClose"]
666
+ },
667
+ {
668
+ guard: "closeOnSelect",
669
+ target: "focused",
670
+ actions: ["selectItem", "invokeOnClose", "setFinalFocus"]
671
+ },
672
+ {
673
+ actions: ["selectItem"]
674
+ }
675
+ ],
676
+ CLOSE: [
677
+ {
678
+ guard: "isOpenControlled",
679
+ actions: ["invokeOnClose"]
680
+ },
681
+ {
682
+ target: "focused",
683
+ actions: ["invokeOnClose", "setFinalFocus"]
684
+ }
685
+ ],
686
+ "VALUE.CLEAR": [
687
+ {
688
+ guard: "isOpenControlled",
689
+ actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"]
690
+ },
691
+ {
692
+ target: "focused",
693
+ actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose", "setFinalFocus"]
694
+ }
695
+ ]
696
+ }
697
+ }
698
+ },
699
+ implementations: {
700
+ guards: {
701
+ isInputValueEmpty: ({ computed }) => computed("isInputValueEmpty"),
702
+ autoComplete: ({ computed, prop }) => computed("autoComplete") && !prop("multiple"),
703
+ autoHighlight: ({ computed }) => computed("autoHighlight"),
704
+ isFirstItemHighlighted: ({ prop, context }) => prop("collection").firstValue === context.get("highlightedValue"),
705
+ isLastItemHighlighted: ({ prop, context }) => prop("collection").lastValue === context.get("highlightedValue"),
706
+ isCustomValue: ({ computed }) => computed("isCustomValue"),
707
+ allowCustomValue: ({ prop }) => !!prop("allowCustomValue"),
708
+ hasHighlightedItem: ({ context }) => context.get("highlightedValue") != null,
709
+ closeOnSelect: ({ prop }) => !!prop("closeOnSelect"),
710
+ isOpenControlled: ({ prop }) => prop("open") != null,
711
+ openOnChange: ({ prop, context }) => {
712
+ const openOnChange = prop("openOnChange");
713
+ if ((0, import_utils.isBoolean)(openOnChange)) return openOnChange;
714
+ return !!openOnChange?.({ inputValue: context.get("inputValue") });
715
+ },
716
+ restoreFocus: ({ event }) => {
717
+ const restoreFocus = event.restoreFocus ?? event.previousEvent?.restoreFocus;
718
+ return restoreFocus == null ? true : !!restoreFocus;
719
+ },
720
+ isChangeEvent: ({ event }) => event.previousEvent?.type === "INPUT.CHANGE",
721
+ autoFocus: ({ prop }) => !!prop("autoFocus"),
722
+ isHighlightedItemRemoved: ({ prop, context }) => !prop("collection").has(context.get("highlightedValue")),
723
+ hasCollectionItems: ({ prop }) => prop("collection").size > 0
724
+ },
725
+ effects: {
726
+ trackFocusVisible({ scope }) {
727
+ return (0, import_focus_visible.trackFocusVisible)({ root: scope.getRootNode?.() });
728
+ },
729
+ trackDismissableLayer({ send, prop, scope }) {
730
+ if (prop("disableLayer")) return;
731
+ const contentEl = () => dom.getContentEl(scope);
732
+ return (0, import_dismissable.trackDismissableElement)(contentEl, {
733
+ type: "listbox",
734
+ defer: true,
735
+ exclude: () => [dom.getInputEl(scope), dom.getTriggerEl(scope), dom.getClearTriggerEl(scope)],
736
+ onFocusOutside: prop("onFocusOutside"),
737
+ onPointerDownOutside: prop("onPointerDownOutside"),
738
+ onInteractOutside: prop("onInteractOutside"),
739
+ onEscapeKeyDown(event) {
740
+ event.preventDefault();
741
+ event.stopPropagation();
742
+ send({ type: "LAYER.ESCAPE", src: "escape-key" });
743
+ },
744
+ onDismiss() {
745
+ send({ type: "LAYER.INTERACT_OUTSIDE", src: "interact-outside", restoreFocus: false });
746
+ }
747
+ });
748
+ },
749
+ trackPlacement({ context, prop, scope }) {
750
+ const anchorEl = () => dom.getControlEl(scope) || dom.getTriggerEl(scope);
751
+ const positionerEl = () => dom.getPositionerEl(scope);
752
+ context.set("currentPlacement", prop("positioning").placement);
753
+ return (0, import_popper.getPlacement)(anchorEl, positionerEl, {
754
+ ...prop("positioning"),
755
+ defer: true,
756
+ onComplete(data) {
757
+ context.set("currentPlacement", data.placement);
758
+ }
759
+ });
760
+ },
761
+ scrollToHighlightedItem({ context, prop, scope }) {
762
+ const inputEl = dom.getInputEl(scope);
763
+ let cleanups = [];
764
+ const exec = (immediate) => {
765
+ const modality = (0, import_focus_visible.getInteractionModality)();
766
+ if (modality === "pointer") return;
767
+ const highlightedValue = context.get("highlightedValue");
768
+ if (!highlightedValue) return;
769
+ const contentEl = dom.getContentEl(scope);
770
+ const scrollToIndexFn = prop("scrollToIndexFn");
771
+ if (scrollToIndexFn) {
772
+ const highlightedIndex = prop("collection").indexOf(highlightedValue);
773
+ scrollToIndexFn({
774
+ index: highlightedIndex,
775
+ immediate,
776
+ getElement: () => dom.getItemEl(scope, highlightedValue)
777
+ });
778
+ return;
779
+ }
780
+ const itemEl = dom.getItemEl(scope, highlightedValue);
781
+ const raf_cleanup = (0, import_dom_query.raf)(() => {
782
+ (0, import_dom_query.scrollIntoView)(itemEl, { rootEl: contentEl, block: "nearest" });
783
+ });
784
+ cleanups.push(raf_cleanup);
785
+ };
786
+ const rafCleanup = (0, import_dom_query.raf)(() => {
787
+ (0, import_focus_visible.setInteractionModality)("virtual");
788
+ exec(true);
789
+ });
790
+ cleanups.push(rafCleanup);
791
+ const observerCleanup = (0, import_dom_query.observeAttributes)(inputEl, {
792
+ attributes: ["aria-activedescendant"],
793
+ callback: () => exec(false)
794
+ });
795
+ cleanups.push(observerCleanup);
796
+ return () => {
797
+ cleanups.forEach((cleanup) => cleanup());
798
+ };
799
+ }
800
+ },
801
+ actions: {
802
+ reposition({ context, prop, scope, event }) {
803
+ const controlEl = () => dom.getControlEl(scope);
804
+ const positionerEl = () => dom.getPositionerEl(scope);
805
+ (0, import_popper.getPlacement)(controlEl, positionerEl, {
806
+ ...prop("positioning"),
807
+ ...event.options,
808
+ defer: true,
809
+ listeners: false,
810
+ onComplete(data) {
811
+ context.set("currentPlacement", data.placement);
812
+ }
813
+ });
814
+ },
815
+ setHighlightedValue({ context, event }) {
816
+ if (event.value == null) return;
817
+ context.set("highlightedValue", event.value);
818
+ },
819
+ clearHighlightedValue({ context }) {
820
+ context.set("highlightedValue", null);
821
+ },
822
+ selectHighlightedItem(params) {
823
+ const { context, prop } = params;
824
+ const collection2 = prop("collection");
825
+ const highlightedValue = context.get("highlightedValue");
826
+ if (!highlightedValue || !collection2.has(highlightedValue)) return;
827
+ const nextValue = prop("multiple") ? (0, import_utils.addOrRemove)(context.get("value"), highlightedValue) : [highlightedValue];
828
+ prop("onSelect")?.({ value: nextValue, itemValue: highlightedValue });
829
+ context.set("value", nextValue);
830
+ const inputValue = (0, import_utils.match)(prop("selectionBehavior"), {
831
+ preserve: context.get("inputValue"),
832
+ replace: collection2.stringifyMany(nextValue),
833
+ clear: ""
834
+ });
835
+ context.set("inputValue", inputValue);
836
+ },
837
+ scrollToHighlightedItem({ context, prop, scope }) {
838
+ (0, import_dom_query.nextTick)(() => {
839
+ const highlightedValue = context.get("highlightedValue");
840
+ if (highlightedValue == null) return;
841
+ const itemEl = dom.getItemEl(scope, highlightedValue);
842
+ const contentEl = dom.getContentEl(scope);
843
+ const scrollToIndexFn = prop("scrollToIndexFn");
844
+ if (scrollToIndexFn) {
845
+ const highlightedIndex = prop("collection").indexOf(highlightedValue);
846
+ scrollToIndexFn({
847
+ index: highlightedIndex,
848
+ immediate: true,
849
+ getElement: () => dom.getItemEl(scope, highlightedValue)
850
+ });
851
+ return;
852
+ }
853
+ (0, import_dom_query.scrollIntoView)(itemEl, { rootEl: contentEl, block: "nearest" });
854
+ });
855
+ },
856
+ selectItem(params) {
857
+ const { context, event, flush, prop } = params;
858
+ if (event.value == null) return;
859
+ flush(() => {
860
+ const nextValue = prop("multiple") ? (0, import_utils.addOrRemove)(context.get("value"), event.value) : [event.value];
861
+ prop("onSelect")?.({ value: nextValue, itemValue: event.value });
862
+ context.set("value", nextValue);
863
+ const inputValue = (0, import_utils.match)(prop("selectionBehavior"), {
864
+ preserve: context.get("inputValue"),
865
+ replace: prop("collection").stringifyMany(nextValue),
866
+ clear: ""
867
+ });
868
+ context.set("inputValue", inputValue);
869
+ });
870
+ },
871
+ clearItem(params) {
872
+ const { context, event, flush, prop } = params;
873
+ if (event.value == null) return;
874
+ flush(() => {
875
+ const nextValue = (0, import_utils.remove)(context.get("value"), event.value);
876
+ context.set("value", nextValue);
877
+ const inputValue = (0, import_utils.match)(prop("selectionBehavior"), {
878
+ preserve: context.get("inputValue"),
879
+ replace: prop("collection").stringifyMany(nextValue),
880
+ clear: ""
881
+ });
882
+ context.set("inputValue", inputValue);
883
+ });
884
+ },
885
+ setInitialFocus({ scope }) {
886
+ (0, import_dom_query.raf)(() => {
887
+ dom.focusInputEl(scope);
888
+ });
889
+ },
890
+ setFinalFocus({ scope }) {
891
+ (0, import_dom_query.raf)(() => {
892
+ const triggerEl = dom.getTriggerEl(scope);
893
+ if (triggerEl?.dataset.focusable == null) {
894
+ dom.focusInputEl(scope);
895
+ } else {
896
+ dom.focusTriggerEl(scope);
897
+ }
898
+ });
899
+ },
900
+ syncInputValue({ context, scope, event }) {
901
+ const inputEl = dom.getInputEl(scope);
902
+ if (!inputEl) return;
903
+ inputEl.value = context.get("inputValue");
904
+ queueMicrotask(() => {
905
+ if (event.current().type === "INPUT.CHANGE") return;
906
+ (0, import_dom_query.setCaretToEnd)(inputEl);
907
+ });
908
+ },
909
+ setInputValue({ context, event }) {
910
+ context.set("inputValue", event.value);
911
+ },
912
+ clearInputValue({ context }) {
913
+ context.set("inputValue", "");
914
+ },
915
+ revertInputValue({ context, prop, computed }) {
916
+ const selectionBehavior = prop("selectionBehavior");
917
+ const inputValue = (0, import_utils.match)(selectionBehavior, {
918
+ replace: computed("hasSelectedItems") ? computed("valueAsString") : "",
919
+ preserve: context.get("inputValue"),
920
+ clear: ""
921
+ });
922
+ context.set("inputValue", inputValue);
923
+ },
924
+ setValue(params) {
925
+ const { context, flush, event, prop } = params;
926
+ flush(() => {
927
+ context.set("value", event.value);
928
+ const inputValue = (0, import_utils.match)(prop("selectionBehavior"), {
929
+ preserve: context.get("inputValue"),
930
+ replace: prop("collection").stringifyMany(event.value),
931
+ clear: ""
932
+ });
933
+ context.set("inputValue", inputValue);
934
+ });
935
+ },
936
+ clearSelectedItems(params) {
937
+ const { context, flush, prop } = params;
938
+ flush(() => {
939
+ context.set("value", []);
940
+ const inputValue = (0, import_utils.match)(prop("selectionBehavior"), {
941
+ preserve: context.get("inputValue"),
942
+ replace: prop("collection").stringifyMany([]),
943
+ clear: ""
944
+ });
945
+ context.set("inputValue", inputValue);
946
+ });
947
+ },
948
+ scrollContentToTop({ prop, scope }) {
949
+ const scrollToIndexFn = prop("scrollToIndexFn");
950
+ if (scrollToIndexFn) {
951
+ const firstValue = prop("collection").firstValue;
952
+ scrollToIndexFn({
953
+ index: 0,
954
+ immediate: true,
955
+ getElement: () => dom.getItemEl(scope, firstValue)
956
+ });
957
+ } else {
958
+ const contentEl = dom.getContentEl(scope);
959
+ if (!contentEl) return;
960
+ contentEl.scrollTop = 0;
961
+ }
962
+ },
963
+ invokeOnOpen({ prop, event, context }) {
964
+ const reason = getOpenChangeReason(event);
965
+ prop("onOpenChange")?.({ open: true, reason, value: context.get("value") });
966
+ },
967
+ invokeOnClose({ prop, event, context }) {
968
+ const reason = getOpenChangeReason(event);
969
+ prop("onOpenChange")?.({ open: false, reason, value: context.get("value") });
970
+ },
971
+ highlightFirstItem({ context, prop, scope }) {
972
+ const exec = dom.getContentEl(scope) ? queueMicrotask : import_dom_query.raf;
973
+ exec(() => {
974
+ const value = prop("collection").firstValue;
975
+ if (value) context.set("highlightedValue", value);
976
+ });
977
+ },
978
+ highlightFirstItemIfNeeded({ computed, action }) {
979
+ if (!computed("autoHighlight")) return;
980
+ action(["highlightFirstItem"]);
981
+ },
982
+ highlightLastItem({ context, prop, scope }) {
983
+ const exec = dom.getContentEl(scope) ? queueMicrotask : import_dom_query.raf;
984
+ exec(() => {
985
+ const value = prop("collection").lastValue;
986
+ if (value) context.set("highlightedValue", value);
987
+ });
988
+ },
989
+ highlightNextItem({ context, prop }) {
990
+ let value = null;
991
+ const highlightedValue = context.get("highlightedValue");
992
+ const collection2 = prop("collection");
993
+ if (highlightedValue) {
994
+ value = collection2.getNextValue(highlightedValue);
995
+ if (!value && prop("loopFocus")) value = collection2.firstValue;
996
+ } else {
997
+ value = collection2.firstValue;
998
+ }
999
+ if (value) context.set("highlightedValue", value);
1000
+ },
1001
+ highlightPrevItem({ context, prop }) {
1002
+ let value = null;
1003
+ const highlightedValue = context.get("highlightedValue");
1004
+ const collection2 = prop("collection");
1005
+ if (highlightedValue) {
1006
+ value = collection2.getPreviousValue(highlightedValue);
1007
+ if (!value && prop("loopFocus")) value = collection2.lastValue;
1008
+ } else {
1009
+ value = collection2.lastValue;
1010
+ }
1011
+ if (value) context.set("highlightedValue", value);
1012
+ },
1013
+ highlightFirstSelectedItem({ context, prop }) {
1014
+ (0, import_dom_query.raf)(() => {
1015
+ const [value] = prop("collection").sort(context.get("value"));
1016
+ if (value) context.set("highlightedValue", value);
1017
+ });
1018
+ },
1019
+ highlightFirstOrSelectedItem({ context, prop, computed }) {
1020
+ (0, import_dom_query.raf)(() => {
1021
+ let value = null;
1022
+ if (computed("hasSelectedItems")) {
1023
+ value = prop("collection").sort(context.get("value"))[0];
1024
+ } else {
1025
+ value = prop("collection").firstValue;
1026
+ }
1027
+ if (value) context.set("highlightedValue", value);
1028
+ });
1029
+ },
1030
+ highlightLastOrSelectedItem({ context, prop, computed }) {
1031
+ (0, import_dom_query.raf)(() => {
1032
+ const collection2 = prop("collection");
1033
+ let value = null;
1034
+ if (computed("hasSelectedItems")) {
1035
+ value = collection2.sort(context.get("value"))[0];
1036
+ } else {
1037
+ value = collection2.lastValue;
1038
+ }
1039
+ if (value) context.set("highlightedValue", value);
1040
+ });
1041
+ },
1042
+ autofillInputValue({ context, computed, prop, event, scope }) {
1043
+ const inputEl = dom.getInputEl(scope);
1044
+ const collection2 = prop("collection");
1045
+ if (!computed("autoComplete") || !inputEl || !event.keypress) return;
1046
+ const valueText = collection2.stringify(context.get("highlightedValue"));
1047
+ (0, import_dom_query.raf)(() => {
1048
+ inputEl.value = valueText || context.get("inputValue");
1049
+ });
1050
+ },
1051
+ syncSelectedItems(params) {
1052
+ queueMicrotask(() => {
1053
+ const { context, prop } = params;
1054
+ const collection2 = prop("collection");
1055
+ const value = context.get("value");
1056
+ const selectedItems = value.map((v) => {
1057
+ const item = context.get("selectedItems").find((item2) => collection2.getItemValue(item2) === v);
1058
+ return item || collection2.find(v);
1059
+ });
1060
+ context.set("selectedItems", selectedItems);
1061
+ const inputValue = (0, import_utils.match)(prop("selectionBehavior"), {
1062
+ preserve: context.get("inputValue"),
1063
+ replace: collection2.stringifyMany(value),
1064
+ clear: ""
1065
+ });
1066
+ context.set("inputValue", inputValue);
1067
+ });
1068
+ },
1069
+ syncHighlightedItem({ context, prop }) {
1070
+ const item = prop("collection").find(context.get("highlightedValue"));
1071
+ context.set("highlightedItem", item);
1072
+ },
1073
+ toggleVisibility({ event, send, prop }) {
1074
+ send({ type: prop("open") ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: event });
1075
+ }
1076
+ }
1077
+ }
1078
+ });
1079
+ function getOpenChangeReason(event) {
1080
+ return (event.previousEvent || event).src;
1081
+ }
1082
+ // Annotate the CommonJS export names for ESM import in node:
1083
+ 0 && (module.exports = {
1084
+ machine
1085
+ });