@agregio-solutions/design-system 2.0.0 → 2.1.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 (221) hide show
  1. package/dist/design-system.cjs +297 -297
  2. package/dist/design-system.js +860 -846
  3. package/dist/packages/components/Button/components/HoldProgress/HoldProgress.d.ts +1 -1
  4. package/dist/packages/components/Button/components/IconLeftElement/IconLeftElement.d.ts +1 -1
  5. package/dist/packages/components/Button/components/IconRightElement/IconRightElement.d.ts +1 -1
  6. package/dist/packages/components/ChartLegend/ChartLegend.d.ts +1 -1
  7. package/dist/packages/components/Combobox/Combobox.d.ts +39 -82
  8. package/dist/packages/components/Combobox/doc.md +362 -7
  9. package/dist/packages/components/FileUpload/components/FileDetails/FileDetails.d.ts +1 -1
  10. package/dist/packages/components/FileUpload/components/FileDetails/FileDetails.styled.d.ts +1 -1
  11. package/dist/packages/components/Icon/components/access_time.d.ts +1 -1
  12. package/dist/packages/components/Icon/components/add.d.ts +1 -1
  13. package/dist/packages/components/Icon/components/add_box.d.ts +1 -1
  14. package/dist/packages/components/Icon/components/arrow_back.d.ts +1 -1
  15. package/dist/packages/components/Icon/components/arrow_downward.d.ts +1 -1
  16. package/dist/packages/components/Icon/components/arrow_enter.d.ts +1 -1
  17. package/dist/packages/components/Icon/components/arrow_forward.d.ts +1 -1
  18. package/dist/packages/components/Icon/components/arrow_upward.d.ts +1 -1
  19. package/dist/packages/components/Icon/components/back_time.d.ts +1 -1
  20. package/dist/packages/components/Icon/components/bar_chart.d.ts +1 -1
  21. package/dist/packages/components/Icon/components/bar_chart_2.d.ts +1 -1
  22. package/dist/packages/components/Icon/components/battery.d.ts +1 -1
  23. package/dist/packages/components/Icon/components/battery_alert.d.ts +1 -1
  24. package/dist/packages/components/Icon/components/battery_empty.d.ts +1 -1
  25. package/dist/packages/components/Icon/components/battery_full.d.ts +1 -1
  26. package/dist/packages/components/Icon/components/battery_half.d.ts +1 -1
  27. package/dist/packages/components/Icon/components/bolt.d.ts +1 -1
  28. package/dist/packages/components/Icon/components/book.d.ts +1 -1
  29. package/dist/packages/components/Icon/components/business.d.ts +1 -1
  30. package/dist/packages/components/Icon/components/calculator.d.ts +1 -1
  31. package/dist/packages/components/Icon/components/calendar.d.ts +1 -1
  32. package/dist/packages/components/Icon/components/calendar_today.d.ts +1 -1
  33. package/dist/packages/components/Icon/components/calibration.d.ts +1 -1
  34. package/dist/packages/components/Icon/components/cancel.d.ts +1 -1
  35. package/dist/packages/components/Icon/components/caret.d.ts +1 -1
  36. package/dist/packages/components/Icon/components/change_circle.d.ts +1 -1
  37. package/dist/packages/components/Icon/components/change_ok.d.ts +1 -1
  38. package/dist/packages/components/Icon/components/chart_curves.d.ts +1 -1
  39. package/dist/packages/components/Icon/components/chart_curves_rounded.d.ts +1 -1
  40. package/dist/packages/components/Icon/components/chart_plus.d.ts +1 -1
  41. package/dist/packages/components/Icon/components/chart_simple.d.ts +1 -1
  42. package/dist/packages/components/Icon/components/chart_up.d.ts +1 -1
  43. package/dist/packages/components/Icon/components/check.d.ts +1 -1
  44. package/dist/packages/components/Icon/components/check_circle_outline.d.ts +1 -1
  45. package/dist/packages/components/Icon/components/chevron_left.d.ts +1 -1
  46. package/dist/packages/components/Icon/components/chevron_right.d.ts +1 -1
  47. package/dist/packages/components/Icon/components/clear.d.ts +1 -1
  48. package/dist/packages/components/Icon/components/close.d.ts +1 -1
  49. package/dist/packages/components/Icon/components/cloud.d.ts +1 -1
  50. package/dist/packages/components/Icon/components/cloud_full.d.ts +1 -1
  51. package/dist/packages/components/Icon/components/collapse_menu.d.ts +1 -1
  52. package/dist/packages/components/Icon/components/content_copy.d.ts +1 -1
  53. package/dist/packages/components/Icon/components/cycle.d.ts +1 -1
  54. package/dist/packages/components/Icon/components/delete_outline.d.ts +1 -1
  55. package/dist/packages/components/Icon/components/dice.d.ts +1 -1
  56. package/dist/packages/components/Icon/components/disconnect.d.ts +1 -1
  57. package/dist/packages/components/Icon/components/download.d.ts +1 -1
  58. package/dist/packages/components/Icon/components/drag_indicator.d.ts +1 -1
  59. package/dist/packages/components/Icon/components/driver.d.ts +1 -1
  60. package/dist/packages/components/Icon/components/edit.d.ts +1 -1
  61. package/dist/packages/components/Icon/components/error_outline.d.ts +1 -1
  62. package/dist/packages/components/Icon/components/euro.d.ts +1 -1
  63. package/dist/packages/components/Icon/components/exit.d.ts +1 -1
  64. package/dist/packages/components/Icon/components/exit_to_app.d.ts +1 -1
  65. package/dist/packages/components/Icon/components/expand_less.d.ts +1 -1
  66. package/dist/packages/components/Icon/components/expand_more.d.ts +1 -1
  67. package/dist/packages/components/Icon/components/eye.d.ts +1 -1
  68. package/dist/packages/components/Icon/components/eye_off.d.ts +1 -1
  69. package/dist/packages/components/Icon/components/fiber_new.d.ts +1 -1
  70. package/dist/packages/components/Icon/components/file_download.d.ts +1 -1
  71. package/dist/packages/components/Icon/components/file_export.d.ts +1 -1
  72. package/dist/packages/components/Icon/components/file_plus.d.ts +1 -1
  73. package/dist/packages/components/Icon/components/filter_alt.d.ts +1 -1
  74. package/dist/packages/components/Icon/components/filter_list.d.ts +1 -1
  75. package/dist/packages/components/Icon/components/first_page.d.ts +1 -1
  76. package/dist/packages/components/Icon/components/flame.d.ts +1 -1
  77. package/dist/packages/components/Icon/components/flex.d.ts +1 -1
  78. package/dist/packages/components/Icon/components/folder_open.d.ts +1 -1
  79. package/dist/packages/components/Icon/components/gaz.d.ts +1 -1
  80. package/dist/packages/components/Icon/components/grid_view.d.ts +1 -1
  81. package/dist/packages/components/Icon/components/hand.d.ts +1 -1
  82. package/dist/packages/components/Icon/components/help_outline.d.ts +1 -1
  83. package/dist/packages/components/Icon/components/home.d.ts +1 -1
  84. package/dist/packages/components/Icon/components/hydraulic.d.ts +1 -1
  85. package/dist/packages/components/Icon/components/id.d.ts +1 -1
  86. package/dist/packages/components/Icon/components/industry.d.ts +1 -1
  87. package/dist/packages/components/Icon/components/insert_emoticon.d.ts +1 -1
  88. package/dist/packages/components/Icon/components/invoice.d.ts +1 -1
  89. package/dist/packages/components/Icon/components/invoice_full.d.ts +1 -1
  90. package/dist/packages/components/Icon/components/joystick.d.ts +1 -1
  91. package/dist/packages/components/Icon/components/language.d.ts +1 -1
  92. package/dist/packages/components/Icon/components/laptop.d.ts +1 -1
  93. package/dist/packages/components/Icon/components/last_page.d.ts +1 -1
  94. package/dist/packages/components/Icon/components/leaf.d.ts +1 -1
  95. package/dist/packages/components/Icon/components/lines_ok.d.ts +1 -1
  96. package/dist/packages/components/Icon/components/lines_plus.d.ts +1 -1
  97. package/dist/packages/components/Icon/components/link.d.ts +1 -1
  98. package/dist/packages/components/Icon/components/list.d.ts +1 -1
  99. package/dist/packages/components/Icon/components/location.d.ts +1 -1
  100. package/dist/packages/components/Icon/components/location_full.d.ts +1 -1
  101. package/dist/packages/components/Icon/components/location_searching.d.ts +1 -1
  102. package/dist/packages/components/Icon/components/logout.d.ts +1 -1
  103. package/dist/packages/components/Icon/components/logs.d.ts +1 -1
  104. package/dist/packages/components/Icon/components/magic_wand.d.ts +1 -1
  105. package/dist/packages/components/Icon/components/mail_empty.d.ts +1 -1
  106. package/dist/packages/components/Icon/components/mail_full.d.ts +1 -1
  107. package/dist/packages/components/Icon/components/mail_off.d.ts +1 -1
  108. package/dist/packages/components/Icon/components/mail_ok.d.ts +1 -1
  109. package/dist/packages/components/Icon/components/mail_open.d.ts +1 -1
  110. package/dist/packages/components/Icon/components/mail_open_full.d.ts +1 -1
  111. package/dist/packages/components/Icon/components/menu.d.ts +1 -1
  112. package/dist/packages/components/Icon/components/minimize.d.ts +1 -1
  113. package/dist/packages/components/Icon/components/modbus.d.ts +1 -1
  114. package/dist/packages/components/Icon/components/money_pig.d.ts +1 -1
  115. package/dist/packages/components/Icon/components/money_pig_full.d.ts +1 -1
  116. package/dist/packages/components/Icon/components/monitor_heart.d.ts +1 -1
  117. package/dist/packages/components/Icon/components/monitoring.d.ts +1 -1
  118. package/dist/packages/components/Icon/components/moon.d.ts +1 -1
  119. package/dist/packages/components/Icon/components/more_horiz.d.ts +1 -1
  120. package/dist/packages/components/Icon/components/more_vert.d.ts +1 -1
  121. package/dist/packages/components/Icon/components/moving.d.ts +1 -1
  122. package/dist/packages/components/Icon/components/notifications_active.d.ts +1 -1
  123. package/dist/packages/components/Icon/components/notifications_none.d.ts +1 -1
  124. package/dist/packages/components/Icon/components/notifications_off.d.ts +1 -1
  125. package/dist/packages/components/Icon/components/one_single.d.ts +1 -1
  126. package/dist/packages/components/Icon/components/pause.d.ts +1 -1
  127. package/dist/packages/components/Icon/components/pause_empty.d.ts +1 -1
  128. package/dist/packages/components/Icon/components/payments.d.ts +1 -1
  129. package/dist/packages/components/Icon/components/pdf.d.ts +1 -1
  130. package/dist/packages/components/Icon/components/phone_1_empty.d.ts +1 -1
  131. package/dist/packages/components/Icon/components/phone_1_full.d.ts +1 -1
  132. package/dist/packages/components/Icon/components/phone_2_empty.d.ts +1 -1
  133. package/dist/packages/components/Icon/components/phone_2_full.d.ts +1 -1
  134. package/dist/packages/components/Icon/components/play.d.ts +1 -1
  135. package/dist/packages/components/Icon/components/play_empty.d.ts +1 -1
  136. package/dist/packages/components/Icon/components/play_full.d.ts +1 -1
  137. package/dist/packages/components/Icon/components/power_off.d.ts +1 -1
  138. package/dist/packages/components/Icon/components/profile.d.ts +1 -1
  139. package/dist/packages/components/Icon/components/profile_full.d.ts +1 -1
  140. package/dist/packages/components/Icon/components/progress.d.ts +1 -1
  141. package/dist/packages/components/Icon/components/question.d.ts +1 -1
  142. package/dist/packages/components/Icon/components/rain.d.ts +1 -1
  143. package/dist/packages/components/Icon/components/receipt_long.d.ts +1 -1
  144. package/dist/packages/components/Icon/components/record.d.ts +1 -1
  145. package/dist/packages/components/Icon/components/record_full.d.ts +1 -1
  146. package/dist/packages/components/Icon/components/refresh.d.ts +1 -1
  147. package/dist/packages/components/Icon/components/remove.d.ts +1 -1
  148. package/dist/packages/components/Icon/components/remove_red_eye.d.ts +1 -1
  149. package/dist/packages/components/Icon/components/rename.d.ts +1 -1
  150. package/dist/packages/components/Icon/components/return.d.ts +1 -1
  151. package/dist/packages/components/Icon/components/save.d.ts +1 -1
  152. package/dist/packages/components/Icon/components/scan.d.ts +1 -1
  153. package/dist/packages/components/Icon/components/science.d.ts +1 -1
  154. package/dist/packages/components/Icon/components/science_2.d.ts +1 -1
  155. package/dist/packages/components/Icon/components/search.d.ts +1 -1
  156. package/dist/packages/components/Icon/components/sell.d.ts +1 -1
  157. package/dist/packages/components/Icon/components/sell_full.d.ts +1 -1
  158. package/dist/packages/components/Icon/components/send.d.ts +1 -1
  159. package/dist/packages/components/Icon/components/settings.d.ts +1 -1
  160. package/dist/packages/components/Icon/components/sms_empty.d.ts +1 -1
  161. package/dist/packages/components/Icon/components/sms_full.d.ts +1 -1
  162. package/dist/packages/components/Icon/components/square_plus.d.ts +1 -1
  163. package/dist/packages/components/Icon/components/ssid_chart.d.ts +1 -1
  164. package/dist/packages/components/Icon/components/stack_batch.d.ts +1 -1
  165. package/dist/packages/components/Icon/components/stacked_line_chart.d.ts +1 -1
  166. package/dist/packages/components/Icon/components/star.d.ts +1 -1
  167. package/dist/packages/components/Icon/components/star_outline.d.ts +1 -1
  168. package/dist/packages/components/Icon/components/storm.d.ts +1 -1
  169. package/dist/packages/components/Icon/components/sun.d.ts +1 -1
  170. package/dist/packages/components/Icon/components/sun_2.d.ts +1 -1
  171. package/dist/packages/components/Icon/components/sun_full.d.ts +1 -1
  172. package/dist/packages/components/Icon/components/swap_horiz.d.ts +1 -1
  173. package/dist/packages/components/Icon/components/tag.d.ts +1 -1
  174. package/dist/packages/components/Icon/components/tag_add.d.ts +1 -1
  175. package/dist/packages/components/Icon/components/tag_ok.d.ts +1 -1
  176. package/dist/packages/components/Icon/components/tag_remove.d.ts +1 -1
  177. package/dist/packages/components/Icon/components/team.d.ts +1 -1
  178. package/dist/packages/components/Icon/components/text_snippet.d.ts +1 -1
  179. package/dist/packages/components/Icon/components/ticket.d.ts +1 -1
  180. package/dist/packages/components/Icon/components/ticket_full.d.ts +1 -1
  181. package/dist/packages/components/Icon/components/tools.d.ts +1 -1
  182. package/dist/packages/components/Icon/components/tree_item.d.ts +1 -1
  183. package/dist/packages/components/Icon/components/undo.d.ts +1 -1
  184. package/dist/packages/components/Icon/components/update.d.ts +1 -1
  185. package/dist/packages/components/Icon/components/update_circle.d.ts +1 -1
  186. package/dist/packages/components/Icon/components/upload.d.ts +1 -1
  187. package/dist/packages/components/Icon/components/wallet.d.ts +1 -1
  188. package/dist/packages/components/Icon/components/warehouse.d.ts +1 -1
  189. package/dist/packages/components/Icon/components/warning_amber.d.ts +1 -1
  190. package/dist/packages/components/Icon/components/warning_badge.d.ts +1 -1
  191. package/dist/packages/components/Icon/components/warning_octogone.d.ts +1 -1
  192. package/dist/packages/components/Icon/components/warning_shield.d.ts +1 -1
  193. package/dist/packages/components/Icon/components/wifi.d.ts +1 -1
  194. package/dist/packages/components/Icon/components/wifi_level.d.ts +1 -1
  195. package/dist/packages/components/Icon/components/wifi_rounded.d.ts +1 -1
  196. package/dist/packages/components/Icon/components/wifi_rounded_alert.d.ts +1 -1
  197. package/dist/packages/components/Icon/components/wifi_settings.d.ts +1 -1
  198. package/dist/packages/components/Icon/components/wind_turbine.d.ts +1 -1
  199. package/dist/packages/components/LinearProgressBar/LinearProgressBar.d.ts +1 -1
  200. package/dist/packages/components/List/components/ListItem/ListItem.d.ts +1 -1
  201. package/dist/packages/components/Loader/Loader.d.ts +1 -1
  202. package/dist/packages/components/MenuItem/MenuItem.d.ts +1 -1
  203. package/dist/packages/components/Navigation/components/AgregioSolutionsLogo.d.ts +1 -1
  204. package/dist/packages/components/Navigation/components/ConnectionManagementLogo.d.ts +1 -1
  205. package/dist/packages/components/Navigation/components/IrisLogo.d.ts +1 -1
  206. package/dist/packages/components/Navigation/components/OBILogo.d.ts +1 -1
  207. package/dist/packages/components/Navigation/components/VPPLogo.d.ts +1 -1
  208. package/dist/packages/components/Notifications/components/EmptyNotifications/EmptyNotifications.d.ts +1 -1
  209. package/dist/packages/components/PageLayout/PageLayout.d.ts +1 -1
  210. package/dist/packages/components/RouterProvider/RouterProvider.d.ts +1 -1
  211. package/dist/packages/components/SelectItem/SelectItem.d.ts +2 -1
  212. package/dist/packages/components/Timeline/Timeline.d.ts +1 -1
  213. package/dist/packages/components/Timeline/components/BlockLineContainer/BlockLineContainer.d.ts +1 -1
  214. package/dist/packages/components/Timeline/components/BlockLineContainer/components/ExpandButton/ExpandButton.d.ts +1 -1
  215. package/dist/packages/components/Timeline/components/BlockLineContainer/components/NameBlock/NameBlock.d.ts +1 -1
  216. package/dist/packages/components/Timeline/components/GroupLineContainer/GroupLineContainer.d.ts +1 -1
  217. package/dist/packages/components/Timeline/components/TimelineRange/TimelineRange.d.ts +1 -1
  218. package/dist/packages/components/Toaster/Toaster.d.ts +1 -1
  219. package/dist/packages/index.d.ts +2 -2
  220. package/dist/packages/internal-components/Logo/Logo.d.ts +1 -1
  221. package/package.json +11 -11
