@zag-js/combobox 0.46.0 → 0.48.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 +86 -31
- package/dist/index.d.ts +86 -31
- package/dist/index.js +627 -276
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +637 -280
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -12
- package/src/combobox.connect.ts +158 -108
- package/src/combobox.dom.ts +2 -0
- package/src/combobox.machine.ts +480 -174
- package/src/combobox.props.ts +11 -4
- package/src/combobox.types.ts +91 -39
- package/src/index.ts +2 -0
package/src/combobox.machine.ts
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
import { ariaHidden } from "@zag-js/aria-hidden"
|
|
2
2
|
import { createMachine, guards } from "@zag-js/core"
|
|
3
3
|
import { trackDismissableElement } from "@zag-js/dismissable"
|
|
4
|
-
import { raf, scrollIntoView } from "@zag-js/dom-query"
|
|
5
|
-
import { observeAttributes, observeChildren } from "@zag-js/mutation-observer"
|
|
4
|
+
import { observeAttributes, observeChildren, raf, scrollIntoView } from "@zag-js/dom-query"
|
|
6
5
|
import { getPlacement } from "@zag-js/popper"
|
|
7
|
-
import { addOrRemove, compact, isEqual, match } from "@zag-js/utils"
|
|
6
|
+
import { addOrRemove, compact, isBoolean, isEqual, match } from "@zag-js/utils"
|
|
8
7
|
import { collection } from "./combobox.collection"
|
|
9
8
|
import { dom } from "./combobox.dom"
|
|
10
9
|
import type { CollectionItem, MachineContext, MachineState, UserDefinedContext } from "./combobox.types"
|
|
11
10
|
|
|
12
11
|
const { and, not } = guards
|
|
13
12
|
|
|
14
|
-
const KEYDOWN_EVENT_REGEX = /(ARROW_UP|ARROW_DOWN|HOME|END|ENTER|ESCAPE)/
|
|
15
|
-
|
|
16
13
|
export function machine<T extends CollectionItem>(userContext: UserDefinedContext<T>) {
|
|
17
14
|
const ctx = compact(userContext)
|
|
18
15
|
return createMachine<MachineContext, MachineState>(
|
|
19
16
|
{
|
|
20
17
|
id: "combobox",
|
|
21
|
-
initial: ctx.
|
|
18
|
+
initial: ctx.open ? "suggesting" : "idle",
|
|
22
19
|
context: {
|
|
23
|
-
|
|
20
|
+
loopFocus: true,
|
|
24
21
|
openOnClick: false,
|
|
25
|
-
composing: false,
|
|
26
22
|
value: [],
|
|
27
23
|
highlightedValue: null,
|
|
28
24
|
inputValue: "",
|
|
29
|
-
selectOnBlur: true,
|
|
30
25
|
allowCustomValue: false,
|
|
31
|
-
closeOnSelect:
|
|
26
|
+
closeOnSelect: !ctx.multiple,
|
|
32
27
|
inputBehavior: "none",
|
|
33
28
|
selectionBehavior: "replace",
|
|
29
|
+
openOnKeyPress: true,
|
|
30
|
+
openOnChange: true,
|
|
31
|
+
dismissable: true,
|
|
32
|
+
popup: "listbox",
|
|
34
33
|
...ctx,
|
|
34
|
+
highlightedItem: null,
|
|
35
|
+
selectedItems: [],
|
|
36
|
+
valueAsString: "",
|
|
35
37
|
collection: ctx.collection ?? collection.empty(),
|
|
36
38
|
positioning: {
|
|
37
39
|
placement: "bottom",
|
|
@@ -46,22 +48,22 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
46
48
|
},
|
|
47
49
|
},
|
|
48
50
|
|
|
49
|
-
created: ["
|
|
51
|
+
created: ["syncInitialValues", "syncSelectionBehavior"],
|
|
50
52
|
|
|
51
53
|
computed: {
|
|
52
54
|
isInputValueEmpty: (ctx) => ctx.inputValue.length === 0,
|
|
53
55
|
isInteractive: (ctx) => !(ctx.readOnly || ctx.disabled),
|
|
54
56
|
autoComplete: (ctx) => ctx.inputBehavior === "autocomplete",
|
|
55
57
|
autoHighlight: (ctx) => ctx.inputBehavior === "autohighlight",
|
|
56
|
-
selectedItems: (ctx) => ctx.collection.items(ctx.value),
|
|
57
|
-
highlightedItem: (ctx) => ctx.collection.item(ctx.highlightedValue),
|
|
58
|
-
valueAsString: (ctx) => ctx.collection.itemsToString(ctx.selectedItems),
|
|
59
58
|
hasSelectedItems: (ctx) => ctx.value.length > 0,
|
|
60
59
|
},
|
|
61
60
|
|
|
62
61
|
watch: {
|
|
62
|
+
value: ["syncSelectedItems"],
|
|
63
63
|
inputValue: ["syncInputValue"],
|
|
64
64
|
highlightedValue: ["autofillInputValue"],
|
|
65
|
+
multiple: ["syncSelectionBehavior"],
|
|
66
|
+
open: ["toggleVisibility"],
|
|
65
67
|
},
|
|
66
68
|
|
|
67
69
|
on: {
|
|
@@ -80,16 +82,6 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
80
82
|
"INPUT_VALUE.SET": {
|
|
81
83
|
actions: "setInputValue",
|
|
82
84
|
},
|
|
83
|
-
"VALUE.CLEAR": {
|
|
84
|
-
target: "focused",
|
|
85
|
-
actions: ["clearInputValue", "clearSelectedItems"],
|
|
86
|
-
},
|
|
87
|
-
"INPUT.COMPOSITION_START": {
|
|
88
|
-
actions: ["setIsComposing"],
|
|
89
|
-
},
|
|
90
|
-
"INPUT.COMPOSITION_END": {
|
|
91
|
-
actions: ["clearIsComposing"],
|
|
92
|
-
},
|
|
93
85
|
"COLLECTION.SET": {
|
|
94
86
|
actions: ["setCollection"],
|
|
95
87
|
},
|
|
@@ -103,33 +95,76 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
103
95
|
tags: ["idle", "closed"],
|
|
104
96
|
entry: ["scrollContentToTop", "clearHighlightedItem"],
|
|
105
97
|
on: {
|
|
106
|
-
"
|
|
98
|
+
"CONTROLLED.OPEN": {
|
|
107
99
|
target: "interacting",
|
|
108
|
-
actions: ["focusInput", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
109
|
-
},
|
|
110
|
-
"INPUT.CLICK": {
|
|
111
|
-
guard: "openOnClick",
|
|
112
|
-
target: "interacting",
|
|
113
|
-
actions: ["highlightFirstSelectedItem", "invokeOnOpen"],
|
|
114
100
|
},
|
|
101
|
+
"TRIGGER.CLICK": [
|
|
102
|
+
{
|
|
103
|
+
guard: "isOpenControlled",
|
|
104
|
+
actions: ["focusInput", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
target: "interacting",
|
|
108
|
+
actions: ["focusInput", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
"INPUT.CLICK": [
|
|
112
|
+
{
|
|
113
|
+
guard: "isOpenControlled",
|
|
114
|
+
actions: ["invokeOnOpen"],
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
target: "interacting",
|
|
118
|
+
actions: ["highlightFirstSelectedItem", "invokeOnOpen"],
|
|
119
|
+
},
|
|
120
|
+
],
|
|
115
121
|
"INPUT.FOCUS": {
|
|
116
122
|
target: "focused",
|
|
117
123
|
},
|
|
118
|
-
OPEN:
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
OPEN: [
|
|
125
|
+
{
|
|
126
|
+
guard: "isOpenControlled",
|
|
127
|
+
actions: ["invokeOnOpen"],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
target: "interacting",
|
|
131
|
+
actions: ["invokeOnOpen"],
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
"VALUE.CLEAR": {
|
|
135
|
+
target: "focused",
|
|
136
|
+
actions: ["clearInputValue", "clearSelectedItems"],
|
|
121
137
|
},
|
|
122
138
|
},
|
|
123
139
|
},
|
|
124
140
|
|
|
125
141
|
focused: {
|
|
126
142
|
tags: ["focused", "closed"],
|
|
127
|
-
entry: ["
|
|
143
|
+
entry: ["focusInputOrTrigger", "scrollContentToTop", "clearHighlightedItem"],
|
|
128
144
|
on: {
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
145
|
+
"CONTROLLED.OPEN": [
|
|
146
|
+
{
|
|
147
|
+
guard: "isChangeEvent",
|
|
148
|
+
target: "suggesting",
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
target: "interacting",
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
"INPUT.CHANGE": [
|
|
155
|
+
{
|
|
156
|
+
guard: and("isOpenControlled", "openOnChange"),
|
|
157
|
+
actions: ["setInputValue", "invokeOnOpen"],
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
guard: "openOnChange",
|
|
161
|
+
target: "suggesting",
|
|
162
|
+
actions: ["setInputValue", "invokeOnOpen"],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
actions: "setInputValue",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
133
168
|
"LAYER.INTERACT_OUTSIDE": {
|
|
134
169
|
target: "idle",
|
|
135
170
|
},
|
|
@@ -140,62 +175,104 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
140
175
|
"INPUT.BLUR": {
|
|
141
176
|
target: "idle",
|
|
142
177
|
},
|
|
143
|
-
"INPUT.CLICK":
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
178
|
+
"INPUT.CLICK": [
|
|
179
|
+
{
|
|
180
|
+
guard: "isOpenControlled",
|
|
181
|
+
actions: ["highlightFirstSelectedItem", "invokeOnOpen"],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
target: "interacting",
|
|
185
|
+
actions: ["highlightFirstSelectedItem", "invokeOnOpen"],
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
"TRIGGER.CLICK": [
|
|
189
|
+
{
|
|
190
|
+
guard: "isOpenControlled",
|
|
191
|
+
actions: ["focusInput", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
target: "interacting",
|
|
195
|
+
actions: ["focusInput", "highlightFirstSelectedItem", "invokeOnOpen"],
|
|
196
|
+
},
|
|
197
|
+
],
|
|
152
198
|
"INPUT.ARROW_DOWN": [
|
|
199
|
+
// == group 1 ==
|
|
200
|
+
{
|
|
201
|
+
guard: and("isOpenControlled", "autoComplete"),
|
|
202
|
+
actions: ["invokeOnOpen"],
|
|
203
|
+
},
|
|
153
204
|
{
|
|
154
205
|
guard: "autoComplete",
|
|
155
206
|
target: "interacting",
|
|
156
207
|
actions: ["invokeOnOpen"],
|
|
157
208
|
},
|
|
209
|
+
// == group 2 ==
|
|
158
210
|
{
|
|
159
|
-
guard: "
|
|
160
|
-
|
|
161
|
-
actions: ["highlightFirstSelectedItem", "invokeOnOpen"],
|
|
211
|
+
guard: "isOpenControlled",
|
|
212
|
+
actions: ["highlightFirstOrSelectedItem", "invokeOnOpen"],
|
|
162
213
|
},
|
|
163
214
|
{
|
|
164
215
|
target: "interacting",
|
|
165
|
-
actions: ["
|
|
216
|
+
actions: ["highlightFirstOrSelectedItem", "invokeOnOpen"],
|
|
166
217
|
},
|
|
167
218
|
],
|
|
168
|
-
"INPUT.ARROW_DOWN+ALT": {
|
|
169
|
-
target: "interacting",
|
|
170
|
-
actions: "invokeOnOpen",
|
|
171
|
-
},
|
|
172
219
|
"INPUT.ARROW_UP": [
|
|
220
|
+
// == group 1 ==
|
|
173
221
|
{
|
|
174
222
|
guard: "autoComplete",
|
|
175
223
|
target: "interacting",
|
|
176
224
|
actions: "invokeOnOpen",
|
|
177
225
|
},
|
|
178
226
|
{
|
|
179
|
-
guard: "
|
|
227
|
+
guard: "autoComplete",
|
|
180
228
|
target: "interacting",
|
|
181
|
-
actions:
|
|
229
|
+
actions: "invokeOnOpen",
|
|
182
230
|
},
|
|
231
|
+
// == group 2 ==
|
|
183
232
|
{
|
|
184
233
|
target: "interacting",
|
|
185
|
-
actions: ["
|
|
234
|
+
actions: ["highlightLastOrSelectedItem", "invokeOnOpen"],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
target: "interacting",
|
|
238
|
+
actions: ["highlightLastOrSelectedItem", "invokeOnOpen"],
|
|
186
239
|
},
|
|
187
240
|
],
|
|
188
|
-
OPEN:
|
|
189
|
-
|
|
190
|
-
|
|
241
|
+
OPEN: [
|
|
242
|
+
{
|
|
243
|
+
guard: "isOpenControlled",
|
|
244
|
+
actions: ["invokeOnOpen"],
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
target: "interacting",
|
|
248
|
+
actions: ["invokeOnOpen"],
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
"VALUE.CLEAR": {
|
|
252
|
+
actions: ["clearInputValue", "clearSelectedItems"],
|
|
191
253
|
},
|
|
192
254
|
},
|
|
193
255
|
},
|
|
194
256
|
|
|
195
257
|
interacting: {
|
|
196
258
|
tags: ["open", "focused"],
|
|
197
|
-
activities: [
|
|
259
|
+
activities: [
|
|
260
|
+
"scrollIntoView",
|
|
261
|
+
"trackDismissableLayer",
|
|
262
|
+
"computePlacement",
|
|
263
|
+
"hideOtherElements",
|
|
264
|
+
"trackContentHeight",
|
|
265
|
+
],
|
|
198
266
|
on: {
|
|
267
|
+
"CONTROLLED.CLOSE": [
|
|
268
|
+
{
|
|
269
|
+
guard: "restoreFocus",
|
|
270
|
+
target: "focused",
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
target: "idle",
|
|
274
|
+
},
|
|
275
|
+
],
|
|
199
276
|
"INPUT.HOME": {
|
|
200
277
|
actions: ["highlightFirstItem"],
|
|
201
278
|
},
|
|
@@ -220,31 +297,32 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
220
297
|
actions: "highlightPrevItem",
|
|
221
298
|
},
|
|
222
299
|
],
|
|
223
|
-
"INPUT.ARROW_UP+ALT": {
|
|
224
|
-
target: "focused",
|
|
225
|
-
},
|
|
226
300
|
"INPUT.ENTER": [
|
|
227
301
|
{
|
|
228
|
-
guard:
|
|
229
|
-
actions: ["selectHighlightedItem"],
|
|
302
|
+
guard: and("isOpenControlled", "closeOnSelect"),
|
|
303
|
+
actions: ["selectHighlightedItem", "invokeOnClose"],
|
|
230
304
|
},
|
|
231
305
|
{
|
|
306
|
+
guard: "closeOnSelect",
|
|
232
307
|
target: "focused",
|
|
233
308
|
actions: ["selectHighlightedItem", "invokeOnClose"],
|
|
234
309
|
},
|
|
310
|
+
{
|
|
311
|
+
actions: ["selectHighlightedItem"],
|
|
312
|
+
},
|
|
235
313
|
],
|
|
236
314
|
"INPUT.CHANGE": [
|
|
237
315
|
{
|
|
238
316
|
guard: "autoComplete",
|
|
239
317
|
target: "suggesting",
|
|
240
|
-
actions: ["setInputValue"],
|
|
318
|
+
actions: ["setInputValue", "invokeOnOpen"],
|
|
241
319
|
},
|
|
242
320
|
{
|
|
243
321
|
target: "suggesting",
|
|
244
|
-
actions: ["clearHighlightedItem", "setInputValue"],
|
|
322
|
+
actions: ["clearHighlightedItem", "setInputValue", "invokeOnOpen"],
|
|
245
323
|
},
|
|
246
324
|
],
|
|
247
|
-
"ITEM.
|
|
325
|
+
"ITEM.POINTER_MOVE": {
|
|
248
326
|
actions: ["setHighlightedItem"],
|
|
249
327
|
},
|
|
250
328
|
"ITEM.POINTER_LEAVE": {
|
|
@@ -252,49 +330,88 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
252
330
|
},
|
|
253
331
|
"ITEM.CLICK": [
|
|
254
332
|
{
|
|
255
|
-
guard:
|
|
256
|
-
actions: ["selectItem"],
|
|
333
|
+
guard: and("isOpenControlled", "closeOnSelect"),
|
|
334
|
+
actions: ["selectItem", "invokeOnClose"],
|
|
257
335
|
},
|
|
258
336
|
{
|
|
337
|
+
guard: "closeOnSelect",
|
|
259
338
|
target: "focused",
|
|
260
339
|
actions: ["selectItem", "invokeOnClose"],
|
|
261
340
|
},
|
|
341
|
+
{
|
|
342
|
+
actions: ["selectItem"],
|
|
343
|
+
},
|
|
262
344
|
],
|
|
263
345
|
"LAYER.ESCAPE": [
|
|
346
|
+
{
|
|
347
|
+
guard: and("isOpenControlled", "autoComplete"),
|
|
348
|
+
actions: ["syncInputValue", "invokeOnClose"],
|
|
349
|
+
},
|
|
264
350
|
{
|
|
265
351
|
guard: "autoComplete",
|
|
266
352
|
target: "focused",
|
|
267
353
|
actions: ["syncInputValue", "invokeOnClose"],
|
|
268
354
|
},
|
|
355
|
+
{
|
|
356
|
+
guard: "isOpenControlled",
|
|
357
|
+
actions: "invokeOnClose",
|
|
358
|
+
},
|
|
269
359
|
{
|
|
270
360
|
target: "focused",
|
|
271
361
|
actions: ["invokeOnClose"],
|
|
272
362
|
},
|
|
273
363
|
],
|
|
274
|
-
"TRIGGER.CLICK":
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
364
|
+
"TRIGGER.CLICK": [
|
|
365
|
+
{
|
|
366
|
+
guard: "isOpenControlled",
|
|
367
|
+
actions: "invokeOnClose",
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
target: "focused",
|
|
371
|
+
actions: "invokeOnClose",
|
|
372
|
+
},
|
|
373
|
+
],
|
|
278
374
|
"LAYER.INTERACT_OUTSIDE": [
|
|
375
|
+
// == group 1 ==
|
|
279
376
|
{
|
|
280
|
-
guard: and("
|
|
281
|
-
|
|
282
|
-
actions: ["selectHighlightedItem", "invokeOnClose"],
|
|
377
|
+
guard: and("isOpenControlled", "isCustomValue", not("allowCustomValue")),
|
|
378
|
+
actions: ["revertInputValue", "invokeOnClose"],
|
|
283
379
|
},
|
|
284
380
|
{
|
|
285
381
|
guard: and("isCustomValue", not("allowCustomValue")),
|
|
286
382
|
target: "idle",
|
|
287
383
|
actions: ["revertInputValue", "invokeOnClose"],
|
|
288
384
|
},
|
|
385
|
+
// == group 2 ==
|
|
386
|
+
{
|
|
387
|
+
guard: "isOpenControlled",
|
|
388
|
+
actions: "invokeOnClose",
|
|
389
|
+
},
|
|
289
390
|
{
|
|
290
391
|
target: "idle",
|
|
291
392
|
actions: "invokeOnClose",
|
|
292
393
|
},
|
|
293
394
|
],
|
|
294
|
-
CLOSE:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
395
|
+
CLOSE: [
|
|
396
|
+
{
|
|
397
|
+
guard: "isOpenControlled",
|
|
398
|
+
actions: "invokeOnClose",
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
target: "focused",
|
|
402
|
+
actions: "invokeOnClose",
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
"VALUE.CLEAR": [
|
|
406
|
+
{
|
|
407
|
+
guard: "isOpenControlled",
|
|
408
|
+
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"],
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
target: "focused",
|
|
412
|
+
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"],
|
|
413
|
+
},
|
|
414
|
+
],
|
|
298
415
|
},
|
|
299
416
|
},
|
|
300
417
|
|
|
@@ -306,11 +423,20 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
306
423
|
"computePlacement",
|
|
307
424
|
"trackChildNodes",
|
|
308
425
|
"hideOtherElements",
|
|
426
|
+
"trackContentHeight",
|
|
309
427
|
],
|
|
310
|
-
entry: ["focusInput"
|
|
428
|
+
entry: ["focusInput"],
|
|
311
429
|
on: {
|
|
430
|
+
"CONTROLLED.CLOSE": [
|
|
431
|
+
{
|
|
432
|
+
guard: "restoreFocus",
|
|
433
|
+
target: "focused",
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
target: "idle",
|
|
437
|
+
},
|
|
438
|
+
],
|
|
312
439
|
CHILDREN_CHANGE: {
|
|
313
|
-
guard: not("isHighlightedItemVisible"),
|
|
314
440
|
actions: ["highlightFirstItem"],
|
|
315
441
|
},
|
|
316
442
|
"INPUT.ARROW_DOWN": {
|
|
@@ -321,9 +447,6 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
321
447
|
target: "interacting",
|
|
322
448
|
actions: "highlightPrevItem",
|
|
323
449
|
},
|
|
324
|
-
"INPUT.ARROW_UP+ALT": {
|
|
325
|
-
target: "focused",
|
|
326
|
-
},
|
|
327
450
|
"INPUT.HOME": {
|
|
328
451
|
target: "interacting",
|
|
329
452
|
actions: ["highlightFirstItem"],
|
|
@@ -334,28 +457,38 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
334
457
|
},
|
|
335
458
|
"INPUT.ENTER": [
|
|
336
459
|
{
|
|
337
|
-
guard:
|
|
338
|
-
actions: ["selectHighlightedItem"],
|
|
460
|
+
guard: and("isOpenControlled", "closeOnSelect"),
|
|
461
|
+
actions: ["selectHighlightedItem", "invokeOnClose"],
|
|
339
462
|
},
|
|
340
463
|
{
|
|
464
|
+
guard: "closeOnSelect",
|
|
341
465
|
target: "focused",
|
|
342
466
|
actions: ["selectHighlightedItem", "invokeOnClose"],
|
|
343
467
|
},
|
|
468
|
+
{
|
|
469
|
+
actions: ["selectHighlightedItem"],
|
|
470
|
+
},
|
|
344
471
|
],
|
|
345
472
|
"INPUT.CHANGE": [
|
|
346
473
|
{
|
|
347
474
|
guard: "autoHighlight",
|
|
348
|
-
actions: ["setInputValue"
|
|
475
|
+
actions: ["setInputValue"],
|
|
349
476
|
},
|
|
350
477
|
{
|
|
351
|
-
actions: ["
|
|
478
|
+
actions: ["setInputValue"],
|
|
352
479
|
},
|
|
353
480
|
],
|
|
354
|
-
"LAYER.ESCAPE":
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
481
|
+
"LAYER.ESCAPE": [
|
|
482
|
+
{
|
|
483
|
+
guard: "isOpenControlled",
|
|
484
|
+
actions: "invokeOnClose",
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
target: "focused",
|
|
488
|
+
actions: "invokeOnClose",
|
|
489
|
+
},
|
|
490
|
+
],
|
|
491
|
+
"ITEM.POINTER_MOVE": {
|
|
359
492
|
target: "interacting",
|
|
360
493
|
actions: "setHighlightedItem",
|
|
361
494
|
},
|
|
@@ -363,34 +496,70 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
363
496
|
actions: "clearHighlightedItem",
|
|
364
497
|
},
|
|
365
498
|
"LAYER.INTERACT_OUTSIDE": [
|
|
499
|
+
// == group 1 ==
|
|
500
|
+
{
|
|
501
|
+
guard: and("isOpenControlled", "isCustomValue", not("allowCustomValue")),
|
|
502
|
+
actions: ["revertInputValue", "invokeOnClose"],
|
|
503
|
+
},
|
|
366
504
|
{
|
|
367
505
|
guard: and("isCustomValue", not("allowCustomValue")),
|
|
368
506
|
target: "idle",
|
|
369
507
|
actions: ["revertInputValue", "invokeOnClose"],
|
|
370
508
|
},
|
|
509
|
+
// == group 2 ==
|
|
510
|
+
{
|
|
511
|
+
guard: "isOpenControlled",
|
|
512
|
+
actions: "invokeOnClose",
|
|
513
|
+
},
|
|
371
514
|
{
|
|
372
515
|
target: "idle",
|
|
373
516
|
actions: "invokeOnClose",
|
|
374
517
|
},
|
|
375
518
|
],
|
|
376
|
-
"TRIGGER.CLICK":
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
519
|
+
"TRIGGER.CLICK": [
|
|
520
|
+
{
|
|
521
|
+
guard: "isOpenControlled",
|
|
522
|
+
actions: "invokeOnClose",
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
target: "focused",
|
|
526
|
+
actions: "invokeOnClose",
|
|
527
|
+
},
|
|
528
|
+
],
|
|
380
529
|
"ITEM.CLICK": [
|
|
381
530
|
{
|
|
382
|
-
guard:
|
|
383
|
-
actions: ["selectItem"],
|
|
531
|
+
guard: and("isOpenControlled", "closeOnSelect"),
|
|
532
|
+
actions: ["selectItem", "invokeOnClose"],
|
|
384
533
|
},
|
|
385
534
|
{
|
|
535
|
+
guard: "closeOnSelect",
|
|
386
536
|
target: "focused",
|
|
387
537
|
actions: ["selectItem", "invokeOnClose"],
|
|
388
538
|
},
|
|
539
|
+
{
|
|
540
|
+
actions: ["selectItem"],
|
|
541
|
+
},
|
|
542
|
+
],
|
|
543
|
+
CLOSE: [
|
|
544
|
+
{
|
|
545
|
+
guard: "isOpenControlled",
|
|
546
|
+
actions: "invokeOnClose",
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
target: "focused",
|
|
550
|
+
actions: "invokeOnClose",
|
|
551
|
+
},
|
|
552
|
+
],
|
|
553
|
+
"VALUE.CLEAR": [
|
|
554
|
+
{
|
|
555
|
+
guard: "isOpenControlled",
|
|
556
|
+
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"],
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
target: "focused",
|
|
560
|
+
actions: ["clearInputValue", "clearSelectedItems", "invokeOnClose"],
|
|
561
|
+
},
|
|
389
562
|
],
|
|
390
|
-
CLOSE: {
|
|
391
|
-
target: "focused",
|
|
392
|
-
actions: "invokeOnClose",
|
|
393
|
-
},
|
|
394
563
|
},
|
|
395
564
|
},
|
|
396
565
|
},
|
|
@@ -398,7 +567,6 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
398
567
|
|
|
399
568
|
{
|
|
400
569
|
guards: {
|
|
401
|
-
openOnClick: (ctx) => !!ctx.openOnClick,
|
|
402
570
|
isInputValueEmpty: (ctx) => ctx.isInputValueEmpty,
|
|
403
571
|
autoComplete: (ctx) => ctx.autoComplete && !ctx.multiple,
|
|
404
572
|
autoHighlight: (ctx) => ctx.autoHighlight,
|
|
@@ -407,23 +575,23 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
407
575
|
isCustomValue: (ctx) => ctx.inputValue !== ctx.valueAsString,
|
|
408
576
|
allowCustomValue: (ctx) => !!ctx.allowCustomValue,
|
|
409
577
|
hasHighlightedItem: (ctx) => ctx.highlightedValue != null,
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
578
|
+
closeOnSelect: (ctx) => !!ctx.closeOnSelect,
|
|
579
|
+
isOpenControlled: (ctx) => !!ctx["open.controlled"],
|
|
580
|
+
openOnChange: (ctx, evt) => {
|
|
581
|
+
if (isBoolean(ctx.openOnChange)) return ctx.openOnChange
|
|
582
|
+
return !!ctx.openOnChange?.({ inputValue: evt.value })
|
|
583
|
+
},
|
|
584
|
+
restoreFocus: (_ctx, evt) => (evt.restoreFocus == null ? true : !!evt.restoreFocus),
|
|
585
|
+
isChangeEvent: (_ctx, evt) => evt.previousEvent?.type === "INPUT.CHANGE",
|
|
414
586
|
},
|
|
415
587
|
|
|
416
588
|
activities: {
|
|
417
589
|
trackDismissableLayer(ctx, _evt, { send }) {
|
|
590
|
+
if (!ctx.dismissable) return
|
|
418
591
|
const contentEl = () => dom.getContentEl(ctx)
|
|
419
592
|
return trackDismissableElement(contentEl, {
|
|
420
593
|
defer: true,
|
|
421
|
-
exclude: () => [
|
|
422
|
-
dom.getInputEl(ctx),
|
|
423
|
-
dom.getContentEl(ctx),
|
|
424
|
-
dom.getTriggerEl(ctx),
|
|
425
|
-
dom.getClearTriggerEl(ctx),
|
|
426
|
-
],
|
|
594
|
+
exclude: () => [dom.getInputEl(ctx), dom.getTriggerEl(ctx), dom.getClearTriggerEl(ctx)],
|
|
427
595
|
onFocusOutside: ctx.onFocusOutside,
|
|
428
596
|
onPointerDownOutside: ctx.onPointerDownOutside,
|
|
429
597
|
onInteractOutside: ctx.onInteractOutside,
|
|
@@ -433,7 +601,7 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
433
601
|
send("LAYER.ESCAPE")
|
|
434
602
|
},
|
|
435
603
|
onDismiss() {
|
|
436
|
-
send("LAYER.INTERACT_OUTSIDE")
|
|
604
|
+
send({ type: "LAYER.INTERACT_OUTSIDE", restoreFocus: false })
|
|
437
605
|
},
|
|
438
606
|
})
|
|
439
607
|
},
|
|
@@ -456,26 +624,64 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
456
624
|
trackChildNodes(ctx, _evt, { send }) {
|
|
457
625
|
if (!ctx.autoHighlight) return
|
|
458
626
|
const exec = () => send("CHILDREN_CHANGE")
|
|
459
|
-
exec()
|
|
460
|
-
|
|
627
|
+
raf(() => exec())
|
|
628
|
+
const contentEl = () => dom.getContentEl(ctx)
|
|
629
|
+
return observeChildren(contentEl, {
|
|
630
|
+
callback: exec,
|
|
631
|
+
defer: true,
|
|
632
|
+
})
|
|
461
633
|
},
|
|
462
634
|
scrollIntoView(ctx, _evt, { getState }) {
|
|
463
635
|
const inputEl = dom.getInputEl(ctx)
|
|
464
636
|
|
|
465
|
-
const exec = () => {
|
|
637
|
+
const exec = (immediate: boolean) => {
|
|
466
638
|
const state = getState()
|
|
467
639
|
|
|
468
|
-
const
|
|
469
|
-
if (
|
|
640
|
+
const pointer = state.event.type.startsWith("ITEM.POINTER")
|
|
641
|
+
if (pointer || !ctx.highlightedValue) return
|
|
470
642
|
|
|
471
643
|
const optionEl = dom.getHighlightedItemEl(ctx)
|
|
472
644
|
const contentEl = dom.getContentEl(ctx)
|
|
473
645
|
|
|
646
|
+
if (ctx.scrollToIndexFn) {
|
|
647
|
+
const highlightedIndex = ctx.collection.indexOf(ctx.highlightedValue)
|
|
648
|
+
ctx.scrollToIndexFn({ index: highlightedIndex, immediate })
|
|
649
|
+
return
|
|
650
|
+
}
|
|
651
|
+
|
|
474
652
|
scrollIntoView(optionEl, { rootEl: contentEl, block: "nearest" })
|
|
475
653
|
}
|
|
476
654
|
|
|
477
|
-
raf(() => exec())
|
|
478
|
-
return observeAttributes(inputEl,
|
|
655
|
+
raf(() => exec(true))
|
|
656
|
+
return observeAttributes(inputEl, {
|
|
657
|
+
attributes: ["aria-activedescendant"],
|
|
658
|
+
callback: () => exec(false),
|
|
659
|
+
})
|
|
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
|
+
})
|
|
683
|
+
|
|
684
|
+
return () => cleanup?.()
|
|
479
685
|
},
|
|
480
686
|
},
|
|
481
687
|
|
|
@@ -493,12 +699,6 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
493
699
|
},
|
|
494
700
|
})
|
|
495
701
|
},
|
|
496
|
-
setIsComposing(ctx) {
|
|
497
|
-
ctx.composing = true
|
|
498
|
-
},
|
|
499
|
-
clearIsComposing(ctx) {
|
|
500
|
-
ctx.composing = false
|
|
501
|
-
},
|
|
502
702
|
setHighlightedItem(ctx, evt) {
|
|
503
703
|
set.highlightedItem(ctx, evt.value)
|
|
504
704
|
},
|
|
@@ -516,19 +716,29 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
516
716
|
set.selectedItems(ctx, value)
|
|
517
717
|
},
|
|
518
718
|
focusInput(ctx) {
|
|
519
|
-
|
|
520
|
-
|
|
719
|
+
// use raf since the input might be rendered in the content
|
|
720
|
+
raf(() => {
|
|
721
|
+
if (dom.isInputFocused(ctx)) return
|
|
722
|
+
dom.getInputEl(ctx)?.focus({ preventScroll: true })
|
|
723
|
+
})
|
|
724
|
+
},
|
|
725
|
+
focusInputOrTrigger(ctx) {
|
|
726
|
+
queueMicrotask(() => {
|
|
727
|
+
if (ctx.popup === "dialog") {
|
|
728
|
+
dom.getTriggerEl(ctx)?.focus({ preventScroll: true })
|
|
729
|
+
} else {
|
|
730
|
+
dom.getInputEl(ctx)?.focus({ preventScroll: true })
|
|
731
|
+
}
|
|
732
|
+
})
|
|
521
733
|
},
|
|
522
734
|
syncInputValue(ctx, evt) {
|
|
523
|
-
const isTyping = !KEYDOWN_EVENT_REGEX.test(evt.type)
|
|
524
735
|
const inputEl = dom.getInputEl(ctx)
|
|
525
|
-
|
|
526
736
|
if (!inputEl) return
|
|
737
|
+
|
|
527
738
|
inputEl.value = ctx.inputValue
|
|
528
739
|
|
|
529
740
|
raf(() => {
|
|
530
|
-
if (
|
|
531
|
-
|
|
741
|
+
if (!evt.keypress) return
|
|
532
742
|
const { selectionStart, selectionEnd } = inputEl
|
|
533
743
|
|
|
534
744
|
if (Math.abs((selectionEnd ?? 0) - (selectionStart ?? 0)) !== 0) return
|
|
@@ -544,24 +754,33 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
544
754
|
set.inputValue(ctx, "")
|
|
545
755
|
},
|
|
546
756
|
revertInputValue(ctx) {
|
|
547
|
-
|
|
548
|
-
ctx,
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const
|
|
558
|
-
|
|
757
|
+
const inputValue = match(ctx.selectionBehavior, {
|
|
758
|
+
replace: ctx.hasSelectedItems ? ctx.valueAsString : "",
|
|
759
|
+
preserve: ctx.inputValue,
|
|
760
|
+
clear: "",
|
|
761
|
+
})
|
|
762
|
+
|
|
763
|
+
set.inputValue(ctx, inputValue)
|
|
764
|
+
},
|
|
765
|
+
syncInitialValues(ctx) {
|
|
766
|
+
const selectedItems = ctx.collection.items(ctx.value)
|
|
767
|
+
const valueAsString = ctx.collection.itemsToString(selectedItems)
|
|
768
|
+
|
|
769
|
+
ctx.highlightedItem = ctx.collection.item(ctx.highlightedValue)
|
|
770
|
+
ctx.selectedItems = selectedItems
|
|
771
|
+
ctx.valueAsString = valueAsString
|
|
772
|
+
|
|
559
773
|
ctx.inputValue = match(ctx.selectionBehavior, {
|
|
560
|
-
preserve: valueAsString,
|
|
774
|
+
preserve: ctx.inputValue || valueAsString,
|
|
561
775
|
replace: valueAsString,
|
|
562
776
|
clear: "",
|
|
563
777
|
})
|
|
564
778
|
},
|
|
779
|
+
syncSelectionBehavior(ctx) {
|
|
780
|
+
if (ctx.multiple) {
|
|
781
|
+
ctx.selectionBehavior = "clear"
|
|
782
|
+
}
|
|
783
|
+
},
|
|
565
784
|
setSelectedItems(ctx, evt) {
|
|
566
785
|
set.selectedItems(ctx, evt.value)
|
|
567
786
|
},
|
|
@@ -569,9 +788,13 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
569
788
|
set.selectedItems(ctx, [])
|
|
570
789
|
},
|
|
571
790
|
scrollContentToTop(ctx) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
791
|
+
if (ctx.scrollToIndexFn) {
|
|
792
|
+
ctx.scrollToIndexFn({ index: 0, immediate: true })
|
|
793
|
+
} else {
|
|
794
|
+
const contentEl = dom.getContentEl(ctx)
|
|
795
|
+
if (!contentEl) return
|
|
796
|
+
contentEl.scrollTop = 0
|
|
797
|
+
}
|
|
575
798
|
},
|
|
576
799
|
invokeOnOpen(ctx) {
|
|
577
800
|
ctx.onOpenChange?.({ open: true })
|
|
@@ -580,28 +803,68 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
580
803
|
ctx.onOpenChange?.({ open: false })
|
|
581
804
|
},
|
|
582
805
|
highlightFirstItem(ctx) {
|
|
583
|
-
|
|
584
|
-
|
|
806
|
+
raf(() => {
|
|
807
|
+
const value = ctx.collection.first()
|
|
808
|
+
set.highlightedItem(ctx, value)
|
|
809
|
+
})
|
|
585
810
|
},
|
|
586
811
|
highlightLastItem(ctx) {
|
|
587
|
-
|
|
588
|
-
|
|
812
|
+
raf(() => {
|
|
813
|
+
const value = ctx.collection.last()
|
|
814
|
+
set.highlightedItem(ctx, value)
|
|
815
|
+
})
|
|
589
816
|
},
|
|
590
817
|
highlightNextItem(ctx) {
|
|
591
|
-
|
|
818
|
+
let value: string | null = null
|
|
819
|
+
if (ctx.highlightedValue) {
|
|
820
|
+
value = ctx.collection.next(ctx.highlightedValue)
|
|
821
|
+
if (!value && ctx.loopFocus) value = ctx.collection.first()
|
|
822
|
+
} else {
|
|
823
|
+
value = ctx.collection.first()
|
|
824
|
+
}
|
|
592
825
|
set.highlightedItem(ctx, value)
|
|
593
826
|
},
|
|
594
827
|
highlightPrevItem(ctx) {
|
|
595
|
-
|
|
828
|
+
let value: string | null = null
|
|
829
|
+
if (ctx.highlightedValue) {
|
|
830
|
+
value = ctx.collection.prev(ctx.highlightedValue)
|
|
831
|
+
if (!value && ctx.loopFocus) value = ctx.collection.last()
|
|
832
|
+
} else {
|
|
833
|
+
value = ctx.collection.last()
|
|
834
|
+
}
|
|
596
835
|
set.highlightedItem(ctx, value)
|
|
597
836
|
},
|
|
598
837
|
highlightFirstSelectedItem(ctx) {
|
|
599
|
-
|
|
600
|
-
|
|
838
|
+
raf(() => {
|
|
839
|
+
const [value] = ctx.collection.sort(ctx.value)
|
|
840
|
+
set.highlightedItem(ctx, value)
|
|
841
|
+
})
|
|
842
|
+
},
|
|
843
|
+
highlightFirstOrSelectedItem(ctx) {
|
|
844
|
+
raf(() => {
|
|
845
|
+
let value: string | null = null
|
|
846
|
+
if (ctx.hasSelectedItems) {
|
|
847
|
+
value = ctx.collection.sort(ctx.value)[0]
|
|
848
|
+
} else {
|
|
849
|
+
value = ctx.collection.first()
|
|
850
|
+
}
|
|
851
|
+
set.highlightedItem(ctx, value)
|
|
852
|
+
})
|
|
853
|
+
},
|
|
854
|
+
highlightLastOrSelectedItem(ctx) {
|
|
855
|
+
raf(() => {
|
|
856
|
+
let value: string | null = null
|
|
857
|
+
if (ctx.hasSelectedItems) {
|
|
858
|
+
value = ctx.collection.sort(ctx.value)[0]
|
|
859
|
+
} else {
|
|
860
|
+
value = ctx.collection.last()
|
|
861
|
+
}
|
|
862
|
+
set.highlightedItem(ctx, value)
|
|
863
|
+
})
|
|
601
864
|
},
|
|
602
865
|
autofillInputValue(ctx, evt) {
|
|
603
866
|
const inputEl = dom.getInputEl(ctx)
|
|
604
|
-
if (!ctx.autoComplete || !inputEl || !
|
|
867
|
+
if (!ctx.autoComplete || !inputEl || !evt.keypress) return
|
|
605
868
|
const valueText = ctx.collection.valueToString(ctx.highlightedValue)
|
|
606
869
|
raf(() => {
|
|
607
870
|
inputEl.value = valueText || ctx.inputValue
|
|
@@ -610,33 +873,76 @@ export function machine<T extends CollectionItem>(userContext: UserDefinedContex
|
|
|
610
873
|
setCollection(ctx, evt) {
|
|
611
874
|
ctx.collection = evt.value
|
|
612
875
|
},
|
|
876
|
+
syncSelectedItems(ctx) {
|
|
877
|
+
const prevSelectedItems = ctx.selectedItems
|
|
878
|
+
ctx.selectedItems = ctx.value.map((v) => {
|
|
879
|
+
const foundItem = prevSelectedItems.find((item) => ctx.collection.itemToValue(item) === v)
|
|
880
|
+
if (foundItem) return foundItem
|
|
881
|
+
return ctx.collection.item(v)
|
|
882
|
+
})
|
|
883
|
+
},
|
|
884
|
+
toggleVisibility(ctx, evt, { send }) {
|
|
885
|
+
send({ type: ctx.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: evt })
|
|
886
|
+
},
|
|
613
887
|
},
|
|
614
888
|
},
|
|
615
889
|
)
|
|
616
890
|
}
|
|
617
891
|
|
|
618
892
|
const invoke = {
|
|
619
|
-
|
|
893
|
+
valueChange: (ctx: MachineContext) => {
|
|
620
894
|
ctx.onValueChange?.({
|
|
621
895
|
value: Array.from(ctx.value),
|
|
622
896
|
items: ctx.selectedItems,
|
|
623
897
|
})
|
|
624
898
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
899
|
+
const prevSelectedItems = ctx.selectedItems
|
|
900
|
+
|
|
901
|
+
// side effect
|
|
902
|
+
ctx.selectedItems = ctx.value.map((v) => {
|
|
903
|
+
const foundItem = prevSelectedItems.find((item) => ctx.collection.itemToValue(item) === v)
|
|
904
|
+
if (foundItem) return foundItem
|
|
905
|
+
return ctx.collection.item(v)
|
|
630
906
|
})
|
|
907
|
+
|
|
908
|
+
const valueAsString = ctx.collection.itemsToString(ctx.selectedItems)
|
|
909
|
+
|
|
910
|
+
ctx.valueAsString = valueAsString
|
|
911
|
+
|
|
912
|
+
let nextInputValue: string | undefined
|
|
913
|
+
|
|
914
|
+
if (ctx.getSelectionValue) {
|
|
915
|
+
//
|
|
916
|
+
nextInputValue = ctx.getSelectionValue({
|
|
917
|
+
inputValue: ctx.inputValue,
|
|
918
|
+
selectedItems: Array.from(ctx.selectedItems),
|
|
919
|
+
valueAsString,
|
|
920
|
+
})
|
|
921
|
+
//
|
|
922
|
+
} else {
|
|
923
|
+
//
|
|
924
|
+
nextInputValue = match(ctx.selectionBehavior, {
|
|
925
|
+
replace: ctx.valueAsString,
|
|
926
|
+
preserve: ctx.inputValue,
|
|
927
|
+
clear: "",
|
|
928
|
+
})
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
ctx.inputValue = nextInputValue
|
|
932
|
+
|
|
933
|
+
invoke.inputChange(ctx)
|
|
631
934
|
},
|
|
632
935
|
highlightChange: (ctx: MachineContext) => {
|
|
633
936
|
ctx.onHighlightChange?.({
|
|
634
937
|
highlightedValue: ctx.highlightedValue,
|
|
635
938
|
highligtedItem: ctx.highlightedItem,
|
|
636
939
|
})
|
|
940
|
+
|
|
941
|
+
// side effect
|
|
942
|
+
ctx.highlightedItem = ctx.collection.item(ctx.highlightedValue)
|
|
637
943
|
},
|
|
638
944
|
inputChange: (ctx: MachineContext) => {
|
|
639
|
-
ctx.onInputValueChange?.({
|
|
945
|
+
ctx.onInputValueChange?.({ inputValue: ctx.inputValue })
|
|
640
946
|
},
|
|
641
947
|
}
|
|
642
948
|
|
|
@@ -648,16 +954,16 @@ const set = {
|
|
|
648
954
|
|
|
649
955
|
if (value == null && force) {
|
|
650
956
|
ctx.value = []
|
|
651
|
-
invoke.
|
|
957
|
+
invoke.valueChange(ctx)
|
|
652
958
|
return
|
|
653
959
|
}
|
|
654
960
|
ctx.value = ctx.multiple ? addOrRemove(ctx.value, value!) : [value!]
|
|
655
|
-
invoke.
|
|
961
|
+
invoke.valueChange(ctx)
|
|
656
962
|
},
|
|
657
963
|
selectedItems: (ctx: MachineContext, value: string[]) => {
|
|
658
964
|
if (isEqual(ctx.value, value)) return
|
|
659
965
|
ctx.value = value
|
|
660
|
-
invoke.
|
|
966
|
+
invoke.valueChange(ctx)
|
|
661
967
|
},
|
|
662
968
|
highlightedItem: (ctx: MachineContext, value: string | null | undefined, force = false) => {
|
|
663
969
|
if (isEqual(ctx.highlightedValue, value)) return
|