@ibobbyts/svelte-ui-utils 0.3.4 → 0.3.6

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 CHANGED
@@ -241,6 +241,8 @@ controls need caller-owned accessible labels. Each label is applied to both
241
241
  `SortableTableEnhanced` composes the same table and adds a controlled current
242
242
  radio immediately after each drag handle. `currentId` is read-only input;
243
243
  `onCurrentChange` asks the caller to persist a new current item. Use
244
+ `showCurrentControl={false}` to omit the radios while retaining the table's
245
+ drag, remove, reorder, and row-color behavior. Use
244
246
  `getCurrentDisabled` for per-row eligibility and `getRowColorPreset` to select
245
247
  the package-owned `red`, `yellow`, or `green` background. The presets include
246
248
  light and dark defaults and expose `--suu-sortable-table-row-*-light` and
@@ -348,7 +350,12 @@ prop is available on all dialog wrapper components.
348
350
 
349
351
  ```svelte
350
352
  <script lang="ts">
351
- import { Dropdown, type DropdownOption, type DropdownValue } from '@ibobbyts/svelte-ui-utils/dropdown';
353
+ import {
354
+ Dropdown,
355
+ DropdownMultiSelect,
356
+ type DropdownOption,
357
+ type DropdownValue
358
+ } from '@ibobbyts/svelte-ui-utils/dropdown';
352
359
 
353
360
  const pageSizeOptions: DropdownOption[] = [
354
361
  { label: '10', value: 10 },
@@ -377,6 +384,36 @@ use `menuAlign="right"` to align their right edges instead. `fitContent` sizes
377
384
  the menu to its longest option while keeping the selected edge aligned.
378
385
  `DataTable` uses this same component for its page-size picker.
379
386
 
387
+ Set `multiselect={true}` to control the component with a `DropdownValue[]`.
388
+ Each option then shows a checkbox, selecting or deselecting an option keeps the
389
+ menu open, and `onChange` receives the complete selected-value array in option
390
+ display order. `DropdownMultiSelect` is the convenience wrapper for this mode:
391
+
392
+ ```svelte
393
+ <script lang="ts">
394
+ import { DropdownMultiSelect, type DropdownMultiValue } from '@ibobbyts/svelte-ui-utils/dropdown';
395
+
396
+ let selectedRoles: DropdownMultiValue = ['editor'];
397
+ </script>
398
+
399
+ <DropdownMultiSelect
400
+ value={selectedRoles}
401
+ options={[
402
+ { label: 'Editor', value: 'editor' },
403
+ { label: 'Reviewer', value: 'reviewer' }
404
+ ]}
405
+ ariaLabel="Roles"
406
+ maxWidth="18rem"
407
+ onChange={(next) => {
408
+ selectedRoles = next;
409
+ }}
410
+ />
411
+ ```
412
+
413
+ The collapsed trigger joins selected labels with `", "` and truncates the
414
+ single line when it exceeds the existing `width` or `maxWidth` constraint.
415
+ Grouped and disabled options retain the same behavior as single-select mode.
416
+
380
417
  The dropdown panel is constrained by default to the space available above or
381
418
  below the trigger and remains scrollable when its contents exceed that height.
382
419
  Set `fitViewport={false}` to fall back to the stylesheet's viewport-height
@@ -5,36 +5,41 @@
5
5
  import type {
6
6
  DropdownChangeHandler,
7
7
  DropdownMenuAlign,
8
+ DropdownMultiChangeHandler,
9
+ DropdownMultiValue,
8
10
  DropdownOption,
9
11
  DropdownOptionGroup,
10
12
  DropdownPlacement,
13
+ DropdownSelectionChangeHandler,
14
+ DropdownSelection,
11
15
  DropdownTriggerClickHandler,
12
16
  DropdownValue
13
17
  } from './types.js';
14
18
 
15
19
  export let id: string | undefined = undefined;
16
- export let value: DropdownValue = '';
20
+ export let value: DropdownSelection = '';
21
+ export let multiselect = false;
17
22
  export let options: DropdownOption[] = [];
18
23
  export let optionGroups: DropdownOptionGroup[] | undefined = undefined;
19
24
  export let ariaLabel: string | undefined = undefined;
20
25
  export let placement: DropdownPlacement = 'auto';
21
26
  export let menuAlign: DropdownMenuAlign = 'left';
22
27
  export let fitViewport = true;
23
- export let fitContent = false;
28
+ export let fitContent = true;
24
29
  export let disabled = false;
25
30
  export let width: string | undefined = undefined;
26
31
  export let minWidth: string | undefined = undefined;
27
32
  export let maxWidth: string | undefined = undefined;
28
33
  export let className: string | undefined = undefined;
29
34
  export let portal = false;
30
- export let onChange: DropdownChangeHandler | undefined = undefined;
35
+ export let onChange: DropdownSelectionChangeHandler | undefined = undefined;
31
36
  export let onTriggerClick: DropdownTriggerClickHandler | undefined = undefined;
32
37
 
33
38
  const viewportMargin = 20;
34
39
  const menuGap = 6;
35
40
 
36
41
  let open = false;
37
- let activeValue: DropdownValue = value;
42
+ let activeValue: DropdownValue = '';
38
43
  let dropdownElement: HTMLSpanElement | undefined;
39
44
  let buttonElement: HTMLButtonElement | undefined;
40
45
  let menuElement: HTMLDivElement | undefined;
@@ -45,20 +50,31 @@
45
50
  let portalMenuRight: string | undefined = undefined;
46
51
  let portalMenuWidth: string | undefined = undefined;
47
52
  let removeOpenViewportListeners: (() => void) | undefined = undefined;
53
+ let removeOutsidePointerListener: (() => void) | undefined = undefined;
48
54
 
49
55
  $: resolvedOptions = optionGroups === undefined ? options : optionGroups.flatMap((group) => group.options);
50
- $: selectedOption = resolvedOptions.find((option) => option.value === value);
51
- $: selectedText = selectedOption?.label ?? String(value);
56
+ $: selectedValues = normalizeSelectedValues(multiselect && Array.isArray(value) ? value : []);
57
+ $: selectedOption = Array.isArray(value) ? undefined : resolvedOptions.find((option) => option.value === value);
58
+ $: selectedText = multiselect
59
+ ? resolvedOptions
60
+ .filter((option) => selectedValues.includes(option.value))
61
+ .map((option) => option.label)
62
+ .join(', ')
63
+ : selectedOption?.label ?? String(value);
52
64
  $: if (!open) {
53
- activeValue = selectedOption?.value ?? firstEnabledOption()?.value ?? value;
65
+ activeValue = initialActiveValue();
54
66
  }
55
67
  $: {
56
68
  placement;
57
69
  if (open) {
58
70
  enableOpenViewportTracking();
71
+ if (multiselect) {
72
+ enableOutsidePointerDismissal();
73
+ }
59
74
  void updateViewportPanelMaxHeight();
60
75
  } else {
61
76
  disableOpenViewportTracking();
77
+ disableOutsidePointerDismissal();
62
78
  resolvedPlacement = placement === 'up' ? 'up' : 'down';
63
79
  viewportPanelMaxHeight = undefined;
64
80
  }
@@ -68,12 +84,36 @@
68
84
  return resolvedOptions.find((option) => !option.disabled);
69
85
  }
70
86
 
87
+ function normalizeSelectedValues(nextValues: DropdownMultiValue): DropdownMultiValue {
88
+ const incoming = new Set(nextValues);
89
+ const normalized: DropdownMultiValue = [];
90
+ for (const option of resolvedOptions) {
91
+ if (incoming.has(option.value) && !normalized.includes(option.value)) {
92
+ normalized.push(option.value);
93
+ }
94
+ }
95
+ return normalized;
96
+ }
97
+
98
+ function initialActiveValue(): DropdownValue {
99
+ const firstSelectedEnabled = resolvedOptions.find(
100
+ (option) => selectedValues.includes(option.value) && !option.disabled
101
+ );
102
+ return firstSelectedEnabled?.value ?? selectedOption?.value ?? firstEnabledOption()?.value ?? '';
103
+ }
104
+
105
+ function isOptionSelected(option: DropdownOption): boolean {
106
+ return multiselect ? selectedValues.includes(option.value) : option.value === value;
107
+ }
108
+
71
109
  function activeOptionIndex(nextActiveValue: DropdownValue): number {
72
110
  const index = resolvedOptions.findIndex((option) => option.value === nextActiveValue && !option.disabled);
73
111
  if (index >= 0) {
74
112
  return index;
75
113
  }
76
- const fallbackIndex = resolvedOptions.findIndex((option) => option.value === value && !option.disabled);
114
+ const fallbackIndex = resolvedOptions.findIndex(
115
+ (option) => isOptionSelected(option) && !option.disabled
116
+ );
77
117
  if (fallbackIndex >= 0) {
78
118
  return fallbackIndex;
79
119
  }
@@ -95,9 +135,21 @@
95
135
  if (option.disabled) {
96
136
  return;
97
137
  }
98
- open = false;
99
138
  activeValue = option.value;
100
- void onChange?.(option.value);
139
+ if (multiselect) {
140
+ const nextSelected = new Set(selectedValues);
141
+ if (nextSelected.has(option.value)) {
142
+ nextSelected.delete(option.value);
143
+ } else {
144
+ nextSelected.add(option.value);
145
+ }
146
+ const nextValues = normalizeSelectedValues([...nextSelected]);
147
+ void (onChange as DropdownMultiChangeHandler | undefined)?.(nextValues);
148
+ return;
149
+ }
150
+
151
+ open = false;
152
+ void (onChange as DropdownChangeHandler | undefined)?.(option.value);
101
153
  buttonElement?.focus();
102
154
  }
103
155
 
@@ -109,7 +161,7 @@
109
161
  updateResolvedPlacement();
110
162
  }
111
163
  open = !open;
112
- activeValue = selectedOption?.value ?? firstEnabledOption()?.value ?? value;
164
+ activeValue = initialActiveValue();
113
165
  }
114
166
 
115
167
  function handleTriggerClick(event: MouseEvent) {
@@ -135,7 +187,7 @@
135
187
  if (!open) {
136
188
  updateResolvedPlacement();
137
189
  open = true;
138
- activeValue = selectedOption?.value ?? firstEnabledOption()?.value ?? value;
190
+ activeValue = initialActiveValue();
139
191
  }
140
192
  moveActiveOption(event.key === 'ArrowDown' ? 1 : -1);
141
193
  return;
@@ -279,13 +331,44 @@
279
331
  removeOpenViewportListeners?.();
280
332
  }
281
333
 
282
- onDestroy(disableOpenViewportTracking);
334
+ function enableOutsidePointerDismissal() {
335
+ if (removeOutsidePointerListener || typeof document === 'undefined') {
336
+ return;
337
+ }
338
+
339
+ const handleOutsidePointer = (event: PointerEvent) => {
340
+ const target = event.target;
341
+ if (!(target instanceof Node)) {
342
+ return;
343
+ }
344
+ if (dropdownElement?.contains(target) || menuElement?.contains(target)) {
345
+ return;
346
+ }
347
+ open = false;
348
+ };
349
+
350
+ document.addEventListener('pointerdown', handleOutsidePointer, true);
351
+ removeOutsidePointerListener = () => {
352
+ document.removeEventListener('pointerdown', handleOutsidePointer, true);
353
+ removeOutsidePointerListener = undefined;
354
+ };
355
+ }
356
+
357
+ function disableOutsidePointerDismissal() {
358
+ removeOutsidePointerListener?.();
359
+ }
360
+
361
+ onDestroy(() => {
362
+ disableOpenViewportTracking();
363
+ disableOutsidePointerDismissal();
364
+ });
283
365
  </script>
284
366
 
285
367
  <span
286
368
  bind:this={dropdownElement}
287
369
  class={[
288
370
  'suu-dropdown',
371
+ multiselect ? 'suu-dropdown--multiselect' : '',
289
372
  width !== undefined || minWidth !== undefined || maxWidth !== undefined
290
373
  ? 'suu-dropdown--sized'
291
374
  : '',
@@ -306,7 +389,7 @@
306
389
  aria-label={ariaLabel}
307
390
  aria-haspopup="listbox"
308
391
  aria-expanded={open}
309
- data-value={String(value)}
392
+ data-value={Array.isArray(value) ? value.map(String).join(',') : String(value)}
310
393
  on:click={handleTriggerClick}
311
394
  on:keydown={handleKeydown}
312
395
  >
@@ -330,7 +413,12 @@
330
413
  style:--suu-dropdown-menu-right={portalMenuRight}
331
414
  style:--suu-dropdown-menu-width={portalMenuWidth}
332
415
  >
333
- <div class="suu-dropdown__panel" role="listbox" aria-label={ariaLabel}>
416
+ <div
417
+ class="suu-dropdown__panel"
418
+ role="listbox"
419
+ aria-label={ariaLabel}
420
+ aria-multiselectable={multiselect || undefined}
421
+ >
334
422
  {#if optionGroups === undefined}
335
423
  {#each options as option}
336
424
  <button
@@ -339,7 +427,7 @@
339
427
  class:suu-dropdown__option--active={option.value === activeValue}
340
428
  class:suu-dropdown__option--disabled={option.disabled}
341
429
  role="option"
342
- aria-selected={option.value === value}
430
+ aria-selected={multiselect ? selectedValues.includes(option.value) : option.value === value}
343
431
  aria-disabled={option.disabled}
344
432
  disabled={option.disabled}
345
433
  data-value={String(option.value)}
@@ -351,6 +439,13 @@
351
439
  }}
352
440
  on:click={() => selectOption(option)}
353
441
  >
442
+ {#if multiselect}
443
+ <span
444
+ class="suu-dropdown__checkbox"
445
+ data-checked={multiselect ? selectedValues.includes(option.value) : option.value === value}
446
+ aria-hidden="true"
447
+ ></span>
448
+ {/if}
354
449
  <span class="suu-dropdown__label">{option.label}</span>
355
450
  </button>
356
451
  {/each}
@@ -367,7 +462,7 @@
367
462
  class:suu-dropdown__option--active={option.value === activeValue}
368
463
  class:suu-dropdown__option--disabled={option.disabled}
369
464
  role="option"
370
- aria-selected={option.value === value}
465
+ aria-selected={multiselect ? selectedValues.includes(option.value) : option.value === value}
371
466
  aria-disabled={option.disabled}
372
467
  disabled={option.disabled}
373
468
  data-value={String(option.value)}
@@ -379,6 +474,13 @@
379
474
  }}
380
475
  on:click={() => selectOption(option)}
381
476
  >
477
+ {#if multiselect}
478
+ <span
479
+ class="suu-dropdown__checkbox"
480
+ data-checked={multiselect ? selectedValues.includes(option.value) : option.value === value}
481
+ aria-hidden="true"
482
+ ></span>
483
+ {/if}
382
484
  <span class="suu-dropdown__label">{option.label}</span>
383
485
  </button>
384
486
  {/each}
@@ -1,4 +1,4 @@
1
- import type { DropdownChangeHandler, DropdownMenuAlign, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownTriggerClickHandler, DropdownValue } from './types.js';
1
+ import type { DropdownMenuAlign, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownSelectionChangeHandler, DropdownSelection, DropdownTriggerClickHandler } from './types.js';
2
2
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
4
  $$bindings?: Bindings;
@@ -14,7 +14,8 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
14
14
  }
15
15
  declare const Dropdown: $$__sveltets_2_IsomorphicComponent<{
16
16
  id?: string | undefined;
17
- value?: DropdownValue;
17
+ value?: DropdownSelection;
18
+ multiselect?: boolean;
18
19
  options?: DropdownOption[];
19
20
  optionGroups?: DropdownOptionGroup[] | undefined;
20
21
  ariaLabel?: string | undefined;
@@ -28,7 +29,7 @@ declare const Dropdown: $$__sveltets_2_IsomorphicComponent<{
28
29
  maxWidth?: string | undefined;
29
30
  className?: string | undefined;
30
31
  portal?: boolean;
31
- onChange?: DropdownChangeHandler | undefined;
32
+ onChange?: DropdownSelectionChangeHandler | undefined;
32
33
  onTriggerClick?: DropdownTriggerClickHandler | undefined;
33
34
  }, {
34
35
  [evt: string]: CustomEvent<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/Dropdown.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC3B,aAAa,EACd,MAAM,YAAY,CAAC;AAwUtB,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,QAAQ;SAVwX,MAAM,GAAG,SAAS;YAAU,aAAa;cAAY,cAAc,EAAE;mBAAiB,mBAAmB,EAAE,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;gBAAc,iBAAiB;gBAAc,iBAAiB;;;;YAAwG,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;;eAAqC,qBAAqB,GAAG,SAAS;qBAAmB,2BAA2B,GAAG,SAAS;;;kBAUt1B,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Dropdown.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/Dropdown.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAER,iBAAiB,EAGjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,iBAAiB,EACjB,2BAA2B,EAE5B,MAAM,YAAY,CAAC;AA6ZtB,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,QAAQ;SAVmZ,MAAM,GAAG,SAAS;YAAU,iBAAiB;;cAA8C,cAAc,EAAE;mBAAiB,mBAAmB,EAAE,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;gBAAc,iBAAiB;gBAAc,iBAAiB;;;;YAAwG,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;;eAAqC,8BAA8B,GAAG,SAAS;qBAAmB,2BAA2B,GAAG,SAAS;;;kBAUh6B,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,53 @@
1
+ <svelte:options runes={false} />
2
+
3
+ <script lang="ts">
4
+ import Dropdown from './Dropdown.svelte';
5
+ import type {
6
+ DropdownMenuAlign,
7
+ DropdownMultiChangeHandler,
8
+ DropdownMultiValue,
9
+ DropdownOption,
10
+ DropdownOptionGroup,
11
+ DropdownPlacement,
12
+ DropdownTriggerClickHandler
13
+ } from './types.js';
14
+
15
+ export let id: string | undefined = undefined;
16
+ export let value: DropdownMultiValue = [];
17
+ export let options: DropdownOption[] = [];
18
+ export let optionGroups: DropdownOptionGroup[] | undefined = undefined;
19
+ export let ariaLabel: string | undefined = undefined;
20
+ export let placement: DropdownPlacement = 'auto';
21
+ export let menuAlign: DropdownMenuAlign = 'left';
22
+ export let fitViewport = true;
23
+ export let fitContent = false;
24
+ export let disabled = false;
25
+ export let width: string | undefined = undefined;
26
+ export let minWidth: string | undefined = undefined;
27
+ export let maxWidth: string | undefined = undefined;
28
+ export let className: string | undefined = undefined;
29
+ export let portal = false;
30
+ export let onChange: DropdownMultiChangeHandler | undefined = undefined;
31
+ export let onTriggerClick: DropdownTriggerClickHandler | undefined = undefined;
32
+ </script>
33
+
34
+ <Dropdown
35
+ {id}
36
+ {value}
37
+ multiselect={true}
38
+ {options}
39
+ {optionGroups}
40
+ {ariaLabel}
41
+ {placement}
42
+ {menuAlign}
43
+ {fitViewport}
44
+ {fitContent}
45
+ {disabled}
46
+ {width}
47
+ {minWidth}
48
+ {maxWidth}
49
+ {className}
50
+ {portal}
51
+ {onChange}
52
+ {onTriggerClick}
53
+ />
@@ -0,0 +1,38 @@
1
+ import type { DropdownMenuAlign, DropdownMultiChangeHandler, DropdownMultiValue, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownTriggerClickHandler } from './types.js';
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const DropdownMultiSelect: $$__sveltets_2_IsomorphicComponent<{
16
+ id?: string | undefined;
17
+ value?: DropdownMultiValue;
18
+ options?: DropdownOption[];
19
+ optionGroups?: DropdownOptionGroup[] | undefined;
20
+ ariaLabel?: string | undefined;
21
+ placement?: DropdownPlacement;
22
+ menuAlign?: DropdownMenuAlign;
23
+ fitViewport?: boolean;
24
+ fitContent?: boolean;
25
+ disabled?: boolean;
26
+ width?: string | undefined;
27
+ minWidth?: string | undefined;
28
+ maxWidth?: string | undefined;
29
+ className?: string | undefined;
30
+ portal?: boolean;
31
+ onChange?: DropdownMultiChangeHandler | undefined;
32
+ onTriggerClick?: DropdownTriggerClickHandler | undefined;
33
+ }, {
34
+ [evt: string]: CustomEvent<any>;
35
+ }, {}, {}, string>;
36
+ type DropdownMultiSelect = InstanceType<typeof DropdownMultiSelect>;
37
+ export default DropdownMultiSelect;
38
+ //# sourceMappingURL=DropdownMultiSelect.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropdownMultiSelect.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/DropdownMultiSelect.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AA+BtB,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,mBAAmB;SAV6W,MAAM,GAAG,SAAS;YAAU,kBAAkB;cAAY,cAAc,EAAE;mBAAiB,mBAAmB,EAAE,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;gBAAc,iBAAiB;gBAAc,iBAAiB;;;;YAAwG,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;;eAAqC,0BAA0B,GAAG,SAAS;qBAAmB,2BAA2B,GAAG,SAAS;;;kBAUr1B,CAAC;AACvF,KAAK,mBAAmB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,eAAe,mBAAmB,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { default as Dropdown } from './Dropdown.svelte';
2
- export type { DropdownChangeHandler, DropdownMenuAlign, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownTriggerClickHandler, DropdownValue } from './types.js';
2
+ export { default as DropdownMultiSelect } from './DropdownMultiSelect.svelte';
3
+ export type { DropdownChangeHandler, DropdownMenuAlign, DropdownMultiChangeHandler, DropdownMultiValue, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownSelectionChangeHandler, DropdownSelection, DropdownTriggerClickHandler, DropdownValue } from './types.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACV,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC3B,aAAa,EACd,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,YAAY,EACV,qBAAqB,EACrB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,iBAAiB,EACjB,2BAA2B,EAC3B,aAAa,EACd,MAAM,YAAY,CAAC"}
@@ -1 +1,2 @@
1
1
  export { default as Dropdown } from './Dropdown.svelte';
2
+ export { default as DropdownMultiSelect } from './DropdownMultiSelect.svelte';
@@ -1,4 +1,6 @@
1
1
  export type DropdownValue = string | number;
2
+ export type DropdownMultiValue = DropdownValue[];
3
+ export type DropdownSelection = DropdownValue | DropdownMultiValue;
2
4
  export type DropdownPlacement = 'auto' | 'up' | 'down';
3
5
  export type DropdownMenuAlign = 'left' | 'right';
4
6
  export interface DropdownOption {
@@ -11,5 +13,9 @@ export interface DropdownOptionGroup {
11
13
  options: DropdownOption[];
12
14
  }
13
15
  export type DropdownChangeHandler = (value: DropdownValue) => void | Promise<void>;
16
+ export type DropdownMultiChangeHandler = (value: DropdownMultiValue) => void | Promise<void>;
17
+ export type DropdownSelectionChangeHandler = {
18
+ bivarianceHack(value: DropdownSelection): void | Promise<void>;
19
+ }['bivarianceHack'];
14
20
  export type DropdownTriggerClickHandler = (event: MouseEvent) => void;
15
21
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,MAAM,kBAAkB,GAAG,aAAa,EAAE,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,MAAM,MAAM,0BAA0B,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7F,MAAM,MAAM,8BAA8B,GAAG;IAC5C,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D,CAAC,gBAAgB,CAAC,CAAC;AAEpB,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC"}
@@ -106,8 +106,10 @@
106
106
  <style>
107
107
  .suu-sortable-table-wrap { overflow: auto; border: 1px solid var(--suu-color-border, #d1d5db); border-radius: var(--suu-radius, 8px); }
108
108
  .suu-sortable-table { width: 100%; border-collapse: collapse; }
109
- .suu-sortable-table__drag-column, .suu-sortable-table__remove-column { width: 38px; }
110
- .suu-sortable-table__drag-cell, .suu-sortable-table__remove-cell { width: 38px; padding: 6px; text-align: center; vertical-align: middle; }
109
+ .suu-sortable-table__drag-column { width: 1%; }
110
+ .suu-sortable-table__remove-column { width: 38px; }
111
+ .suu-sortable-table__drag-cell { width: 1%; padding: 6px; text-align: center; vertical-align: middle; white-space: nowrap; }
112
+ .suu-sortable-table__remove-cell { width: 38px; padding: 6px; text-align: center; vertical-align: middle; }
111
113
  .suu-sortable-table__drag-handle, .suu-sortable-table__remove { display: inline-grid; place-items: center; border: 0; background: transparent; cursor: grab; color: var(--suu-color-text-dim, #6b7280); padding: 4px; font: inherit; }
112
114
  .suu-sortable-table__remove { width: 30px; height: 30px; cursor: pointer; color: var(--suu-color-danger, #dc2626); }
113
115
  .suu-sortable-table__remove svg { width: 16px; height: 16px; }
@@ -13,6 +13,7 @@
13
13
  disabled = false,
14
14
  allowRemoveLast = false,
15
15
  tableClass = '',
16
+ showCurrentControl = true,
16
17
  currentId = null,
17
18
  getCurrentDisabled = () => false,
18
19
  getCurrentLabel = (item: Item) => `Set ${getId(item)} as current`,
@@ -30,6 +31,7 @@
30
31
  disabled?: boolean;
31
32
  allowRemoveLast?: boolean;
32
33
  tableClass?: string;
34
+ showCurrentControl?: boolean;
33
35
  currentId?: string | null;
34
36
  getCurrentDisabled?: (item: Item, index: number) => boolean;
35
37
  getCurrentLabel?: (item: Item, index: number) => string;
@@ -80,19 +82,12 @@
80
82
  {getRemoveLabel}
81
83
  {onReorder}
82
84
  {onRemove}
83
- dragAccessory={currentControl}
85
+ dragAccessory={showCurrentControl ? currentControl : undefined}
84
86
  {header}
85
87
  {children}
86
88
  />
87
89
 
88
90
  <style>
89
- :global(.suu-sortable-table-enhanced .suu-sortable-table__drag-column),
90
- :global(.suu-sortable-table-enhanced .suu-sortable-table__drag-cell) {
91
- width: 68px;
92
- }
93
- :global(.suu-sortable-table-enhanced .suu-sortable-table__drag-cell) {
94
- white-space: nowrap;
95
- }
96
91
  .suu-sortable-table-enhanced__current {
97
92
  width: 16px;
98
93
  height: 16px;
@@ -7,6 +7,7 @@ declare function $$render<Item extends SortableTableItem>(): {
7
7
  disabled?: boolean;
8
8
  allowRemoveLast?: boolean;
9
9
  tableClass?: string;
10
+ showCurrentControl?: boolean;
10
11
  currentId?: string | null;
11
12
  getCurrentDisabled?: (item: Item, index: number) => boolean;
12
13
  getCurrentLabel?: (item: Item, index: number) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"SortableTableEnhanced.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-table/SortableTableEnhanced.svelte.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SortableTableEnhanced.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/sortable-table/SortableTableEnhanced.svelte.ts"],"names":[],"mappings":"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"}
package/dist/style.css CHANGED
@@ -1155,6 +1155,14 @@
1155
1155
  line-height: 1.2;
1156
1156
  }
1157
1157
 
1158
+ .suu-dropdown--multiselect .suu-dropdown__button .suu-dropdown__label {
1159
+ display: block;
1160
+ white-space: nowrap;
1161
+ overflow-wrap: normal;
1162
+ -webkit-line-clamp: unset;
1163
+ line-clamp: unset;
1164
+ }
1165
+
1158
1166
  .suu-dropdown--sized .suu-dropdown__button {
1159
1167
  width: 100%;
1160
1168
  }
@@ -1274,6 +1282,39 @@
1274
1282
  text-align: left;
1275
1283
  }
1276
1284
 
1285
+ .suu-dropdown--multiselect .suu-dropdown__option {
1286
+ display: flex;
1287
+ gap: 10px;
1288
+ align-items: center;
1289
+ }
1290
+
1291
+ .suu-dropdown__checkbox {
1292
+ position: relative;
1293
+ flex: 0 0 auto;
1294
+ width: 1em;
1295
+ height: 1em;
1296
+ border: 1px solid var(--suu-color-border);
1297
+ border-radius: 0.2em;
1298
+ background: var(--suu-color-bg);
1299
+ }
1300
+
1301
+ .suu-dropdown__checkbox[data-checked='true'] {
1302
+ border-color: var(--suu-color-accent);
1303
+ background: var(--suu-color-accent);
1304
+ }
1305
+
1306
+ .suu-dropdown__checkbox[data-checked='true']::after {
1307
+ position: absolute;
1308
+ top: 0.08em;
1309
+ left: 0.3em;
1310
+ width: 0.26em;
1311
+ height: 0.52em;
1312
+ border-right: 0.13em solid var(--suu-color-bg);
1313
+ border-bottom: 0.13em solid var(--suu-color-bg);
1314
+ content: '';
1315
+ transform: rotate(45deg);
1316
+ }
1317
+
1277
1318
  .suu-dropdown__option:last-child {
1278
1319
  border-bottom: 0;
1279
1320
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibobbyts/svelte-ui-utils",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Reusable Svelte 5 UI utilities for dialogs, toast notifications, dropdown search, and data tables.",
5
5
  "type": "module",
6
6
  "license": "MIT",