@studiocms/ui 0.4.15 → 0.4.17
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/components/SearchSelect/SearchSelect.astro +29 -26
- package/dist/components/SearchSelect/searchselect.css +14 -9
- package/dist/components/SearchSelect/searchselect.js +32 -15
- package/dist/components/Select/Select.astro +28 -25
- package/dist/components/Select/select.css +14 -8
- package/dist/components/Select/select.js +2 -11
- package/package.json +1 -1
|
@@ -154,31 +154,33 @@ const defaultLabel = selected
|
|
|
154
154
|
/>
|
|
155
155
|
<Icon name="chevron-up-down" class="sui-search-select-indicator" width={24} height={24} />
|
|
156
156
|
</div>
|
|
157
|
-
<
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
157
|
+
<div class="sui-search-select-dropdown">
|
|
158
|
+
<ul class="sui-search-select-dropdown-list" role="listbox" id={`${name}-dropdown`}>
|
|
159
|
+
{
|
|
160
|
+
options.map((x, i) => {
|
|
161
|
+
const isSelected = Array.isArray(selected)
|
|
162
|
+
? selected.map((y) => y && y.value).includes(x.value)
|
|
163
|
+
: selected?.value === x.value;
|
|
164
|
+
return (
|
|
165
|
+
<li
|
|
166
|
+
class="sui-search-select-option"
|
|
167
|
+
role="option"
|
|
168
|
+
value={x.value}
|
|
169
|
+
class:list={[
|
|
170
|
+
isSelected && `selected`,
|
|
171
|
+
x.disabled && "disabled"
|
|
172
|
+
]}
|
|
173
|
+
id={isSelected ? `${name}-selected` : ""}
|
|
174
|
+
data-option-index={i}
|
|
175
|
+
data-value={x.value}
|
|
176
|
+
>
|
|
177
|
+
{x.label}
|
|
178
|
+
</li>
|
|
179
|
+
)
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
</ul>
|
|
183
|
+
</div>
|
|
182
184
|
</div>
|
|
183
185
|
<select class="sui-hidden-search-select" id={name} name={name} required={isRequired} multiple={multiple ? "" : undefined} hidden tabindex="-1">
|
|
184
186
|
<option value={""}> Select </option>
|
|
@@ -187,7 +189,8 @@ const defaultLabel = selected
|
|
|
187
189
|
const isSelected = Array.isArray(selected)
|
|
188
190
|
? selected.map((y) => y && y.value).includes(x.value)
|
|
189
191
|
: selected?.value === x.value;
|
|
190
|
-
|
|
192
|
+
|
|
193
|
+
return (
|
|
191
194
|
<option
|
|
192
195
|
value={x.value}
|
|
193
196
|
selected={isSelected}
|
|
@@ -32,19 +32,25 @@
|
|
|
32
32
|
.sui-search-select-dropdown {
|
|
33
33
|
position: absolute;
|
|
34
34
|
width: 100%;
|
|
35
|
-
border: 1px solid hsl(var(--border));
|
|
36
|
-
list-style: none;
|
|
37
|
-
margin: 0;
|
|
38
|
-
padding: 0;
|
|
39
|
-
flex-direction: column;
|
|
40
|
-
border-radius: var(--radius-md);
|
|
41
|
-
background-color: hsl(var(--background-step-2));
|
|
42
|
-
overflow: hidden;
|
|
43
35
|
top: calc(100% + 0.25rem);
|
|
44
36
|
left: 0;
|
|
45
37
|
display: none;
|
|
38
|
+
max-height: 300px;
|
|
39
|
+
border: 1px solid hsl(var(--border));
|
|
40
|
+
border-radius: var(--radius-md);
|
|
41
|
+
background-color: hsl(var(--background-step-2));
|
|
46
42
|
z-index: 90;
|
|
47
43
|
box-shadow: 0px 4px 8px hsl(var(--shadow), 0.5);
|
|
44
|
+
overflow: hidden;
|
|
45
|
+
}
|
|
46
|
+
.sui-search-select-dropdown-list {
|
|
47
|
+
width: 100%;
|
|
48
|
+
list-style: none;
|
|
49
|
+
margin: 0;
|
|
50
|
+
padding: 0;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
overflow-y: auto;
|
|
53
|
+
scrollbar-color: hsl(var(--border)) hsl(var(--background-step-2));
|
|
48
54
|
}
|
|
49
55
|
.sui-search-select-dropdown.above {
|
|
50
56
|
top: auto;
|
|
@@ -105,7 +111,6 @@
|
|
|
105
111
|
position: absolute;
|
|
106
112
|
bottom: .675rem;
|
|
107
113
|
right: .675rem;
|
|
108
|
-
pointer-events: none;
|
|
109
114
|
}
|
|
110
115
|
.sui-search-input-wrapper:has(input:focus) + .sui-search-select-dropdown {
|
|
111
116
|
display: flex;
|
|
@@ -82,12 +82,9 @@ function loadSearchSelects() {
|
|
|
82
82
|
);
|
|
83
83
|
if (option) {
|
|
84
84
|
option.classList.toggle("selected", forceState ?? !isCurrentlySelected);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
);
|
|
89
|
-
if (selectOption) {
|
|
90
|
-
selectOption.selected = forceState ?? !isCurrentlySelected;
|
|
85
|
+
if (container?.select) {
|
|
86
|
+
container.select.value = option.getAttribute("value");
|
|
87
|
+
}
|
|
91
88
|
}
|
|
92
89
|
const selectedCountEl = container.querySelector(
|
|
93
90
|
".sui-search-select-max-span .sui-search-select-select-count"
|
|
@@ -117,12 +114,12 @@ function loadSearchSelects() {
|
|
|
117
114
|
};
|
|
118
115
|
const reconstructOptions = (filteredOptions, state2, container) => {
|
|
119
116
|
container.dropdown.innerHTML = "";
|
|
120
|
-
let i = 0;
|
|
121
117
|
const selectedValues = state2.selectedOptionsMap[container.dataset.id] || [];
|
|
122
118
|
if (filteredOptions.length === 0) {
|
|
123
119
|
container.dropdown.innerHTML = '<li class="empty-search-results">No results found</li>';
|
|
124
120
|
return;
|
|
125
121
|
}
|
|
122
|
+
let i = 0;
|
|
126
123
|
for (const option of filteredOptions) {
|
|
127
124
|
const element = document.createElement("li");
|
|
128
125
|
element.classList.add("sui-search-select-option");
|
|
@@ -153,6 +150,26 @@ function loadSearchSelects() {
|
|
|
153
150
|
if (!target.closest("input")) {
|
|
154
151
|
e.preventDefault();
|
|
155
152
|
}
|
|
153
|
+
if (container.input?.value.length === 0) {
|
|
154
|
+
reconstructOptions(state2.optionsMap[container.dataset.id] ?? [], state2, container);
|
|
155
|
+
}
|
|
156
|
+
if (target.closest(".sui-search-select-indicator")) {
|
|
157
|
+
if (container.dropdown?.parentElement?.classList.contains("active")) {
|
|
158
|
+
container.dropdown?.parentElement?.classList.remove("active", "above");
|
|
159
|
+
container.input?.blur();
|
|
160
|
+
container.input.value = "";
|
|
161
|
+
} else {
|
|
162
|
+
container.dropdown?.parentElement?.classList.add("active");
|
|
163
|
+
container.input?.focus();
|
|
164
|
+
container.input.value = "";
|
|
165
|
+
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (target.closest(".sui-search-select-badge-container")) {
|
|
169
|
+
container.dropdown?.parentElement?.classList.remove("active", "above");
|
|
170
|
+
container.input?.blur();
|
|
171
|
+
container.input.value = "";
|
|
172
|
+
}
|
|
156
173
|
state2.isSelectingOption = true;
|
|
157
174
|
setTimeout(() => {
|
|
158
175
|
state2.isSelectingOption = false;
|
|
@@ -185,7 +202,7 @@ function loadSearchSelects() {
|
|
|
185
202
|
}
|
|
186
203
|
updateOptionSelection(opt.dataset.value, container, state2, true);
|
|
187
204
|
updateLabel(false, state2, container);
|
|
188
|
-
container.dropdown?.classList.remove("active", "above");
|
|
205
|
+
container.dropdown?.parentElement?.classList.remove("active", "above");
|
|
189
206
|
container.input?.blur();
|
|
190
207
|
container.input.value = "";
|
|
191
208
|
}
|
|
@@ -194,7 +211,7 @@ function loadSearchSelects() {
|
|
|
194
211
|
const focusedElement = document.activeElement;
|
|
195
212
|
if (e.key === "Escape" || e.key === "Tab") {
|
|
196
213
|
container.input?.blur();
|
|
197
|
-
container.dropdown?.classList.remove("active", "above");
|
|
214
|
+
container.dropdown?.parentElement?.classList.remove("active", "above");
|
|
198
215
|
return;
|
|
199
216
|
}
|
|
200
217
|
if ((e.key === "Enter" || e.key === " ") && focusedElement?.tagName.toLowerCase() === "svg") {
|
|
@@ -281,7 +298,7 @@ function loadSearchSelects() {
|
|
|
281
298
|
}
|
|
282
299
|
updateOptionSelection(value, container, state2, true);
|
|
283
300
|
updateLabel(false, state2, container);
|
|
284
|
-
container.dropdown?.classList.remove("active", "above");
|
|
301
|
+
container.dropdown?.parentElement?.classList.remove("active", "above");
|
|
285
302
|
container.input.value = "";
|
|
286
303
|
}
|
|
287
304
|
}
|
|
@@ -304,20 +321,20 @@ function loadSearchSelects() {
|
|
|
304
321
|
if (state2.isSelectingOption) return;
|
|
305
322
|
container.input.value = "";
|
|
306
323
|
reconstructOptions(state2.optionsMap[container.dataset.id] ?? [], state2, container);
|
|
307
|
-
container.dropdown?.classList.remove("active", "above");
|
|
324
|
+
container.dropdown?.parentElement?.classList.remove("active", "above");
|
|
308
325
|
};
|
|
309
326
|
const handleContainerFocusIn = (state2, container) => {
|
|
310
|
-
const allDropdowns = document.querySelectorAll(".sui-search-select-dropdown");
|
|
327
|
+
const allDropdowns = document.querySelectorAll(".sui-search-select-dropdown-list");
|
|
311
328
|
for (const dropdown of allDropdowns) {
|
|
312
329
|
if (dropdown !== container.dropdown) {
|
|
313
|
-
dropdown.classList.remove("active", "above");
|
|
330
|
+
dropdown.parentElement?.classList.remove("active", "above");
|
|
314
331
|
}
|
|
315
332
|
}
|
|
316
333
|
const { isAbove } = getDropdownPosition(
|
|
317
334
|
container.input,
|
|
318
335
|
state2.optionsMap[container.dataset.id]?.length ?? 0
|
|
319
336
|
);
|
|
320
|
-
container.dropdown?.classList.add("active", ...isAbove ? [] : ["above"]);
|
|
337
|
+
container.dropdown?.parentElement?.classList.add("active", ...isAbove ? [] : ["above"]);
|
|
321
338
|
};
|
|
322
339
|
const state = {
|
|
323
340
|
optionsMap: {},
|
|
@@ -333,7 +350,7 @@ function loadSearchSelects() {
|
|
|
333
350
|
const id = container.dataset.id;
|
|
334
351
|
const specialContainer = Object.assign(container, {
|
|
335
352
|
input: container.querySelector("input"),
|
|
336
|
-
dropdown: container.querySelector(".sui-search-select-dropdown"),
|
|
353
|
+
dropdown: container.querySelector(".sui-search-select-dropdown-list"),
|
|
337
354
|
select: container.querySelector("select")
|
|
338
355
|
});
|
|
339
356
|
const selectedOptions = Array.from(
|
|
@@ -166,30 +166,32 @@ const defaultLabel = selected
|
|
|
166
166
|
</span>
|
|
167
167
|
<Icon name="chevron-up-down" width={24} height={24} class="sui-select-chevron" />
|
|
168
168
|
</button>
|
|
169
|
-
<
|
|
170
|
-
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
169
|
+
<div class="sui-select-dropdown">
|
|
170
|
+
<ul class="sui-select-dropdown-list" role="listbox" id={`${name}-dropdown`}>
|
|
171
|
+
{
|
|
172
|
+
options.map((x, i) => {
|
|
173
|
+
const isSelected = Array.isArray(selected)
|
|
174
|
+
? selected.map((y) => y && y.value).includes(x.value)
|
|
175
|
+
: selected?.value === x.value;
|
|
176
|
+
return (
|
|
177
|
+
<li
|
|
178
|
+
class="sui-select-option"
|
|
179
|
+
role="option"
|
|
180
|
+
value={x.value}
|
|
181
|
+
class:list={[
|
|
182
|
+
isSelected && `selected`,
|
|
183
|
+
x.disabled && "disabled",
|
|
184
|
+
]}
|
|
185
|
+
id={isSelected ? `${name}-selected` : ""}
|
|
186
|
+
data-option-index={i}
|
|
187
|
+
>
|
|
188
|
+
{x.label}
|
|
189
|
+
</li>
|
|
190
|
+
)
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
</ul>
|
|
194
|
+
</div>
|
|
193
195
|
</div>
|
|
194
196
|
<select class="sui-hidden-select" id={name} name={name} required={isRequired} multiple={multiple ? "" : undefined} hidden tabindex="-1">
|
|
195
197
|
<option value={""}> Select </option>
|
|
@@ -198,7 +200,8 @@ const defaultLabel = selected
|
|
|
198
200
|
const isSelected = Array.isArray(selected)
|
|
199
201
|
? selected.map((y) => y && y.value).includes(x.value)
|
|
200
202
|
: selected?.value === x.value;
|
|
201
|
-
|
|
203
|
+
|
|
204
|
+
return (
|
|
202
205
|
<option
|
|
203
206
|
value={x.value}
|
|
204
207
|
selected={isSelected}
|
|
@@ -70,19 +70,25 @@
|
|
|
70
70
|
.sui-select-dropdown {
|
|
71
71
|
position: absolute;
|
|
72
72
|
width: 100%;
|
|
73
|
-
border: 1px solid hsl(var(--border));
|
|
74
|
-
list-style: none;
|
|
75
|
-
margin: 0;
|
|
76
|
-
padding: 0;
|
|
77
|
-
flex-direction: column;
|
|
78
|
-
border-radius: var(--radius-md);
|
|
79
|
-
background-color: hsl(var(--background-step-2));
|
|
80
|
-
overflow: hidden;
|
|
81
73
|
top: calc(100% + 0.25rem);
|
|
82
74
|
left: 0;
|
|
83
75
|
display: none;
|
|
76
|
+
max-height: 300px;
|
|
77
|
+
border: 1px solid hsl(var(--border));
|
|
78
|
+
border-radius: var(--radius-md);
|
|
79
|
+
background-color: hsl(var(--background-step-2));
|
|
84
80
|
z-index: 90;
|
|
85
81
|
box-shadow: 0px 4px 8px hsl(var(--shadow), 0.5);
|
|
82
|
+
overflow: hidden;
|
|
83
|
+
}
|
|
84
|
+
.sui-select-dropdown-list {
|
|
85
|
+
width: 100%;
|
|
86
|
+
list-style: none;
|
|
87
|
+
margin: 0;
|
|
88
|
+
padding: 0;
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
overflow-y: auto;
|
|
91
|
+
scrollbar-color: hsl(var(--border)) hsl(var(--background-step-2));
|
|
86
92
|
}
|
|
87
93
|
.sui-select-dropdown.active {
|
|
88
94
|
display: flex;
|
|
@@ -188,20 +188,11 @@ function loadSelects() {
|
|
|
188
188
|
} else {
|
|
189
189
|
if (lastActive) {
|
|
190
190
|
lastActive.classList.remove("selected");
|
|
191
|
-
const lastSelectOpt = container?.select?.querySelector(
|
|
192
|
-
`option[value='${lastActive.getAttribute("value")}']`
|
|
193
|
-
);
|
|
194
|
-
if (lastSelectOpt) {
|
|
195
|
-
lastSelectOpt.selected = false;
|
|
196
|
-
}
|
|
197
191
|
}
|
|
198
192
|
if (option) {
|
|
199
193
|
option.classList.add("selected");
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
203
|
-
if (selectOpt) {
|
|
204
|
-
selectOpt.selected = true;
|
|
194
|
+
if (container?.select) {
|
|
195
|
+
container.select.value = option.getAttribute("value");
|
|
205
196
|
}
|
|
206
197
|
updateLabel(state2, container);
|
|
207
198
|
}
|