@poirazis/supercomponents-shared 0.0.1

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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -0
  3. package/dist/index.js +30635 -0
  4. package/dist/index.umd.cjs +12 -0
  5. package/dist/style.css +1 -0
  6. package/package.json +117 -0
  7. package/src/index.js +29 -0
  8. package/src/index.ts +31 -0
  9. package/src/lib/Actions/autoresize_textarea.js +14 -0
  10. package/src/lib/Actions/click_outside.js +80 -0
  11. package/src/lib/Actions/index.js +4 -0
  12. package/src/lib/Actions/position_dropdown.js +129 -0
  13. package/src/lib/SuperButton/SuperButton.svelte +341 -0
  14. package/src/lib/SuperFieldLabel/SuperFieldLabel.svelte +91 -0
  15. package/src/lib/SuperFieldsCommon.css +54 -0
  16. package/src/lib/SuperList/SuperList.svelte +308 -0
  17. package/src/lib/SuperList/drag-handle.svelte +31 -0
  18. package/src/lib/SuperPopover/SuperPopover.svelte +134 -0
  19. package/src/lib/SuperTable/SuperTable.css +410 -0
  20. package/src/lib/SuperTable/SuperTable.svelte +1332 -0
  21. package/src/lib/SuperTable/constants.js +85 -0
  22. package/src/lib/SuperTable/controls/ColumnsSection.svelte +34 -0
  23. package/src/lib/SuperTable/controls/ControlSection.svelte +3 -0
  24. package/src/lib/SuperTable/controls/RowButtonsColumn.svelte +169 -0
  25. package/src/lib/SuperTable/controls/SelectionColumn.svelte +174 -0
  26. package/src/lib/SuperTable/controls/SuperTableWelcome.svelte +58 -0
  27. package/src/lib/SuperTable/overlays/AddNewRowOverlay.svelte +52 -0
  28. package/src/lib/SuperTable/overlays/EmptyResultSetOverlay.svelte +13 -0
  29. package/src/lib/SuperTable/overlays/LoadingOverlay.svelte +3 -0
  30. package/src/lib/SuperTable/overlays/RowContextMenu copy.svelte +57 -0
  31. package/src/lib/SuperTable/overlays/RowContextMenu.svelte +58 -0
  32. package/src/lib/SuperTable/overlays/ScrollbarsOverlay.svelte +184 -0
  33. package/src/lib/SuperTable/overlays/SelectedActionsOverlay.svelte +64 -0
  34. package/src/lib/SuperTable/state/API.js +0 -0
  35. package/src/lib/SuperTable/state/SuperTableStateMachine.js +0 -0
  36. package/src/lib/SuperTable/types.js +0 -0
  37. package/src/lib/SuperTableCells/CellAttachment.svelte +288 -0
  38. package/src/lib/SuperTableCells/CellBoolean.svelte +158 -0
  39. package/src/lib/SuperTableCells/CellColor.svelte +460 -0
  40. package/src/lib/SuperTableCells/CellCommon.css +319 -0
  41. package/src/lib/SuperTableCells/CellDatetime.svelte +180 -0
  42. package/src/lib/SuperTableCells/CellIcon.svelte +627 -0
  43. package/src/lib/SuperTableCells/CellJSON.svelte +297 -0
  44. package/src/lib/SuperTableCells/CellLink.svelte +274 -0
  45. package/src/lib/SuperTableCells/CellLinkAdvanced.svelte +298 -0
  46. package/src/lib/SuperTableCells/CellLinkPickerSelect.svelte +355 -0
  47. package/src/lib/SuperTableCells/CellLinkPickerTable.svelte +91 -0
  48. package/src/lib/SuperTableCells/CellLinkPickerTree.svelte +226 -0
  49. package/src/lib/SuperTableCells/CellNumber.svelte +179 -0
  50. package/src/lib/SuperTableCells/CellNumberSimple.svelte +56 -0
  51. package/src/lib/SuperTableCells/CellOptions.svelte +631 -0
  52. package/src/lib/SuperTableCells/CellOptionsAdvanced.svelte +684 -0
  53. package/src/lib/SuperTableCells/CellSkeleton.svelte +59 -0
  54. package/src/lib/SuperTableCells/CellString.svelte +178 -0
  55. package/src/lib/SuperTableCells/CellStringSimple.svelte +55 -0
  56. package/src/lib/SuperTableCells/index.js +21 -0
  57. package/src/lib/SuperTableCells/remixIcons.js +6772 -0
  58. package/src/lib/SuperTableColumn/SuperTableColumn.svelte +392 -0
  59. package/src/lib/SuperTableColumn/index.js +9 -0
  60. package/src/lib/SuperTableColumn/parts/SuperColumnBody.svelte +57 -0
  61. package/src/lib/SuperTableColumn/parts/SuperColumnFooter.svelte +14 -0
  62. package/src/lib/SuperTableColumn/parts/SuperColumnHeader.svelte +228 -0
  63. package/src/lib/SuperTableColumn/parts/SuperColumnRow.svelte +142 -0
  64. package/src/lib/SuperTableColumn/parts/SuperColumnRowNew.svelte +34 -0
  65. package/src/lib/SuperTree/SuperTree.svelte +117 -0
  66. package/src/types/svelte-portal.d.ts +1 -0