@@ -19,4 +19,4 @@ export interface Props {
19
19
  * percent would mean re-rendering on each frame, and the label already tells
20
20
  * the user what to do.
21
21
  */
22
- export default function HoldProgress({ size, duration }: Props): import("react").JSX.Element;
22
+ export default function HoldProgress({ size, duration }: Props): import('react').JSX.Element;
@@ -8,4 +8,4 @@ export interface Props {
8
8
  /**
9
9
  * Leading slot of a button: the loader takes over the icon while loading.
10
10
  */
11
- export default function IconLeftElement({ iconLeft, isLoading, size }: Props): import("react").JSX.Element | null;
11
+ export default function IconLeftElement({ iconLeft, isLoading, size }: Props): import('react').JSX.Element | null;
@@ -9,4 +9,4 @@ export interface Props {
9
9
  /**
10
10
  * Trailing slot of a button.
11
11
  */
12
- export default function IconRightElement({ iconRight, text, isLoading, size, }: Props): import("react").JSX.Element | null;
12
+ export default function IconRightElement({ iconRight, text, isLoading, size, }: Props): import('react').JSX.Element | null;
@@ -35,4 +35,4 @@ export type Props = Omit<ButtonProps, "onPress" | "isDisabled" | "children"> & {
35
35
  */
36
36
  customIcon?: React.ReactNode;
37
37
  };
38
- export default function ChartLegend({ text, chartColor, onClick, isSelected, icon, customIcon, circleOutlineColor, ...reactAriaButtonProps }: Props): import("react").JSX.Element;
38
+ export default function ChartLegend({ text, chartColor, onClick, isSelected, icon, customIcon, circleOutlineColor, ...reactAriaButtonProps }: Props): import('react').JSX.Element;
@@ -3,6 +3,11 @@ import { Props as FormGroupWrapperProps } from '../../internal-components/FormGr
3
3
  import { Props as SelectItemProps } from '../SelectItem/SelectItem';
4
4
  import { Props as LabelProps } from '../Label/Label';
5
5
  export type ComboboxItem = SelectItemProps;
6
+ /**
7
+ * The props of the single selection mode, and of the deprecated multiple selection workaround.
8
+ * Kept as a single object type so that the types consumers derive from it (`Omit`, `Props["value"]`, `interface extends`) keep compiling.
9
+ * The native multiple selection mode has its own props: `MultipleProps`.
10
+ */
6
11
  export type Props = Pick<LabelProps, "label" | "labelIconRight" | "labelIconRightTooltip" | "required"> & Pick<FormGroupWrapperProps, "helperText" | "helperTextIcon" | "errorHelperText" | "errorHelperTextIcon" | "successHelperText" | "successHelperTextIcon" | "warningHelperText" | "warningHelperTextIcon" | "orientation"> & {
7
12
  /**
8
13
  * Required id, used mainly to link the label to the field.
@@ -10,10 +15,12 @@ export type Props = Pick<LabelProps, "label" | "labelIconRight" | "labelIconRigh
10
15
  id: string;
11
16
  /**
12
17
  * The controlled value of the Combobox. Should be used in conjunction with `onChange`.
18
+ * Not used in the native multiple selection mode, see `selectedKeys`.
13
19
  */
14
20
  value: string | null;
15
21
  /**
16
22
  * Event handler called when the value changes.
23
+ * Not used in the native multiple selection mode, see `onSelectionChange`.
17
24
  */
18
25
  onChange: (value: string) => void;
19
26
  /**
@@ -28,6 +35,8 @@ export type Props = Pick<LabelProps, "label" | "labelIconRight" | "labelIconRigh
28
35
  items?: Array<ComboboxItem>;
29
36
  /**
30
37
  * The selection mode of the Combobox.
38
+ * For multiple selection, pass `selectedKeys` and `onSelectionChange` instead of `value` and `onChange`.
39
+ * Using `"multiple"` with `value` and `onChange` is deprecated: this workaround fakes the multiple selection on top of a single one.
31
40
  * @default "single"
32
41
  */
33
42
  selectionMode?: "single" | "multiple";
@@ -91,92 +100,40 @@ export type Props = Pick<LabelProps, "label" | "labelIconRight" | "labelIconRigh
91
100
  */
92
101
  triggerContentRight?: React.ReactNode;
93
102
  };
94
- declare const Combobox: React.ForwardRefExoticComponent<Pick<LabelProps, "label" | "required" | "labelIconRight" | "labelIconRightTooltip"> & Pick<FormGroupWrapperProps, "orientation" | "helperText" | "helperTextIcon" | "errorHelperText" | "errorHelperTextIcon" | "successHelperText" | "successHelperTextIcon" | "warningHelperText" | "warningHelperTextIcon"> & {
95
- /**
96
- * Required id, used mainly to link the label to the field.
97
- */
98
- id: string;
99
- /**
100
- * The controlled value of the Combobox. Should be used in conjunction with `onChange`.
101
- */
102
- value: string | null;
103
- /**
104
- * Event handler called when the value changes.
105
- */
106
- onChange: (value: string) => void;
107
- /**
108
- * The items to display in the dropdown (uncontrolled, filtering managed internally).
109
- */
110
- defaultItems?: Array<ComboboxItem>;
111
- /**
112
- * The items to display in the dropdown.
113
- * /!\ Warning: using this prop will make the filtering mode "controlled" !
114
- * Use it in pair with `inputValue` and `onInputChange` props, and manage the filtered of items yourself.
115
- */
116
- items?: Array<ComboboxItem>;
103
+ /**
104
+ * The props of the native multiple selection mode.
105
+ */
106
+ export type MultipleProps = Omit<Props, "value" | "onChange" | "selectionMode"> & {
117
107
  /**
118
108
  * The selection mode of the Combobox.
119
- * @default "single"
120
- */
121
- selectionMode?: "single" | "multiple";
122
- /**
123
- * Specifies the nature of the Combobox (mainly to change the trigger border color and helperText color).
124
- * If you do not pass a nature prop, the component will automatically set the nature based on the presence of success/error messages
125
- */
126
- nature?: "default" | "negative" | "positive" | "warning";
127
- /**
128
- * The value of the ComboBox input (controlled).
129
- */
130
- inputValue?: string;
131
- /**
132
- * Event handler called when the input value changes (controlled).
133
109
  */
134
- onInputChange?: (value: string) => void;
110
+ selectionMode: "multiple";
135
111
  /**
136
- * The default value of the ComboBox input (uncontrolled).
112
+ * The ids of the selected items (controlled). Pass `[]` when nothing is selected.
137
113
  */
138
- defaultInputValue?: string;
114
+ selectedKeys: Array<string>;
139
115
  /**
140
- * When true, prevents the user from interacting with Combobox.
116
+ * Event handler called with the ids of all the selected items when the selection changes.
141
117
  */
142
- disabled?: boolean;
143
- /**
144
- * The content that will be rendered inside the input when no value or defaultValue is set.
145
- */
146
- placeholder?: string;
147
- /**
148
- * Props to pass to the wrapper div (for example, style or className)
149
- */
150
- wrapperProps?: React.HTMLProps<HTMLDivElement>;
151
- /**
152
- * Props to pass to the input (for example, style or className).
153
- */
154
- inputProps?: React.HTMLProps<HTMLInputElement>;
155
- /**
156
- * Whether the input should take the full width available
157
- */
158
- fullWidth?: boolean;
159
- /**
160
- * Disabled items in the dropdown, should be the item's id.
161
- */
162
- disabledIds?: Array<string>;
163
- /**
164
- * If you give a ReactNode as label, you should then provide an aria-label as string to ensure there is no accessibility issue
165
- */
166
- "aria-label"?: string;
167
- /**
168
- * The filter function used to determine if a option should be included in the combo box list.
169
- */
170
- defaultFilter?: (textValue: string, inputValue: string) => boolean;
171
- /**
172
- * When true, increases the dropdown max-height from 200px to 400px.
173
- */
174
- tallDropdown?: boolean;
175
- /**
176
- * An element rendered inside the field, on the left of the dropdown trigger.
177
- * Typically a `Badge` displaying the number of selected items in `selectionMode="multiple"`.
178
- * It lays out in the flow, so the input shrinks to make room for it whatever its width.
179
- */
180
- triggerContentRight?: React.ReactNode;
181
- } & React.RefAttributes<HTMLInputElement>>;
182
- export default Combobox;
118
+ onSelectionChange: (selectedKeys: Array<string>) => void;
119
+ };
120
+ type SingleProps = Omit<Props, "selectionMode"> & {
121
+ selectionMode?: "single";
122
+ };
123
+ type WithRef<P> = P & React.RefAttributes<HTMLInputElement>;
124
+ /**
125
+ * Overloads: TypeScript resolves a JSX element against each signature in order.
126
+ * The order matters: Storybook documents the props of the first signature,
127
+ * and `ComponentProps<typeof Combobox>` reads the last one, which stays `Props`.
128
+ */
129
+ type ComboboxComponent = {
130
+ (props: WithRef<SingleProps>): React.ReactNode;
131
+ (props: WithRef<MultipleProps>): React.ReactNode;
132
+ /**
133
+ * @deprecated The multiple selection with `value` and `onChange` is a workaround on top of a single selection.
134
+ * Use `selectedKeys` and `onSelectionChange` instead, see the "Multiple selection" section of the Combobox docs.
135
+ */
136
+ (props: WithRef<Props>): React.ReactNode;
137
+ } & Omit<React.ForwardRefExoticComponent<WithRef<Props>>, never>;
138
+ declare const _default: ComboboxComponent;
139
+ export default _default;
@@ -181,12 +181,13 @@ Here are some more advanced stories with more testing coverage and examples that
181
181
  import { Meta, StoryObj } from "@storybook/react-vite";
182
182
 
183
183
  import Badge from "@packages/components/Badge/Badge";
184
+ import ErrorBoundary from "@packages/internal-components/ErrorBoundary/ErrorBoundary";
184
185
  import Combobox from "../Combobox";
185
186
  import { Playground } from "../Combobox.stories";
186
187
  import { userEvent, within, screen, expect } from "storybook/test";
187
188
  import { expectNotPresent } from "@internal/test-utils-storybook/test-utils-storybook";
188
189
  import * as ComboboxStories from "../Combobox.stories";
189
- import { useEffect, useState } from "react";
190
+ import { ComponentProps, useEffect, useState } from "react";
190
191
  import { useController, useForm } from "react-hook-form";
191
192
 
192
193
  const meta: Meta<typeof Combobox> = {
@@ -539,6 +540,298 @@ export const ExampleWithCustomFiltering: StoryObj<typeof Combobox> = {
539
540
  };
540
541
 
541
542
  export const MultipleSelectionExample: StoryObj<typeof Combobox> = {
543
+ parameters: {
544
+ ...meta.parameters,
545
+ layout: "padded",
546
+ },
547
+ render: () => {
548
+ const data = new Array(10).fill(0).map((_, index) => ({
549
+ id: `${index + 1}`,
550
+ name: `Perimeter ${index + 1}`,
551
+ }));
552
+
553
+ const ParentComponent = () => {
554
+ // List of the selected perimeters ids
555
+ const [selectedPerimetersIds, setSelectedPerimetersIds] = useState<
556
+ Array<string>
557
+ >([]);
558
+
559
+ // List of the selected perimeters (derived state)
560
+ const selectedPerimeters = data.filter((perimeter) =>
561
+ selectedPerimetersIds.includes(perimeter.id),
562
+ );
563
+
564
+ return (
565
+ <div style={{ display: "flex", gap: "var(--spacing-xs)" }}>
566
+ <Combobox
567
+ id="perimeters-combobox"
568
+ label="Select perimeters"
569
+ selectionMode="multiple"
570
+ selectedKeys={selectedPerimetersIds}
571
+ onSelectionChange={setSelectedPerimetersIds}
572
+ defaultItems={data.map((perimeter) => ({
573
+ text: perimeter.name,
574
+ id: perimeter.id,
575
+ }))}
576
+ // Display the number of selected items inside the field
577
+ triggerContentRight={
578
+ <Badge
579
+ value={selectedPerimetersIds.length}
580
+ nature="informative"
581
+ />
582
+ }
583
+ />
584
+
585
+ <div>
586
+ <div>Selected perimeters:</div>
587
+ <ul>
588
+ {selectedPerimeters.map((perimeter) => (
589
+ <li key={perimeter.id}>{perimeter.name}</li>
590
+ ))}
591
+ </ul>
592
+ </div>
593
+ </div>
594
+ );
595
+ };
596
+ return <ParentComponent />;
597
+ },
598
+ };
599
+
600
+ const MULTIPLE_LABEL = "Select perimeters";
601
+
602
+ const MULTIPLE_ITEMS = Array.from({ length: 10 }, (_, index) => ({
603
+ id: `${index + 1}`,
604
+ text: `Perimeter ${index + 1}`,
605
+ }));
606
+
607
+ const MultipleCombobox = (
608
+ props: Pick<ComponentProps<typeof Combobox>, "disabledIds" | "required">,
609
+ ) => {
610
+ const [selectedKeys, setSelectedKeys] = useState<Array<string>>([]);
611
+
612
+ return (
613
+ <>
614
+ <Combobox
615
+ {...props}
616
+ id="perimeters-combobox"
617
+ label={MULTIPLE_LABEL}
618
+ selectionMode="multiple"
619
+ selectedKeys={selectedKeys}
620
+ onSelectionChange={setSelectedKeys}
621
+ defaultItems={MULTIPLE_ITEMS}
622
+ triggerContentRight={
623
+ <Badge value={selectedKeys.length} nature="informative" />
624
+ }
625
+ />
626
+ <button type="button" onClick={() => setSelectedKeys([])}>
627
+ Clear selection
628
+ </button>
629
+ </>
630
+ );
631
+ };
632
+
633
+ const getMultipleField = (canvasElement: HTMLElement) => {
634
+ const input = within(canvasElement).getByLabelText(MULTIPLE_LABEL);
635
+ return { input, field: within(input.parentElement!) };
636
+ };
637
+
638
+ // The badge is the only text of the field besides the trigger icon
639
+ const expectSelectedCount = async (canvasElement: HTMLElement, count: number) =>
640
+ expect(
641
+ getMultipleField(canvasElement).field.getByText(String(count)),
642
+ ).toBeInTheDocument();
643
+
644
+ const findOption = async (text: string) =>
645
+ (await screen.findByText(text, { selector: "span" })).closest(
646
+ '[role="option"]',
647
+ );
648
+
649
+ export const ShouldSelectMultipleValues: StoryObj<typeof Combobox> = {
650
+ ...MultipleSelectionExample,
651
+ play: async ({ canvasElement }) => {
652
+ const user = userEvent.setup({ delay: 50 });
653
+ const { input, field } = getMultipleField(canvasElement);
654
+ const clickOption = async (text: string) =>
655
+ user.click(await screen.findByText(text, { selector: "span" }));
656
+ const selectedList = within(within(canvasElement).getByRole("list"));
657
+
658
+ // The badge renders nothing while no item is selected
659
+ await expectNotPresent(() => field.queryByText("0"));
660
+
661
+ // The dropdown stays open across selections
662
+ await user.click(field.getByRole("button"));
663
+
664
+ await clickOption("Perimeter 1");
665
+ await expectSelectedCount(canvasElement, 1);
666
+
667
+ await clickOption("Perimeter 2");
668
+ await expectSelectedCount(canvasElement, 2);
669
+ await expect(await findOption("Perimeter 1")).toHaveAttribute(
670
+ "aria-selected",
671
+ "true",
672
+ );
673
+ await expect(await findOption("Perimeter 2")).toHaveAttribute(
674
+ "aria-selected",
675
+ "true",
676
+ );
677
+
678
+ // Unselecting brings the count back down
679
+ await clickOption("Perimeter 1");
680
+ await expectSelectedCount(canvasElement, 1);
681
+ await expect(
682
+ selectedList.queryByText("Perimeter 1"),
683
+ ).not.toBeInTheDocument();
684
+ await expect(selectedList.getByText("Perimeter 2")).toBeInTheDocument();
685
+
686
+ // Typing filters the options, and the input is cleared after a selection
687
+ await user.type(input, "10");
688
+ await clickOption("Perimeter 10");
689
+ await expect(input).toHaveValue("");
690
+ await expectSelectedCount(canvasElement, 2);
691
+ await expect(selectedList.getByText("Perimeter 10")).toBeInTheDocument();
692
+ },
693
+ };
694
+
695
+ export const ShouldSelectMultipleValuesWithTheKeyboard: StoryObj<
696
+ typeof Combobox
697
+ > = {
698
+ render: () => <MultipleCombobox />,
699
+ play: async ({ canvasElement }) => {
700
+ const user = userEvent.setup({ delay: 50 });
701
+ const { input } = getMultipleField(canvasElement);
702
+
703
+ await user.click(input);
704
+ await user.keyboard("{ArrowDown}");
705
+ await screen.findByRole("listbox");
706
+ await user.keyboard("{Enter}");
707
+ await expectSelectedCount(canvasElement, 1);
708
+
709
+ // The dropdown stays open, so the next option can be selected right away
710
+ await user.keyboard("{ArrowDown}{Enter}");
711
+ await expectSelectedCount(canvasElement, 2);
712
+ await expect(await findOption("Perimeter 1")).toHaveAttribute(
713
+ "aria-selected",
714
+ "true",
715
+ );
716
+ await expect(await findOption("Perimeter 2")).toHaveAttribute(
717
+ "aria-selected",
718
+ "true",
719
+ );
720
+
721
+ await user.keyboard("{Escape}");
722
+ await expectNotPresent(() => screen.queryByRole("listbox"));
723
+ },
724
+ };
725
+
726
+ export const ShouldResetTheMultipleSelectionFromTheParent: StoryObj<
727
+ typeof Combobox
728
+ > = {
729
+ render: () => <MultipleCombobox />,
730
+ play: async ({ canvasElement }) => {
731
+ const canvas = within(canvasElement);
732
+ const user = userEvent.setup({ delay: 50 });
733
+ const { field } = getMultipleField(canvasElement);
734
+
735
+ await user.click(field.getByRole("button"));
736
+ await user.click(
737
+ await screen.findByText("Perimeter 1", { selector: "span" }),
738
+ );
739
+ await expectSelectedCount(canvasElement, 1);
740
+
741
+ // The open dropdown hides the rest of the page from assistive technologies
742
+ await user.keyboard("{Escape}");
743
+ await user.click(canvas.getByRole("button", { name: "Clear selection" }));
744
+ await expectNotPresent(() => field.queryByText("1"));
745
+
746
+ await user.click(field.getByRole("button"));
747
+ await expect(await findOption("Perimeter 1")).toHaveAttribute(
748
+ "aria-selected",
749
+ "false",
750
+ );
751
+ },
752
+ };
753
+
754
+ export const ShouldNotSelectADisabledOptionInMultipleMode: StoryObj<
755
+ typeof Combobox
756
+ > = {
757
+ render: () => <MultipleCombobox disabledIds={["2"]} />,
758
+ play: async ({ canvasElement }) => {
759
+ const user = userEvent.setup({ delay: 50 });
760
+ const { field } = getMultipleField(canvasElement);
761
+
762
+ await user.click(field.getByRole("button"));
763
+ await user.click(
764
+ await screen.findByText("Perimeter 2", { selector: "span" }),
765
+ );
766
+ await expect(await findOption("Perimeter 2")).toHaveAttribute(
767
+ "aria-disabled",
768
+ "true",
769
+ );
770
+ await expectNotPresent(() => field.queryByText("1"));
771
+ },
772
+ };
773
+
774
+ export const ShouldBeRequiredInMultipleMode: StoryObj<typeof Combobox> = {
775
+ render: () => <MultipleCombobox required />,
776
+ play: async ({ canvasElement }) => {
777
+ await expect(getMultipleField(canvasElement).input).toBeRequired();
778
+ },
779
+ };
780
+
781
+ export const ShouldThrowWhenSelectedKeysIsNotAnArray: StoryObj<
782
+ typeof Combobox
783
+ > = {
784
+ decorators: [(Story) => <ErrorBoundary>{Story()}</ErrorBoundary>],
785
+ render: () => (
786
+ <Combobox
787
+ id="perimeters-combobox"
788
+ label={MULTIPLE_LABEL}
789
+ selectionMode="multiple"
790
+ // Simulates a loosely typed form value that is not initialized yet
791
+ selectedKeys={undefined as unknown as Array<string>}
792
+ onSelectionChange={() => {}}
793
+ defaultItems={MULTIPLE_ITEMS}
794
+ />
795
+ ),
796
+ play: async ({ canvasElement }) => {
797
+ await within(canvasElement).findByText(
798
+ 'Error: Combobox "perimeters-combobox": `selectedKeys` must be an array, use `[]` when nothing is selected',
799
+ );
800
+ },
801
+ };
802
+
803
+ export const ShouldThrowWhenSelectedKeysIsUsedWithoutMultipleMode: StoryObj<
804
+ typeof Combobox
805
+ > = {
806
+ decorators: [(Story) => <ErrorBoundary>{Story()}</ErrorBoundary>],
807
+ render: () => {
808
+ // Bypasses the types, as a loosely typed consumer would
809
+ const looseProps = {
810
+ selectedKeys: [],
811
+ onSelectionChange: () => {},
812
+ } as unknown as ComponentProps<typeof Combobox>;
813
+ return (
814
+ <Combobox
815
+ {...looseProps}
816
+ id="perimeters-combobox"
817
+ label={MULTIPLE_LABEL}
818
+ defaultItems={MULTIPLE_ITEMS}
819
+ />
820
+ );
821
+ },
822
+ play: async ({ canvasElement }) => {
823
+ await within(canvasElement).findByText(
824
+ 'Error: Combobox "perimeters-combobox": `selectedKeys` requires `selectionMode="multiple"`',
825
+ );
826
+ },
827
+ };
828
+
829
+ /**
830
+ * @deprecated Multiple selection faked on top of a single selection.
831
+ * Use `selectedKeys` and `onSelectionChange` instead (see `MultipleSelectionExample`).
832
+ * Kept to guarantee the legacy usage keeps working.
833
+ */
834
+ export const LegacyMultipleSelectionExample: StoryObj<typeof Combobox> = {
542
835
  parameters: {
543
836
  ...meta.parameters,
544
837
  layout: "padded",
@@ -705,7 +998,7 @@ export const ShouldCloseTheDropdownWhenNoOptionMatches: StoryObj<
705
998
 
706
999
  Here are the notes available for the developer on the built Storybook, you can read them to understand the component and how to use it.
707
1000
 
708
- ```mdx
1001
+ ````mdx
709
1002
  import {
710
1003
  Meta,
711
1004
  Canvas,
@@ -778,16 +1071,78 @@ Interacting with link items navigates to the provided URL and does not update th
778
1071
 
779
1072
  ## Multiple selection
780
1073
 
781
- Here is an example of how to use the combobox with multiple selection.
782
- Please note that this is a temporary solution, the React Aria combobox does not support multiple selection yet.
783
- The implementation details may change in the future.
1074
+ Set `selectionMode="multiple"` and control the selection with `selectedKeys` (the selected ids) and `onSelectionChange` (called with all the selected ids).
784
1075
 
785
- Because the selection is owned by the consumer, the combobox cannot count the selected items itself.
1076
+ - The dropdown stays open after each selection, so the user can pick several items in a row.
1077
+ - The input is cleared after each selection, ready for the next search.
1078
+ - The selected items are checked in the dropdown: no need to pass `isSelected` on the items.
1079
+
1080
+ `selectedKeys` must always be an array: pass `[]` when nothing is selected (for example while a form value is not initialized yet).
1081
+ The combobox throws an error otherwise, or when `selectedKeys` is used without `selectionMode="multiple"`.
1082
+
1083
+ The combobox does not display the selection itself.
786
1084
  Use the `triggerContentRight` prop to display a `Badge` with the count inside the field, on the left of the dropdown trigger.
787
1085
  The element lays out in the flow, so the input shrinks to make room for it whatever its width, and it takes no room at all when the badge renders nothing.
788
1086
 
789
1087
  <Source of={ComboboxTests.MultipleSelectionExample} type="code" dark />
790
1088
 
1089
+ ### Typing a wrapper component
1090
+
1091
+ The props of the multiple selection are exported as `ComboboxMultipleProps`:
1092
+
1093
+ ```tsx
1094
+ import {
1095
+ Combobox,
1096
+ ComboboxMultipleProps,
1097
+ } from "@agregio-solutions/design-system";
1098
+
1099
+ type PerimetersComboboxProps = Omit<ComboboxMultipleProps, "label">;
1100
+
1101
+ const PerimetersCombobox = (props: PerimetersComboboxProps) => (
1102
+ <Combobox {...props} label="Perimeters" />
1103
+ );
1104
+ ```
1105
+
1106
+ `ComponentProps<typeof Combobox>` still returns the props of the single selection (with `value` and `onChange`), so the existing wrappers keep compiling unchanged.
1107
+
1108
+ ### Migrating from the deprecated multiple selection
1109
+
1110
+ Before React Aria supported multiple selection, it was faked on top of a single selection: `value=""` was forced, `onChange` received the clicked id and the consumer toggled it in its own list, then marked the items with `isSelected`.
1111
+
1112
+ This workaround is **deprecated**. It still works and compiles, but your editor strikes `<Combobox>` through when it is used this way.
1113
+ It will be removed in a future major version. To migrate:
1114
+
1115
+ - Replace `value=""` with `selectedKeys={selectedIds}`.
1116
+ - Replace the `onChange` toggling logic with `onSelectionChange={setSelectedIds}`.
1117
+ - Remove `isSelected` from the items.
1118
+
1119
+ ```tsx
1120
+ // Before (deprecated)
1121
+ <Combobox
1122
+ selectionMode="multiple"
1123
+ value=""
1124
+ onChange={(id) =>
1125
+ setSelectedIds(
1126
+ selectedIds.includes(id)
1127
+ ? selectedIds.filter((selectedId) => selectedId !== id)
1128
+ : [...selectedIds, id],
1129
+ )
1130
+ }
1131
+ defaultItems={items.map((item) => ({
1132
+ ...item,
1133
+ isSelected: selectedIds.includes(item.id),
1134
+ }))}
1135
+ />
1136
+
1137
+ // After
1138
+ <Combobox
1139
+ selectionMode="multiple"
1140
+ selectedKeys={selectedIds}
1141
+ onSelectionChange={setSelectedIds}
1142
+ defaultItems={items}
1143
+ />
1144
+ ```
1145
+
791
1146
  ## How to test this component?
792
1147
 
793
1148
  Here is a code snippet that you can use as an example to know how to test this component with react testing library:
@@ -801,4 +1156,4 @@ Here is a code snippet that you can use as an example to know how to test this c
801
1156
  <Controls of={Combobox.Playground} />
802
1157
 
803
1158
  <Stories />
804
- ```
1159
+ ````
@@ -20,4 +20,4 @@ export type Props = {
20
20
  */
21
21
  onDelete: () => void;
22
22
  };
23
- export default function FileDetails({ id, fileName, fileSize, isUploading, onDelete, }: Props): import("react").JSX.Element;
23
+ export default function FileDetails({ id, fileName, fileSize, isUploading, onDelete, }: Props): import('react').JSX.Element;
@@ -3,7 +3,7 @@ export declare const Root: import('styled-components/dist/types').IStyledCompone
3
3
  }> & string;
4
4
  export declare const FileIcon: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('../../../Icon/Icon').Props, "style"> & {
5
5
  style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars | undefined;
6
- }> & string & Omit<({ name, ...props }: import('../../../Icon/Icon').Props) => import("react").JSX.Element, keyof import('react').Component<any, {}, any>>;
6
+ }> & string & Omit<({ name, ...props }: import('../../../Icon/Icon').Props) => import('react').JSX.Element, keyof import('react').Component<any, {}, any>>;
7
7
  export declare const Informations: import('styled-components/dist/types').IStyledComponentBase<"web", Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "style"> & {
8
8
  style?: import('react').CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars | undefined;
9
9
  }> & string;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconAccessTime(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconAccessTime(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconAdd(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconAdd(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconAddBox(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconAddBox(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconArrowBack(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconArrowBack(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconArrowDownward(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconArrowDownward(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconArrowEnter(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconArrowEnter(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconArrowForward(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconArrowForward(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconArrowUpward(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconArrowUpward(props: IconBaseProps): import('react').JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { IconBaseProps } from '../Icon';
2
- export default function IconBackTime(props: IconBaseProps): import("react").JSX.Element;
2
+ export default function IconBackTime(props: IconBaseProps): import('react').JSX.Element;