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