@mozaic-ds/web-components 1.6.0 → 1.8.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 (215) hide show
  1. package/dist/Condition20.js +1 -1
  2. package/dist/attributes.js +1 -1
  3. package/dist/attributes.js.map +1 -1
  4. package/dist/branches.js +1 -1
  5. package/dist/branches.js.map +1 -1
  6. package/dist/bundle.d.ts +2 -0
  7. package/dist/bundle.d.ts.map +1 -1
  8. package/dist/bundle.js +2 -0
  9. package/dist/components/accordionlist/AccordionList.js +2 -2
  10. package/dist/components/accordionlistItem/AccordionListItem.js +2 -2
  11. package/dist/components/actionbottombar/ActionBottomBar.js +2 -2
  12. package/dist/components/actionlistbox/ActionListbox.js +3 -3
  13. package/dist/components/actionlistbox/ActionListbox.js.map +1 -1
  14. package/dist/components/actionlistbox/ActionListbox.svelte +1 -1
  15. package/dist/components/actionlistboxitem/ActionListboxItem.js +2 -2
  16. package/dist/components/avatar/Avatar.js +2 -2
  17. package/dist/components/breadcrumb/Breadcrumb.js +2 -2
  18. package/dist/components/builtinmenu/BuiltInMenu.js +2 -2
  19. package/dist/components/builtinmenuitem/BuiltInMenuItem.js +2 -2
  20. package/dist/components/button/Button.js +1 -1
  21. package/dist/components/callout/Callout.js +2 -2
  22. package/dist/components/carousel/Carousel.js +2 -2
  23. package/dist/components/checkbox/Checkbox.js +2 -2
  24. package/dist/components/checkboxgroup/CheckboxGroup.js +1 -1
  25. package/dist/components/checklistmenu/CheckListMenu.js +1 -1
  26. package/dist/components/circularprogressbar/CircularProgressbar.js +2 -2
  27. package/dist/components/combobox/Combobox.js +4 -0
  28. package/dist/components/combobox/Combobox.js.map +1 -0
  29. package/dist/components/combobox/Combobox.spec.js +186 -0
  30. package/dist/components/combobox/Combobox.stories.d.ts +17 -0
  31. package/dist/components/combobox/Combobox.stories.d.ts.map +1 -0
  32. package/dist/components/combobox/Combobox.stories.js +126 -0
  33. package/dist/components/combobox/Combobox.svelte +421 -0
  34. package/dist/components/combobox/Combobox.svelte.d.ts +104 -0
  35. package/dist/components/combobox/Combobox.svelte.d.ts.map +1 -0
  36. package/dist/components/combobox/README.md +38 -0
  37. package/dist/components/container/Container.js +2 -2
  38. package/dist/components/datepicker/Datepicker.js +3 -3
  39. package/dist/components/datepicker/Datepicker.js.map +1 -1
  40. package/dist/components/datepicker/Datepicker.svelte +2 -1
  41. package/dist/components/divider/Divider.js +2 -2
  42. package/dist/components/drawer/Drawer.js +4 -4
  43. package/dist/components/drawer/Drawer.svelte +2 -1
  44. package/dist/components/field/Field.js +2 -2
  45. package/dist/components/fileuploader/FileUploader.js +2 -2
  46. package/dist/components/fileuploader/FileUploader.js.map +1 -1
  47. package/dist/components/fileuploader/FileUploader.svelte +4 -4
  48. package/dist/components/fileuploader/FileUploader.svelte.d.ts +1 -0
  49. package/dist/components/fileuploader/FileUploader.svelte.d.ts.map +1 -1
  50. package/dist/components/fileuploaderitem/FileUploaderItem.js +3 -3
  51. package/dist/components/fileuploaderitem/FileUploaderItem.svelte +1 -4
  52. package/dist/components/flag/Flag.js +2 -2
  53. package/dist/components/iconbutton/IconButton.js +2 -2
  54. package/dist/components/kpiitem/KpiItem.js +2 -2
  55. package/dist/components/linearprogressbarbuffer/LinearProgressbarBuffer.js +2 -2
  56. package/dist/components/linearprogressbarpercentage/LinearProgressbarPercentage.js +2 -2
  57. package/dist/components/link/Link.js +1 -1
  58. package/dist/components/loader/Loader.js +2 -2
  59. package/dist/components/loadingoverlay/LoadingOverlay.js +2 -2
  60. package/dist/components/loadingoverlay/LoadingOverlay.svelte +1 -1
  61. package/dist/components/modal/Modal.js +4 -4
  62. package/dist/components/modal/Modal.js.map +1 -1
  63. package/dist/components/modal/Modal.spec.js +3 -1
  64. package/dist/components/modal/Modal.svelte +9 -3
  65. package/dist/components/modal/Modal.svelte.d.ts +4 -0
  66. package/dist/components/modal/Modal.svelte.d.ts.map +1 -1
  67. package/dist/components/modal/README.md +1 -0
  68. package/dist/components/navigationindicator/NavigationIndicator.js +2 -2
  69. package/dist/components/numberbadge/NumberBadge.js +2 -2
  70. package/dist/components/optionlistbox/OptionListbox.js +23 -0
  71. package/dist/components/optionlistbox/OptionListbox.js.map +1 -0
  72. package/dist/components/optionlistbox/OptionListbox.spec.js +350 -0
  73. package/dist/components/optionlistbox/OptionListbox.svelte +566 -0
  74. package/dist/components/optionlistbox/OptionListbox.svelte.d.ts +92 -0
  75. package/dist/components/optionlistbox/OptionListbox.svelte.d.ts.map +1 -0
  76. package/dist/components/optionlistbox/README.md +38 -0
  77. package/dist/components/overlay/Overlay.js +2 -2
  78. package/dist/components/overlay/Overlay.svelte +2 -2
  79. package/dist/components/pageheader/PageHeader.js +2 -2
  80. package/dist/components/pagination/Pagination.js +4 -4
  81. package/dist/components/passwordinput/PasswordInput.js +3 -3
  82. package/dist/components/passwordinput/PasswordInput.js.map +1 -1
  83. package/dist/components/passwordinput/PasswordInput.svelte +2 -1
  84. package/dist/components/phonenumber/PhoneNumber.js +4 -4
  85. package/dist/components/phonenumber/PhoneNumber.js.map +1 -1
  86. package/dist/components/phonenumber/PhoneNumber.svelte +3 -2
  87. package/dist/components/pincode/Pincode.js +2 -2
  88. package/dist/components/pincode/Pincode.js.map +1 -1
  89. package/dist/components/pincode/Pincode.svelte +3 -2
  90. package/dist/components/pincode/Pincode.svelte.d.ts +2 -1
  91. package/dist/components/pincode/Pincode.svelte.d.ts.map +1 -1
  92. package/dist/components/pincode/README.md +1 -1
  93. package/dist/components/popover/Popover.js +2 -2
  94. package/dist/components/quantityselector/QuantitySelector.js +3 -3
  95. package/dist/components/quantityselector/QuantitySelector.svelte +1 -1
  96. package/dist/components/radio/Radio.js +2 -2
  97. package/dist/components/radiogroup/RadioGroup.js +3 -3
  98. package/dist/components/radiogroup/RadioGroup.js.map +1 -1
  99. package/dist/components/radiogroup/RadioGroup.svelte +3 -2
  100. package/dist/components/radiogroup/RadioGroup.svelte.d.ts +1 -0
  101. package/dist/components/radiogroup/RadioGroup.svelte.d.ts.map +1 -1
  102. package/dist/components/segmentedcontrol/README.md +6 -3
  103. package/dist/components/segmentedcontrol/SegmentedControl.js +2 -2
  104. package/dist/components/segmentedcontrol/SegmentedControl.js.map +1 -1
  105. package/dist/components/segmentedcontrol/SegmentedControl.spec.js +60 -23
  106. package/dist/components/segmentedcontrol/SegmentedControl.stories.d.ts.map +1 -1
  107. package/dist/components/segmentedcontrol/SegmentedControl.stories.js +6 -1
  108. package/dist/components/segmentedcontrol/SegmentedControl.svelte +23 -10
  109. package/dist/components/segmentedcontrol/SegmentedControl.svelte.d.ts +10 -3
  110. package/dist/components/segmentedcontrol/SegmentedControl.svelte.d.ts.map +1 -1
  111. package/dist/components/select/Select.js +2 -2
  112. package/dist/components/sidebar/Sidebar.js +2 -2
  113. package/dist/components/sidebarexpandableitem/SidebarExpandableItem.js +2 -2
  114. package/dist/components/sidebarfooter/SidebarFooter.js +2 -2
  115. package/dist/components/sidebarfooter/_SidebarFooterMenu.js +2 -2
  116. package/dist/components/sidebarheader/SidebarHeader.js +2 -2
  117. package/dist/components/sidebarnavitem/SidebarNavItem.js +2 -2
  118. package/dist/components/sidebarshortcutitem/SidebarShortcutItem.js +2 -2
  119. package/dist/components/sidebarshortcuts/SidebarShortcuts.js +2 -2
  120. package/dist/components/starrating/StarRating.js +2 -2
  121. package/dist/components/statusbadge/StatusBadge.js +2 -2
  122. package/dist/components/statusdot/StatusDot.js +2 -2
  123. package/dist/components/statusmessage/StatusMessage.js +2 -2
  124. package/dist/components/statusmessage/StatusMessage.js.map +1 -1
  125. package/dist/components/statusmessage/StatusMessage.svelte +5 -0
  126. package/dist/components/statusnotification/StatusNotification.js +2 -2
  127. package/dist/components/statusnotification/StatusNotification.js.map +1 -1
  128. package/dist/components/statusnotification/StatusNotification.svelte +5 -0
  129. package/dist/components/stepperbottombar/StepperBottomBar.js +1 -1
  130. package/dist/components/steppercompact/StepperCompact.js +2 -2
  131. package/dist/components/stepperinline/README.md +6 -2
  132. package/dist/components/stepperinline/StepperInline.js +2 -2
  133. package/dist/components/stepperinline/StepperInline.js.map +1 -1
  134. package/dist/components/stepperinline/StepperInline.spec.js +57 -23
  135. package/dist/components/stepperinline/StepperInline.stories.d.ts.map +1 -1
  136. package/dist/components/stepperinline/StepperInline.stories.js +6 -11
  137. package/dist/components/stepperinline/StepperInline.svelte +23 -10
  138. package/dist/components/stepperinline/StepperInline.svelte.d.ts +10 -2
  139. package/dist/components/stepperinline/StepperInline.svelte.d.ts.map +1 -1
  140. package/dist/components/stepperstacked/README.md +15 -0
  141. package/dist/components/stepperstacked/StepperStacked.js +18 -0
  142. package/dist/components/stepperstacked/StepperStacked.js.map +1 -0
  143. package/dist/components/stepperstacked/StepperStacked.spec.js +138 -0
  144. package/dist/components/stepperstacked/StepperStacked.stories.d.ts +8 -0
  145. package/dist/components/stepperstacked/StepperStacked.stories.d.ts.map +1 -0
  146. package/dist/components/stepperstacked/StepperStacked.stories.js +33 -0
  147. package/dist/components/stepperstacked/StepperStacked.svelte +214 -0
  148. package/dist/components/stepperstacked/StepperStacked.svelte.d.ts +35 -0
  149. package/dist/components/stepperstacked/StepperStacked.svelte.d.ts.map +1 -0
  150. package/dist/components/tab/README.md +1 -0
  151. package/dist/components/tab/Tab.js +2 -2
  152. package/dist/components/tab/Tab.js.map +1 -1
  153. package/dist/components/tab/Tab.svelte +17 -1
  154. package/dist/components/tab/Tab.svelte.d.ts +4 -0
  155. package/dist/components/tab/Tab.svelte.d.ts.map +1 -1
  156. package/dist/components/tabs/Tabs.js +2 -2
  157. package/dist/components/tabs/Tabs.stories.d.ts +1 -0
  158. package/dist/components/tabs/Tabs.stories.d.ts.map +1 -1
  159. package/dist/components/tabs/Tabs.stories.js +10 -0
  160. package/dist/components/tag/README.md +1 -0
  161. package/dist/components/tag/Tag.js +2 -2
  162. package/dist/components/tag/Tag.js.map +1 -1
  163. package/dist/components/tag/Tag.svelte +7 -0
  164. package/dist/components/tag/Tag.svelte.d.ts +4 -0
  165. package/dist/components/tag/Tag.svelte.d.ts.map +1 -1
  166. package/dist/components/textarea/README.md +1 -1
  167. package/dist/components/textarea/Textarea.js +2 -2
  168. package/dist/components/textarea/Textarea.js.map +1 -1
  169. package/dist/components/textarea/Textarea.svelte +2 -1
  170. package/dist/components/textarea/Textarea.svelte.d.ts +1 -1
  171. package/dist/components/textarea/Textarea.svelte.d.ts.map +1 -1
  172. package/dist/components/textinput/README.md +1 -0
  173. package/dist/components/textinput/Textinput.js +4 -4
  174. package/dist/components/textinput/Textinput.js.map +1 -1
  175. package/dist/components/textinput/Textinput.stories.d.ts.map +1 -1
  176. package/dist/components/textinput/Textinput.stories.js +1 -0
  177. package/dist/components/textinput/Textinput.svelte +5 -1
  178. package/dist/components/textinput/Textinput.svelte.d.ts +2 -1
  179. package/dist/components/textinput/Textinput.svelte.d.ts.map +1 -1
  180. package/dist/components/tile/Tile.js +2 -2
  181. package/dist/components/tileclickable/TileClickable.js +1 -1
  182. package/dist/components/tileexpandable/TileExpandable.js +2 -2
  183. package/dist/components/tileexpandable/TileExpandable.js.map +1 -1
  184. package/dist/components/tileselectable/TileSelectable.js +2 -2
  185. package/dist/components/toaster/Toaster.js +3 -3
  186. package/dist/components/toaster/Toaster.js.map +1 -1
  187. package/dist/components/toaster/Toaster.svelte +6 -1
  188. package/dist/components/toggle/Toggle.js +2 -2
  189. package/dist/components/togglegroup/ToggleGroup.js +3 -3
  190. package/dist/components/togglegroup/ToggleGroup.js.map +1 -1
  191. package/dist/components/togglegroup/ToggleGroup.svelte +3 -2
  192. package/dist/components/togglegroup/ToggleGroup.svelte.d.ts +1 -0
  193. package/dist/components/togglegroup/ToggleGroup.svelte.d.ts.map +1 -1
  194. package/dist/components/tooltip/Tooltip.js +2 -2
  195. package/dist/custom-element.js +3 -3
  196. package/dist/custom-element.js.map +1 -1
  197. package/dist/documentation/DarkMode.mdx +115 -0
  198. package/dist/each.js +1 -1
  199. package/dist/each.js.map +1 -1
  200. package/dist/floating-item.svelte.js +1 -1
  201. package/dist/if.js +1 -1
  202. package/dist/if.js.map +1 -1
  203. package/dist/index-client.js +1 -1
  204. package/dist/input.js +1 -1
  205. package/dist/input.js.map +1 -1
  206. package/dist/main.d.ts +3 -1
  207. package/dist/main.d.ts.map +1 -1
  208. package/dist/main.js +3 -1
  209. package/dist/svelte-component.js +1 -1
  210. package/dist/svelte-component.js.map +1 -1
  211. package/dist/svelte-element.js +1 -1
  212. package/dist/svelte-element.js.map +1 -1
  213. package/dist/this.js +1 -1
  214. package/dist/this.js.map +1 -1
  215. package/package.json +7 -5
