@sveltia/ui 0.16.0 → 0.17.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 (156) hide show
  1. package/package/components/alert/alert.svelte +22 -7
  2. package/package/components/alert/alert.svelte.d.ts +32 -28
  3. package/package/components/button/button-group.svelte +16 -6
  4. package/package/components/button/button-group.svelte.d.ts +23 -23
  5. package/package/components/button/button.svelte +41 -136
  6. package/package/components/button/button.svelte.d.ts +5 -146
  7. package/package/components/button/select-button-group.svelte +31 -37
  8. package/package/components/button/select-button-group.svelte.d.ts +76 -34
  9. package/package/components/button/select-button.svelte +19 -62
  10. package/package/components/button/select-button.svelte.d.ts +17 -73
  11. package/package/components/button/split-button.svelte +37 -47
  12. package/package/components/button/split-button.svelte.d.ts +40 -47
  13. package/package/components/calendar/calendar.svelte +80 -55
  14. package/package/components/calendar/calendar.svelte.d.ts +13 -10
  15. package/package/components/checkbox/checkbox-group.svelte +23 -20
  16. package/package/components/checkbox/checkbox-group.svelte.d.ts +49 -27
  17. package/package/components/checkbox/checkbox.svelte +57 -67
  18. package/package/components/checkbox/checkbox.svelte.d.ts +67 -55
  19. package/package/components/dialog/alert-dialog.svelte +9 -36
  20. package/package/components/dialog/alert-dialog.svelte.d.ts +5 -44
  21. package/package/components/dialog/confirmation-dialog.svelte +9 -41
  22. package/package/components/dialog/confirmation-dialog.svelte.d.ts +5 -46
  23. package/package/components/dialog/dialog.svelte +60 -105
  24. package/package/components/dialog/dialog.svelte.d.ts +5 -102
  25. package/package/components/dialog/prompt-dialog.svelte +32 -61
  26. package/package/components/dialog/prompt-dialog.svelte.d.ts +38 -62
  27. package/package/components/disclosure/disclosure.svelte +39 -34
  28. package/package/components/disclosure/disclosure.svelte.d.ts +74 -56
  29. package/package/components/divider/divider.svelte +18 -14
  30. package/package/components/divider/divider.svelte.d.ts +31 -10
  31. package/package/components/divider/spacer.svelte +13 -8
  32. package/package/components/divider/spacer.svelte.d.ts +20 -9
  33. package/package/components/drawer/drawer.svelte +63 -76
  34. package/package/components/drawer/drawer.svelte.d.ts +102 -84
  35. package/package/components/grid/grid-body.svelte +15 -10
  36. package/package/components/grid/grid-body.svelte.d.ts +30 -24
  37. package/package/components/grid/grid-cell.svelte +16 -6
  38. package/package/components/grid/grid-cell.svelte.d.ts +23 -23
  39. package/package/components/grid/grid-col-header.svelte +16 -6
  40. package/package/components/grid/grid-col-header.svelte.d.ts +23 -23
  41. package/package/components/grid/grid-foot.svelte +16 -6
  42. package/package/components/grid/grid-foot.svelte.d.ts +23 -23
  43. package/package/components/grid/grid-head.svelte +16 -6
  44. package/package/components/grid/grid-head.svelte.d.ts +23 -23
  45. package/package/components/grid/grid-row-header.svelte +16 -6
  46. package/package/components/grid/grid-row-header.svelte.d.ts +23 -23
  47. package/package/components/grid/grid-row.svelte +19 -23
  48. package/package/components/grid/grid-row.svelte.d.ts +48 -38
  49. package/package/components/grid/grid.svelte +28 -25
  50. package/package/components/grid/grid.svelte.d.ts +56 -32
  51. package/package/components/icon/icon.svelte +14 -9
  52. package/package/components/icon/icon.svelte.d.ts +20 -9
  53. package/package/components/listbox/listbox.svelte +46 -52
  54. package/package/components/listbox/listbox.svelte.d.ts +102 -40
  55. package/package/components/listbox/option-group.svelte +23 -19
  56. package/package/components/listbox/option-group.svelte.d.ts +49 -27
  57. package/package/components/listbox/option.svelte +44 -57
  58. package/package/components/listbox/option.svelte.d.ts +54 -84
  59. package/package/components/menu/menu-button.svelte +42 -63
  60. package/package/components/menu/menu-button.svelte.d.ts +18 -72
  61. package/package/components/menu/menu-item-checkbox.svelte +29 -41
  62. package/package/components/menu/menu-item-checkbox.svelte.d.ts +5 -44
  63. package/package/components/menu/menu-item-group.svelte +22 -19
  64. package/package/components/menu/menu-item-group.svelte.d.ts +41 -27
  65. package/package/components/menu/menu-item-radio.svelte +29 -41
  66. package/package/components/menu/menu-item-radio.svelte.d.ts +5 -44
  67. package/package/components/menu/menu-item.svelte +66 -75
  68. package/package/components/menu/menu-item.svelte.d.ts +5 -80
  69. package/package/components/menu/menu.svelte +27 -22
  70. package/package/components/menu/menu.svelte.d.ts +50 -30
  71. package/package/components/radio/radio-group.svelte +38 -42
  72. package/package/components/radio/radio-group.svelte.d.ts +85 -35
  73. package/package/components/radio/radio.svelte +45 -48
  74. package/package/components/radio/radio.svelte.d.ts +96 -42
  75. package/package/components/select/combobox.svelte +76 -101
  76. package/package/components/select/combobox.svelte.d.ts +5 -56
  77. package/package/components/select/select-tags.svelte +48 -59
  78. package/package/components/select/select-tags.svelte.d.ts +109 -28
  79. package/package/components/select/select.svelte +18 -37
  80. package/package/components/select/select.svelte.d.ts +5 -40
  81. package/package/components/slider/slider.svelte +71 -68
  82. package/package/components/slider/slider.svelte.d.ts +142 -31
  83. package/package/components/switch/switch.svelte +36 -46
  84. package/package/components/switch/switch.svelte.d.ts +83 -37
  85. package/package/components/table/table-body.svelte +15 -11
  86. package/package/components/table/table-body.svelte.d.ts +30 -24
  87. package/package/components/table/table-cell.svelte +16 -6
  88. package/package/components/table/table-cell.svelte.d.ts +23 -23
  89. package/package/components/table/table-col-header.svelte +16 -6
  90. package/package/components/table/table-col-header.svelte.d.ts +23 -23
  91. package/package/components/table/table-foot.svelte +16 -6
  92. package/package/components/table/table-foot.svelte.d.ts +23 -23
  93. package/package/components/table/table-head.svelte +16 -6
  94. package/package/components/table/table-head.svelte.d.ts +23 -23
  95. package/package/components/table/table-row-header.svelte +16 -6
  96. package/package/components/table/table-row-header.svelte.d.ts +23 -23
  97. package/package/components/table/table-row.svelte +16 -6
  98. package/package/components/table/table-row.svelte.d.ts +23 -23
  99. package/package/components/table/table.svelte +16 -6
  100. package/package/components/table/table.svelte.d.ts +23 -23
  101. package/package/components/tabs/tab-box.svelte +16 -9
  102. package/package/components/tabs/tab-box.svelte.d.ts +32 -22
  103. package/package/components/tabs/tab-list.svelte +36 -35
  104. package/package/components/tabs/tab-list.svelte.d.ts +65 -33
  105. package/package/components/tabs/tab-panel.svelte +16 -6
  106. package/package/components/tabs/tab-panel.svelte.d.ts +23 -23
  107. package/package/components/tabs/tab-panels.svelte +16 -6
  108. package/package/components/tabs/tab-panels.svelte.d.ts +23 -21
  109. package/package/components/tabs/tab.svelte +28 -25
  110. package/package/components/tabs/tab.svelte.d.ts +17 -63
  111. package/package/components/text-editor/lexical-root.svelte +38 -32
  112. package/package/components/text-editor/lexical-root.svelte.d.ts +74 -13
  113. package/package/components/text-editor/text-editor.svelte +63 -79
  114. package/package/components/text-editor/text-editor.svelte.d.ts +97 -20
  115. package/package/components/text-editor/toolbar/editor-toolbar.svelte +41 -24
  116. package/package/components/text-editor/toolbar/editor-toolbar.svelte.d.ts +32 -7
  117. package/package/components/text-editor/toolbar/format-text-button.svelte +15 -5
  118. package/package/components/text-editor/toolbar/format-text-button.svelte.d.ts +13 -6
  119. package/package/components/text-editor/toolbar/insert-link-button.svelte +18 -16
  120. package/package/components/text-editor/toolbar/insert-link-button.svelte.d.ts +4 -8
  121. package/package/components/text-editor/toolbar/toggle-block-menu-item.svelte +19 -7
  122. package/package/components/text-editor/toolbar/toggle-block-menu-item.svelte.d.ts +13 -6
  123. package/package/components/text-field/number-input.svelte +63 -81
  124. package/package/components/text-field/number-input.svelte.d.ts +48 -55
  125. package/package/components/text-field/password-input.svelte +38 -57
  126. package/package/components/text-field/password-input.svelte.d.ts +16 -45
  127. package/package/components/text-field/search-bar.svelte +45 -62
  128. package/package/components/text-field/search-bar.svelte.d.ts +25 -66
  129. package/package/components/text-field/text-area.svelte +38 -54
  130. package/package/components/text-field/text-area.svelte.d.ts +100 -35
  131. package/package/components/text-field/text-input.svelte +28 -86
  132. package/package/components/text-field/text-input.svelte.d.ts +4 -78
  133. package/package/components/toast/toast.svelte +36 -30
  134. package/package/components/toast/toast.svelte.d.ts +50 -28
  135. package/package/components/toolbar/toolbar.svelte +25 -25
  136. package/package/components/toolbar/toolbar.svelte.d.ts +57 -29
  137. package/package/components/util/app-shell.svelte +22 -10
  138. package/package/components/util/app-shell.svelte.d.ts +25 -29
  139. package/package/components/util/group.svelte +20 -15
  140. package/package/components/util/group.svelte.d.ts +40 -26
  141. package/package/components/util/modal.svelte +89 -105
  142. package/package/components/util/modal.svelte.d.ts +6 -71
  143. package/package/components/util/placeholder.svelte +21 -0
  144. package/package/components/util/{portal.svelte.d.ts → placeholder.svelte.d.ts} +17 -25
  145. package/package/components/util/popup.svelte +65 -62
  146. package/package/components/util/popup.svelte.d.ts +89 -77
  147. package/package/services/{group.js → group.svelte.js} +11 -12
  148. package/package/services/{popup.js → popup.svelte.js} +6 -5
  149. package/package/typedefs.d.ts +545 -0
  150. package/package/typedefs.js +202 -0
  151. package/package.json +12 -19
  152. package/package/components/util/portal.svelte +0 -36
  153. /package/package/services/{events.d.ts → events.svelte.d.ts} +0 -0
  154. /package/package/services/{events.js → events.svelte.js} +0 -0
  155. /package/package/services/{group.d.ts → group.svelte.d.ts} +0 -0
  156. /package/package/services/{popup.d.ts → popup.svelte.d.ts} +0 -0
