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