@zag-js/combobox 0.47.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.connect.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
clickIfLink,
|
|
3
|
+
getEventKey,
|
|
4
|
+
getNativeEvent,
|
|
5
|
+
isContextMenuEvent,
|
|
6
|
+
isLeftClick,
|
|
7
|
+
type EventKeyMap,
|
|
8
|
+
} from "@zag-js/dom-event"
|
|
9
|
+
import { ariaAttr, dataAttr, isDownloadingEvent, isOpeningInNewTab, raf } from "@zag-js/dom-query"
|
|
3
10
|
import { getPlacementStyles } from "@zag-js/popper"
|
|
4
11
|
import type { NormalizeProps, PropTypes } from "@zag-js/types"
|
|
5
12
|
import { parts } from "./combobox.anatomy"
|
|
6
13
|
import { dom } from "./combobox.dom"
|
|
7
|
-
import type { CollectionItem, ItemProps, MachineApi, Send, State } from "./combobox.types"
|
|
14
|
+
import type { CollectionItem, ItemProps, ItemState, MachineApi, Send, State } from "./combobox.types"
|
|
8
15
|
|
|
9
16
|
export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
10
17
|
state: State,
|
|
@@ -14,36 +21,37 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
14
21
|
const translations = state.context.translations
|
|
15
22
|
const collection = state.context.collection
|
|
16
23
|
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
24
|
+
const disabled = state.context.disabled
|
|
25
|
+
const interactive = state.context.isInteractive
|
|
26
|
+
const invalid = state.context.invalid
|
|
27
|
+
const readOnly = state.context.readOnly
|
|
21
28
|
|
|
22
|
-
const
|
|
23
|
-
const
|
|
29
|
+
const open = state.hasTag("open")
|
|
30
|
+
const focused = state.hasTag("focused")
|
|
31
|
+
const isDialogPopup = state.context.popup === "dialog"
|
|
24
32
|
|
|
25
33
|
const popperStyles = getPlacementStyles({
|
|
26
34
|
...state.context.positioning,
|
|
27
35
|
placement: state.context.currentPlacement,
|
|
28
36
|
})
|
|
29
37
|
|
|
30
|
-
function getItemState(props: ItemProps) {
|
|
38
|
+
function getItemState(props: ItemProps): ItemState {
|
|
31
39
|
const { item } = props
|
|
32
40
|
const disabled = collection.isItemDisabled(item)
|
|
33
41
|
const value = collection.itemToValue(item)
|
|
34
42
|
return {
|
|
35
43
|
value,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
disabled: Boolean(disabled || disabled),
|
|
45
|
+
highlighted: state.context.highlightedValue === value,
|
|
46
|
+
selected: state.context.value.includes(value),
|
|
39
47
|
}
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
return {
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
focused,
|
|
52
|
+
open,
|
|
45
53
|
inputValue: state.context.inputValue,
|
|
46
|
-
|
|
54
|
+
inputEmpty: state.context.isInputValueEmpty,
|
|
47
55
|
highlightedValue: state.context.highlightedValue,
|
|
48
56
|
highlightedItem: state.context.highlightedItem,
|
|
49
57
|
value: state.context.value,
|
|
@@ -79,19 +87,16 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
79
87
|
focus() {
|
|
80
88
|
dom.getInputEl(state.context)?.focus()
|
|
81
89
|
},
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
setOpen(_open) {
|
|
91
|
+
if (_open === open) return
|
|
92
|
+
send(_open ? "OPEN" : "CLOSE")
|
|
84
93
|
},
|
|
85
|
-
close() {
|
|
86
|
-
send("CLOSE")
|
|
87
|
-
},
|
|
88
|
-
|
|
89
94
|
rootProps: normalize.element({
|
|
90
95
|
...parts.root.attrs,
|
|
91
96
|
dir: state.context.dir,
|
|
92
97
|
id: dom.getRootId(state.context),
|
|
93
|
-
"data-invalid": dataAttr(
|
|
94
|
-
"data-readonly": dataAttr(
|
|
98
|
+
"data-invalid": dataAttr(invalid),
|
|
99
|
+
"data-readonly": dataAttr(readOnly),
|
|
95
100
|
}),
|
|
96
101
|
|
|
97
102
|
labelProps: normalize.label({
|
|
@@ -99,20 +104,25 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
99
104
|
dir: state.context.dir,
|
|
100
105
|
htmlFor: dom.getInputId(state.context),
|
|
101
106
|
id: dom.getLabelId(state.context),
|
|
102
|
-
"data-readonly": dataAttr(
|
|
103
|
-
"data-disabled": dataAttr(
|
|
104
|
-
"data-invalid": dataAttr(
|
|
105
|
-
"data-focus": dataAttr(
|
|
107
|
+
"data-readonly": dataAttr(readOnly),
|
|
108
|
+
"data-disabled": dataAttr(disabled),
|
|
109
|
+
"data-invalid": dataAttr(invalid),
|
|
110
|
+
"data-focus": dataAttr(focused),
|
|
111
|
+
onClick(event) {
|
|
112
|
+
if (!isDialogPopup) return
|
|
113
|
+
event.preventDefault()
|
|
114
|
+
dom.getTriggerEl(state.context)?.focus({ preventScroll: true })
|
|
115
|
+
},
|
|
106
116
|
}),
|
|
107
117
|
|
|
108
118
|
controlProps: normalize.element({
|
|
109
119
|
...parts.control.attrs,
|
|
110
120
|
dir: state.context.dir,
|
|
111
121
|
id: dom.getControlId(state.context),
|
|
112
|
-
"data-state":
|
|
113
|
-
"data-focus": dataAttr(
|
|
114
|
-
"data-disabled": dataAttr(
|
|
115
|
-
"data-invalid": dataAttr(
|
|
122
|
+
"data-state": open ? "open" : "closed",
|
|
123
|
+
"data-focus": dataAttr(focused),
|
|
124
|
+
"data-disabled": dataAttr(disabled),
|
|
125
|
+
"data-invalid": dataAttr(invalid),
|
|
116
126
|
}),
|
|
117
127
|
|
|
118
128
|
positionerProps: normalize.element({
|
|
@@ -125,97 +135,93 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
125
135
|
inputProps: normalize.input({
|
|
126
136
|
...parts.input.attrs,
|
|
127
137
|
dir: state.context.dir,
|
|
128
|
-
"aria-invalid": ariaAttr(
|
|
129
|
-
"data-invalid": dataAttr(
|
|
138
|
+
"aria-invalid": ariaAttr(invalid),
|
|
139
|
+
"data-invalid": dataAttr(invalid),
|
|
130
140
|
name: state.context.name,
|
|
131
141
|
form: state.context.form,
|
|
132
|
-
disabled:
|
|
142
|
+
disabled: disabled,
|
|
133
143
|
autoFocus: state.context.autoFocus,
|
|
134
144
|
autoComplete: "off",
|
|
135
145
|
autoCorrect: "off",
|
|
136
146
|
autoCapitalize: "none",
|
|
137
147
|
spellCheck: "false",
|
|
138
|
-
readOnly:
|
|
148
|
+
readOnly: readOnly,
|
|
139
149
|
placeholder: state.context.placeholder,
|
|
140
150
|
id: dom.getInputId(state.context),
|
|
141
151
|
type: "text",
|
|
142
152
|
role: "combobox",
|
|
143
153
|
defaultValue: state.context.inputValue,
|
|
144
154
|
"aria-autocomplete": state.context.autoComplete ? "both" : "list",
|
|
145
|
-
"aria-controls":
|
|
146
|
-
"aria-expanded":
|
|
147
|
-
"data-state":
|
|
155
|
+
"aria-controls": isDialogPopup ? dom.getListId(state.context) : dom.getContentId(state.context),
|
|
156
|
+
"aria-expanded": open,
|
|
157
|
+
"data-state": open ? "open" : "closed",
|
|
148
158
|
"aria-activedescendant": state.context.highlightedValue
|
|
149
159
|
? dom.getItemId(state.context, state.context.highlightedValue)
|
|
150
160
|
: undefined,
|
|
151
|
-
onCompositionStart() {
|
|
152
|
-
send("INPUT.COMPOSITION_START")
|
|
153
|
-
},
|
|
154
|
-
onCompositionEnd() {
|
|
155
|
-
raf(() => {
|
|
156
|
-
send("INPUT.COMPOSITION_END")
|
|
157
|
-
})
|
|
158
|
-
},
|
|
159
161
|
onClick() {
|
|
160
|
-
if (!
|
|
162
|
+
if (!state.context.openOnClick) return
|
|
163
|
+
if (!interactive) return
|
|
161
164
|
send("INPUT.CLICK")
|
|
162
165
|
},
|
|
163
166
|
onFocus() {
|
|
164
|
-
if (
|
|
167
|
+
if (disabled) return
|
|
165
168
|
send("INPUT.FOCUS")
|
|
166
169
|
},
|
|
167
170
|
onBlur() {
|
|
168
|
-
if (
|
|
171
|
+
if (disabled) return
|
|
169
172
|
send("INPUT.BLUR")
|
|
170
173
|
},
|
|
171
174
|
onChange(event) {
|
|
172
175
|
send({ type: "INPUT.CHANGE", value: event.currentTarget.value })
|
|
173
176
|
},
|
|
174
177
|
onKeyDown(event) {
|
|
175
|
-
if (
|
|
178
|
+
if (event.defaultPrevented) return
|
|
179
|
+
if (!interactive) return
|
|
176
180
|
|
|
177
181
|
const evt = getNativeEvent(event)
|
|
178
182
|
if (evt.ctrlKey || evt.shiftKey || evt.isComposing) return
|
|
179
183
|
|
|
184
|
+
const openOnKeyPress = state.context.openOnKeyPress
|
|
185
|
+
const isModifierKey = event.ctrlKey || event.metaKey || event.shiftKey
|
|
186
|
+
const keypress = true
|
|
187
|
+
|
|
180
188
|
const keymap: EventKeyMap = {
|
|
181
189
|
ArrowDown(event) {
|
|
182
|
-
|
|
190
|
+
if (!openOnKeyPress && !open) return
|
|
191
|
+
send({ type: event.altKey ? "OPEN" : "INPUT.ARROW_DOWN", keypress })
|
|
183
192
|
event.preventDefault()
|
|
184
|
-
event.stopPropagation()
|
|
185
193
|
},
|
|
186
194
|
ArrowUp() {
|
|
187
|
-
|
|
195
|
+
if (!openOnKeyPress && !open) return
|
|
196
|
+
send({ type: event.altKey ? "CLOSE" : "INPUT.ARROW_UP", keypress })
|
|
188
197
|
event.preventDefault()
|
|
189
|
-
event.stopPropagation()
|
|
190
198
|
},
|
|
191
199
|
Home(event) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (isOpen) {
|
|
200
|
+
if (isModifierKey) return
|
|
201
|
+
send({ type: "INPUT.HOME", keypress })
|
|
202
|
+
if (open) {
|
|
196
203
|
event.preventDefault()
|
|
197
|
-
event.stopPropagation()
|
|
198
204
|
}
|
|
199
205
|
},
|
|
200
206
|
End(event) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (isOpen) {
|
|
207
|
+
if (isModifierKey) return
|
|
208
|
+
send({ type: "INPUT.END", keypress })
|
|
209
|
+
if (open) {
|
|
205
210
|
event.preventDefault()
|
|
206
|
-
event.stopPropagation()
|
|
207
211
|
}
|
|
208
212
|
},
|
|
209
|
-
Enter() {
|
|
210
|
-
if (
|
|
211
|
-
send("INPUT.ENTER")
|
|
212
|
-
|
|
213
|
-
|
|
213
|
+
Enter(event) {
|
|
214
|
+
if (evt.isComposing) return
|
|
215
|
+
send({ type: "INPUT.ENTER", keypress })
|
|
216
|
+
if (open) {
|
|
217
|
+
event.preventDefault()
|
|
218
|
+
}
|
|
219
|
+
const itemEl = dom.getHighlightedItemEl(state.context)
|
|
220
|
+
clickIfLink(itemEl)
|
|
214
221
|
},
|
|
215
222
|
Escape() {
|
|
216
|
-
send("INPUT.ESCAPE")
|
|
223
|
+
send({ type: "INPUT.ESCAPE", keypress })
|
|
217
224
|
event.preventDefault()
|
|
218
|
-
// don't stop propagation. this is handled by the dismissable layer
|
|
219
225
|
},
|
|
220
226
|
}
|
|
221
227
|
|
|
@@ -229,59 +235,97 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
229
235
|
...parts.trigger.attrs,
|
|
230
236
|
dir: state.context.dir,
|
|
231
237
|
id: dom.getTriggerId(state.context),
|
|
232
|
-
"aria-haspopup": "listbox",
|
|
238
|
+
"aria-haspopup": isDialogPopup ? "dialog" : "listbox",
|
|
233
239
|
type: "button",
|
|
234
|
-
tabIndex: -1,
|
|
240
|
+
tabIndex: isDialogPopup ? 0 : -1,
|
|
235
241
|
"aria-label": translations.triggerLabel,
|
|
236
|
-
"aria-expanded":
|
|
237
|
-
"data-state":
|
|
238
|
-
"aria-controls":
|
|
239
|
-
disabled:
|
|
240
|
-
"data-readonly": dataAttr(
|
|
241
|
-
"data-disabled": dataAttr(
|
|
242
|
-
|
|
242
|
+
"aria-expanded": open,
|
|
243
|
+
"data-state": open ? "open" : "closed",
|
|
244
|
+
"aria-controls": open ? dom.getContentId(state.context) : undefined,
|
|
245
|
+
disabled: disabled,
|
|
246
|
+
"data-readonly": dataAttr(readOnly),
|
|
247
|
+
"data-disabled": dataAttr(disabled),
|
|
248
|
+
onClick(event) {
|
|
243
249
|
const evt = getNativeEvent(event)
|
|
244
|
-
if (!
|
|
250
|
+
if (!interactive) return
|
|
251
|
+
if (!isLeftClick(evt)) return
|
|
245
252
|
send("TRIGGER.CLICK")
|
|
253
|
+
},
|
|
254
|
+
onPointerDown(event) {
|
|
255
|
+
if (!interactive) return
|
|
256
|
+
if (event.pointerType === "touch") return
|
|
246
257
|
event.preventDefault()
|
|
258
|
+
queueMicrotask(() => {
|
|
259
|
+
dom.getInputEl(state.context)?.focus({ preventScroll: true })
|
|
260
|
+
})
|
|
247
261
|
},
|
|
248
|
-
|
|
249
|
-
if (event.
|
|
250
|
-
|
|
262
|
+
onKeyDown(event) {
|
|
263
|
+
if (event.defaultPrevented) return
|
|
264
|
+
if (!isDialogPopup) return
|
|
265
|
+
|
|
266
|
+
const keyMap: EventKeyMap = {
|
|
267
|
+
ArrowDown() {
|
|
268
|
+
send("INPUT.FOCUS")
|
|
269
|
+
send("INPUT.ARROW_DOWN")
|
|
270
|
+
raf(() => {
|
|
271
|
+
dom.getInputEl(state.context)?.focus({ preventScroll: true })
|
|
272
|
+
})
|
|
273
|
+
},
|
|
274
|
+
ArrowUp() {
|
|
275
|
+
send("INPUT.FOCUS")
|
|
276
|
+
send("INPUT.ARROW_UP")
|
|
277
|
+
raf(() => {
|
|
278
|
+
dom.getInputEl(state.context)?.focus({ preventScroll: true })
|
|
279
|
+
})
|
|
280
|
+
},
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const key = getEventKey(event, state.context)
|
|
284
|
+
const exec = keyMap[key]
|
|
285
|
+
|
|
286
|
+
if (exec) {
|
|
287
|
+
exec(event)
|
|
288
|
+
event.preventDefault()
|
|
289
|
+
}
|
|
251
290
|
},
|
|
252
|
-
style: { outline: 0 },
|
|
253
291
|
}),
|
|
254
292
|
|
|
255
293
|
contentProps: normalize.element({
|
|
256
294
|
...parts.content.attrs,
|
|
257
295
|
dir: state.context.dir,
|
|
258
296
|
id: dom.getContentId(state.context),
|
|
259
|
-
role: "listbox",
|
|
297
|
+
role: isDialogPopup ? "dialog" : "listbox",
|
|
260
298
|
tabIndex: -1,
|
|
261
|
-
hidden: !
|
|
262
|
-
"data-state":
|
|
299
|
+
hidden: !open,
|
|
300
|
+
"data-state": open ? "open" : "closed",
|
|
263
301
|
"aria-labelledby": dom.getLabelId(state.context),
|
|
264
|
-
"aria-multiselectable": state.context.multiple ? true : undefined,
|
|
302
|
+
"aria-multiselectable": state.context.multiple && !isDialogPopup ? true : undefined,
|
|
265
303
|
onPointerDown(event) {
|
|
266
304
|
// prevent options or elements within listbox from taking focus
|
|
267
305
|
event.preventDefault()
|
|
268
306
|
},
|
|
269
307
|
}),
|
|
270
308
|
|
|
309
|
+
// only used when triggerOnly: true
|
|
310
|
+
listProps: normalize.element({
|
|
311
|
+
id: dom.getListId(state.context),
|
|
312
|
+
role: isDialogPopup ? "listbox" : undefined,
|
|
313
|
+
"aria-multiselectable": isDialogPopup && state.context.multiple ? true : undefined,
|
|
314
|
+
}),
|
|
315
|
+
|
|
271
316
|
clearTriggerProps: normalize.button({
|
|
272
317
|
...parts.clearTrigger.attrs,
|
|
273
318
|
dir: state.context.dir,
|
|
274
319
|
id: dom.getClearTriggerId(state.context),
|
|
275
320
|
type: "button",
|
|
276
321
|
tabIndex: -1,
|
|
277
|
-
disabled:
|
|
322
|
+
disabled: disabled,
|
|
278
323
|
"aria-label": translations.clearTriggerLabel,
|
|
324
|
+
"aria-controls": dom.getInputId(state.context),
|
|
279
325
|
hidden: !state.context.value.length,
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (!isInteractive || !isLeftClick(evt)) return
|
|
326
|
+
onClick() {
|
|
327
|
+
if (!interactive) return
|
|
283
328
|
send({ type: "VALUE.CLEAR", src: "clear-trigger" })
|
|
284
|
-
event.preventDefault()
|
|
285
329
|
},
|
|
286
330
|
}),
|
|
287
331
|
|
|
@@ -297,22 +341,28 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
297
341
|
id: dom.getItemId(state.context, value),
|
|
298
342
|
role: "option",
|
|
299
343
|
tabIndex: -1,
|
|
300
|
-
"data-highlighted": dataAttr(itemState.
|
|
301
|
-
"data-state": itemState.
|
|
302
|
-
"aria-selected": itemState.
|
|
303
|
-
"aria-disabled": itemState.
|
|
304
|
-
"data-disabled": dataAttr(itemState.
|
|
344
|
+
"data-highlighted": dataAttr(itemState.highlighted),
|
|
345
|
+
"data-state": itemState.selected ? "checked" : "unchecked",
|
|
346
|
+
"aria-selected": itemState.highlighted,
|
|
347
|
+
"aria-disabled": itemState.disabled,
|
|
348
|
+
"data-disabled": dataAttr(itemState.disabled),
|
|
305
349
|
"data-value": itemState.value,
|
|
306
350
|
onPointerMove() {
|
|
307
|
-
if (itemState.
|
|
308
|
-
send({ type: "ITEM.
|
|
351
|
+
if (itemState.disabled) return
|
|
352
|
+
send({ type: "ITEM.POINTER_MOVE", value })
|
|
309
353
|
},
|
|
310
354
|
onPointerLeave() {
|
|
311
|
-
if (
|
|
355
|
+
if (props.persistFocus) return
|
|
356
|
+
if (itemState.disabled) return
|
|
357
|
+
const mouseMoved = state.previousEvent.type === "ITEM.POINTER_MOVE"
|
|
358
|
+
if (!mouseMoved) return
|
|
312
359
|
send({ type: "ITEM.POINTER_LEAVE", value })
|
|
313
360
|
},
|
|
314
361
|
onPointerUp(event) {
|
|
315
|
-
if (
|
|
362
|
+
if (isDownloadingEvent(event)) return
|
|
363
|
+
if (isOpeningInNewTab(event)) return
|
|
364
|
+
if (isContextMenuEvent(event)) return
|
|
365
|
+
if (itemState.disabled) return
|
|
316
366
|
send({ type: "ITEM.CLICK", src: "pointerup", value })
|
|
317
367
|
},
|
|
318
368
|
onTouchEnd(event) {
|
|
@@ -328,8 +378,8 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
328
378
|
return normalize.element({
|
|
329
379
|
...parts.itemText.attrs,
|
|
330
380
|
dir: state.context.dir,
|
|
331
|
-
"data-disabled": dataAttr(itemState.
|
|
332
|
-
"data-highlighted": dataAttr(itemState.
|
|
381
|
+
"data-disabled": dataAttr(itemState.disabled),
|
|
382
|
+
"data-highlighted": dataAttr(itemState.highlighted),
|
|
333
383
|
})
|
|
334
384
|
},
|
|
335
385
|
getItemIndicatorProps(props) {
|
|
@@ -338,8 +388,8 @@ export function connect<T extends PropTypes, V extends CollectionItem>(
|
|
|
338
388
|
"aria-hidden": true,
|
|
339
389
|
...parts.itemIndicator.attrs,
|
|
340
390
|
dir: state.context.dir,
|
|
341
|
-
"data-state": itemState.
|
|
342
|
-
hidden: !itemState.
|
|
391
|
+
"data-state": itemState.selected ? "checked" : "unchecked",
|
|
392
|
+
hidden: !itemState.selected,
|
|
343
393
|
})
|
|
344
394
|
},
|
|
345
395
|
|
package/src/combobox.dom.ts
CHANGED
|
@@ -7,6 +7,7 @@ export const dom = createScope({
|
|
|
7
7
|
getControlId: (ctx: Ctx) => ctx.ids?.control ?? `combobox:${ctx.id}:control`,
|
|
8
8
|
getInputId: (ctx: Ctx) => ctx.ids?.input ?? `combobox:${ctx.id}:input`,
|
|
9
9
|
getContentId: (ctx: Ctx) => ctx.ids?.content ?? `combobox:${ctx.id}:content`,
|
|
10
|
+
getListId: (ctx: Ctx) => `combobox:${ctx.id}:listbox`,
|
|
10
11
|
getPositionerId: (ctx: Ctx) => ctx.ids?.positioner ?? `combobox:${ctx.id}:popper`,
|
|
11
12
|
getTriggerId: (ctx: Ctx) => ctx.ids?.trigger ?? `combobox:${ctx.id}:toggle-btn`,
|
|
12
13
|
getClearTriggerId: (ctx: Ctx) => ctx.ids?.clearTrigger ?? `combobox:${ctx.id}:clear-btn`,
|
|
@@ -16,6 +17,7 @@ export const dom = createScope({
|
|
|
16
17
|
getItemId: (ctx: Ctx, id: string) => `combobox:${ctx.id}:option:${id}`,
|
|
17
18
|
|
|
18
19
|
getContentEl: (ctx: Ctx) => dom.getById(ctx, dom.getContentId(ctx)),
|
|
20
|
+
getListEl: (ctx: Ctx) => dom.getById(ctx, dom.getListId(ctx)),
|
|
19
21
|
getInputEl: (ctx: Ctx) => dom.getById<HTMLInputElement>(ctx, dom.getInputId(ctx)),
|
|
20
22
|
getPositionerEl: (ctx: Ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
|
|
21
23
|
getControlEl: (ctx: Ctx) => dom.getById(ctx, dom.getControlId(ctx)),
|