@studiocms/ui 0.0.1 → 0.3.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/README.md +28 -544
- package/package.json +11 -6
- package/src/components/Button.astro +303 -269
- package/src/components/Card.astro +37 -13
- package/src/components/Center.astro +2 -2
- package/src/components/Checkbox.astro +99 -29
- package/src/components/Divider.astro +15 -8
- package/src/components/Dropdown/Dropdown.astro +102 -41
- package/src/components/Dropdown/dropdown.ts +111 -23
- package/src/components/Footer.astro +137 -0
- package/src/components/Input.astro +42 -14
- package/src/components/Modal/Modal.astro +84 -30
- package/src/components/Modal/modal.ts +43 -9
- package/src/components/RadioGroup.astro +153 -29
- package/src/components/Row.astro +16 -7
- package/src/components/SearchSelect.astro +278 -222
- package/src/components/Select.astro +260 -127
- package/src/components/Sidebar/Double.astro +12 -12
- package/src/components/Sidebar/Single.astro +6 -6
- package/src/components/Sidebar/helpers.ts +53 -7
- package/src/components/Tabs/TabItem.astro +47 -0
- package/src/components/Tabs/Tabs.astro +376 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Textarea.astro +56 -15
- package/src/components/ThemeToggle.astro +14 -8
- package/src/components/Toast/Toaster.astro +171 -31
- package/src/components/Toggle.astro +89 -21
- package/src/components/User.astro +34 -15
- package/src/components/index.ts +24 -22
- package/src/components.ts +2 -0
- package/src/css/colors.css +65 -65
- package/src/css/resets.css +0 -1
- package/src/integration.ts +18 -0
- package/src/layouts/RootLayout.astro +1 -2
- package/src/types/index.ts +1 -1
- package/src/utils/ThemeHelper.ts +135 -117
- package/src/utils/create-resolver.ts +30 -0
|
@@ -3,22 +3,65 @@ import Icon from '../utils/Icon.astro';
|
|
|
3
3
|
import { generateID } from '../utils/generateID';
|
|
4
4
|
import Input from './Input.astro';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* An option in the select dropdown
|
|
8
|
+
*/
|
|
6
9
|
interface Option {
|
|
10
|
+
/**
|
|
11
|
+
* The label of the option.
|
|
12
|
+
*/
|
|
7
13
|
label: string;
|
|
14
|
+
/**
|
|
15
|
+
* The value of the option.
|
|
16
|
+
*/
|
|
8
17
|
value: string;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the option is disabled.
|
|
20
|
+
*/
|
|
9
21
|
disabled?: boolean;
|
|
10
|
-
}
|
|
22
|
+
}
|
|
11
23
|
|
|
24
|
+
/**
|
|
25
|
+
* The props for the search select component.
|
|
26
|
+
*/
|
|
12
27
|
interface Props {
|
|
28
|
+
/**
|
|
29
|
+
* The label of the search select.
|
|
30
|
+
*/
|
|
13
31
|
label?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The default value of the search select. Needs to be one of the values in the options.
|
|
34
|
+
*/
|
|
14
35
|
defaultValue?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Additional classes to apply to the search select.
|
|
38
|
+
*/
|
|
15
39
|
class?: string;
|
|
40
|
+
/**
|
|
41
|
+
* The name of the search select.
|
|
42
|
+
*/
|
|
16
43
|
name?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Whether the search select is required. Defaults to `false`.
|
|
46
|
+
*/
|
|
17
47
|
isRequired?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* The options to display in the search select.
|
|
50
|
+
*/
|
|
18
51
|
options: Option[];
|
|
52
|
+
/**
|
|
53
|
+
* Whether the search select is disabled. Defaults to `false`.
|
|
54
|
+
*/
|
|
19
55
|
disabled?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the search select should take up the full width of its container.
|
|
58
|
+
*/
|
|
20
59
|
fullWidth?: boolean;
|
|
21
|
-
|
|
60
|
+
/**
|
|
61
|
+
* The placeholder of the search select.
|
|
62
|
+
*/
|
|
63
|
+
placeholder?: string;
|
|
64
|
+
}
|
|
22
65
|
|
|
23
66
|
const {
|
|
24
67
|
label,
|
|
@@ -29,29 +72,33 @@ const {
|
|
|
29
72
|
options = [],
|
|
30
73
|
disabled,
|
|
31
74
|
fullWidth,
|
|
75
|
+
placeholder,
|
|
32
76
|
} = Astro.props;
|
|
33
77
|
---
|
|
34
78
|
|
|
35
79
|
<div
|
|
36
80
|
id={`${name}-container`}
|
|
37
|
-
class="search-select-label"
|
|
81
|
+
class="sui-search-select-label"
|
|
38
82
|
class:list={[disabled && "disabled", className, fullWidth && "full"]}
|
|
83
|
+
data-options={JSON.stringify(options)}
|
|
84
|
+
data-id={name}
|
|
39
85
|
>
|
|
40
|
-
<
|
|
41
|
-
{label}
|
|
42
|
-
<span class="req-star">{isRequired && "*"}</span>
|
|
43
|
-
</label>
|
|
44
|
-
<div class="search-input-wrapper" id={`${name}-search-input-wrapper`}>
|
|
86
|
+
<div class="sui-search-input-wrapper" id={`${name}-search-input-wrapper`}>
|
|
45
87
|
<Input
|
|
46
|
-
placeholder={options.find((x) => x.value === defaultValue)?.label || "Select"}
|
|
88
|
+
placeholder={options.find((x) => x.value === defaultValue)?.label || (placeholder || "Select")}
|
|
89
|
+
role='combobox'
|
|
90
|
+
aria-controls={`${name}-dropdown`}
|
|
91
|
+
aria-expanded="false"
|
|
92
|
+
label={label || ''}
|
|
93
|
+
isRequired={isRequired || false}
|
|
47
94
|
/>
|
|
48
|
-
<Icon name="chevron-up-down" class="search-select-indicator" width={24} height={24} />
|
|
95
|
+
<Icon name="chevron-up-down" class="sui-search-select-indicator" width={24} height={24} />
|
|
49
96
|
</div>
|
|
50
|
-
<ul class="search-select-dropdown" role="listbox" id={`${name}-dropdown`}>
|
|
97
|
+
<ul class="sui-search-select-dropdown" role="listbox" id={`${name}-dropdown`}>
|
|
51
98
|
{
|
|
52
99
|
options.map((x, i) => (
|
|
53
100
|
<li
|
|
54
|
-
class="search-select-option"
|
|
101
|
+
class="sui-search-select-option"
|
|
55
102
|
role="option"
|
|
56
103
|
value={x.value}
|
|
57
104
|
class:list={[
|
|
@@ -67,7 +114,7 @@ const {
|
|
|
67
114
|
))
|
|
68
115
|
}
|
|
69
116
|
</ul>
|
|
70
|
-
<select class="hidden-select" id={name} name={name} required={isRequired}>
|
|
117
|
+
<select class="sui-hidden-select" id={name} name={name} required={isRequired} hidden tabindex="-1">
|
|
71
118
|
<option value={""}> Select </option>
|
|
72
119
|
{
|
|
73
120
|
options.map((x) => (
|
|
@@ -82,247 +129,253 @@ const {
|
|
|
82
129
|
}
|
|
83
130
|
</select>
|
|
84
131
|
</div>
|
|
85
|
-
<script
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
132
|
+
<script>
|
|
133
|
+
interface Option {
|
|
134
|
+
label: string;
|
|
135
|
+
value: string;
|
|
136
|
+
disabled?: boolean;
|
|
137
|
+
}
|
|
138
|
+
// id: name, options, defaultValue
|
|
139
|
+
const searchSelects = document.querySelectorAll<HTMLDivElement>('.sui-search-select-label');
|
|
140
|
+
|
|
141
|
+
for (const container of searchSelects) {
|
|
142
|
+
const hiddenSelect = container.querySelector<HTMLSelectElement>('select')!;
|
|
143
|
+
const searchWrapper = container.querySelector<HTMLDivElement>(`.sui-search-input-wrapper`)!;
|
|
144
|
+
const searchInput = searchWrapper.querySelector('input')!;
|
|
145
|
+
const dropdown = container.querySelector(`.sui-search-select-dropdown`)!;
|
|
146
|
+
let optionElements = container.querySelectorAll("li");
|
|
147
|
+
|
|
148
|
+
let active = false;
|
|
149
|
+
|
|
150
|
+
const options = JSON.parse(container.dataset.options!) as Option[];
|
|
151
|
+
const id = container.dataset.id!;
|
|
152
|
+
let filteredOptions = options;
|
|
153
|
+
|
|
154
|
+
searchWrapper.addEventListener("click", () => {
|
|
155
|
+
const { bottom, left, right, width, x, y, height } = searchWrapper.getBoundingClientRect();
|
|
156
|
+
|
|
157
|
+
const optionHeight = 36;
|
|
158
|
+
const totalBorderSize = 2;
|
|
159
|
+
const margin = 4;
|
|
160
|
+
|
|
161
|
+
const dropdownHeight = options.length * optionHeight + totalBorderSize + margin;
|
|
162
|
+
|
|
163
|
+
const CustomRect = {
|
|
164
|
+
top: bottom + margin,
|
|
165
|
+
left,
|
|
166
|
+
right,
|
|
167
|
+
bottom: bottom + margin + dropdownHeight,
|
|
168
|
+
width,
|
|
169
|
+
height: dropdownHeight,
|
|
170
|
+
x,
|
|
171
|
+
y: y + height + margin,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (active) {
|
|
175
|
+
searchInput.ariaExpanded = 'false';
|
|
176
|
+
dropdown.classList.remove("active", "above");
|
|
177
|
+
active = false;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
123
180
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
CustomRect.top >= 0 &&
|
|
128
|
-
CustomRect.left >= 0 &&
|
|
129
|
-
CustomRect.bottom <=
|
|
130
|
-
(window.innerHeight || document.documentElement.clientHeight) &&
|
|
131
|
-
CustomRect.right <=
|
|
132
|
-
(window.innerWidth || document.documentElement.clientWidth)
|
|
133
|
-
) {
|
|
134
|
-
dropdown.classList.add("active");
|
|
135
|
-
} else {
|
|
136
|
-
dropdown.classList.add("active", "above");
|
|
137
|
-
}
|
|
138
|
-
});
|
|
181
|
+
active = true;
|
|
182
|
+
searchInput.ariaExpanded = 'true';
|
|
139
183
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
184
|
+
if (
|
|
185
|
+
CustomRect.top >= 0 &&
|
|
186
|
+
CustomRect.left >= 0 &&
|
|
187
|
+
CustomRect.bottom <=
|
|
188
|
+
(window.innerHeight || document.documentElement.clientHeight) &&
|
|
189
|
+
CustomRect.right <=
|
|
190
|
+
(window.innerWidth || document.documentElement.clientWidth)
|
|
191
|
+
) {
|
|
192
|
+
dropdown.classList.add("active");
|
|
193
|
+
} else {
|
|
194
|
+
dropdown.classList.add("active", "above");
|
|
195
|
+
}
|
|
196
|
+
});
|
|
144
197
|
|
|
145
|
-
const
|
|
198
|
+
const handleSelection = (e: MouseEvent, option: HTMLLIElement) => {
|
|
199
|
+
e.stopImmediatePropagation();
|
|
200
|
+
|
|
201
|
+
if (option.id === `${id}-selected` || !id) return;
|
|
146
202
|
|
|
147
|
-
|
|
148
|
-
currentlySelected.classList.remove("selected");
|
|
149
|
-
currentlySelected.id = "";
|
|
150
|
-
}
|
|
203
|
+
const currentlySelected = document.getElementById(`${id}-selected`);
|
|
151
204
|
|
|
152
|
-
|
|
153
|
-
|
|
205
|
+
if (currentlySelected) {
|
|
206
|
+
currentlySelected.classList.remove("selected");
|
|
207
|
+
currentlySelected.id = "";
|
|
208
|
+
}
|
|
154
209
|
|
|
155
|
-
|
|
156
|
-
|
|
210
|
+
option.id = `${id}-selected`;
|
|
211
|
+
option.classList.add("selected");
|
|
157
212
|
|
|
158
|
-
|
|
159
|
-
|
|
213
|
+
const index = options.findIndex((x) => x.value === option.dataset.value);
|
|
214
|
+
focusIndex = index;
|
|
160
215
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
searchInput.blur();
|
|
216
|
+
const opt = options[index]!;
|
|
217
|
+
hiddenSelect.value = opt.value;
|
|
164
218
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
219
|
+
searchInput.placeholder = opt.label;
|
|
220
|
+
dropdown.classList.remove("active", "above");
|
|
221
|
+
// searchInput.blur();
|
|
168
222
|
|
|
169
|
-
|
|
170
|
-
|
|
223
|
+
searchInput.value = "";
|
|
224
|
+
filteredOptions = options;
|
|
225
|
+
constructOptionsBasedOnOptions(options);
|
|
171
226
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
});
|
|
227
|
+
active = false;
|
|
228
|
+
}
|
|
175
229
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
230
|
+
optionElements.forEach((option) => {
|
|
231
|
+
option.addEventListener("click", (e) => handleSelection(e, option));
|
|
232
|
+
});
|
|
180
233
|
|
|
181
|
-
|
|
234
|
+
window.addEventListener("scroll", () => {
|
|
235
|
+
dropdown.classList.remove("active", "above");
|
|
236
|
+
active = false;
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
hideOnClickOutside(container);
|
|
240
|
+
|
|
241
|
+
function hideOnClickOutside(element: HTMLElement) {
|
|
242
|
+
const outsideClickListener = (event: MouseEvent) => {
|
|
243
|
+
if (
|
|
244
|
+
!element.contains(event.target! as Element) &&
|
|
245
|
+
isVisible(element) &&
|
|
246
|
+
active === true
|
|
247
|
+
) {
|
|
248
|
+
// or use: event.target.closest(selector) === null
|
|
249
|
+
dropdown.classList.remove("active", "above");
|
|
250
|
+
active = false;
|
|
251
|
+
}
|
|
252
|
+
};
|
|
182
253
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (
|
|
186
|
-
!element.contains(event.target) &&
|
|
187
|
-
isVisible(element) &&
|
|
188
|
-
active === true
|
|
189
|
-
) {
|
|
190
|
-
// or use: event.target.closest(selector) === null
|
|
191
|
-
dropdown.classList.remove("active", "above");
|
|
192
|
-
active = false;
|
|
193
|
-
}
|
|
194
|
-
};
|
|
254
|
+
document.addEventListener("click", outsideClickListener);
|
|
255
|
+
}
|
|
195
256
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
257
|
+
// source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
|
|
258
|
+
const isVisible = (elem: HTMLElement) =>
|
|
259
|
+
!!elem &&
|
|
260
|
+
!!(
|
|
261
|
+
elem.offsetWidth ||
|
|
262
|
+
elem.offsetHeight ||
|
|
263
|
+
elem.getClientRects().length
|
|
264
|
+
);
|
|
199
265
|
|
|
200
|
-
|
|
201
|
-
}
|
|
266
|
+
let focusIndex = 0;
|
|
202
267
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
let focusIndex = 0;
|
|
213
|
-
|
|
214
|
-
const recomputeOptions = () => {
|
|
215
|
-
for (const entry of optionElements) {
|
|
216
|
-
if (entry.dataset.optionIndex == focusIndex) {
|
|
217
|
-
entry.classList.add('focused');
|
|
218
|
-
} else {
|
|
219
|
-
entry.classList.remove('focused');
|
|
268
|
+
const recomputeOptions = () => {
|
|
269
|
+
for (const entry of optionElements) {
|
|
270
|
+
if (Number.parseInt(entry.dataset.optionIndex!) == focusIndex) {
|
|
271
|
+
entry.classList.add('focused');
|
|
272
|
+
} else {
|
|
273
|
+
entry.classList.remove('focused');
|
|
274
|
+
}
|
|
220
275
|
}
|
|
221
276
|
}
|
|
222
|
-
}
|
|
223
277
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
active = false;
|
|
230
|
-
dropdown.classList.remove("active", "above");
|
|
231
|
-
searchInput.blur();
|
|
232
|
-
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
278
|
+
searchInput.addEventListener('keydown', (e) => {
|
|
279
|
+
if (e.key === "Escape") {
|
|
280
|
+
e.preventDefault();
|
|
281
|
+
e.stopImmediatePropagation();
|
|
235
282
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
283
|
+
active = false;
|
|
284
|
+
dropdown.classList.remove("active", "above");
|
|
285
|
+
searchInput.blur();
|
|
286
|
+
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
239
289
|
|
|
240
|
-
focusIndex
|
|
241
|
-
|
|
290
|
+
if (e.key === "ArrowUp" && focusIndex > 0) {
|
|
291
|
+
e.preventDefault();
|
|
292
|
+
e.stopImmediatePropagation();
|
|
242
293
|
|
|
243
|
-
|
|
244
|
-
|
|
294
|
+
focusIndex--;
|
|
295
|
+
recomputeOptions();
|
|
245
296
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
e.stopImmediatePropagation();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
249
299
|
|
|
250
|
-
focusIndex
|
|
251
|
-
|
|
300
|
+
if (e.key === "ArrowDown" && focusIndex + 1 < filteredOptions.filter(x => !x.disabled).length) {
|
|
301
|
+
e.preventDefault();
|
|
302
|
+
e.stopImmediatePropagation();
|
|
252
303
|
|
|
253
|
-
|
|
254
|
-
|
|
304
|
+
focusIndex++;
|
|
305
|
+
recomputeOptions();
|
|
255
306
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
e.stopImmediatePropagation();
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
259
309
|
|
|
260
|
-
|
|
310
|
+
if (e.key === "Enter") {
|
|
311
|
+
e.preventDefault();
|
|
312
|
+
e.stopImmediatePropagation();
|
|
261
313
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
314
|
+
for (const entry of optionElements) {
|
|
315
|
+
if (Number.parseInt(entry.dataset.optionIndex!) === focusIndex) {
|
|
316
|
+
entry.click();
|
|
317
|
+
}
|
|
265
318
|
}
|
|
319
|
+
|
|
320
|
+
return;
|
|
266
321
|
}
|
|
322
|
+
});
|
|
267
323
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
});
|
|
324
|
+
searchInput.addEventListener('keyup', (e) => {
|
|
325
|
+
if (["Enter", "ArrowUp", "ArrowDown"].includes(e.key)) return;
|
|
271
326
|
|
|
272
|
-
|
|
273
|
-
|
|
327
|
+
if (searchInput.value.trim().length === 0) {
|
|
328
|
+
constructOptionsBasedOnOptions(options);
|
|
329
|
+
filteredOptions = options;
|
|
330
|
+
return;
|
|
331
|
+
};
|
|
274
332
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
filteredOptions = options;
|
|
278
|
-
return;
|
|
279
|
-
};
|
|
333
|
+
filteredOptions = options.filter(x => x.label.includes(searchInput.value));
|
|
334
|
+
focusIndex = 0;
|
|
280
335
|
|
|
281
|
-
|
|
282
|
-
|
|
336
|
+
constructOptionsBasedOnOptions(filteredOptions);
|
|
337
|
+
});
|
|
283
338
|
|
|
284
|
-
constructOptionsBasedOnOptions(
|
|
285
|
-
|
|
339
|
+
function constructOptionsBasedOnOptions(options: Option[]) {
|
|
340
|
+
dropdown.innerHTML = '';
|
|
286
341
|
|
|
287
|
-
|
|
288
|
-
|
|
342
|
+
if (options.length === 0) {
|
|
343
|
+
const element = document.createElement('li');
|
|
344
|
+
element.classList.add('empty-search-results');
|
|
345
|
+
element.textContent = "No results found.";
|
|
289
346
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
element.classList.add('empty-search-results');
|
|
293
|
-
element.textContent = "No results found.";
|
|
347
|
+
dropdown.appendChild(element);
|
|
348
|
+
}
|
|
294
349
|
|
|
295
|
-
|
|
296
|
-
}
|
|
350
|
+
let i = 0;
|
|
297
351
|
|
|
298
|
-
|
|
352
|
+
for (const option of options) {
|
|
353
|
+
const element = document.createElement('li');
|
|
354
|
+
element.classList.add(...[
|
|
355
|
+
'sui-search-select-option',
|
|
356
|
+
option.disabled && "disabled",
|
|
357
|
+
focusIndex === i && 'focused',
|
|
358
|
+
].filter((x) => typeof x === 'string'));
|
|
359
|
+
element.role = "option";
|
|
360
|
+
element.value = Number.parseInt(option.value);
|
|
361
|
+
element.id = "";
|
|
362
|
+
element.dataset.optionIndex = i.toString();
|
|
363
|
+
element.dataset.value = option.value;
|
|
364
|
+
element.textContent = option.label;
|
|
299
365
|
|
|
300
|
-
|
|
301
|
-
const element = document.createElement('li');
|
|
302
|
-
element.classList.add(...[
|
|
303
|
-
'search-select-option',
|
|
304
|
-
option.disabled && "disabled",
|
|
305
|
-
focusIndex === i && 'focused',
|
|
306
|
-
].filter(Boolean));
|
|
307
|
-
element.role = "option";
|
|
308
|
-
element.value = option.value;
|
|
309
|
-
element.id = "";
|
|
310
|
-
element.dataset.optionIndex = i;
|
|
311
|
-
element.dataset.value = option.value;
|
|
312
|
-
element.textContent = option.label;
|
|
366
|
+
element.addEventListener("click", (e) => handleSelection(e, element));
|
|
313
367
|
|
|
314
|
-
|
|
368
|
+
dropdown.appendChild(element);
|
|
315
369
|
|
|
316
|
-
|
|
370
|
+
i++;
|
|
371
|
+
}
|
|
317
372
|
|
|
318
|
-
|
|
373
|
+
optionElements = container.querySelectorAll("li");
|
|
319
374
|
}
|
|
320
|
-
|
|
321
|
-
optionElements = container.querySelectorAll("li");
|
|
322
375
|
}
|
|
323
376
|
</script>
|
|
324
377
|
<style is:global>
|
|
325
|
-
.search-select-label {
|
|
378
|
+
.sui-search-select-label {
|
|
326
379
|
width: fit-content;
|
|
327
380
|
display: flex;
|
|
328
381
|
flex-direction: column;
|
|
@@ -331,11 +384,11 @@ const {
|
|
|
331
384
|
position: relative;
|
|
332
385
|
}
|
|
333
386
|
|
|
334
|
-
.search-select-label.full {
|
|
387
|
+
.sui-search-select-label.full {
|
|
335
388
|
width: 100%;
|
|
336
389
|
}
|
|
337
390
|
|
|
338
|
-
.search-select-label.disabled {
|
|
391
|
+
.sui-search-select-label.disabled {
|
|
339
392
|
opacity: 0.5;
|
|
340
393
|
pointer-events: none;
|
|
341
394
|
color: hsl(var(--text-muted));
|
|
@@ -350,7 +403,7 @@ const {
|
|
|
350
403
|
font-weight: 700;
|
|
351
404
|
}
|
|
352
405
|
|
|
353
|
-
.search-select-dropdown {
|
|
406
|
+
.sui-search-select-dropdown {
|
|
354
407
|
position: absolute;
|
|
355
408
|
width: 100%;
|
|
356
409
|
border: 1px solid hsl(var(--border));
|
|
@@ -368,34 +421,34 @@ const {
|
|
|
368
421
|
box-shadow: 0px 4px 8px hsl(var(--shadow), 0.5);
|
|
369
422
|
}
|
|
370
423
|
|
|
371
|
-
.search-select-dropdown.above {
|
|
424
|
+
.sui-search-select-dropdown.above {
|
|
372
425
|
top: auto;
|
|
373
426
|
bottom: calc(100% - 18px + 0.25rem);
|
|
374
427
|
}
|
|
375
428
|
|
|
376
|
-
.search-select-option, .empty-search-results {
|
|
429
|
+
.sui-search-select-option, .empty-search-results {
|
|
377
430
|
padding: 0.5rem;
|
|
378
431
|
cursor: pointer;
|
|
379
432
|
font-size: 0.975em;
|
|
380
433
|
transition: all 0.15s ease;
|
|
381
434
|
}
|
|
382
435
|
|
|
383
|
-
.search-select-option.disabled {
|
|
436
|
+
.sui-search-select-option.disabled {
|
|
384
437
|
pointer-events: none;
|
|
385
438
|
color: hsl(var(--text-muted));
|
|
386
439
|
}
|
|
387
440
|
|
|
388
|
-
.search-select-option:hover, .search-select-option.focused {
|
|
441
|
+
.sui-search-select-option:hover, .sui-search-select-option.focused {
|
|
389
442
|
background-color: hsl(var(--background-step-3));
|
|
390
443
|
}
|
|
391
444
|
|
|
392
|
-
.search-select-option.selected {
|
|
445
|
+
.sui-search-select-option.selected {
|
|
393
446
|
background-color: hsl(var(--primary-base));
|
|
394
447
|
color: hsl(var(--text-inverted));
|
|
395
448
|
cursor: default;
|
|
396
449
|
}
|
|
397
450
|
|
|
398
|
-
.hidden-select {
|
|
451
|
+
.sui-hidden-select {
|
|
399
452
|
height: 0;
|
|
400
453
|
width: 0;
|
|
401
454
|
border: none;
|
|
@@ -406,25 +459,28 @@ const {
|
|
|
406
459
|
opacity: 0;
|
|
407
460
|
}
|
|
408
461
|
|
|
409
|
-
.search-input-wrapper {
|
|
462
|
+
.sui-search-input-wrapper {
|
|
410
463
|
width: 100%;
|
|
411
464
|
position: relative;
|
|
412
465
|
height: fit-content;
|
|
413
466
|
cursor: pointer;
|
|
414
467
|
}
|
|
415
468
|
|
|
416
|
-
.search-
|
|
469
|
+
.sui-search-input-wrapper input {
|
|
470
|
+
padding-right: 2.5rem;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.sui-search-select-indicator {
|
|
417
474
|
position: absolute;
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
right: .5rem;
|
|
475
|
+
bottom: .675rem;
|
|
476
|
+
right: .675rem;
|
|
421
477
|
}
|
|
422
478
|
|
|
423
|
-
.search-input-wrapper:has(input:focus) + .search-select-dropdown {
|
|
479
|
+
.sui-search-input-wrapper:has(input:focus) + .sui-search-select-dropdown {
|
|
424
480
|
display: flex;
|
|
425
481
|
}
|
|
426
482
|
|
|
427
|
-
.search-select-dropdown.active, .search-select-dropdown:has(> li:active) {
|
|
483
|
+
.sui-search-select-dropdown.active, .sui-search-select-dropdown:has(> li:active) {
|
|
428
484
|
display: flex;
|
|
429
485
|
}
|
|
430
486
|
</style>
|