@@ -1,26 +1,8 @@
1
1
  export default Radio;
2
- type Radio = SvelteComponent<$$__sveltets_2_PropsWithChildren<{
3
- [x: string]: any;
4
- class?: string | undefined;
5
- name?: string | undefined;
6
- disabled?: boolean | undefined;
7
- label?: string | undefined;
8
- checked?: boolean | undefined;
9
- value?: string | undefined;
10
- hidden?: boolean | undefined;
11
- }, {
12
- default: {};
13
- }>, {
14
- focus: FocusEvent;
15
- blur: FocusEvent;
16
- select: CustomEvent<any>;
17
- change: CustomEvent<any>;
18
- } & {
2
+ type Radio = SvelteComponent<Props & Record<string, any>, {
19
3
  [evt: string]: CustomEvent<any>;
20
- }, {
21
- default: {};
22
- }> & {
23
- $$bindings?: string | undefined;
4
+ }, {}> & {
5
+ $$bindings?: "" | undefined;
24
6
  };
25
7
  /**
26
8
  * The equivalent of the HTML `<input type="radio">` element.
@@ -28,32 +10,104 @@ type Radio = SvelteComponent<$$__sveltets_2_PropsWithChildren<{
28
10
  * @see https://w3c.github.io/aria/#radio
29
11
  * @see https://www.w3.org/WAI/ARIA/apg/patterns/radio/
30
12
  */
31
- declare const Radio: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
32
- [x: string]: any;
13
+ declare const Radio: $$__sveltets_2_IsomorphicComponent<{
14
+ /**
15
+ * - The `class` attribute on the wrapper element.
16
+ */
33
17
  class?: string | undefined;
34
- name?: string | undefined;
18
+ /**
19
+ * - Whether to hide the widget.
20
+ */
21
+ hidden?: boolean | undefined;
22
+ /**
23
+ * - Whether to disable the widget. An alias of the `aria-disabled`
24
+ * attribute.
25
+ */
35
26
  disabled?: boolean | undefined;
36
- label?: string | undefined;
27
+ /**
28
+ * - Whether to check the widget. An alias of the `aria-checked`
29
+ * attribute.
30
+ */
37
31
  checked?: boolean | undefined;
32
+ /**
33
+ * - The `name` attribute on the `<button>` element.
34
+ */
35
+ name?: string | undefined;
36
+ /**
37
+ * - The `value` attribute on the `<button>` element.
38
+ */
38
39
  value?: string | undefined;
39
- hidden?: boolean | undefined;
40
- }, {
41
- default: {};
42
- }>, {
43
- focus: FocusEvent;
44
- blur: FocusEvent;
45
- select: CustomEvent<any>;
46
- change: CustomEvent<any>;
47
- } & {
40
+ /**
41
+ * - Text label displayed next to the checkbox.
42
+ */
43
+ label?: string | undefined;
44
+ /**
45
+ * - Primary slot content.
46
+ */
47
+ children?: import("svelte").Snippet<[]> | undefined;
48
+ /**
49
+ * - Default slot content.
50
+ */
51
+ default?: import("svelte").Snippet<[]> | undefined;
52
+ /**
53
+ * - Custom `Change` event handler.
54
+ */
55
+ onChange?: ((event: CustomEvent) => void) | undefined;
56
+ /**
57
+ * - Custom `Select` event handler.
58
+ */
59
+ onSelect?: ((event: CustomEvent) => void) | undefined;
60
+ } & Record<string, any>, {
48
61
  [evt: string]: CustomEvent<any>;
49
- }, {
50
- default: {};
51
- }, {}, string>;
52
- type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
53
- default: any;
54
- } ? Props extends Record<string, never> ? any : {
55
- children?: any;
56
- } : {});
62
+ }, {}, {}, "">;
63
+ type Props = {
64
+ /**
65
+ * - The `class` attribute on the wrapper element.
66
+ */
67
+ class?: string | undefined;
68
+ /**
69
+ * - Whether to hide the widget.
70
+ */
71
+ hidden?: boolean | undefined;
72
+ /**
73
+ * - Whether to disable the widget. An alias of the `aria-disabled`
74
+ * attribute.
75
+ */
76
+ disabled?: boolean | undefined;
77
+ /**
78
+ * - Whether to check the widget. An alias of the `aria-checked`
79
+ * attribute.
80
+ */
81
+ checked?: boolean | undefined;
82
+ /**
83
+ * - The `name` attribute on the `<button>` element.
84
+ */
85
+ name?: string | undefined;
86
+ /**
87
+ * - The `value` attribute on the `<button>` element.
88
+ */
89
+ value?: string | undefined;
90
+ /**
91
+ * - Text label displayed next to the checkbox.
92
+ */
93
+ label?: string | undefined;
94
+ /**
95
+ * - Primary slot content.
96
+ */
97
+ children?: import("svelte").Snippet<[]> | undefined;
98
+ /**
99
+ * - Default slot content.
100
+ */
101
+ default?: import("svelte").Snippet<[]> | undefined;
102
+ /**
103
+ * - Custom `Change` event handler.
104
+ */
105
+ onChange?: ((event: CustomEvent) => void) | undefined;
106
+ /**
107
+ * - Custom `Select` event handler.
108
+ */
109
+ onSelect?: ((event: CustomEvent) => void) | undefined;
110
+ };
57
111
  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> {
58
112
  new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
59
113
  $$bindings?: Bindings;
@@ -7,9 +7,7 @@
7
7
  -->
8
8
  <script>
9
9
  import { generateElementId } from '@sveltia/utils/element';
10
- import { createEventDispatcher } from 'svelte';
11
10
  import { _ } from 'svelte-i18n';
12
- import { writable } from 'svelte/store';
13
11
  import Button from '../button/button.svelte';
14
12
  import Icon from '../icon/icon.svelte';
15
13
  import Listbox from '../listbox/listbox.svelte';
@@ -18,78 +16,56 @@
18
16
  import Popup from '../util/popup.svelte';
19
17
 
20
18
  /**
21
- * The `class` attribute on the wrapper element.
22
- * @type {string}
19
+ * @type {import('../../typedefs').ComboboxProps & import('../../typedefs').TextInputProps &
20
+ * Record<string, any>}
23
21
  */
24
- let className = '';
25
- export { className as class };
26
- /**
27
- * Whether to hide the widget. An alias of the `aria-hidden` attribute.
28
- * @type {boolean | undefined}
29
- */
30
- export let hidden = undefined;
31
- /**
32
- * Whether to disable the widget. An alias of the `aria-disabled` attribute.
33
- * @type {boolean}
34
- */
35
- export let disabled = false;
36
- /**
37
- * Whether to make the widget read-only. An alias of the `aria-readonly` attribute.
38
- * @type {boolean}
39
- */
40
- export let readonly = false;
41
- /**
42
- * Whether to mark the widget required. An alias of the `aria-required` attribute.
43
- * @type {boolean}
44
- */
45
- export let required = false;
46
- /**
47
- * Whether to mark the widget invalid. An alias of the `aria-invalid` attribute.
48
- * @type {boolean}
49
- */
50
- export let invalid = false;
51
- /**
52
- * Selected option’s value.
53
- * @type {(string | number | undefined)}
54
- */
55
- export let value = undefined;
56
- /**
57
- * Whether to make the `combobox` editable.
58
- */
59
- export let editable = true;
60
- /**
61
- * Where to show the dropdown menu.
62
- * @type {import('../../typedefs').PopupPosition}
63
- */
64
- export let position = 'bottom-left';
22
+ let {
23
+ /* eslint-disable prefer-const */
24
+ value = $bindable(),
25
+ class: className,
26
+ hidden = false,
27
+ disabled = false,
28
+ readonly = false,
29
+ required = false,
30
+ invalid = false,
31
+ editable = true,
32
+ position = 'bottom-left',
33
+ children,
34
+ chevronIcon,
35
+ onChange,
36
+ ...restProps
37
+ /* eslint-enable prefer-const */
38
+ } = $props();
65
39
 
66
- const dispatch = createEventDispatcher();
67
40
  const id = generateElementId('combobox');
68
41
  const selectedSelector = '[role="option"][aria-selected="true"]';
69
- /** @type {HTMLElement} */
70
- let comboboxElement;
71
- /** @type {TextInput | undefined} */
72
- let inputComponent;
73
- /** @type {Popup | undefined} */
74
- let popupComponent;
75
- let isPopupOpen = writable(false);
42
+ let isPopupOpen = $state(false);
43
+
44
+ /** @type {HTMLElement | undefined} */
45
+ let comboboxElement = $state();
46
+ /** @type {HTMLInputElement | undefined} */
47
+ let inputElement = $state();
48
+ /** @type {HTMLElement | undefined} */
49
+ let popupContent = $state();
76
50
  /** @type {string} */
77
- let label = '';
51
+ let label = $state('');
78
52
  /** @type {boolean} */
79
- let showFilter = false;
53
+ let showFilter = $state(false);
80
54
  /** @type {string} */
81
- let searchTerms = '';
55
+ let searchTerms = $state('');
82
56
  /** @type {boolean} */
83
- let hasMatchingOptions = true;
57
+ let hasMatchingOptions = $state(true);
58
+ /** @type {HTMLElement} */
59
+ const anchor = $derived(/** @type {HTMLElement} */ (comboboxElement ?? inputElement));
84
60
 
85
61
  /**
86
62
  * Update the {@link label} and selected option when the {@link value} is changed.
87
63
  */
88
- const onChange = () => {
89
- const selected = popupComponent?.content?.querySelector(selectedSelector);
64
+ const _onChange = () => {
65
+ const selected = popupContent?.querySelector(selectedSelector);
90
66
 
91
67
  const target = /** @type {HTMLButtonElement} */ (
92
- popupComponent?.content?.querySelector(`[role="option"][value="${value}"]`)
68
+ popupContent?.querySelector(`[role="option"][value="${value}"]`)
93
69
  );
94
70
 
95
71
  if (target) {
@@ -106,53 +82,48 @@
106
82
  * Update the {@link value} whenever an option is selected.
107
83
  * @param {HTMLButtonElement} target - Selected option.
108
84
  */
109
- const onSelect = (target) => {
85
+ const _onSelect = (target) => {
110
86
  // @todo support more types
87
+ // @ts-ignore
111
88
  value = target.dataset.type === 'number' ? Number(target.value) : target.value;
112
- onChange();
113
- dispatch('change', { target: inputComponent?.element, value });
89
+ _onChange();
90
+ onChange?.(new CustomEvent('Change', { detail: { target: inputElement, value } }));
114
91
  };
115
92
 
116
- $: {
117
- if (popupComponent?.content) {
93
+ $effect(() => {
94
+ if (popupContent) {
118
95
  globalThis.requestAnimationFrame(() => {
119
- const selected = popupComponent?.content?.querySelector(selectedSelector);
96
+ const selected = popupContent?.querySelector(selectedSelector);
120
97
 
121
98
  if (selected) {
122
- onSelect(/** @type {HTMLButtonElement} */ (selected));
99
+ _onSelect(/** @type {HTMLButtonElement} */ (selected));
123
100
  }
124
101
  });
125
102
  }
126
- }
103
+ });
127
104
 
128
- $: {
105
+ $effect(() => {
129
106
  void value;
130
- onChange();
131
- }
107
+ _onChange();
108
+ });
132
109
  </script>
133
110
 
134
- <div
135
- role="none"
136
- class="sui combobox {className}"
137
- class:editable
138
- hidden={hidden || undefined}
139
- {...$$restProps}
140
- >
111
+ <div {...restProps} role="none" class="sui combobox {className}" class:editable {hidden}>
141
112
  {#if !editable}
142
113
  <div
114
+ bind:this={comboboxElement}
115
+ {...restProps}
143
116
  role="combobox"
144
117
  {id}
145
118
  class:selected={value !== undefined}
146
119
  tabindex={disabled ? -1 : 0}
147
120
  aria-controls="{id}-popup"
148
- aria-expanded={$isPopupOpen}
121
+ aria-expanded={isPopupOpen}
149
122
  aria-hidden={hidden}
150
123
  aria-disabled={disabled}
151
124
  aria-readonly={readonly}
152
125
  aria-haspopup="listbox"
153
126
  aria-activedescendant="selected-option"
154
- {...$$restProps}
155
- bind:this={comboboxElement}
156
127
  >
157
128
  <div role="none" class="label">
158
129
  {value !== undefined ? label : $_('_sui.combobox.select_an_option')}
@@ -160,6 +131,8 @@
160
131
  </div>
161
132
  {:else}
162
133
  <TextInput
134
+ {...restProps}
135
+ bind:element={inputElement}
163
136
  role="combobox"
164
137
  {id}
165
138
  {value}
@@ -169,11 +142,9 @@
169
142
  {required}
170
143
  {invalid}
171
144
  aria-controls="{id}-popup"
172
- aria-expanded={$isPopupOpen}
145
+ aria-expanded={isPopupOpen}
173
146
  aria-haspopup="listbox"
174
147
  aria-activedescendant="selected-option"
175
- {...$$restProps}
176
- bind:this={inputComponent}
177
148
  />
178
149
  {/if}
179
150
  <Button
@@ -182,33 +153,37 @@
182
153
  {hidden}
183
154
  {disabled}
184
155
  tabindex={readonly || disabled ? -1 : 0}
185
- aria-label={$isPopupOpen ? $_('_sui.collapse') : $_('_sui.expand')}
156
+ aria-label={isPopupOpen ? $_('_sui.collapse') : $_('_sui.expand')}
186
157
  aria-controls="{id}-popup"
187
- aria-expanded={$isPopupOpen}
188
- on:click={(event) => {
158
+ aria-expanded={isPopupOpen}
159
+ onclick={(event) => {
189
160
  event.preventDefault();
190
161
  event.stopPropagation();
191
162
 
192
163
  if (!disabled && !readonly) {
193
- $isPopupOpen = !$isPopupOpen;
164
+ isPopupOpen = !isPopupOpen;
194
165
  }
195
166
  }}
196
167
  >
197
- <slot name="chevron-icon" slot="start-icon">
198
- <Icon name="expand_more" />
199
- </slot>
168
+ {#snippet startIcon()}
169
+ {#if chevronIcon}
170
+ {@render chevronIcon()}
171
+ {:else}
172
+ <Icon name="expand_more" />
173
+ {/if}
174
+ {/snippet}
200
175
  </Button>
201
176
  </div>
202
177
  <Popup
178
+ bind:content={popupContent}
203
179
  id="{id}-popup"
204
180
  class="combobox"
205
- anchor={comboboxElement ?? inputComponent?.element}
181
+ {anchor}
206
182
  {position}
207
183
  touchOptimized={true}
208
184
  bind:open={isPopupOpen}
209
- bind:this={popupComponent}
210
- on:open={() => {
211
- showFilter = (popupComponent?.content?.querySelectorAll('[role="option"]')?.length ?? 0) > 5;
185
+ onopen={() => {
186
+ showFilter = (popupContent?.querySelectorAll('[role="option"]')?.length ?? 0) > 5;
212
187
  searchTerms = '';
213
188
  }}
214
189
  >
@@ -219,10 +194,10 @@
219
194
  aria-label={$_('_sui.combobox.filter_options')}
220
195
  aria-controls="{id}-listbox"
221
196
  bind:value={searchTerms}
222
- on:keydown={(event) => {
197
+ onkeydown={(event) => {
223
198
  if (['ArrowUp', 'ArrowDown', 'Enter'].includes(event.key)) {
224
199
  event.preventDefault();
225
- popupComponent?.content
200
+ popupContent
226
201
  ?.querySelector('.sui.listbox')
227
202
  ?.dispatchEvent(new KeyboardEvent('keydown', event));
228
203
  }
@@ -233,16 +208,16 @@
233
208
  id="{id}-listbox"
234
209
  class="in-combobox"
235
210
  {searchTerms}
236
- on:click={(event) => {
211
+ onclick={(event) => {
237
212
  if (/** @type {HTMLElement} */ (event.target).matches('[role="option"]')) {
238
- onSelect(/** @type {HTMLButtonElement} */ (event.target));
213
+ _onSelect(/** @type {HTMLButtonElement} */ (event.target));
239
214
  }
240
215
  }}
241
- on:filter={(event) => {
216
+ onFilter={(event) => {
242
217
  hasMatchingOptions = !!(/** @type {CustomEvent} */ (event).detail.matched);
243
218
  }}
244
219
  >
245
- <slot />
220
+ {@render children?.()}
246
221
  </Listbox>
247
222
  {#if !hasMatchingOptions}
248
223
  <div role="alert" class="no-options">
@@ -1,31 +1,8 @@
1
1
  export default Combobox;
2
- type Combobox = SvelteComponent<$$__sveltets_2_PropsWithChildren<{
3
- [x: string]: any;
4
- class?: string | undefined;
5
- disabled?: boolean | undefined;
6
- invalid?: boolean | undefined;
7
- required?: boolean | undefined;
8
- value?: string | number | undefined;
9
- position?: PopupPosition | undefined;
10
- hidden?: boolean | undefined;
11
- readonly?: boolean | undefined;
12
- editable?: boolean | undefined;
13
- }, {
14
- 'chevron-icon': {
15
- slot: string;
16
- };
17
- default: {};
18
- }>, {
19
- change: CustomEvent<any>;
20
- } & {
2
+ type Combobox = SvelteComponent<ComboboxProps & TextInputProps & Record<string, any>, {
21
3
  [evt: string]: CustomEvent<any>;
22
- }, {
23
- 'chevron-icon': {
24
- slot: string;
25
- };
26
- default: {};
27
- }> & {
28
- $$bindings?: string | undefined;
4
+ }, {}> & {
5
+ $$bindings?: "value" | undefined;
29
6
  };
30
7
  /**
31
8
  * A variant of the `<Select>` widget with an auto-complete text input field.
@@ -33,37 +10,9 @@ type Combobox = SvelteComponent<$$__sveltets_2_PropsWithChildren<{
33
10
  * @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
34
11
  * @todo Add DOM API compatibility.
35
12
  */
36
- declare const Combobox: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
37
- [x: string]: any;
38
- class?: string | undefined;
39
- disabled?: boolean | undefined;
40
- invalid?: boolean | undefined;
41
- required?: boolean | undefined;
42
- value?: (string | number | undefined);
43
- position?: import("../../typedefs").PopupPosition | undefined;
44
- hidden?: boolean | undefined;
45
- readonly?: boolean | undefined;
46
- editable?: boolean | undefined;
47
- }, {
48
- 'chevron-icon': {
49
- slot: string;
50
- };
51
- default: {};
52
- }>, {
53
- change: CustomEvent<any>;
54
- } & {
13
+ declare const Combobox: $$__sveltets_2_IsomorphicComponent<import("../../typedefs").ComboboxProps & import("../../typedefs").TextInputProps & Record<string, any>, {
55
14
  [evt: string]: CustomEvent<any>;
56
- }, {
57
- 'chevron-icon': {
58
- slot: string;
59
- };
60
- default: {};
61
- }, {}, string>;
62
- type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
63
- default: any;
64
- } ? Props extends Record<string, never> ? any : {
65
- children?: any;
66
- } : {});
15
+ }, {}, {}, "value">;
67
16
  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> {
68
17
  new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
69
18
  $$bindings?: Bindings;
@@ -1,5 +1,4 @@
1
1
  <script>
2
- import { createEventDispatcher } from 'svelte';
3
2
  import { _ } from 'svelte-i18n';
4
3
  import Button from '../button/button.svelte';
5
4
  import Icon from '../icon/icon.svelte';
@@ -7,66 +6,54 @@
7
6
  import Select from './select.svelte';
8
7
 
9
8
  /**
10
- * The `class` attribute on the wrapper element.
11
- * @type {string}
9
+ * @typedef {object} Props
10
+ * @property {{ label: string, value: string, searchValue?: string }[]} options - Available
11
+ * options.
12
+ * @property {string[]} [values] - Selected option values.
13
+ * @property {number | undefined} [max] - Maximum number of selectable options.
14
+ * @property {string} [class] - The `class` attribute on the wrapper element.
15
+ * @property {boolean} [hidden] - Whether to hide the widget.
16
+ * @property {boolean} [disabled] - Whether to disable the widget. An alias of the `aria-disabled`
17
+ * attribute.
18
+ * @property {boolean} [readonly] - Whether to make the widget read-only. An alias of the
19
+ * `aria-readonly` attribute.
20
+ * @property {boolean} [required] - Whether to mark the widget required. An alias of the
21
+ * `aria-required` attribute.
22
+ * @property {boolean} [invalid] - Whether to mark the widget invalid. An alias of the
23
+ * `aria-invalid` attribute.
24
+ * @property {import('svelte').Snippet} [children] - Primary slot content.
25
+ * @property {(event: CustomEvent) => void} [onAddValue] - Custom `AddValue` event handler.
26
+ * @property {(event: CustomEvent) => void} [onRemoveValue] - Custom `RemoveValue` event handler.
12
27
  */
13
- let className = '';
14
- export { className as class };
15
- /**
16
- * Whether to hide the widget. An alias of the `aria-hidden` attribute.
17
- * @type {boolean | undefined}
18
- */
19
- export let hidden = undefined;
20
- /**
21
- * Whether to disable the widget. An alias of the `aria-disabled` attribute.
22
- * @type {boolean}
23
- */
24
- export let disabled = false;
25
- /**
26
- * Whether to make the widget read-only. An alias of the `aria-readonly` attribute.
27
- * @type {boolean}
28
- */
29
- export let readonly = false;
30
- /**
31
- * Whether to mark the widget required. An alias of the `aria-required` attribute.
32
- * @type {boolean}
33
- */
34
- export let required = false;
35
- /**
36
- * Whether to mark the widget invalid. An alias of the `aria-invalid` attribute.
37
- * @type {boolean}
38
- */
39
- export let invalid = false;
40
- /**
41
- * Available options.
42
- * @type {{ label: string, value: string, searchValue?: string }[]}
43
- */
44
- export let options;
45
- /**
46
- * Selected option values.
47
- * @type {string[]}
48
- */
49
- export let values = [];
28
+
50
29
  /**
51
- * Maximum number of selectable options.
52
- * @type {number | undefined}
30
+ * @type {Props & Record<string, any>}
53
31
  */
54
- export let max = undefined;
32
+ let {
33
+ /* eslint-disable prefer-const */
34
+ values = $bindable([]),
35
+ options,
36
+ max = undefined,
37
+ class: className,
38
+ hidden = false,
39
+ disabled = false,
40
+ readonly = false,
41
+ required = false,
42
+ invalid = false,
43
+ children,
44
+ onAddValue,
45
+ onRemoveValue,
46
+ ...restProps
47
+ /* eslint-enable prefer-const */
48
+ } = $props();
55
49
 
56
50
  /**
57
51
  * @type {string | undefined}
58
52
  */
59
- let selectedValue = undefined;
60
-
61
- const dispatch = createEventDispatcher();
53
+ let selectedValue = $state();
62
54
  </script>
63
55
 
64
- <div
65
- role="none"
66
- class="sui select-tags {className}"
67
- class:disabled={disabled || readonly}
68
- hidden={hidden || undefined}
69
- >
56
+ <div role="none" class="sui select-tags {className}" class:disabled={disabled || readonly} {hidden}>
70
57
  {#each values as value}
71
58
  {@const option = options.find((o) => o.value === value)}
72
59
  {#if option}
@@ -77,28 +64,30 @@
77
64
  size="small"
78
65
  disabled={disabled || readonly}
79
66
  aria-label={$_('remove_x', { values: { name: option.label } })}
80
- on:click={() => {
67
+ onclick={() => {
81
68
  values = values.filter((v) => v !== value);
82
- dispatch('RemoveValue', { value });
69
+ onRemoveValue?.(new CustomEvent('RemoveValue', { detail: { value } }));
83
70
  }}
84
71
  >
85
- <Icon slot="start-icon" name="close" />
72
+ {#snippet startIcon()}
73
+ <Icon name="close" />
74
+ {/snippet}
86
75
  </Button>
87
76
  </span>
88
77
  {/if}
89
78
  {/each}
90
79
  {#if (typeof max !== 'number' || values.length < max) && values.length < options.length}
91
80
  <Select
81
+ {...restProps}
82
+ bind:value={selectedValue}
92
83
  disabled={disabled || readonly}
93
84
  {readonly}
94
85
  {required}
95
86
  {invalid}
96
- {...$$restProps}
97
- bind:value={selectedValue}
98
- on:change={() => {
87
+ onChange={() => {
99
88
  if (selectedValue) {
100
89
  values = [...values, selectedValue];
101
- dispatch('AddValue', { value: selectedValue });
90
+ onAddValue?.(new CustomEvent('AddValue', { detail: { value: selectedValue } }));
102
91
  // Reset the combobox
103
92
  selectedValue = undefined;
104
93
  }