@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.
Files changed (37) hide show
  1. package/README.md +28 -544
  2. package/package.json +11 -6
  3. package/src/components/Button.astro +303 -269
  4. package/src/components/Card.astro +37 -13
  5. package/src/components/Center.astro +2 -2
  6. package/src/components/Checkbox.astro +99 -29
  7. package/src/components/Divider.astro +15 -8
  8. package/src/components/Dropdown/Dropdown.astro +102 -41
  9. package/src/components/Dropdown/dropdown.ts +111 -23
  10. package/src/components/Footer.astro +137 -0
  11. package/src/components/Input.astro +42 -14
  12. package/src/components/Modal/Modal.astro +84 -30
  13. package/src/components/Modal/modal.ts +43 -9
  14. package/src/components/RadioGroup.astro +153 -29
  15. package/src/components/Row.astro +16 -7
  16. package/src/components/SearchSelect.astro +278 -222
  17. package/src/components/Select.astro +260 -127
  18. package/src/components/Sidebar/Double.astro +12 -12
  19. package/src/components/Sidebar/Single.astro +6 -6
  20. package/src/components/Sidebar/helpers.ts +53 -7
  21. package/src/components/Tabs/TabItem.astro +47 -0
  22. package/src/components/Tabs/Tabs.astro +376 -0
  23. package/src/components/Tabs/index.ts +2 -0
  24. package/src/components/Textarea.astro +56 -15
  25. package/src/components/ThemeToggle.astro +14 -8
  26. package/src/components/Toast/Toaster.astro +171 -31
  27. package/src/components/Toggle.astro +89 -21
  28. package/src/components/User.astro +34 -15
  29. package/src/components/index.ts +24 -22
  30. package/src/components.ts +2 -0
  31. package/src/css/colors.css +65 -65
  32. package/src/css/resets.css +0 -1
  33. package/src/integration.ts +18 -0
  34. package/src/layouts/RootLayout.astro +1 -2
  35. package/src/types/index.ts +1 -1
  36. package/src/utils/ThemeHelper.ts +135 -117
  37. 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
