@zag-js/combobox 0.48.0 → 0.50.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.d.mts +26 -16
- package/dist/index.d.ts +26 -16
- package/dist/index.js +229 -214
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +240 -225
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
- package/src/combobox.connect.ts +81 -78
- package/src/combobox.dom.ts +13 -6
- package/src/combobox.machine.ts +125 -137
- package/src/combobox.props.ts +2 -2
- package/src/combobox.types.ts +23 -13
- package/src/index.ts +3 -0
package/src/combobox.machine.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createMachine, guards } from "@zag-js/core"
|
|
|
3
3
|
import { trackDismissableElement } from "@zag-js/dismissable"
|
|
4
4
|
import { observeAttributes, observeChildren, raf, scrollIntoView } from "@zag-js/dom-query"
|
|
5
5
|
import { getPlacement } from "@zag-js/popper"
|
|
6
|
-
import { addOrRemove, compact, isBoolean, isEqual, match } from "@zag-js/utils"
|
|
6
|
+
import { addOrRemove, compact, isArray, isBoolean, isEqual, match } from "@zag-js/utils"
|
|
7
7
|
import { collection } from "./combobox.collection"
|
|
8
8
|
import { dom } from "./combobox.dom"
|
|
9
9
|
import type { CollectionItem, MachineContext, MachineState, UserDefinedContext } from "./combobox.types"
|
|
@@ -28,8 +28,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
28
28
|
selectionBehavior: "replace",
|
|
29
29
|
openOnKeyPress: true,
|
|
30
30
|
openOnChange: true,
|
|
31
|
-
|
|
32
|
-
popup: "listbox",
|
|
31
|
+
composite: true,
|
|
33
32
|
...ctx,
|
|
34
33
|
highlightedItem: null,
|
|
35
34
|
selectedItems: [],
|
|
@@ -61,7 +60,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
61
60
|
watch: {
|
|
62
61
|
value: ["syncSelectedItems"],
|
|
63
62
|
inputValue: ["syncInputValue"],
|
|
64
|
-
highlightedValue: ["autofillInputValue"],
|
|
63
|
+
highlightedValue: ["syncHighlightedItem", "autofillInputValue"],
|
|
65
64
|
multiple: ["syncSelectionBehavior"],
|
|
66
65
|
open: ["toggleVisibility"],
|
|
67
66
|
},
|
|
@@ -101,17 +100,17 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
101
100
|
"TRIGGER.CLICK": [
|
|
102
101
|
{
|
|
103
102
|
guard: "isOpenControlled",
|
|
104
|
-
actions: ["
|
|
103
|
+
actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
105
104
|
},
|
|
106
105
|
{
|
|
107
106
|
target: "interacting",
|
|
108
|
-
actions: ["
|
|
107
|
+
actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
109
108
|
},
|
|
110
109
|
],
|
|
111
110
|
"INPUT.CLICK": [
|
|
112
111
|
{
|
|
113
112
|
guard: "isOpenControlled",
|
|
114
|
-
actions: ["invokeOnOpen"],
|
|
113
|
+
actions: ["highlightFirstSelectedItem", "invokeOnOpen"],
|
|
115
114
|
},
|
|
116
115
|
{
|
|
117
116
|
target: "interacting",
|
|
@@ -133,14 +132,14 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
133
132
|
],
|
|
134
133
|
"VALUE.CLEAR": {
|
|
135
134
|
target: "focused",
|
|
136
|
-
actions: ["clearInputValue", "clearSelectedItems"],
|
|
135
|
+
actions: ["clearInputValue", "clearSelectedItems", "setInitialFocus"],
|
|
137
136
|
},
|
|
138
137
|
},
|
|
139
138
|
},
|
|
140
139
|
|
|
141
140
|
focused: {
|
|
142
141
|
tags: ["focused", "closed"],
|
|
143
|
-
entry: ["
|
|
142
|
+
entry: ["scrollContentToTop", "clearHighlightedItem"],
|
|
144
143
|
on: {
|
|
145
144
|
"CONTROLLED.OPEN": [
|
|
146
145
|
{
|
|
@@ -154,12 +153,12 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
154
153
|
"INPUT.CHANGE": [
|
|
155
154
|
{
|
|
156
155
|
guard: and("isOpenControlled", "openOnChange"),
|
|
157
|
-
actions: ["setInputValue", "invokeOnOpen"],
|
|
156
|
+
actions: ["setInputValue", "invokeOnOpen", "highlightFirstItemIfNeeded"],
|
|
158
157
|
},
|
|
159
158
|
{
|
|
160
159
|
guard: "openOnChange",
|
|
161
160
|
target: "suggesting",
|
|
162
|
-
actions: ["setInputValue", "invokeOnOpen"],
|
|
161
|
+
actions: ["setInputValue", "invokeOnOpen", "highlightFirstItemIfNeeded"],
|
|
163
162
|
},
|
|
164
163
|
{
|
|
165
164
|
actions: "setInputValue",
|
|
@@ -188,11 +187,11 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
188
187
|
"TRIGGER.CLICK": [
|
|
189
188
|
{
|
|
190
189
|
guard: "isOpenControlled",
|
|
191
|
-
actions: ["
|
|
190
|
+
actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
192
191
|
},
|
|
193
192
|
{
|
|
194
193
|
target: "interacting",
|
|
195
|
-
actions: ["
|
|
194
|
+
actions: ["setInitialFocus", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
196
195
|
},
|
|
197
196
|
],
|
|
198
197
|
"INPUT.ARROW_DOWN": [
|
|
@@ -256,18 +255,14 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
256
255
|
|
|
257
256
|
interacting: {
|
|
258
257
|
tags: ["open", "focused"],
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
"trackDismissableLayer",
|
|
262
|
-
"computePlacement",
|
|
263
|
-
"hideOtherElements",
|
|
264
|
-
"trackContentHeight",
|
|
265
|
-
],
|
|
258
|
+
entry: ["setInitialFocus"],
|
|
259
|
+
activities: ["scrollToHighlightedItem", "trackDismissableLayer", "computePlacement", "hideOtherElements"],
|
|
266
260
|
on: {
|
|
267
261
|
"CONTROLLED.CLOSE": [
|
|
268
262
|
{
|
|
269
263
|
guard: "restoreFocus",
|
|
270
264
|
target: "focused",
|
|
265
|
+
actions: ["setFinalFocus"],
|
|
271
266
|
},
|
|
272
267
|
{
|
|
273
268
|
target: "idle",
|
|
@@ -305,7 +300,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
305
300
|
{
|
|
306
301
|
guard: "closeOnSelect",
|
|
307
302
|
target: "focused",
|
|
308
|
-
actions: ["selectHighlightedItem", "invokeOnClose"],
|
|
303
|
+
actions: ["selectHighlightedItem", "invokeOnClose", "setFinalFocus"],
|
|
309
304
|
},
|
|
310
305
|
{
|
|
311
306
|
actions: ["selectHighlightedItem"],
|
|
@@ -336,7 +331,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
336
331
|
{
|
|
337
332
|
guard: "closeOnSelect",
|
|
338
333
|
target: "focused",
|
|
339
|
-
actions: ["selectItem", "invokeOnClose"],
|
|
334
|
+
actions: ["selectItem", "invokeOnClose", "setFinalFocus"],
|
|
340
335
|
},
|
|
341
336
|
{
|
|
342
337
|
actions: ["selectItem"],
|
|
@@ -358,7 +353,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
358
353
|
},
|
|
359
354
|
{
|
|
360
355
|
target: "focused",
|
|
361
|
-
actions: ["invokeOnClose"],
|
|
356
|
+
actions: ["invokeOnClose", "setFinalFocus"],
|
|
362
357
|
},
|
|
363
358
|
],
|
|
364
359
|
"TRIGGER.CLICK": [
|
|
@@ -395,11 +390,11 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
395
390
|
CLOSE: [
|
|
396
391
|
{
|
|
397
392
|
guard: "isOpenControlled",
|
|
398
|
-
actions: "invokeOnClose",
|
|
393
|
+
actions: ["invokeOnClose"],
|
|
399
394
|
},
|
|
400
395
|
{
|
|
401
396
|
target: "focused",
|
|
402
|
-
actions: "invokeOnClose",
|
|
397
|
+
actions: ["invokeOnClose", "setFinalFocus"],
|
|
403
398
|
},
|
|
404
399
|
],
|
|
405
400
|
"VALUE.CLEAR": [
|
|
@@ -409,7 +404,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
409
404
|
},
|
|
410
405
|
{
|
|
411
406
|
target: "focused",
|
|
412
|
-
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"],
|
|
407
|
+
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose", "setFinalFocus"],
|
|
413
408
|
},
|
|
414
409
|
],
|
|
415
410
|
},
|
|
@@ -419,18 +414,18 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
419
414
|
tags: ["open", "focused"],
|
|
420
415
|
activities: [
|
|
421
416
|
"trackDismissableLayer",
|
|
422
|
-
"
|
|
417
|
+
"scrollToHighlightedItem",
|
|
423
418
|
"computePlacement",
|
|
424
419
|
"trackChildNodes",
|
|
425
420
|
"hideOtherElements",
|
|
426
|
-
"trackContentHeight",
|
|
427
421
|
],
|
|
428
|
-
entry: ["
|
|
422
|
+
entry: ["setInitialFocus"],
|
|
429
423
|
on: {
|
|
430
424
|
"CONTROLLED.CLOSE": [
|
|
431
425
|
{
|
|
432
426
|
guard: "restoreFocus",
|
|
433
427
|
target: "focused",
|
|
428
|
+
actions: ["setFinalFocus"],
|
|
434
429
|
},
|
|
435
430
|
{
|
|
436
431
|
target: "idle",
|
|
@@ -441,11 +436,11 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
441
436
|
},
|
|
442
437
|
"INPUT.ARROW_DOWN": {
|
|
443
438
|
target: "interacting",
|
|
444
|
-
actions: "highlightNextItem",
|
|
439
|
+
actions: ["highlightNextItem"],
|
|
445
440
|
},
|
|
446
441
|
"INPUT.ARROW_UP": {
|
|
447
442
|
target: "interacting",
|
|
448
|
-
actions: "highlightPrevItem",
|
|
443
|
+
actions: ["highlightPrevItem"],
|
|
449
444
|
},
|
|
450
445
|
"INPUT.HOME": {
|
|
451
446
|
target: "interacting",
|
|
@@ -463,7 +458,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
463
458
|
{
|
|
464
459
|
guard: "closeOnSelect",
|
|
465
460
|
target: "focused",
|
|
466
|
-
actions: ["selectHighlightedItem", "invokeOnClose"],
|
|
461
|
+
actions: ["selectHighlightedItem", "invokeOnClose", "setFinalFocus"],
|
|
467
462
|
},
|
|
468
463
|
{
|
|
469
464
|
actions: ["selectHighlightedItem"],
|
|
@@ -481,19 +476,19 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
481
476
|
"LAYER.ESCAPE": [
|
|
482
477
|
{
|
|
483
478
|
guard: "isOpenControlled",
|
|
484
|
-
actions: "invokeOnClose",
|
|
479
|
+
actions: ["invokeOnClose"],
|
|
485
480
|
},
|
|
486
481
|
{
|
|
487
482
|
target: "focused",
|
|
488
|
-
actions: "invokeOnClose",
|
|
483
|
+
actions: ["invokeOnClose"],
|
|
489
484
|
},
|
|
490
485
|
],
|
|
491
486
|
"ITEM.POINTER_MOVE": {
|
|
492
487
|
target: "interacting",
|
|
493
|
-
actions: "setHighlightedItem",
|
|
488
|
+
actions: ["setHighlightedItem"],
|
|
494
489
|
},
|
|
495
490
|
"ITEM.POINTER_LEAVE": {
|
|
496
|
-
actions: "clearHighlightedItem",
|
|
491
|
+
actions: ["clearHighlightedItem"],
|
|
497
492
|
},
|
|
498
493
|
"LAYER.INTERACT_OUTSIDE": [
|
|
499
494
|
// == group 1 ==
|
|
@@ -509,21 +504,21 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
509
504
|
// == group 2 ==
|
|
510
505
|
{
|
|
511
506
|
guard: "isOpenControlled",
|
|
512
|
-
actions: "invokeOnClose",
|
|
507
|
+
actions: ["invokeOnClose"],
|
|
513
508
|
},
|
|
514
509
|
{
|
|
515
510
|
target: "idle",
|
|
516
|
-
actions: "invokeOnClose",
|
|
511
|
+
actions: ["invokeOnClose"],
|
|
517
512
|
},
|
|
518
513
|
],
|
|
519
514
|
"TRIGGER.CLICK": [
|
|
520
515
|
{
|
|
521
516
|
guard: "isOpenControlled",
|
|
522
|
-
actions: "invokeOnClose",
|
|
517
|
+
actions: ["invokeOnClose"],
|
|
523
518
|
},
|
|
524
519
|
{
|
|
525
520
|
target: "focused",
|
|
526
|
-
actions: "invokeOnClose",
|
|
521
|
+
actions: ["invokeOnClose"],
|
|
527
522
|
},
|
|
528
523
|
],
|
|
529
524
|
"ITEM.CLICK": [
|
|
@@ -534,7 +529,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
534
529
|
{
|
|
535
530
|
guard: "closeOnSelect",
|
|
536
531
|
target: "focused",
|
|
537
|
-
actions: ["selectItem", "invokeOnClose"],
|
|
532
|
+
actions: ["selectItem", "invokeOnClose", "setFinalFocus"],
|
|
538
533
|
},
|
|
539
534
|
{
|
|
540
535
|
actions: ["selectItem"],
|
|
@@ -543,11 +538,11 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
543
538
|
CLOSE: [
|
|
544
539
|
{
|
|
545
540
|
guard: "isOpenControlled",
|
|
546
|
-
actions: "invokeOnClose",
|
|
541
|
+
actions: ["invokeOnClose"],
|
|
547
542
|
},
|
|
548
543
|
{
|
|
549
544
|
target: "focused",
|
|
550
|
-
actions: "invokeOnClose",
|
|
545
|
+
actions: ["invokeOnClose", "setFinalFocus"],
|
|
551
546
|
},
|
|
552
547
|
],
|
|
553
548
|
"VALUE.CLEAR": [
|
|
@@ -557,7 +552,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
557
552
|
},
|
|
558
553
|
{
|
|
559
554
|
target: "focused",
|
|
560
|
-
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"],
|
|
555
|
+
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose", "setFinalFocus"],
|
|
561
556
|
},
|
|
562
557
|
],
|
|
563
558
|
},
|
|
@@ -587,7 +582,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
587
582
|
|
|
588
583
|
activities: {
|
|
589
584
|
trackDismissableLayer(ctx, _evt, { send }) {
|
|
590
|
-
if (
|
|
585
|
+
if (ctx.disableLayer) return
|
|
591
586
|
const contentEl = () => dom.getContentEl(ctx)
|
|
592
587
|
return trackDismissableElement(contentEl, {
|
|
593
588
|
defer: true,
|
|
@@ -624,23 +619,24 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
624
619
|
trackChildNodes(ctx, _evt, { send }) {
|
|
625
620
|
if (!ctx.autoHighlight) return
|
|
626
621
|
const exec = () => send("CHILDREN_CHANGE")
|
|
627
|
-
raf(() => exec())
|
|
628
622
|
const contentEl = () => dom.getContentEl(ctx)
|
|
629
623
|
return observeChildren(contentEl, {
|
|
630
624
|
callback: exec,
|
|
631
625
|
defer: true,
|
|
632
626
|
})
|
|
633
627
|
},
|
|
634
|
-
|
|
628
|
+
scrollToHighlightedItem(ctx, _evt, { getState }) {
|
|
635
629
|
const inputEl = dom.getInputEl(ctx)
|
|
636
630
|
|
|
631
|
+
let cleanups: VoidFunction[] = []
|
|
632
|
+
|
|
637
633
|
const exec = (immediate: boolean) => {
|
|
638
634
|
const state = getState()
|
|
639
635
|
|
|
640
|
-
const pointer = state.event.type.
|
|
636
|
+
const pointer = state.event.type.includes("POINTER")
|
|
641
637
|
if (pointer || !ctx.highlightedValue) return
|
|
642
638
|
|
|
643
|
-
const
|
|
639
|
+
const itemEl = dom.getHighlightedItemEl(ctx)
|
|
644
640
|
const contentEl = dom.getContentEl(ctx)
|
|
645
641
|
|
|
646
642
|
if (ctx.scrollToIndexFn) {
|
|
@@ -649,39 +645,24 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
649
645
|
return
|
|
650
646
|
}
|
|
651
647
|
|
|
652
|
-
|
|
648
|
+
const rafCleanup = raf(() => {
|
|
649
|
+
scrollIntoView(itemEl, { rootEl: contentEl, block: "nearest" })
|
|
650
|
+
})
|
|
651
|
+
cleanups.push(rafCleanup)
|
|
653
652
|
}
|
|
654
653
|
|
|
655
|
-
raf(() => exec(true))
|
|
656
|
-
|
|
654
|
+
const rafCleanup = raf(() => exec(true))
|
|
655
|
+
cleanups.push(rafCleanup)
|
|
656
|
+
|
|
657
|
+
const observerCleanup = observeAttributes(inputEl, {
|
|
657
658
|
attributes: ["aria-activedescendant"],
|
|
658
659
|
callback: () => exec(false),
|
|
659
660
|
})
|
|
660
|
-
|
|
661
|
-
trackContentHeight(ctx) {
|
|
662
|
-
let cleanup: VoidFunction
|
|
663
|
-
|
|
664
|
-
raf(() => {
|
|
665
|
-
const contentEl = dom.getContentEl(ctx)
|
|
666
|
-
const listboxEl = dom.getListEl(ctx)
|
|
667
|
-
|
|
668
|
-
if (!contentEl || !listboxEl) return
|
|
669
|
-
const win = dom.getWin(ctx)
|
|
670
|
-
|
|
671
|
-
let rafId: number
|
|
672
|
-
const observer = new win.ResizeObserver(() => {
|
|
673
|
-
rafId = requestAnimationFrame(() => {
|
|
674
|
-
contentEl.style.setProperty(`--height`, `${listboxEl.offsetHeight}px`)
|
|
675
|
-
})
|
|
676
|
-
})
|
|
677
|
-
observer.observe(contentEl)
|
|
678
|
-
cleanup = () => {
|
|
679
|
-
cancelAnimationFrame(rafId)
|
|
680
|
-
observer.unobserve(contentEl)
|
|
681
|
-
}
|
|
682
|
-
})
|
|
661
|
+
cleanups.push(observerCleanup)
|
|
683
662
|
|
|
684
|
-
return () =>
|
|
663
|
+
return () => {
|
|
664
|
+
cleanups.forEach((cleanup) => cleanup())
|
|
665
|
+
}
|
|
685
666
|
},
|
|
686
667
|
},
|
|
687
668
|
|
|
@@ -700,45 +681,46 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
700
681
|
})
|
|
701
682
|
},
|
|
702
683
|
setHighlightedItem(ctx, evt) {
|
|
703
|
-
|
|
684
|
+
if (evt.value == null) return
|
|
685
|
+
set.highlightedValue(ctx, evt.value)
|
|
704
686
|
},
|
|
705
687
|
clearHighlightedItem(ctx) {
|
|
706
|
-
set.
|
|
688
|
+
set.highlightedValue(ctx, null, true)
|
|
707
689
|
},
|
|
708
690
|
selectHighlightedItem(ctx) {
|
|
709
|
-
set.
|
|
691
|
+
set.value(ctx, ctx.highlightedValue)
|
|
710
692
|
},
|
|
711
693
|
selectItem(ctx, evt) {
|
|
712
|
-
|
|
694
|
+
if (evt.value == null) return
|
|
695
|
+
set.value(ctx, evt.value)
|
|
713
696
|
},
|
|
714
697
|
clearItem(ctx, evt) {
|
|
698
|
+
if (evt.value == null) return
|
|
715
699
|
const value = ctx.value.filter((v) => v !== evt.value)
|
|
716
|
-
set.
|
|
700
|
+
set.value(ctx, value)
|
|
717
701
|
},
|
|
718
|
-
|
|
719
|
-
// use raf since the input might be rendered in the content
|
|
702
|
+
setInitialFocus(ctx) {
|
|
720
703
|
raf(() => {
|
|
721
|
-
|
|
722
|
-
dom.getInputEl(ctx)?.focus({ preventScroll: true })
|
|
704
|
+
dom.focusInputEl(ctx)
|
|
723
705
|
})
|
|
724
706
|
},
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
707
|
+
setFinalFocus(ctx) {
|
|
708
|
+
raf(() => {
|
|
709
|
+
const triggerEl = dom.getTriggerEl(ctx)
|
|
710
|
+
if (triggerEl?.dataset.focusable == null) {
|
|
711
|
+
dom.focusInputEl(ctx)
|
|
729
712
|
} else {
|
|
730
|
-
dom.
|
|
713
|
+
dom.focusTriggerEl(ctx)
|
|
731
714
|
}
|
|
732
715
|
})
|
|
733
716
|
},
|
|
734
|
-
syncInputValue(ctx
|
|
717
|
+
syncInputValue(ctx) {
|
|
735
718
|
const inputEl = dom.getInputEl(ctx)
|
|
736
719
|
if (!inputEl) return
|
|
737
720
|
|
|
738
721
|
inputEl.value = ctx.inputValue
|
|
739
722
|
|
|
740
|
-
|
|
741
|
-
if (!evt.keypress) return
|
|
723
|
+
queueMicrotask(() => {
|
|
742
724
|
const { selectionStart, selectionEnd } = inputEl
|
|
743
725
|
|
|
744
726
|
if (Math.abs((selectionEnd ?? 0) - (selectionStart ?? 0)) !== 0) return
|
|
@@ -782,10 +764,11 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
782
764
|
}
|
|
783
765
|
},
|
|
784
766
|
setSelectedItems(ctx, evt) {
|
|
785
|
-
|
|
767
|
+
if (!isArray(evt.value)) return
|
|
768
|
+
set.value(ctx, evt.value)
|
|
786
769
|
},
|
|
787
770
|
clearSelectedItems(ctx) {
|
|
788
|
-
set.
|
|
771
|
+
set.value(ctx, [])
|
|
789
772
|
},
|
|
790
773
|
scrollContentToTop(ctx) {
|
|
791
774
|
if (ctx.scrollToIndexFn) {
|
|
@@ -805,13 +788,20 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
805
788
|
highlightFirstItem(ctx) {
|
|
806
789
|
raf(() => {
|
|
807
790
|
const value = ctx.collection.first()
|
|
808
|
-
set.
|
|
791
|
+
set.highlightedValue(ctx, value)
|
|
792
|
+
})
|
|
793
|
+
},
|
|
794
|
+
highlightFirstItemIfNeeded(ctx) {
|
|
795
|
+
if (!ctx.autoHighlight) return
|
|
796
|
+
raf(() => {
|
|
797
|
+
const value = ctx.collection.first()
|
|
798
|
+
set.highlightedValue(ctx, value)
|
|
809
799
|
})
|
|
810
800
|
},
|
|
811
801
|
highlightLastItem(ctx) {
|
|
812
802
|
raf(() => {
|
|
813
803
|
const value = ctx.collection.last()
|
|
814
|
-
set.
|
|
804
|
+
set.highlightedValue(ctx, value)
|
|
815
805
|
})
|
|
816
806
|
},
|
|
817
807
|
highlightNextItem(ctx) {
|
|
@@ -822,7 +812,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
822
812
|
} else {
|
|
823
813
|
value = ctx.collection.first()
|
|
824
814
|
}
|
|
825
|
-
set.
|
|
815
|
+
set.highlightedValue(ctx, value)
|
|
826
816
|
},
|
|
827
817
|
highlightPrevItem(ctx) {
|
|
828
818
|
let value: string | null = null
|
|
@@ -832,12 +822,12 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
832
822
|
} else {
|
|
833
823
|
value = ctx.collection.last()
|
|
834
824
|
}
|
|
835
|
-
set.
|
|
825
|
+
set.highlightedValue(ctx, value)
|
|
836
826
|
},
|
|
837
827
|
highlightFirstSelectedItem(ctx) {
|
|
838
828
|
raf(() => {
|
|
839
829
|
const [value] = ctx.collection.sort(ctx.value)
|
|
840
|
-
set.
|
|
830
|
+
set.highlightedValue(ctx, value)
|
|
841
831
|
})
|
|
842
832
|
},
|
|
843
833
|
highlightFirstOrSelectedItem(ctx) {
|
|
@@ -848,7 +838,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
848
838
|
} else {
|
|
849
839
|
value = ctx.collection.first()
|
|
850
840
|
}
|
|
851
|
-
set.
|
|
841
|
+
set.highlightedValue(ctx, value)
|
|
852
842
|
})
|
|
853
843
|
},
|
|
854
844
|
highlightLastOrSelectedItem(ctx) {
|
|
@@ -859,7 +849,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
859
849
|
} else {
|
|
860
850
|
value = ctx.collection.last()
|
|
861
851
|
}
|
|
862
|
-
set.
|
|
852
|
+
set.highlightedValue(ctx, value)
|
|
863
853
|
})
|
|
864
854
|
},
|
|
865
855
|
autofillInputValue(ctx, evt) {
|
|
@@ -874,12 +864,10 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
874
864
|
ctx.collection = evt.value
|
|
875
865
|
},
|
|
876
866
|
syncSelectedItems(ctx) {
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
return ctx.collection.item(v)
|
|
882
|
-
})
|
|
867
|
+
sync.valueChange(ctx)
|
|
868
|
+
},
|
|
869
|
+
syncHighlightedItem(ctx) {
|
|
870
|
+
sync.highlightChange(ctx)
|
|
883
871
|
},
|
|
884
872
|
toggleVisibility(ctx, evt, { send }) {
|
|
885
873
|
send({ type: ctx.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: evt })
|
|
@@ -889,31 +877,25 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
889
877
|
)
|
|
890
878
|
}
|
|
891
879
|
|
|
892
|
-
const
|
|
880
|
+
const sync = {
|
|
893
881
|
valueChange: (ctx: MachineContext) => {
|
|
894
|
-
ctx.onValueChange?.({
|
|
895
|
-
value: Array.from(ctx.value),
|
|
896
|
-
items: ctx.selectedItems,
|
|
897
|
-
})
|
|
898
|
-
|
|
899
|
-
const prevSelectedItems = ctx.selectedItems
|
|
900
|
-
|
|
901
882
|
// side effect
|
|
883
|
+
const prevSelectedItems = ctx.selectedItems
|
|
902
884
|
ctx.selectedItems = ctx.value.map((v) => {
|
|
903
885
|
const foundItem = prevSelectedItems.find((item) => ctx.collection.itemToValue(item) === v)
|
|
904
886
|
if (foundItem) return foundItem
|
|
905
887
|
return ctx.collection.item(v)
|
|
906
888
|
})
|
|
907
889
|
|
|
890
|
+
// set valueAsString
|
|
908
891
|
const valueAsString = ctx.collection.itemsToString(ctx.selectedItems)
|
|
909
|
-
|
|
910
892
|
ctx.valueAsString = valueAsString
|
|
911
893
|
|
|
912
|
-
|
|
913
|
-
|
|
894
|
+
// set inputValue
|
|
895
|
+
let inputValue: string | undefined
|
|
914
896
|
if (ctx.getSelectionValue) {
|
|
915
897
|
//
|
|
916
|
-
|
|
898
|
+
inputValue = ctx.getSelectionValue({
|
|
917
899
|
inputValue: ctx.inputValue,
|
|
918
900
|
selectedItems: Array.from(ctx.selectedItems),
|
|
919
901
|
valueAsString,
|
|
@@ -921,25 +903,34 @@ const invoke = {
|
|
|
921
903
|
//
|
|
922
904
|
} else {
|
|
923
905
|
//
|
|
924
|
-
|
|
906
|
+
inputValue = match(ctx.selectionBehavior, {
|
|
925
907
|
replace: ctx.valueAsString,
|
|
926
908
|
preserve: ctx.inputValue,
|
|
927
909
|
clear: "",
|
|
928
910
|
})
|
|
929
911
|
}
|
|
930
912
|
|
|
931
|
-
|
|
913
|
+
set.inputValue(ctx, inputValue)
|
|
914
|
+
},
|
|
915
|
+
highlightChange: (ctx: MachineContext) => {
|
|
916
|
+
ctx.highlightedItem = ctx.collection.item(ctx.highlightedValue)
|
|
917
|
+
},
|
|
918
|
+
}
|
|
932
919
|
|
|
933
|
-
|
|
920
|
+
const invoke = {
|
|
921
|
+
valueChange: (ctx: MachineContext) => {
|
|
922
|
+
sync.valueChange(ctx)
|
|
923
|
+
ctx.onValueChange?.({
|
|
924
|
+
value: Array.from(ctx.value),
|
|
925
|
+
items: Array.from(ctx.selectedItems),
|
|
926
|
+
})
|
|
934
927
|
},
|
|
935
928
|
highlightChange: (ctx: MachineContext) => {
|
|
929
|
+
sync.highlightChange(ctx)
|
|
936
930
|
ctx.onHighlightChange?.({
|
|
937
931
|
highlightedValue: ctx.highlightedValue,
|
|
938
|
-
|
|
932
|
+
highlightedItem: ctx.highlightedItem,
|
|
939
933
|
})
|
|
940
|
-
|
|
941
|
-
// side effect
|
|
942
|
-
ctx.highlightedItem = ctx.collection.item(ctx.highlightedValue)
|
|
943
934
|
},
|
|
944
935
|
inputChange: (ctx: MachineContext) => {
|
|
945
936
|
ctx.onInputValueChange?.({ inputValue: ctx.inputValue })
|
|
@@ -947,25 +938,22 @@ const invoke = {
|
|
|
947
938
|
}
|
|
948
939
|
|
|
949
940
|
const set = {
|
|
950
|
-
|
|
941
|
+
value: (ctx: MachineContext, value: string | string[] | null | undefined, force = false) => {
|
|
951
942
|
if (isEqual(ctx.value, value)) return
|
|
952
|
-
|
|
953
943
|
if (value == null && !force) return
|
|
954
|
-
|
|
955
944
|
if (value == null && force) {
|
|
956
945
|
ctx.value = []
|
|
957
946
|
invoke.valueChange(ctx)
|
|
958
947
|
return
|
|
959
948
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
ctx.value = value
|
|
949
|
+
if (isArray(value)) {
|
|
950
|
+
ctx.value = value
|
|
951
|
+
} else if (value != null) {
|
|
952
|
+
ctx.value = ctx.multiple ? addOrRemove(ctx.value, value) : [value]
|
|
953
|
+
}
|
|
966
954
|
invoke.valueChange(ctx)
|
|
967
955
|
},
|
|
968
|
-
|
|
956
|
+
highlightedValue: (ctx: MachineContext, value: string | null | undefined, force = false) => {
|
|
969
957
|
if (isEqual(ctx.highlightedValue, value)) return
|
|
970
958
|
if (!value && !force) return
|
|
971
959
|
ctx.highlightedValue = value || null
|
package/src/combobox.props.ts
CHANGED
|
@@ -9,7 +9,7 @@ export const props = createProps<UserDefinedContext>()([
|
|
|
9
9
|
"collection",
|
|
10
10
|
"dir",
|
|
11
11
|
"disabled",
|
|
12
|
-
"
|
|
12
|
+
"disableLayer",
|
|
13
13
|
"form",
|
|
14
14
|
"getRootNode",
|
|
15
15
|
"getSelectionValue",
|
|
@@ -41,7 +41,7 @@ export const props = createProps<UserDefinedContext>()([
|
|
|
41
41
|
"scrollToIndexFn",
|
|
42
42
|
"selectionBehavior",
|
|
43
43
|
"translations",
|
|
44
|
-
"
|
|
44
|
+
"composite",
|
|
45
45
|
"value",
|
|
46
46
|
])
|
|
47
47
|
export const splitProps = createSplitProps<Partial<UserDefinedContext>>(props)
|