@@ -0,0 +1,631 @@
1
+ <script>
2
+ import { getContext, createEventDispatcher, onMount } from "svelte";
3
+ import SuperPopover from "../SuperPopover/SuperPopover.svelte";
4
+ import CellString from "./CellString.svelte";
5
+ import fsm from "svelte-fsm";
6
+
7
+ const dispatch = createEventDispatcher();
8
+ const { API, QueryUtils, fetchData, memo, derivedMemo } = getContext("sdk");
9
+
10
+ export let cellOptions;
11
+ export let value;
12
+ export let fieldSchema;
13
+ export let multi = false;
14
+ export let autofocus;
15
+
16
+ let anchor;
17
+ let editor;
18
+ let options = memo([]);
19
+ let labels = {};
20
+ let optionColors = {};
21
+ let filteredOptions = [];
22
+ let focusedOptionIdx = -1;
23
+ let timer;
24
+ let picker;
25
+ let search;
26
+ let value_dom;
27
+
28
+ const colors = derivedMemo(options, ($options) => {
29
+ let obj = {};
30
+ $options.forEach(
31
+ (option, index) =>
32
+ (obj[option] = optionColors[option] || colorsArray[index % 14])
33
+ );
34
+ return obj;
35
+ });
36
+
37
+ const colorsArray = [
38
+ "hsla(0, 90%, 75%, 0.35)",
39
+ "hsla(25, 90%, 75%, 0.35)",
40
+ "hsla(50, 80%, 75%, 0.35)",
41
+ "hsla(75, 80%, 75%, 0.35)",
42
+ "hsla(100, 80%, 75%, 0.35)",
43
+ "hsla(125, 90%, 75%, 0.35)",
44
+ "hsla(150, 90%, 75%, 0.35)",
45
+ "hsla(175, 90%, 75%, 0.35)",
46
+ "hsla(200, 90%, 75%, 0.35)",
47
+ "hsla(225, 90%, 75%, 0.35)",
48
+ "hsla(250, 90%, 75%, 0.35)",
49
+ "hsla(275, 90%, 75%, 0.35)",
50
+ "hsla(300, 90%, 75%, 0.35)",
51
+ "hsla(325, 90%, 75%, 0.35)",
52
+ "hsla(350, 90%, 75%, 0.35)",
53
+ ];
54
+
55
+ let originalValue = JSON.stringify(
56
+ Array.isArray(value) ? value : value ? [value] : []
57
+ );
58
+
59
+ $: ({
60
+ controlType,
61
+ optionsSource,
62
+ valueColumn,
63
+ labelColumn,
64
+ iconColumn,
65
+ colorColumn,
66
+ customOptions,
67
+ optionsViewMode,
68
+ icon,
69
+ role,
70
+ readonly,
71
+ disabled,
72
+ error,
73
+ color,
74
+ background,
75
+ } = cellOptions);
76
+
77
+ // Handle Options from Data Source
78
+ const dataSourceStore = memo(cellOptions?.datasource ?? {});
79
+ $: dataSourceStore.set(cellOptions.datasource);
80
+ $: fetch = optionsSource == "data" ? createFetch($dataSourceStore) : memo({});
81
+ $: cellState.syncFetch($fetch);
82
+
83
+ // React to property changes
84
+ $: cellState.refresh(
85
+ fieldSchema,
86
+ optionsSource,
87
+ labelColumn,
88
+ valueColumn,
89
+ iconColumn,
90
+ colorColumn,
91
+ $dataSourceStore
92
+ );
93
+
94
+ // We always keep an internal value as an array
95
+ $: localValue = Array.isArray(value) ? value : value ? [value] : [];
96
+ $: isObjects =
97
+ localValue.length && typeof localValue[0] == "object" ? true : false;
98
+
99
+ $: isEmpty = localValue.length < 1;
100
+
101
+ $: isDirty = inEdit && originalValue !== JSON.stringify(localValue);
102
+ $: inEdit = $cellState == "Editing";
103
+ $: pills = optionsViewMode == "pills";
104
+ $: multi = fieldSchema ? fieldSchema?.type == "array" && multi : multi;
105
+ $: placeholder = disabled || readonly ? "" : cellOptions.placeholder || "";
106
+
107
+ export let cellState = fsm("Loading", {
108
+ "*": {
109
+ goTo(state) {
110
+ return state;
111
+ },
112
+ refresh() {
113
+ $options = [];
114
+ return "Loading";
115
+ },
116
+ loadSchemaOptions() {
117
+ optionColors = fieldSchema?.optionColors || {};
118
+ $options = fieldSchema?.constraints?.inclusion || [];
119
+ },
120
+ loadDataOptions(rows) {
121
+ if (rows && rows.length) {
122
+ rows.forEach((row) => {
123
+ $options.push(row[valueColumn]);
124
+ labels[row[valueColumn]] = row[labelColumn || valueColumn];
125
+ });
126
+ }
127
+ $options = $options;
128
+ },
129
+ loadCustomOptions() {
130
+ if (customOptions?.length) {
131
+ customOptions.forEach((row) => {
132
+ $options.push(row.value || row);
133
+ labels[row.value] = row.label || row;
134
+ });
135
+ }
136
+ $options = $options;
137
+ },
138
+ clearFilters() {
139
+ filteredOptions = $options;
140
+ },
141
+ },
142
+ Loading: {
143
+ _enter() {
144
+ if (cellOptions.optionsSource != "data" || $fetch?.loaded)
145
+ this.goTo.debounce(5, cellOptions.initialState || "View");
146
+ },
147
+ _exit() {
148
+ if (cellOptions.optionsSource == "custom") this.loadCustomOptions();
149
+ else if (optionsSource == "data") this.loadDataOptions($fetch?.rows);
150
+ else this.loadSchemaOptions();
151
+
152
+ filteredOptions = $options;
153
+ },
154
+ syncFetch(fetch) {
155
+ if (fetch?.loaded) {
156
+ return cellOptions.initialState || "View";
157
+ }
158
+ },
159
+ },
160
+ View: {
161
+ _enter() {},
162
+ focus(e) {
163
+ if (!cellOptions.readonly && !cellOptions.disabled) {
164
+ return "Editing";
165
+ }
166
+ },
167
+ },
168
+ Editing: {
169
+ _enter() {
170
+ originalValue = JSON.stringify(
171
+ Array.isArray(value) ? value : value ? [value] : []
172
+ );
173
+ if (controlType != "inputSelect") editorState.open();
174
+ dispatch("enteredit");
175
+ },
176
+ _exit() {
177
+ editorState.close();
178
+ this.clearFilters();
179
+ dispatch("exitedit");
180
+ },
181
+ focusout(e) {
182
+ // If the focus is moving to the search input inside the popup, ignore
183
+ if (picker?.contains(e?.relatedTarget)) return;
184
+
185
+ dispatch("focusout");
186
+ this.submit();
187
+ return "View";
188
+ },
189
+ submit() {
190
+ if (isDirty && !cellOptions.debounce) {
191
+ if (multi) dispatch("change", localValue);
192
+ else dispatch("change", localValue[0]);
193
+ }
194
+ },
195
+ clear() {
196
+ localValue = [];
197
+ if (cellOptions.debounce) dispatch("change", localValue[0]);
198
+ },
199
+ cancel() {
200
+ return "View";
201
+ },
202
+ },
203
+ });
204
+
205
+ let editorState = fsm("Closed", {
206
+ "*": {
207
+ close() {
208
+ value_dom?.focus();
209
+ return "Closed";
210
+ },
211
+ toggleOption(idx) {
212
+ if (idx < 0) return;
213
+
214
+ if (cellOptions.disabled || cellOptions.readonly) return;
215
+ let option = filteredOptions[idx];
216
+ let pos = localValue.indexOf(option);
217
+
218
+ if (multi && pos > -1) {
219
+ localValue.splice(pos, 1);
220
+ localValue = [...localValue];
221
+ } else if (multi) {
222
+ localValue = [...localValue, option];
223
+ } else {
224
+ if (localValue[0] == option) localValue.length = 0;
225
+ else localValue[0] = option;
226
+ }
227
+
228
+ if (cellOptions.debounce) {
229
+ clearTimeout(timer);
230
+ timer = setTimeout(() => {
231
+ dispatch("change", multi ? localValue : localValue[0]);
232
+ }, cellOptions.debounce ?? 0);
233
+ }
234
+
235
+ if (cellOptions.autocomplete) {
236
+ if (multi) {
237
+ this.filterOptions();
238
+ }
239
+ }
240
+ if (!multi) {
241
+ this.close.debounce(10);
242
+ anchor?.focus();
243
+ }
244
+ },
245
+ },
246
+ Open: {
247
+ _enter() {
248
+ focusedOptionIdx = -1;
249
+ },
250
+ _exit() {
251
+ search = false;
252
+ },
253
+ filterOptions(term) {
254
+ if (term) {
255
+ filteredOptions = $options.filter((x) =>
256
+ x?.toLowerCase().startsWith(term.toLowerCase())
257
+ );
258
+ } else {
259
+ filteredOptions = $options;
260
+ search = false;
261
+ value_dom.focus();
262
+ }
263
+ },
264
+ toggle() {
265
+ value_dom?.focus();
266
+ return "Closed";
267
+ },
268
+ handleInputKeyboard(e) {
269
+ if (e.key == "Enter" || e.key == "Tab") {
270
+ if (focusedOptionIdx > -1 && filteredOptions[focusedOptionIdx])
271
+ if (!multi) this.toggleOption(focusedOptionIdx);
272
+
273
+ cellState.submit();
274
+ editorState.close();
275
+ }
276
+
277
+ if (e.key == "ArrowDown") this.highlightNext(e.stopPropagation());
278
+ if (e.key == "ArrowUp")
279
+ this.highlightPrevious(e.preventDefault(), e.stopPropagation());
280
+ if (e.key == "Escape") this.close();
281
+ },
282
+
283
+ handleKeyboard(e) {
284
+ if (e.keyCode == 32) {
285
+ if (focusedOptionIdx > -1) {
286
+ this.toggleOption(focusedOptionIdx, e.preventDefault());
287
+ if (!multi) this.close(e.preventDefault());
288
+ } else if (!cellOptions.autocomplete) {
289
+ this.close(e.preventDefault());
290
+ }
291
+ }
292
+
293
+ if (e.key == "Escape") {
294
+ this.cancel();
295
+ }
296
+
297
+ if (e.key == "Enter" || e.key == "Tab") {
298
+ if (focusedOptionIdx > -1 && filteredOptions[focusedOptionIdx])
299
+ if (!multi) this.toggleOption(focusedOptionIdx);
300
+
301
+ cellState.submit();
302
+ editorState.close();
303
+ }
304
+
305
+ if (e.key == "ArrowDown") this.highlightNext();
306
+ if (e.key == "ArrowUp") this.highlightPrevious(e.preventDefault());
307
+
308
+ if (e.key == "Escape") this.close();
309
+
310
+ if (controlType != "inputSelect") search = true;
311
+ },
312
+ highlightNext() {
313
+ focusedOptionIdx += 1;
314
+ if (focusedOptionIdx > filteredOptions.length - 1) focusedOptionIdx = 0;
315
+
316
+ if (editor) editor.value = filteredOptions[focusedOptionIdx];
317
+ },
318
+ highlightPrevious() {
319
+ focusedOptionIdx -= 1;
320
+ if (focusedOptionIdx < 0) focusedOptionIdx = filteredOptions.length - 1;
321
+
322
+ if (editor) editor.value = filteredOptions[focusedOptionIdx];
323
+ },
324
+ },
325
+ Closed: {
326
+ toggle() {
327
+ return "Open";
328
+ },
329
+ open() {
330
+ return "Open";
331
+ },
332
+ highlightNext() {
333
+ this.open();
334
+ focusedOptionIdx = 0;
335
+ },
336
+ handleInputKeyboard(e) {
337
+ if (e.key == "Escape") cellState.cancel();
338
+ if (e.key != "Tab") {
339
+ this.open();
340
+ focusedOptionIdx = 0;
341
+ }
342
+ },
343
+ handleKeyboard(e) {
344
+ if (e.key == "Escape") cellState.cancel();
345
+ if (controlType == "select" && e.key != "Tab") {
346
+ search = true;
347
+ if (e.key == "ArrowDown" || e.keyCode == 32) this.toggle();
348
+ if (e.key == "Backspace" || e.key == "Delete") {
349
+ localValue = [];
350
+ dispatch("change", localValue);
351
+ }
352
+ }
353
+ },
354
+ },
355
+ });
356
+
357
+ const createFetch = (datasource) => {
358
+ return fetchData({
359
+ API,
360
+ datasource,
361
+ options: {
362
+ query: QueryUtils.buildQuery(cellOptions.filter),
363
+ sortColumn: cellOptions.sortColumn,
364
+ sortOrder: cellOptions.sortOrder,
365
+ limit: cellOptions.limit,
366
+ },
367
+ });
368
+ };
369
+
370
+ const focus = (node) => {
371
+ node?.focus();
372
+ };
373
+
374
+ onMount(() => {
375
+ if (autofocus)
376
+ setTimeout(() => {
377
+ cellState.focus();
378
+ editor?.focus();
379
+ }, 30);
380
+ });
381
+ </script>
382
+
383
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
384
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
385
+ <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
386
+ <div
387
+ bind:this={anchor}
388
+ class="superCell"
389
+ class:isDirty={isDirty && cellOptions.showDirty}
390
+ class:inEdit
391
+ class:disabled
392
+ class:readonly
393
+ class:error
394
+ style:color
395
+ style:background
396
+ style:font-weight={cellOptions.fontWeight}
397
+ class:inline={role == "inlineInput"}
398
+ class:tableCell={role == "tableCell"}
399
+ class:formInput={role == "formInput"}
400
+ >
401
+ {#if icon}
402
+ <i class={icon + " icon"} />
403
+ {/if}
404
+
405
+ {#if inEdit && controlType == "inputSelect"}
406
+ {#if multi}
407
+ {#if localValue.length > 0}
408
+ <div
409
+ class="value"
410
+ style:width={"auto"}
411
+ style:padding-left={cellOptions.icon ? "32px" : cellOptions.padding}
412
+ >
413
+ <div
414
+ class="items"
415
+ class:pills
416
+ style:justify-content={cellOptions.align ?? "flex-start"}
417
+ >
418
+ {#each localValue as val (val)}
419
+ <div class="item" style:--option-color={$colors[val]}>
420
+ {#if pills}
421
+ <div class="loope" />
422
+ {/if}
423
+ <span> {labels[val] || val} </span>
424
+ </div>
425
+ {/each}
426
+ </div>
427
+ </div>
428
+ {/if}
429
+ {/if}
430
+
431
+ <input
432
+ bind:this={editor}
433
+ tabindex="0"
434
+ class="editor"
435
+ class:with-icon={cellOptions.icon}
436
+ on:input={(e) => editorState.filterOptions(e.target.value)}
437
+ on:keydown={editorState.handleInputKeyboard}
438
+ on:focusout={cellState.focusout}
439
+ use:focus
440
+ {placeholder}
441
+ />
442
+ <div
443
+ class="actionIcon"
444
+ on:mousedown|preventDefault|stopPropagation={editorState.toggle}
445
+ >
446
+ <i class="ri-arrow-down-s-line"></i>
447
+ </div>
448
+ {:else}
449
+ <div
450
+ class="value"
451
+ class:with-icon={icon}
452
+ class:placeholder={isEmpty}
453
+ tabindex={cellOptions?.disabled ? "-1" : "0"}
454
+ bind:this={value_dom}
455
+ on:focusin={cellState.focus}
456
+ on:focusout={cellState.focusout}
457
+ on:keydown={editorState.handleKeyboard}
458
+ on:mousedown={inEdit ? editorState.toggle : () => {}}
459
+ >
460
+ {#if isEmpty}
461
+ <span>{placeholder}</span>
462
+ {:else if optionsViewMode == "text"}
463
+ <div style:flex={"auto"}>
464
+ <span>
465
+ {localValue.join(", ")}
466
+ </span>
467
+ </div>
468
+ {:else}
469
+ <div
470
+ class="items"
471
+ class:pills
472
+ class:colorText={optionsViewMode == "colorText"}
473
+ style:justify-content={cellOptions.align ?? "flex-start"}
474
+ >
475
+ {#each localValue as val (val)}
476
+ <div class="item" style:--option-color={$colors[val]}>
477
+ <i class="ri-checkbox-blank-fill" />
478
+ <span> {isObjects ? "JSON" : labels[val] || val} </span>
479
+ </div>
480
+ {/each}
481
+ </div>
482
+ {/if}
483
+
484
+ {#if inEdit && !isEmpty}
485
+ <i
486
+ class="ri-close-line clearIcon"
487
+ style:right={"28px"}
488
+ on:mousedown|self|preventDefault={cellState.clear}
489
+ ></i>
490
+ {/if}
491
+
492
+ {#if !cellOptions.readonly && (role == "formInput" || inEdit)}
493
+ <i class="ri-arrow-down-s-line controlIcon" />
494
+ {/if}
495
+ </div>
496
+ {/if}
497
+ </div>
498
+
499
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
500
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
501
+ {#if inEdit}
502
+ <SuperPopover
503
+ {anchor}
504
+ useAnchorWidth
505
+ maxHeight={400}
506
+ open={$editorState == "Open"}
507
+ >
508
+ <div
509
+ bind:this={picker}
510
+ class="options"
511
+ on:wheel={(e) => e.stopPropagation()}
512
+ on:mouseleave={() => (focusedOptionIdx = -1)}
513
+ >
514
+ {#if search}
515
+ <div
516
+ class="searchControl"
517
+ style="min-height: 2rem;"
518
+ on:keydown={editorState.handleInputKeyboard}
519
+ >
520
+ <CellString
521
+ autofocus
522
+ on:change={(e) => editorState.filterOptions(e.detail)}
523
+ cellOptions={{
524
+ icon: "ri-search-line",
525
+ initialState: "Editing",
526
+ role: "inlineInput",
527
+ debounce: 25,
528
+ placeholder: "Search",
529
+ }}
530
+ value=""
531
+ />
532
+ </div>
533
+ {/if}
534
+ {#if filteredOptions?.length < 1}
535
+ <div class="option">
536
+ <span>
537
+ <i class="ri-close-line" />
538
+ No Options Found
539
+ </span>
540
+ </div>
541
+ {:else}
542
+ {#each filteredOptions as option, idx (idx)}
543
+ <div
544
+ class="option"
545
+ class:text={optionsViewMode == "text"}
546
+ class:focused={focusedOptionIdx === idx}
547
+ class:selected={localValue?.includes(option)}
548
+ style:--option-color={$colors[option]}
549
+ on:mousedown|preventDefault={(e) => editorState.toggleOption(idx)}
550
+ on:mouseenter={() => (focusedOptionIdx = idx)}
551
+ >
552
+ <span>
553
+ <i class="ri-checkbox-blank-fill" />
554
+ {labels[option] || option}
555
+ </span>
556
+ {#if localValue?.includes(option)}
557
+ <i class="ri-check-fill" />
558
+ {/if}
559
+ </div>
560
+ {/each}
561
+ {/if}
562
+ </div>
563
+ </SuperPopover>
564
+ {/if}
565
+
566
+ <style>
567
+ .searchControl {
568
+ display: flex;
569
+ align-items: stretch;
570
+ border-bottom: 1px solid var(--spectrum-global-color-gray-300);
571
+ }
572
+ .options {
573
+ display: flex;
574
+ flex-direction: column;
575
+ align-items: stretch;
576
+ overflow-y: auto;
577
+ color: var(--spectrum-global-color-gray-700);
578
+ }
579
+
580
+ .option {
581
+ min-height: 1.75rem;
582
+ display: flex;
583
+ gap: 0.5rem;
584
+ align-items: center;
585
+ justify-content: space-between;
586
+ cursor: pointer;
587
+ padding: 0 0.5rem;
588
+
589
+ &.selected {
590
+ color: var(--spectrum-global-color-gray-800);
591
+ font-weight: 600;
592
+ }
593
+
594
+ &.focused {
595
+ background-color: var(--spectrum-global-color-gray-200);
596
+ color: var(--spectrum-global-color-gray-800);
597
+ }
598
+
599
+ & > i {
600
+ font-size: 14px;
601
+ color: var(--spectrum-global-color-green-400);
602
+ }
603
+ & > span {
604
+ display: flex;
605
+ align-items: center;
606
+ gap: 0.5rem;
607
+ overflow: hidden;
608
+ text-overflow: ellipsis;
609
+ white-space: nowrap;
610
+
611
+ & > i {
612
+ font-size: 16px;
613
+ color: var(--option-color);
614
+ }
615
+ }
616
+ }
617
+ .actionIcon {
618
+ height: 100%;
619
+ display: flex;
620
+ justify-content: center;
621
+ align-items: center;
622
+ border-left: 1px solid var(--spectrum-global-color-blue-500);
623
+ min-width: 2rem;
624
+ font-size: 16px;
625
+ }
626
+ .actionIcon:hover {
627
+ cursor: pointer;
628
+ background-color: var(--spectrum-global-color-gray-75);
629
+ font-weight: 800;
630
+ }
631
+ </style>