@@ -0,0 +1,126 @@
1
+ import { html } from 'lit';
2
+ import './Combobox.svelte';
3
+ import { ifDefined } from 'lit-html/directives/if-defined.js';
4
+ const defaultOptions = Array.from({ length: 12 }).map((_el, index) => {
5
+ return {
6
+ id: (index + 1).toString(),
7
+ label: `Option ${index + 1}`,
8
+ value: `option${index + 1}`,
9
+ };
10
+ });
11
+ let optionCount = 0;
12
+ const optionsWithSections = Array.from({ length: 12 }).map((_el, index) => {
13
+ const isSection = index % 3 === 0;
14
+ if (!isSection) {
15
+ optionCount++;
16
+ }
17
+ return {
18
+ label: `${isSection ? 'Section' : 'Option'} ${isSection ? index / 3 + 1 : optionCount}`,
19
+ value: !isSection ? `option${optionCount}` : undefined,
20
+ type: isSection ? 'section' : 'option',
21
+ };
22
+ });
23
+ const meta = {
24
+ title: 'Form elements/Combobox',
25
+ component: 'm-combobox',
26
+ tags: ['v2'],
27
+ parameters: {
28
+ docs: {
29
+ story: {
30
+ height: '300px',
31
+ },
32
+ },
33
+ },
34
+ args: {
35
+ search: false,
36
+ actions: true,
37
+ value: null,
38
+ checkablesections: true,
39
+ options: defaultOptions,
40
+ },
41
+ render: (args) => html `
42
+ <m-combobox
43
+ .value="${args.value}"
44
+ ?multiple="${args.multiple}"
45
+ ?compact="${args.compact}"
46
+ size="${ifDefined(args.size)}"
47
+ ?disabled="${args.disabled}"
48
+ ?readonly="${args.readonly}"
49
+ ?invalid="${args.invalid}"
50
+ ?clearable="${args.clearable}"
51
+ ?search="${args.search}"
52
+ ?actions="${args.actions}"
53
+ ?checkablesections="${args.checkablesections}"
54
+ placeholder="${ifDefined(args.placeholder)}"
55
+ counterlabel="${ifDefined(args.counterlabel)}"
56
+ searchplaceholder="${ifDefined(args.searchplaceholder)}"
57
+ selectlabel="${ifDefined(args.selectlabel)}"
58
+ clearlabel="${ifDefined(args.clearlabel)}"
59
+ showlabel="${ifDefined(args.showlabel)}"
60
+ .options="${args.options}"
61
+ ></m-combobox>
62
+ `,
63
+ };
64
+ export default meta;
65
+ export const Standard = {};
66
+ export const Multiple = {
67
+ args: {
68
+ multiple: true,
69
+ value: [],
70
+ },
71
+ };
72
+ export const SearchInput = {
73
+ args: {
74
+ search: true,
75
+ value: [],
76
+ multiple: true,
77
+ },
78
+ };
79
+ export const ActionButtons = {
80
+ args: {
81
+ value: [],
82
+ multiple: true,
83
+ actions: true,
84
+ },
85
+ };
86
+ export const WithSections = {
87
+ args: {
88
+ options: optionsWithSections,
89
+ },
90
+ };
91
+ export const SelectableSections = {
92
+ args: {
93
+ value: [],
94
+ multiple: true,
95
+ options: optionsWithSections,
96
+ checkablesections: true,
97
+ },
98
+ };
99
+ export const Clearable = {
100
+ args: {
101
+ clearable: true,
102
+ },
103
+ };
104
+ export const Disabled = {
105
+ args: {
106
+ disabled: true,
107
+ },
108
+ };
109
+ export const Readonly = {
110
+ args: {
111
+ readonly: true,
112
+ },
113
+ };
114
+ export const Invalid = {
115
+ args: {
116
+ invalid: true,
117
+ },
118
+ };
119
+ export const AdditionalInformation = {
120
+ args: {
121
+ options: defaultOptions.map((option) => ({
122
+ ...option,
123
+ content: 'Additional information',
124
+ })),
125
+ },
126
+ };
@@ -0,0 +1,421 @@
1
+ <svelte:options
2
+ customElement={{
3
+ tag: 'm-combobox',
4
+ props: {
5
+ multiple: { reflect: true, type: 'Boolean', attribute: 'multiple' },
6
+ compact: { reflect: true, type: 'Boolean', attribute: 'compact' },
7
+ disabled: { reflect: true, type: 'Boolean', attribute: 'disabled' },
8
+ readonly: { reflect: true, type: 'Boolean', attribute: 'readonly' },
9
+ invalid: { reflect: true, type: 'Boolean', attribute: 'invalid' },
10
+ clearable: { reflect: true, type: 'Boolean', attribute: 'clearable' },
11
+ search: { reflect: true, type: 'Boolean', attribute: 'search' },
12
+ actions: { reflect: true, type: 'Boolean', attribute: 'actions' },
13
+ checkablesections: { reflect: true, type: 'Boolean', attribute: 'checkablesections' },
14
+ },
15
+ }}
16
+ />
17
+
18
+ <script lang="ts">
19
+ import { onDestroy } from 'svelte';
20
+ import OptionListbox from '../optionlistbox/OptionListbox.svelte';
21
+ import { ChevronDown24, CrossCircleFilled24 } from '@mozaic-ds/icons-svelte';
22
+
23
+ /**
24
+ * A combobox is an input field that allows users to select an option from a dropdown list or enter a custom value. It combines the functionality of a text input and a dropdown menu, providing flexibility and ease of use in forms and user interfaces.
25
+ * @slot optionPrefix - Use this slot to add a prefix to options.
26
+ * @event update:open {CustomEvent<boolean>} - Emitted when the listbox is opened or closed.
27
+ */
28
+ interface Props {
29
+ /**
30
+ * The current selected value(s) of the combobox.
31
+ */
32
+ value: string | number | null | (string | number)[];
33
+ /**
34
+ * Enable multiple value mode.
35
+ */
36
+ multiple?: boolean;
37
+ /**
38
+ * Size of the combobox: small ('s') or medium ('m').
39
+ */
40
+ size?: 's' | 'm';
41
+ /**
42
+ * Disable the combobox input.
43
+ */
44
+ disabled?: boolean;
45
+ /**
46
+ * Make the combobox read-only.
47
+ */
48
+ readonly?: boolean;
49
+ /**
50
+ * Mark the combobox as invalid.
51
+ */
52
+ invalid?: boolean;
53
+ /**
54
+ * Show a clear value button.
55
+ */
56
+ clearable?: boolean;
57
+ /**
58
+ * Enable the search input inside the listbox.
59
+ */
60
+ search?: boolean;
61
+ /**
62
+ * Show select all / clear buttons when multiple.
63
+ */
64
+ actions?: boolean;
65
+ /**
66
+ * Enable checkable section headers in the listbox.
67
+ */
68
+ checkablesections?: boolean;
69
+ /**
70
+ * Placeholder text when no value is selected.
71
+ */
72
+ placeholder?: string;
73
+ /**
74
+ * Label for the selected items counter.
75
+ */
76
+ counterlabel?: string;
77
+ /**
78
+ * Placeholder text for the search input.
79
+ */
80
+ searchplaceholder?: string;
81
+ /**
82
+ * Label for the "Select all" button.
83
+ */
84
+ selectlabel?: string;
85
+ /**
86
+ * Label for the "Clear value" button.
87
+ */
88
+ clearlabel?: string;
89
+ /**
90
+ * Array of options to display in the listbox.
91
+ */
92
+ options: Array<{
93
+ label: string;
94
+ content?: string;
95
+ value?: string | number;
96
+ disabled?: boolean;
97
+ type?: 'option' | 'section';
98
+ }>;
99
+ /**
100
+ * Callback to trigger when the listbox is opened or closed.
101
+ */
102
+ onopen?: (value: boolean) => void;
103
+ }
104
+
105
+ let {
106
+ value = $bindable(),
107
+ multiple,
108
+ size = 'm',
109
+ disabled,
110
+ readonly,
111
+ invalid,
112
+ clearable,
113
+ search,
114
+ actions,
115
+ checkablesections,
116
+ placeholder = 'Select an option',
117
+ counterlabel = '99 selected',
118
+ searchplaceholder = 'Find an option...',
119
+ selectlabel = 'Select all',
120
+ clearlabel = 'Clear',
121
+ options,
122
+ onopen,
123
+ }: Props = $props();
124
+
125
+ const id = crypto.randomUUID();
126
+
127
+ let combobox: HTMLElement;
128
+ let listbox: InstanceType<typeof OptionListbox> | null = $state(null);
129
+ let listboxEl: HTMLElement | null | undefined = $state(null);
130
+ let comboboxControl: HTMLElement;
131
+
132
+ let isOpen = $state(false);
133
+
134
+ let activeIndex = $state(-1);
135
+
136
+ const activeDescendantId = $derived.by(() => {
137
+ return activeIndex >= 0 ? `option-${id}-${activeIndex}` : undefined;
138
+ });
139
+
140
+ const selectionLabel = $derived.by(() => {
141
+ if (Array.isArray(value)) {
142
+ if (!value.length) return placeholder;
143
+ return (value as (string | number)[]).join(', ');
144
+ }
145
+
146
+ return options.find((option) => option.value === value)?.label || placeholder;
147
+ });
148
+
149
+ const hasValue = $derived.by(() =>
150
+ multiple ? !!(value as (string | number)[]).length : !!value,
151
+ );
152
+
153
+ function handleClickOutside(event: MouseEvent) {
154
+ const path = event.composedPath ? event.composedPath() : [];
155
+ if (!path.includes(combobox) && !path.includes(listboxEl!)) {
156
+ close();
157
+ }
158
+ }
159
+
160
+ function open() {
161
+ isOpen = true;
162
+ handleOpen();
163
+ document.addEventListener('click', handleClickOutside);
164
+ }
165
+
166
+ function close() {
167
+ isOpen = false;
168
+ handleOpen();
169
+ document.removeEventListener('click', handleClickOutside);
170
+ }
171
+
172
+ function toggleListbox() {
173
+ return isOpen ? close() : open();
174
+ }
175
+
176
+ function handleOpen() {
177
+ onopen?.(isOpen);
178
+
179
+ combobox.dispatchEvent(new CustomEvent('update:open', { bubbles: true, composed: true }));
180
+ }
181
+
182
+ onDestroy(() => {
183
+ document.removeEventListener('click', handleClickOutside);
184
+ });
185
+ </script>
186
+
187
+ <div
188
+ bind:this={combobox}
189
+ class={{
190
+ 'mc-combobox': true,
191
+ 'mc-combobox--open': isOpen,
192
+ 'mc-combobox--multiple': multiple,
193
+ 'mc-combobox--invalid': invalid,
194
+ 'mc-combobox--s': size === 's',
195
+ 'mc-combobox--disabled': disabled,
196
+ 'mc-combobox--readonly': readonly,
197
+ }}
198
+ >
199
+ <div class="mc-combobox__input">
200
+ <button
201
+ bind:this={comboboxControl}
202
+ aria-expanded={isOpen}
203
+ aria-haspopup="listbox"
204
+ aria-controls={`listbox-${id}`}
205
+ {disabled}
206
+ class="mc-combobox__control"
207
+ aria-label="Combobox input"
208
+ onclick={toggleListbox}
209
+ {...search
210
+ ? {}
211
+ : {
212
+ role: 'combobox',
213
+ 'aria-activedescendant': activeDescendantId,
214
+ onkeydown: listbox?.handleKeydown,
215
+ }}
216
+ >
217
+ {selectionLabel}
218
+ </button>
219
+ {#if multiple}
220
+ <span class="mc-combobox__counter">
221
+ {counterlabel}
222
+ </span>
223
+ {/if}
224
+
225
+ {#if clearable && hasValue}
226
+ <button
227
+ type="button"
228
+ class="mc-combobox__clear"
229
+ aria-label="Clear value"
230
+ onclick={() => listbox?.clearSelection()}
231
+ >
232
+ <CrossCircleFilled24 />
233
+ </button>
234
+ {/if}
235
+
236
+ <button
237
+ type="button"
238
+ tabindex={-1}
239
+ class="mc-combobox__icon"
240
+ aria-label="Expand options list"
241
+ onclick={toggleListbox}
242
+ >
243
+ <ChevronDown24 />
244
+ </button>
245
+ </div>
246
+
247
+ <div class="mc-combobox__listbox">
248
+ <OptionListbox
249
+ bind:this={listbox}
250
+ bind:element={listboxEl}
251
+ bind:value
252
+ {id}
253
+ open={isOpen}
254
+ {multiple}
255
+ {search}
256
+ {actions}
257
+ {checkablesections}
258
+ {searchplaceholder}
259
+ {selectlabel}
260
+ {clearlabel}
261
+ {options}
262
+ activeindex={activeIndex}
263
+ onopen={open}
264
+ onclose={() => {
265
+ close();
266
+ comboboxControl?.focus();
267
+ }}
268
+ >
269
+ <slot name="optionPrefix" slot="optionPrefix" />
270
+ </OptionListbox>
271
+ </div>
272
+ </div>
273
+
274
+ <style>/**
275
+ * Do not edit directly, this file was auto-generated.
276
+ */
277
+ .mc-combobox {
278
+ position: relative;
279
+ width: 18.75rem;
280
+ }
281
+ .mc-combobox__input {
282
+ transition: box-shadow 200ms ease;
283
+ background-color: var(--forms-color-background-default, #ffffff);
284
+ border: var(--border-width-s, 0.0625rem) solid var(--forms-color-border-default, #666666);
285
+ border-radius: var(--forms-border-radius, 0.25rem);
286
+ transition: all ease 200ms;
287
+ color: var(--forms-color-text-default, #000000);
288
+ display: block;
289
+ width: 100%;
290
+ display: flex;
291
+ align-items: center;
292
+ gap: 0.5rem;
293
+ box-sizing: border-box;
294
+ }
295
+ .mc-combobox__input:focus-within {
296
+ box-shadow: 0 0 0 0.125rem var(--focus-color-mid, var(--focus-color-outline-mid, #ffffff)), 0 0 0 0.25rem var(--focus-color-outer, var(--focus-color-outline-outer, #000000));
297
+ outline: 0.125rem solid transparent;
298
+ outline-offset: 0.125rem;
299
+ }
300
+ .mc-combobox__input:hover:not(:focus-within) {
301
+ border-color: var(--forms-color-border-hover, #4d4d4d);
302
+ box-shadow: 0 0 0 var(--border-width-s, 0.0625rem) var(--forms-color-border-hover, #4d4d4d);
303
+ }
304
+ .mc-combobox__input:has(.mc-combobox__control:disabled) {
305
+ background-color: var(--forms-color-background-disabled, #d9d9d9);
306
+ cursor: not-allowed;
307
+ border-color: transparent;
308
+ box-shadow: none;
309
+ color: var(--forms-color-text-disabled, #737373);
310
+ pointer-events: none;
311
+ }
312
+ .mc-combobox__input .mc-combobox__control {
313
+ text-align: left;
314
+ font-size: var(--font-size-150, 1rem);
315
+ font-weight: var(--font-weight-regular, 400);
316
+ color: var(--forms-color-text-default, #000000);
317
+ background-color: transparent;
318
+ border: none;
319
+ padding-left: 0.75rem;
320
+ padding-right: 0;
321
+ flex-grow: 1;
322
+ height: 3rem;
323
+ cursor: pointer;
324
+ overflow: hidden;
325
+ text-overflow: ellipsis;
326
+ white-space: nowrap;
327
+ }
328
+ .mc-combobox__input .mc-combobox__control:focus-within {
329
+ outline: none;
330
+ }
331
+ .mc-combobox__icon {
332
+ border: none;
333
+ display: flex;
334
+ align-items: center;
335
+ cursor: pointer;
336
+ padding-right: 0.75rem;
337
+ background: none;
338
+ color: var(--forms-color-icon-interactive, #000000);
339
+ fill: currentcolor;
340
+ }
341
+ .mc-combobox__clear {
342
+ padding: 0;
343
+ display: flex;
344
+ align-items: center;
345
+ justify-content: center;
346
+ border: none;
347
+ background: none;
348
+ cursor: pointer;
349
+ color: var(--forms-color-icon-clear, #666666);
350
+ fill: currentcolor;
351
+ }
352
+ .mc-combobox__counter {
353
+ height: 1.5rem;
354
+ display: flex;
355
+ flex-shrink: 0;
356
+ align-items: center;
357
+ justify-content: center;
358
+ padding: 0 0.5rem;
359
+ border-radius: var(--border-radius-l, 1rem);
360
+ background-color: var(--forms-color-selection-counter-background, #464e63);
361
+ font-weight: var(--font-weight-regular, 400);
362
+ font-size: var(--font-size-50, 0.75rem);
363
+ line-height: var(--line-height-s, 1.3);
364
+ color: var(--forms-color-selection-counter-text, #ffffff);
365
+ }
366
+ .mc-combobox__listbox {
367
+ position: absolute;
368
+ left: 0;
369
+ top: calc(100% + 0.25rem);
370
+ visibility: hidden;
371
+ opacity: 0;
372
+ box-shadow: var(--shadow-bottom-s-x, 0px) var(--shadow-bottom-s-y, 5px) var(--shadow-bottom-s-blur, 10px) var(--shadow-bottom-s-spread, -2px) rgba(0, 0, 0, var(--shadow-bottom-s-opacity, 20%));
373
+ border: var(--border-width-s, 0.0625rem) solid var(--color-border-primary, #cccccc);
374
+ border-radius: var(--border-radius-m, 0.5rem);
375
+ width: 100%;
376
+ z-index: 10;
377
+ background-color: var(--color-background-primary, #ffffff);
378
+ pointer-events: all;
379
+ }
380
+ .mc-combobox--open .mc-combobox__listbox {
381
+ visibility: visible;
382
+ opacity: 1;
383
+ }
384
+ .mc-combobox--s .mc-combobox__control {
385
+ height: 2rem;
386
+ font-size: var(--font-size-100, 0.875rem);
387
+ padding-left: 0.5rem;
388
+ }
389
+ .mc-combobox--s .mc-combobox__icon {
390
+ padding-right: 0.5rem;
391
+ }
392
+ .mc-combobox--s .mc-combobox__clear {
393
+ width: 1.25rem;
394
+ height: 1.25rem;
395
+ }
396
+ .mc-combobox--invalid .mc-combobox__input {
397
+ border-color: var(--forms-color-border-invalid, #ea302d);
398
+ box-shadow: 0 0 0 var(--border-width-s, 0.0625rem) var(--forms-color-border-invalid, #ea302d);
399
+ }
400
+ .mc-combobox--invalid .mc-combobox__input:hover:not(:focus-within) {
401
+ border-color: var(--forms-color-border-invalid-hover, #c61112);
402
+ box-shadow: 0 0 0 var(--border-width-s, 0.0625rem) var(--forms-color-border-invalid-hover, #c61112);
403
+ }
404
+ .mc-combobox--disabled .mc-combobox__input {
405
+ background-color: var(--forms-color-background-disabled, #d9d9d9);
406
+ cursor: not-allowed;
407
+ border-color: transparent;
408
+ box-shadow: none;
409
+ color: var(--forms-color-text-disabled, #737373);
410
+ pointer-events: none;
411
+ }
412
+ .mc-combobox--disabled .mc-combobox__control {
413
+ color: var(--forms-color-text-disabled, #737373);
414
+ }
415
+ .mc-combobox--disabled .mc-combobox__icon {
416
+ color: var(--forms-color-icon-disabled, #737373);
417
+ }
418
+ .mc-combobox--readonly .mc-combobox__input {
419
+ border-color: var(--forms-color-border-read-only, #cccccc);
420
+ pointer-events: none;
421
+ }</style>
@@ -0,0 +1,104 @@
1
+ /**
2
+ * A combobox is an input field that allows users to select an option from a dropdown list or enter a custom value. It combines the functionality of a text input and a dropdown menu, providing flexibility and ease of use in forms and user interfaces.
3
+ * @slot optionPrefix - Use this slot to add a prefix to options.
4
+ * @event update:open {CustomEvent<boolean>} - Emitted when the listbox is opened or closed.
5
+ */
6
+ interface Props {
7
+ /**
8
+ * The current selected value(s) of the combobox.
9
+ */
10
+ value: string | number | null | (string | number)[];
11
+ /**
12
+ * Enable multiple value mode.
13
+ */
14
+ multiple?: boolean;
15
+ /**
16
+ * Size of the combobox: small ('s') or medium ('m').
17
+ */
18
+ size?: 's' | 'm';
19
+ /**
20
+ * Disable the combobox input.
21
+ */
22
+ disabled?: boolean;
23
+ /**
24
+ * Make the combobox read-only.
25
+ */
26
+ readonly?: boolean;
27
+ /**
28
+ * Mark the combobox as invalid.
29
+ */
30
+ invalid?: boolean;
31
+ /**
32
+ * Show a clear value button.
33
+ */
34
+ clearable?: boolean;
35
+ /**
36
+ * Enable the search input inside the listbox.
37
+ */
38
+ search?: boolean;
39
+ /**
40
+ * Show select all / clear buttons when multiple.
41
+ */
42
+ actions?: boolean;
43
+ /**
44
+ * Enable checkable section headers in the listbox.
45
+ */
46
+ checkablesections?: boolean;
47
+ /**
48
+ * Placeholder text when no value is selected.
49
+ */
50
+ placeholder?: string;
51
+ /**
52
+ * Label for the selected items counter.
53
+ */
54
+ counterlabel?: string;
55
+ /**
56
+ * Placeholder text for the search input.
57
+ */
58
+ searchplaceholder?: string;
59
+ /**
60
+ * Label for the "Select all" button.
61
+ */
62
+ selectlabel?: string;
63
+ /**
64
+ * Label for the "Clear value" button.
65
+ */
66
+ clearlabel?: string;
67
+ /**
68
+ * Array of options to display in the listbox.
69
+ */
70
+ options: Array<{
71
+ label: string;
72
+ content?: string;
73
+ value?: string | number;
74
+ disabled?: boolean;
75
+ type?: 'option' | 'section';
76
+ }>;
77
+ /**
78
+ * Callback to trigger when the listbox is opened or closed.
79
+ */
80
+ onopen?: (value: boolean) => void;
81
+ }
82
+ 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> {
83
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
84
+ $$bindings?: Bindings;
85
+ } & Exports;
86
+ (internal: unknown, props: Props & {
87
+ $$events?: Events;
88
+ $$slots?: Slots;
89
+ }): Exports & {
90
+ $set?: any;
91
+ $on?: any;
92
+ };
93
+ z_$$bindings?: Bindings;
94
+ }
95
+ declare const Combobox: $$__sveltets_2_IsomorphicComponent<Props, {
96
+ [evt: string]: CustomEvent<any>;
97
+ }, {
98
+ optionPrefix: {
99
+ slot: string;
100
+ };
101
+ }, {}, "value">;
102
+ type Combobox = InstanceType<typeof Combobox>;
103
+ export default Combobox;
104
+ //# sourceMappingURL=Combobox.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Combobox.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/combobox/Combobox.svelte.ts"],"names":[],"mappings":"AAQE;;;;GAIG;AACH,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACpD;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;KAC7B,CAAC,CAAC;IACH;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACnC;AA0JH,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;AAUD,QAAA,MAAM,QAAQ;;;;;;eAAqF,CAAC;AAClF,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,38 @@
1
+ # `m-combobox`
2
+
3
+ A combobox is an input field that allows users to select an option from a dropdown list or enter a custom value. It combines the functionality of a text input and a dropdown menu, providing flexibility and ease of use in forms and user interfaces.
4
+
5
+ ## Props
6
+
7
+ | Name | Description | Type | Default |
8
+ |------|-------------|------|---------|
9
+ | `value*` | The current selected value(s) of the combobox. | `string` `number` `null` `(string` `number)[]` | `$bindable()` |
10
+ | `multiple` | Enable multiple value mode. | `boolean` | |
11
+ | `size` | Size of the combobox: small ('s') or medium ('m'). | `'s'` `'m'` | `m` |
12
+ | `disabled` | Disable the combobox input. | `boolean` | |
13
+ | `readonly` | Make the combobox read-only. | `boolean` | |
14
+ | `invalid` | Mark the combobox as invalid. | `boolean` | |
15
+ | `clearable` | Show a clear value button. | `boolean` | |
16
+ | `search` | Enable the search input inside the listbox. | `boolean` | |
17
+ | `actions` | Show select all / clear buttons when multiple. | `boolean` | |
18
+ | `checkablesections` | Enable checkable section headers in the listbox. | `boolean` | |
19
+ | `placeholder` | Placeholder text when no value is selected. | `string` | `Select an option` |
20
+ | `counterlabel` | Label for the selected items counter. | `string` | `99 selected` |
21
+ | `searchplaceholder` | Placeholder text for the search input. | `string` | `Find an option...` |
22
+ | `selectlabel` | Label for the "Select all" button. | `string` | `Select all` |
23
+ | `clearlabel` | Label for the "Clear value" button. | `string` | `Clear` |
24
+ | `options*` | Array of options to display in the listbox. | `Array<{ label: string; content?: string; value?: string` `number; disabled?: boolean; type?: 'option'` `'section'; }>` | |
25
+ | `onopen` | Callback to trigger when the listbox is opened or closed. | `(value: boolean) => void` | |
26
+
27
+ ## Slots
28
+
29
+ | Name | Description |
30
+ |------|-------------|
31
+ | `optionPrefix` | Use this slot to add a prefix to options. |
32
+
33
+ ## Events
34
+
35
+ | Name | Description | Type |
36
+ |------|------|-------------|
37
+ | `update:open` | Emitted when the listbox is opened or closed. | `CustomEvent<boolean>` |
38
+