shadcn_phlexcomponents 0.1.11 → 0.1.14
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.
- checksums.yaml +4 -4
- data/app/javascript/controllers/accordion_controller.ts +65 -62
- data/app/javascript/controllers/alert_dialog_controller.ts +12 -0
- data/app/javascript/controllers/avatar_controller.ts +7 -2
- data/app/javascript/controllers/checkbox_controller.ts +11 -4
- data/app/javascript/controllers/collapsible_controller.ts +12 -5
- data/app/javascript/controllers/combobox_controller.ts +270 -39
- data/app/javascript/controllers/command_controller.ts +223 -51
- data/app/javascript/controllers/date_picker_controller.ts +185 -125
- data/app/javascript/controllers/date_range_picker_controller.ts +89 -79
- data/app/javascript/controllers/dialog_controller.ts +59 -57
- data/app/javascript/controllers/dropdown_menu_controller.ts +212 -36
- data/app/javascript/controllers/dropdown_menu_sub_controller.ts +31 -29
- data/app/javascript/controllers/form_field_controller.ts +6 -1
- data/app/javascript/controllers/hover_card_controller.ts +36 -26
- data/app/javascript/controllers/loading_button_controller.ts +6 -1
- data/app/javascript/controllers/popover_controller.ts +42 -65
- data/app/javascript/controllers/progress_controller.ts +9 -3
- data/app/javascript/controllers/radio_group_controller.ts +16 -9
- data/app/javascript/controllers/select_controller.ts +206 -65
- data/app/javascript/controllers/slider_controller.ts +23 -16
- data/app/javascript/controllers/switch_controller.ts +11 -4
- data/app/javascript/controllers/tabs_controller.ts +26 -18
- data/app/javascript/controllers/theme_switcher_controller.ts +6 -1
- data/app/javascript/controllers/toast_container_controller.ts +6 -1
- data/app/javascript/controllers/toast_controller.ts +7 -1
- data/app/javascript/controllers/toggle_controller.ts +28 -0
- data/app/javascript/controllers/toggle_group_controller.ts +28 -0
- data/app/javascript/controllers/tooltip_controller.ts +43 -31
- data/app/javascript/shadcn_phlexcomponents.ts +29 -25
- data/app/javascript/utils/command.ts +544 -0
- data/app/javascript/utils/floating_ui.ts +196 -0
- data/app/javascript/utils/index.ts +417 -0
- data/app/stylesheets/date_picker.css +118 -0
- data/lib/shadcn_phlexcomponents/alias.rb +3 -0
- data/lib/shadcn_phlexcomponents/components/accordion.rb +2 -1
- data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +18 -15
- data/lib/shadcn_phlexcomponents/components/base.rb +14 -0
- data/lib/shadcn_phlexcomponents/components/collapsible.rb +1 -2
- data/lib/shadcn_phlexcomponents/components/combobox.rb +87 -57
- data/lib/shadcn_phlexcomponents/components/command.rb +77 -47
- data/lib/shadcn_phlexcomponents/components/date_picker.rb +25 -81
- data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +21 -4
- data/lib/shadcn_phlexcomponents/components/dialog.rb +14 -12
- data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +5 -4
- data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +2 -1
- data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +64 -0
- data/lib/shadcn_phlexcomponents/components/form.rb +14 -0
- data/lib/shadcn_phlexcomponents/components/hover_card.rb +3 -2
- data/lib/shadcn_phlexcomponents/components/popover.rb +3 -3
- data/lib/shadcn_phlexcomponents/components/select.rb +10 -25
- data/lib/shadcn_phlexcomponents/components/sheet.rb +15 -11
- data/lib/shadcn_phlexcomponents/components/table.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/tabs.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/toast_container.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/toggle.rb +54 -0
- data/lib/shadcn_phlexcomponents/components/tooltip.rb +3 -2
- data/lib/shadcn_phlexcomponents/engine.rb +1 -5
- data/lib/shadcn_phlexcomponents/version.rb +1 -1
- metadata +9 -4
- data/app/javascript/controllers/command_root_controller.ts +0 -355
- data/app/javascript/controllers/dropdown_menu_root_controller.ts +0 -234
- data/app/javascript/utils.ts +0 -437
@@ -0,0 +1,544 @@
|
|
1
|
+
import { Command } from '../controllers/command_controller'
|
2
|
+
import {
|
3
|
+
Combobox,
|
4
|
+
ComboboxController,
|
5
|
+
} from '../controllers/combobox_controller'
|
6
|
+
import { getNextEnabledIndex, getPreviousEnabledIndex } from '.'
|
7
|
+
|
8
|
+
const scrollToItem = (controller: Command | Combobox, index: number) => {
|
9
|
+
const item = controller.filteredItems[index]
|
10
|
+
const itemRect = item.getBoundingClientRect()
|
11
|
+
const listContainerRect =
|
12
|
+
controller.listContainerTarget.getBoundingClientRect()
|
13
|
+
let newScrollTop = null as number | null
|
14
|
+
|
15
|
+
const maxScrollTop =
|
16
|
+
controller.listContainerTarget.scrollHeight -
|
17
|
+
controller.listContainerTarget.clientHeight
|
18
|
+
|
19
|
+
// scroll to bottom
|
20
|
+
if (itemRect.bottom - listContainerRect.bottom > 0) {
|
21
|
+
if (index === controller.filteredItems.length - 1) {
|
22
|
+
newScrollTop = maxScrollTop
|
23
|
+
} else {
|
24
|
+
newScrollTop =
|
25
|
+
controller.listContainerTarget.scrollTop +
|
26
|
+
(itemRect.bottom - listContainerRect.bottom)
|
27
|
+
}
|
28
|
+
} else if (listContainerRect.top - itemRect.top > 0) {
|
29
|
+
// scroll to top
|
30
|
+
if (index === 0) {
|
31
|
+
newScrollTop = 0
|
32
|
+
} else {
|
33
|
+
newScrollTop =
|
34
|
+
controller.listContainerTarget.scrollTop -
|
35
|
+
(listContainerRect.top - itemRect.top)
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
if (newScrollTop !== null) {
|
40
|
+
controller.scrollingViaKeyboard = true
|
41
|
+
|
42
|
+
if (newScrollTop >= 0 && newScrollTop <= maxScrollTop) {
|
43
|
+
controller.listContainerTarget.scrollTop = newScrollTop
|
44
|
+
}
|
45
|
+
|
46
|
+
// Clear the flag after scroll settles
|
47
|
+
clearTimeout(controller.keyboardScrollTimeout)
|
48
|
+
controller.keyboardScrollTimeout = window.setTimeout(() => {
|
49
|
+
controller.scrollingViaKeyboard = false
|
50
|
+
}, 200)
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
const highlightItem = (
|
55
|
+
controller: Command | Combobox,
|
56
|
+
event: MouseEvent | KeyboardEvent | null = null,
|
57
|
+
index: number | null = null,
|
58
|
+
) => {
|
59
|
+
if (event !== null) {
|
60
|
+
if (event instanceof KeyboardEvent) {
|
61
|
+
const key = event.key
|
62
|
+
const item = controller.filteredItems.find(
|
63
|
+
(i) => i.dataset.highlighted === 'true',
|
64
|
+
)
|
65
|
+
|
66
|
+
if (item) {
|
67
|
+
const index = controller.filteredItems.indexOf(item)
|
68
|
+
|
69
|
+
let newIndex = 0
|
70
|
+
if (key === 'ArrowUp') {
|
71
|
+
newIndex = getPreviousEnabledIndex({
|
72
|
+
items: controller.filteredItems,
|
73
|
+
currentIndex: index,
|
74
|
+
filterFn: (item: HTMLElement) =>
|
75
|
+
item.dataset.disabled === undefined,
|
76
|
+
wrapAround: false,
|
77
|
+
})
|
78
|
+
} else {
|
79
|
+
newIndex = getNextEnabledIndex({
|
80
|
+
items: controller.filteredItems,
|
81
|
+
currentIndex: index,
|
82
|
+
filterFn: (item: HTMLElement) =>
|
83
|
+
item.dataset.disabled === undefined,
|
84
|
+
wrapAround: false,
|
85
|
+
})
|
86
|
+
}
|
87
|
+
|
88
|
+
controller.highlightItemByIndex(newIndex)
|
89
|
+
controller.scrollToItem(newIndex)
|
90
|
+
} else {
|
91
|
+
if (key === 'ArrowUp') {
|
92
|
+
controller.highlightItemByIndex(controller.filteredItems.length - 1)
|
93
|
+
} else {
|
94
|
+
controller.highlightItemByIndex(0)
|
95
|
+
}
|
96
|
+
}
|
97
|
+
} else {
|
98
|
+
// mouse event
|
99
|
+
if (controller.scrollingViaKeyboard) {
|
100
|
+
event.stopImmediatePropagation()
|
101
|
+
return
|
102
|
+
} else {
|
103
|
+
const item = event.currentTarget as HTMLElement
|
104
|
+
const index = controller.filteredItems.indexOf(item)
|
105
|
+
controller.highlightItemByIndex(index)
|
106
|
+
}
|
107
|
+
}
|
108
|
+
} else if (index !== null) {
|
109
|
+
controller.highlightItemByIndex(index)
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
const highlightItemByIndex = (
|
114
|
+
controller: Command | Combobox,
|
115
|
+
index: number,
|
116
|
+
) => {
|
117
|
+
controller.filteredItems.forEach((item, i) => {
|
118
|
+
if (i === index) {
|
119
|
+
item.dataset.highlighted = 'true'
|
120
|
+
} else {
|
121
|
+
item.dataset.highlighted = 'false'
|
122
|
+
}
|
123
|
+
})
|
124
|
+
}
|
125
|
+
|
126
|
+
const filteredItemsChanged = (
|
127
|
+
controller: Command | Combobox,
|
128
|
+
filteredItemIndexes: number[],
|
129
|
+
) => {
|
130
|
+
if (controller.orderedItems) {
|
131
|
+
const filteredItems = filteredItemIndexes.map(
|
132
|
+
(i) => controller.orderedItems[i],
|
133
|
+
)
|
134
|
+
|
135
|
+
// 1. Toggle visibility of items
|
136
|
+
controller.orderedItems.forEach((item) => {
|
137
|
+
if (filteredItems.includes(item)) {
|
138
|
+
item.ariaHidden = 'false'
|
139
|
+
item.classList.remove('hidden')
|
140
|
+
} else {
|
141
|
+
item.ariaHidden = 'true'
|
142
|
+
item.classList.add('hidden')
|
143
|
+
}
|
144
|
+
})
|
145
|
+
|
146
|
+
// 2. Get groups based on order of filtered items
|
147
|
+
const groupIds = filteredItems.map((item) => item.dataset.groupId)
|
148
|
+
const uniqueGroupIds = [...new Set(groupIds)].filter((groupId) => !!groupId)
|
149
|
+
const orderedGroups = uniqueGroupIds.map((groupId) => {
|
150
|
+
return controller.listTarget.querySelector(
|
151
|
+
`[aria-labelledby=${groupId}]`,
|
152
|
+
) as HTMLElement
|
153
|
+
})
|
154
|
+
|
155
|
+
// 3. Append items and groups based on filtered items
|
156
|
+
const appendedGroupIds = [] as string[]
|
157
|
+
|
158
|
+
filteredItems.forEach((item) => {
|
159
|
+
const groupId = item.dataset.groupId
|
160
|
+
|
161
|
+
if (groupId) {
|
162
|
+
const group = orderedGroups.find(
|
163
|
+
(g) => g.getAttribute('aria-labelledby') === groupId,
|
164
|
+
)
|
165
|
+
|
166
|
+
if (group) {
|
167
|
+
group.appendChild(item)
|
168
|
+
|
169
|
+
if (!appendedGroupIds.includes(groupId)) {
|
170
|
+
controller.listTarget.appendChild(group)
|
171
|
+
appendedGroupIds.push(groupId)
|
172
|
+
}
|
173
|
+
}
|
174
|
+
} else {
|
175
|
+
controller.listTarget.appendChild(item)
|
176
|
+
}
|
177
|
+
})
|
178
|
+
|
179
|
+
// 4. Toggle visibility of groups
|
180
|
+
controller.groupTargets.forEach((group) => {
|
181
|
+
const itemsCount = group.querySelectorAll(
|
182
|
+
`[data-${controller.identifier}-target=item][aria-hidden=false]`,
|
183
|
+
).length
|
184
|
+
if (itemsCount > 0) {
|
185
|
+
group.classList.remove('hidden')
|
186
|
+
} else {
|
187
|
+
group.classList.add('hidden')
|
188
|
+
}
|
189
|
+
})
|
190
|
+
|
191
|
+
// 5. Move remote items to the end
|
192
|
+
const remoteItems = Array.from(
|
193
|
+
controller.element.querySelectorAll(
|
194
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-item"][data-remote='true']`,
|
195
|
+
),
|
196
|
+
)
|
197
|
+
remoteItems.forEach((i) => {
|
198
|
+
const isInsideGroup =
|
199
|
+
i.parentElement?.dataset?.shadcnPhlexcomponents ===
|
200
|
+
`${controller.identifier}-group`
|
201
|
+
|
202
|
+
if (isInsideGroup) {
|
203
|
+
const isRemoteGroup = i.parentElement.dataset.remote === 'true'
|
204
|
+
|
205
|
+
// Move group to last
|
206
|
+
if (isRemoteGroup) {
|
207
|
+
controller.listTarget.appendChild(i.parentElement)
|
208
|
+
}
|
209
|
+
} else {
|
210
|
+
// Move item to last
|
211
|
+
controller.listTarget.appendChild(i)
|
212
|
+
}
|
213
|
+
})
|
214
|
+
|
215
|
+
// 6. Assign filteredItems based on the order it is displayed in the DOM
|
216
|
+
controller.filteredItems = Array.from(
|
217
|
+
controller.listTarget.querySelectorAll(
|
218
|
+
`[data-${controller.identifier}-target=item][aria-hidden=false]`,
|
219
|
+
),
|
220
|
+
)
|
221
|
+
|
222
|
+
// 7. Highlight first item
|
223
|
+
controller.highlightItemByIndex(0)
|
224
|
+
|
225
|
+
// 8. Toggle visibility of empty
|
226
|
+
if (controller.isDirty && !controller.isLoading) {
|
227
|
+
if (controller.filteredItems.length > 0) {
|
228
|
+
hideEmpty(controller)
|
229
|
+
} else {
|
230
|
+
showEmpty(controller)
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
const setItemsGroupId = (controller: Command | Combobox) => {
|
237
|
+
controller.itemTargets.forEach((item) => {
|
238
|
+
const parent = item.parentElement
|
239
|
+
|
240
|
+
if (parent?.dataset[`${controller.identifier}Target`] === 'group') {
|
241
|
+
item.dataset.groupId = parent.getAttribute('aria-labelledby') as string
|
242
|
+
}
|
243
|
+
})
|
244
|
+
}
|
245
|
+
|
246
|
+
const search = (controller: Command | Combobox, event: InputEvent) => {
|
247
|
+
const input = event.target as HTMLInputElement
|
248
|
+
const value = input.value.trim()
|
249
|
+
|
250
|
+
if (value.length > 0) {
|
251
|
+
const results = controller.fuse.search(value)
|
252
|
+
|
253
|
+
// Don't show disabled items when filtering
|
254
|
+
let filteredItemIndexes = results.map((result) => result.refIndex)
|
255
|
+
filteredItemIndexes = filteredItemIndexes.filter((index) => {
|
256
|
+
const item = controller.orderedItems[index]
|
257
|
+
return item.dataset.disabled === undefined
|
258
|
+
})
|
259
|
+
|
260
|
+
if (controller.searchPath) {
|
261
|
+
hideSelectedRemoteItems(controller)
|
262
|
+
showLoading(controller)
|
263
|
+
hideList(controller)
|
264
|
+
hideEmpty(controller)
|
265
|
+
controller.filteredItemIndexesValue = filteredItemIndexes
|
266
|
+
performRemoteSearch(controller, value)
|
267
|
+
} else {
|
268
|
+
controller.filteredItemIndexesValue = filteredItemIndexes
|
269
|
+
}
|
270
|
+
} else {
|
271
|
+
if (controller.searchPath) {
|
272
|
+
showSelectedRemoteItems(controller)
|
273
|
+
}
|
274
|
+
controller.filteredItemIndexesValue = Array.from(
|
275
|
+
{ length: controller.orderedItems.length },
|
276
|
+
(_, i) => i,
|
277
|
+
)
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
const performRemoteSearch = async (
|
282
|
+
controller: Command | Combobox,
|
283
|
+
query: string,
|
284
|
+
) => {
|
285
|
+
// Cancel previous request
|
286
|
+
if (controller.abortController) {
|
287
|
+
controller.abortController.abort()
|
288
|
+
}
|
289
|
+
|
290
|
+
// Create new abort controller
|
291
|
+
controller.abortController = new AbortController()
|
292
|
+
|
293
|
+
try {
|
294
|
+
const response = await fetch(`${controller.searchPath}?q=${query}`, {
|
295
|
+
signal: controller.abortController.signal,
|
296
|
+
headers: {
|
297
|
+
Accept: 'application/json',
|
298
|
+
'Content-Type': 'application/json',
|
299
|
+
},
|
300
|
+
})
|
301
|
+
|
302
|
+
if (!response.ok) {
|
303
|
+
throw new Error(`HTTP error! status: ${response.status}`)
|
304
|
+
}
|
305
|
+
|
306
|
+
const data = await response.json()
|
307
|
+
renderRemoteResults(controller, data)
|
308
|
+
showList(controller)
|
309
|
+
} catch (error) {
|
310
|
+
if (error instanceof Error && error.name !== 'AbortError') {
|
311
|
+
console.error('Remote search error:', error)
|
312
|
+
showError(controller)
|
313
|
+
}
|
314
|
+
} finally {
|
315
|
+
hideLoading(controller)
|
316
|
+
}
|
317
|
+
}
|
318
|
+
|
319
|
+
const renderRemoteResults = (
|
320
|
+
controller: Command | Combobox,
|
321
|
+
data: { html: string; group?: string }[],
|
322
|
+
) => {
|
323
|
+
console.log('data', data)
|
324
|
+
data.forEach((item) => {
|
325
|
+
const tempDiv = document.createElement('div')
|
326
|
+
tempDiv.innerHTML = item.html
|
327
|
+
const itemEl = tempDiv.firstElementChild as HTMLElement
|
328
|
+
itemEl.dataset.remote = 'true'
|
329
|
+
itemEl.ariaHidden = 'false'
|
330
|
+
|
331
|
+
if (controller instanceof ComboboxController) {
|
332
|
+
// Don't append same item
|
333
|
+
if (controller.selectedValue === itemEl.dataset.value) {
|
334
|
+
const item = controller.itemTargets.find(
|
335
|
+
(i) => i.dataset.value === controller.selectedValue,
|
336
|
+
)
|
337
|
+
if (item) {
|
338
|
+
item.classList.remove('hidden')
|
339
|
+
item.ariaHidden = 'false'
|
340
|
+
}
|
341
|
+
|
342
|
+
return
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
const group = item.group
|
347
|
+
|
348
|
+
if (group) {
|
349
|
+
const groupEl = controller.groupTargets.find((g) => {
|
350
|
+
const label = g.querySelector(
|
351
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-label"]`,
|
352
|
+
) as HTMLElement
|
353
|
+
if (!label) return false
|
354
|
+
return label.textContent === group
|
355
|
+
})
|
356
|
+
|
357
|
+
if (groupEl) {
|
358
|
+
groupEl.classList.remove('hidden')
|
359
|
+
groupEl.append(itemEl)
|
360
|
+
} else {
|
361
|
+
const template = controller.element.querySelector(
|
362
|
+
'template',
|
363
|
+
) as HTMLTemplateElement
|
364
|
+
|
365
|
+
const clone = template.content.cloneNode(true) as HTMLElement
|
366
|
+
const groupEl = clone.querySelector(
|
367
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-group"]`,
|
368
|
+
) as HTMLElement
|
369
|
+
const groupId = crypto.randomUUID()
|
370
|
+
const label = clone.querySelector(
|
371
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-label"]`,
|
372
|
+
) as HTMLElement
|
373
|
+
label.textContent = group
|
374
|
+
label.id = groupId
|
375
|
+
groupEl.setAttribute('aria-labelledby', groupId)
|
376
|
+
groupEl.dataset.remote = 'true'
|
377
|
+
groupEl.append(itemEl)
|
378
|
+
controller.listTarget.append(clone)
|
379
|
+
}
|
380
|
+
} else {
|
381
|
+
controller.listTarget.append(itemEl)
|
382
|
+
}
|
383
|
+
})
|
384
|
+
|
385
|
+
// Update filtered items for keyboard navigation
|
386
|
+
controller.filteredItems = Array.from(
|
387
|
+
controller.listTarget.querySelectorAll(
|
388
|
+
`[data-${controller.identifier}-target="item"][aria-hidden=false]`,
|
389
|
+
),
|
390
|
+
)
|
391
|
+
|
392
|
+
controller.highlightItemByIndex(0)
|
393
|
+
|
394
|
+
console.log('controller.filteredItems', controller.filteredItems)
|
395
|
+
if (controller.filteredItems.length > 0) {
|
396
|
+
hideEmpty(controller)
|
397
|
+
} else {
|
398
|
+
showEmpty(controller)
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
402
|
+
const clearRemoteResults = (controller: Command | Combobox) => {
|
403
|
+
const remoteGroups = Array.from(
|
404
|
+
controller.element.querySelectorAll(
|
405
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-group"][data-remote='true']`,
|
406
|
+
),
|
407
|
+
)
|
408
|
+
|
409
|
+
remoteGroups.forEach((g) => {
|
410
|
+
const containsSelected = g.querySelector('[aria-selected="true"]')
|
411
|
+
|
412
|
+
if (!containsSelected) {
|
413
|
+
g.remove()
|
414
|
+
}
|
415
|
+
})
|
416
|
+
|
417
|
+
const remoteItems = Array.from(
|
418
|
+
controller.element.querySelectorAll(
|
419
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-item"][data-remote='true']:not([aria-selected="true"])`,
|
420
|
+
),
|
421
|
+
)
|
422
|
+
|
423
|
+
remoteItems.forEach((i) => i.remove())
|
424
|
+
}
|
425
|
+
|
426
|
+
const resetState = (controller: Command | Combobox) => {
|
427
|
+
controller.searchInputTarget.value = ''
|
428
|
+
|
429
|
+
if (controller.searchPath) {
|
430
|
+
clearRemoteResults(controller)
|
431
|
+
showSelectedRemoteItems(controller)
|
432
|
+
}
|
433
|
+
|
434
|
+
controller.filteredItemIndexesValue = Array.from(
|
435
|
+
{ length: controller.orderedItems.length },
|
436
|
+
(_, i) => i,
|
437
|
+
)
|
438
|
+
}
|
439
|
+
|
440
|
+
const showLoading = (controller: Command | Combobox) => {
|
441
|
+
controller.isLoading = true
|
442
|
+
controller.loadingTarget.classList.remove('hidden')
|
443
|
+
}
|
444
|
+
|
445
|
+
const hideLoading = (controller: Command | Combobox) => {
|
446
|
+
controller.isLoading = false
|
447
|
+
controller.loadingTarget.classList.add('hidden')
|
448
|
+
}
|
449
|
+
|
450
|
+
const showList = (controller: Command | Combobox) => {
|
451
|
+
controller.listTarget.classList.remove('hidden')
|
452
|
+
}
|
453
|
+
|
454
|
+
const hideList = (controller: Command | Combobox) => {
|
455
|
+
controller.listTarget.classList.add('hidden')
|
456
|
+
}
|
457
|
+
|
458
|
+
const showError = (controller: Command | Combobox) => {
|
459
|
+
controller.errorTarget.classList.remove('hidden')
|
460
|
+
}
|
461
|
+
|
462
|
+
const hideError = (controller: Command | Combobox) => {
|
463
|
+
controller.errorTarget.classList.add('hidden')
|
464
|
+
}
|
465
|
+
|
466
|
+
const showEmpty = (controller: Command | Combobox) => {
|
467
|
+
controller.emptyTarget.classList.remove('hidden')
|
468
|
+
}
|
469
|
+
|
470
|
+
const hideEmpty = (controller: Command | Combobox) => {
|
471
|
+
controller.emptyTarget.classList.add('hidden')
|
472
|
+
}
|
473
|
+
|
474
|
+
const showSelectedRemoteItems = (controller: Command | Combobox) => {
|
475
|
+
const remoteItems = Array.from(
|
476
|
+
controller.element.querySelectorAll(
|
477
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-item"][data-remote='true']`,
|
478
|
+
),
|
479
|
+
)
|
480
|
+
|
481
|
+
remoteItems.forEach((i) => {
|
482
|
+
const isInsideGroup =
|
483
|
+
i.parentElement?.dataset?.shadcnPhlexcomponents ===
|
484
|
+
`${controller.identifier}-group`
|
485
|
+
|
486
|
+
if (isInsideGroup) {
|
487
|
+
const isRemoteGroup = i.parentElement.dataset.remote === 'true'
|
488
|
+
|
489
|
+
if (isRemoteGroup) {
|
490
|
+
i.parentElement.classList.remove('hidden')
|
491
|
+
}
|
492
|
+
}
|
493
|
+
|
494
|
+
i.ariaHidden = 'false'
|
495
|
+
i.classList.remove('hidden')
|
496
|
+
})
|
497
|
+
}
|
498
|
+
|
499
|
+
const hideSelectedRemoteItems = (controller: Command | Combobox) => {
|
500
|
+
const remoteItems = Array.from(
|
501
|
+
controller.element.querySelectorAll(
|
502
|
+
`[data-shadcn-phlexcomponents="${controller.identifier}-item"][data-remote='true']`,
|
503
|
+
),
|
504
|
+
)
|
505
|
+
|
506
|
+
remoteItems.forEach((i) => {
|
507
|
+
const isInsideGroup =
|
508
|
+
i.parentElement?.dataset?.shadcnPhlexcomponents ===
|
509
|
+
`${controller.identifier}-group`
|
510
|
+
|
511
|
+
if (isInsideGroup) {
|
512
|
+
const isRemoteGroup = i.parentElement.dataset.remote === 'true'
|
513
|
+
|
514
|
+
if (isRemoteGroup) {
|
515
|
+
i.parentElement.classList.add('hidden')
|
516
|
+
}
|
517
|
+
}
|
518
|
+
|
519
|
+
i.ariaHidden = 'true'
|
520
|
+
i.classList.add('hidden')
|
521
|
+
})
|
522
|
+
}
|
523
|
+
|
524
|
+
export {
|
525
|
+
scrollToItem,
|
526
|
+
highlightItem,
|
527
|
+
highlightItemByIndex,
|
528
|
+
filteredItemsChanged,
|
529
|
+
setItemsGroupId,
|
530
|
+
search,
|
531
|
+
performRemoteSearch,
|
532
|
+
clearRemoteResults,
|
533
|
+
resetState,
|
534
|
+
showLoading,
|
535
|
+
hideLoading,
|
536
|
+
showList,
|
537
|
+
hideList,
|
538
|
+
showError,
|
539
|
+
hideError,
|
540
|
+
showEmpty,
|
541
|
+
hideEmpty,
|
542
|
+
showSelectedRemoteItems,
|
543
|
+
hideSelectedRemoteItems,
|
544
|
+
}
|