- <label class="label" for={`${name}-search-select-btn`}>
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 is:inline define:vars={{ id: name, options, defaultValue }}>
86
- const container = document.getElementById(`${id}-container`);
87
- const hiddenSelect = document.getElementById(id);
88
- const searchWrapper = document.getElementById(`${id}-search-input-wrapper`);
89
- const searchInput = searchWrapper.querySelector('input');
90
- const valueSpan = document.getElementById(`${id}-value-span`);
91
- const dropdown = document.getElementById(`${id}-dropdown`);
92
- let optionElements = container.querySelectorAll("li");
93
-
94
- let active = false;
95
-
96
- let filteredOptions = options;
97
-
98
- searchWrapper.addEventListener("click", () => {
99
- const { bottom, left, right, width, x, y, height } = searchWrapper.getBoundingClientRect();
100
-
101
- const optionHeight = 36;
102
- const totalBorderSize = 2;
103
- const margin = 4;
104
-
105
- const dropdownHeight = options.length * optionHeight + totalBorderSize + margin;
106
-
107
- const CustomRect = {
108
- top: bottom + margin,
109
- left,
110
- right,
111
- bottom: bottom + margin + dropdownHeight,
112
- width,
113
- height: dropdownHeight,
114
- x,
115
- y: y + height + margin,
116
- };
117
-
118
- if (active) {
119
- dropdown.classList.remove("active", "above");
120
- active = false;
121
- return;
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
- active = true;
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
- const handleSelection = (e, option) => {
141
- e.stopImmediatePropagation();
142
-
143
- if (option.id === `${id}-selected` || !id) return;
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 currentlySelected = document.getElementById(`${id}-selected`);
198
+ const handleSelection = (e: MouseEvent, option: HTMLLIElement) => {
199
+ e.stopImmediatePropagation();
200
+
201
+ if (option.id === `${id}-selected` || !id) return;
146
202
 
147
- if (currentlySelected) {
148
- currentlySelected.classList.remove("selected");
149
- currentlySelected.id = "";
150
- }
203
+ const currentlySelected = document.getElementById(`${id}-selected`);
151
204
 
152
- option.id = `${id}-selected`;
153
- option.classList.add("selected");
205
+ if (currentlySelected) {
206
+ currentlySelected.classList.remove("selected");
207
+ currentlySelected.id = "";
208
+ }
154
209
 
155
- const index = options.findIndex((x) => x.value === option.dataset.value);
156
- focusIndex = index;
210
+ option.id = `${id}-selected`;
211
+ option.classList.add("selected");
157
212
 
158
- const opt = options[index];
159
- hiddenSelect.value = opt.value;
213
+ const index = options.findIndex((x) => x.value === option.dataset.value);
214
+ focusIndex = index;
160
215
 
161
- searchInput.placeholder = opt.label;
162
- dropdown.classList.remove("active", "above");
163
- searchInput.blur();
216
+ const opt = options[index]!;
217
+ hiddenSelect.value = opt.value;
164
218
 
165
- searchInput.value = "";
166
- filteredOptions = options;
167
- constructOptionsBasedOnOptions(options);
219
+ searchInput.placeholder = opt.label;
220
+ dropdown.classList.remove("active", "above");
221
+ // searchInput.blur();
168
222
 
169
- active = false;
170
- }
223
+ searchInput.value = "";
224
+ filteredOptions = options;
225
+ constructOptionsBasedOnOptions(options);
171
226
 
172
- optionElements.forEach((option) => {
173
- option.addEventListener("click", (e) => handleSelection(e, option));
174
- });
227
+ active = false;
228
+ }
175
229
 
176
- window.addEventListener("scroll", () => {
177
- dropdown.classList.remove("active", "above");
178
- active = false;
179
- });
230
+ optionElements.forEach((option) => {
231
+ option.addEventListener("click", (e) => handleSelection(e, option));
232
+ });
180
233
 
181
- hideOnClickOutside(container);
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
- function hideOnClickOutside(element) {
184
- const outsideClickListener = (event) => {
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
- const removeClickListener = () => {
197
- document.removeEventListener("click", outsideClickListener);
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
- document.addEventListener("click", outsideClickListener);
201
- }
266
+ let focusIndex = 0;
202
267
 
203
- // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
204
- const isVisible = (elem) =>
205
- !!elem &&
206
- !!(
207
- elem.offsetWidth ||
208
- elem.offsetHeight ||
209
- elem.getClientRects().length
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
- searchInput.addEventListener('keydown', (e) => {
225
- if (e.key === "Escape") {
226
- e.preventDefault();
227
- e.stopImmediatePropagation();
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
- if (e.key === "ArrowUp" && focusIndex > 0) {
237
- e.preventDefault();
238
- e.stopImmediatePropagation();
283
+ active = false;
284
+ dropdown.classList.remove("active", "above");
285
+ searchInput.blur();
286
+
287
+ return;
288
+ }
239
289
 
240
- focusIndex--;
241
- recomputeOptions();
290
+ if (e.key === "ArrowUp" && focusIndex > 0) {
291
+ e.preventDefault();
292
+ e.stopImmediatePropagation();
242
293
 
243
- return;
244
- }
294
+ focusIndex--;
295
+ recomputeOptions();
245
296
 
246
- if (e.key === "ArrowDown" && focusIndex + 1 < filteredOptions.filter(x => !x.disabled).length) {
247
- e.preventDefault();
248
- e.stopImmediatePropagation();
297
+ return;
298
+ }
249
299
 
250
- focusIndex++;
251
- recomputeOptions();
300
+ if (e.key === "ArrowDown" && focusIndex + 1 < filteredOptions.filter(x => !x.disabled).length) {
301
+ e.preventDefault();
302
+ e.stopImmediatePropagation();
252
303
 
253
- return;
254
- }
304
+ focusIndex++;
305
+ recomputeOptions();
255
306
 
256
- if (e.key === "Enter") {
257
- e.preventDefault();
258
- e.stopImmediatePropagation();
307
+ return;
308
+ }
259
309
 
260
- console.log(optionElements, focusIndex);
310
+ if (e.key === "Enter") {
311
+ e.preventDefault();
312
+ e.stopImmediatePropagation();
261
313
 
262
- for (const entry of optionElements) {
263
- if (entry.dataset.optionIndex == focusIndex) {
264
- entry.click();
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
- return;
269
- }
270
- });
324
+ searchInput.addEventListener('keyup', (e) => {
325
+ if (["Enter", "ArrowUp", "ArrowDown"].includes(e.key)) return;
271
326
 
272
- searchInput.addEventListener('keyup', (e) => {
273
- if (["Enter", "ArrowUp", "ArrowDown"].includes(e.key)) return;
327
+ if (searchInput.value.trim().length === 0) {
328
+ constructOptionsBasedOnOptions(options);
329
+ filteredOptions = options;
330
+ return;
331
+ };
274
332
 
275
- if (searchInput.value.trim().length === 0) {
276
- constructOptionsBasedOnOptions(options);
277
- filteredOptions = options;
278
- return;
279
- };
333
+ filteredOptions = options.filter(x => x.label.includes(searchInput.value));
334
+ focusIndex = 0;
280
335
 
281
- filteredOptions = options.filter(x => x.label.includes(searchInput.value));
282
- focusIndex = 0;
336
+ constructOptionsBasedOnOptions(filteredOptions);
337
+ });
283
338
 
284
- constructOptionsBasedOnOptions(filteredOptions);
285
- });
339
+ function constructOptionsBasedOnOptions(options: Option[]) {
340
+ dropdown.innerHTML = '';
286
341
 
287
- function constructOptionsBasedOnOptions(options) {
288
- dropdown.innerHTML = '';
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
- if (options.length === 0) {
291
- const element = document.createElement('li');
292
- element.classList.add('empty-search-results');
293
- element.textContent = "No results found.";
347
+ dropdown.appendChild(element);
348
+ }
294
349
 
295
- dropdown.appendChild(element);
296
- }
350
+ let i = 0;
297
351
 
298
- let i = 0;
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
- for (const option of options) {
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
- element.addEventListener("click", (e) => handleSelection(e, element));
368
+ dropdown.appendChild(element);
315
369
 
316
- dropdown.appendChild(element);
370
+ i++;
371
+ }
317
372
 
318
- i++;
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-select-indicator {
469
+ .sui-search-input-wrapper input {
470
+ padding-right: 2.5rem;
471
+ }
472
+
473
+ .sui-search-select-indicator {
417
474
  position: absolute;
418
- top: calc(65% + 1px);
419
- transform: translateY(-65%);
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>