@itwin/itwinui-react 3.0.4 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/cjs/core/Alert/Alert.js +46 -106
  3. package/cjs/core/Avatar/Avatar.js +21 -58
  4. package/cjs/core/AvatarGroup/AvatarGroup.js +26 -64
  5. package/cjs/core/Backdrop/Backdrop.js +8 -16
  6. package/cjs/core/Badge/Badge.js +22 -39
  7. package/cjs/core/Breadcrumbs/Breadcrumbs.js +61 -138
  8. package/cjs/core/ButtonGroup/ButtonGroup.js +32 -68
  9. package/cjs/core/Buttons/Button.js +11 -57
  10. package/cjs/core/Buttons/DropdownButton.js +15 -49
  11. package/cjs/core/Buttons/IconButton.js +13 -53
  12. package/cjs/core/Buttons/IdeasButton.js +8 -20
  13. package/cjs/core/Buttons/SplitButton.js +43 -103
  14. package/cjs/core/Carousel/Carousel.js +54 -78
  15. package/cjs/core/Carousel/CarouselContext.js +4 -4
  16. package/cjs/core/Carousel/CarouselDot.js +12 -23
  17. package/cjs/core/Carousel/CarouselDotsList.js +92 -153
  18. package/cjs/core/Carousel/CarouselNavigation.js +41 -84
  19. package/cjs/core/Carousel/CarouselSlide.js +26 -49
  20. package/cjs/core/Carousel/CarouselSlider.js +47 -66
  21. package/cjs/core/Checkbox/Checkbox.js +32 -88
  22. package/cjs/core/ColorPicker/ColorBuilder.js +174 -292
  23. package/cjs/core/ColorPicker/ColorInputPanel.js +246 -411
  24. package/cjs/core/ColorPicker/ColorPalette.js +23 -47
  25. package/cjs/core/ColorPicker/ColorPicker.js +53 -87
  26. package/cjs/core/ColorPicker/ColorPickerContext.js +9 -11
  27. package/cjs/core/ColorPicker/ColorSwatch.js +15 -40
  28. package/cjs/core/ComboBox/ComboBox.js +280 -402
  29. package/cjs/core/ComboBox/ComboBoxEndIcon.js +12 -28
  30. package/cjs/core/ComboBox/ComboBoxInput.js +131 -207
  31. package/cjs/core/ComboBox/ComboBoxInputContainer.js +12 -35
  32. package/cjs/core/ComboBox/ComboBoxMenu.js +43 -87
  33. package/cjs/core/ComboBox/ComboBoxMenuItem.js +21 -73
  34. package/cjs/core/ComboBox/ComboBoxMultipleContainer.js +7 -13
  35. package/cjs/core/ComboBox/helpers.js +43 -47
  36. package/cjs/core/DatePicker/DatePicker.js +333 -569
  37. package/cjs/core/Dialog/Dialog.js +36 -65
  38. package/cjs/core/Dialog/DialogBackdrop.js +27 -47
  39. package/cjs/core/Dialog/DialogButtonBar.js +3 -3
  40. package/cjs/core/Dialog/DialogContent.js +18 -26
  41. package/cjs/core/Dialog/DialogContext.js +5 -5
  42. package/cjs/core/Dialog/DialogDragContext.js +8 -8
  43. package/cjs/core/Dialog/DialogMain.js +137 -183
  44. package/cjs/core/Dialog/DialogTitleBar.js +20 -67
  45. package/cjs/core/Dialog/DialogTitleBarTitle.js +3 -3
  46. package/cjs/core/Divider/Divider.js +8 -14
  47. package/cjs/core/DropdownMenu/DropdownMenu.js +46 -80
  48. package/cjs/core/ExpandableBlock/ExpandableBlock.js +101 -206
  49. package/cjs/core/Fieldset/Fieldset.js +14 -25
  50. package/cjs/core/FileUpload/FileEmptyCard.js +17 -43
  51. package/cjs/core/FileUpload/FileUpload.js +42 -88
  52. package/cjs/core/FileUpload/FileUploadCard.js +84 -169
  53. package/cjs/core/FileUpload/FileUploadTemplate.js +16 -51
  54. package/cjs/core/Flex/Flex.js +77 -93
  55. package/cjs/core/Footer/Footer.js +64 -103
  56. package/cjs/core/Footer/FooterItem.js +3 -3
  57. package/cjs/core/Footer/FooterList.js +3 -3
  58. package/cjs/core/Footer/FooterSeparator.js +5 -8
  59. package/cjs/core/Header/Header.js +22 -67
  60. package/cjs/core/Header/HeaderBasicButton.js +13 -24
  61. package/cjs/core/Header/HeaderBreadcrumbs.js +14 -38
  62. package/cjs/core/Header/HeaderButton.js +22 -76
  63. package/cjs/core/Header/HeaderDropdownButton.js +20 -48
  64. package/cjs/core/Header/HeaderLogo.js +11 -42
  65. package/cjs/core/Header/HeaderSplitButton.js +21 -66
  66. package/cjs/core/Icon/Icon.js +18 -32
  67. package/cjs/core/InformationPanel/InformationPanel.js +42 -77
  68. package/cjs/core/InformationPanel/InformationPanelBody.js +4 -6
  69. package/cjs/core/InformationPanel/InformationPanelContent.js +8 -20
  70. package/cjs/core/InformationPanel/InformationPanelHeader.js +14 -34
  71. package/cjs/core/InformationPanel/InformationPanelWrapper.js +4 -6
  72. package/cjs/core/Input/Input.js +10 -18
  73. package/cjs/core/InputGrid/InputGrid.js +8 -17
  74. package/cjs/core/InputGroup/InputGroup.js +25 -72
  75. package/cjs/core/InputWithDecorations/InputWithDecorations.js +23 -51
  76. package/cjs/core/Label/Label.js +11 -32
  77. package/cjs/core/LabeledInput/LabeledInput.js +20 -70
  78. package/cjs/core/LabeledSelect/LabeledSelect.js +28 -77
  79. package/cjs/core/LabeledTextarea/LabeledTextarea.js +7 -13
  80. package/cjs/core/LinkAction/LinkAction.js +3 -3
  81. package/cjs/core/List/List.js +3 -3
  82. package/cjs/core/List/ListItem.js +35 -55
  83. package/cjs/core/Menu/Menu.js +53 -66
  84. package/cjs/core/Menu/MenuDivider.js +4 -4
  85. package/cjs/core/Menu/MenuExtraContent.js +4 -4
  86. package/cjs/core/Menu/MenuItem.js +92 -168
  87. package/cjs/core/Menu/MenuItemSkeleton.js +19 -54
  88. package/cjs/core/Modal/Modal.js +11 -38
  89. package/cjs/core/Modal/ModalButtonBar.js +4 -7
  90. package/cjs/core/Modal/ModalContent.js +3 -3
  91. package/cjs/core/NonIdealState/ErrorPage.js +131 -187
  92. package/cjs/core/NonIdealState/NonIdealState.js +12 -77
  93. package/cjs/core/NotificationMarker/NotificationMarker.js +8 -29
  94. package/cjs/core/Overlay/Overlay.d.ts +20 -24
  95. package/cjs/core/Overlay/Overlay.js +50 -64
  96. package/cjs/core/Popover/Popover.js +87 -157
  97. package/cjs/core/ProgressIndicators/ProgressLinear.js +11 -49
  98. package/cjs/core/ProgressIndicators/ProgressRadial.js +19 -51
  99. package/cjs/core/Radio/Radio.js +12 -54
  100. package/cjs/core/RadioTiles/RadioTile.js +14 -80
  101. package/cjs/core/RadioTiles/RadioTileGroup.js +9 -16
  102. package/cjs/core/SearchBox/SearchBox.js +104 -221
  103. package/cjs/core/Select/Select.js +141 -276
  104. package/cjs/core/Select/SelectTag.js +9 -21
  105. package/cjs/core/Select/SelectTagContainer.js +14 -30
  106. package/cjs/core/SideNavigation/SideNavigation.js +29 -138
  107. package/cjs/core/SideNavigation/SidenavButton.js +8 -30
  108. package/cjs/core/SideNavigation/SidenavSubmenu.js +9 -23
  109. package/cjs/core/SideNavigation/SidenavSubmenuHeader.js +10 -29
  110. package/cjs/core/SkipToContentLink/SkipToContentLink.js +8 -20
  111. package/cjs/core/Slider/Slider.js +195 -376
  112. package/cjs/core/Slider/Thumb.js +57 -108
  113. package/cjs/core/Slider/Track.js +55 -83
  114. package/cjs/core/StatusMessage/StatusMessage.js +12 -34
  115. package/cjs/core/Stepper/Stepper.js +21 -80
  116. package/cjs/core/Stepper/StepperStep.js +36 -109
  117. package/cjs/core/Stepper/WorkflowDiagram.js +15 -38
  118. package/cjs/core/Stepper/WorkflowDiagramStep.js +11 -39
  119. package/cjs/core/Surface/Surface.js +54 -94
  120. package/cjs/core/Table/SubRowExpander.js +15 -37
  121. package/cjs/core/Table/Table.js +419 -763
  122. package/cjs/core/Table/TableCell.js +63 -113
  123. package/cjs/core/Table/TablePaginator.js +136 -312
  124. package/cjs/core/Table/TableRowMemoized.js +64 -137
  125. package/cjs/core/Table/actionHandlers/expandHandler.js +12 -12
  126. package/cjs/core/Table/actionHandlers/filterHandler.js +17 -25
  127. package/cjs/core/Table/actionHandlers/index.js +14 -56
  128. package/cjs/core/Table/actionHandlers/resizeHandler.js +13 -13
  129. package/cjs/core/Table/actionHandlers/selectHandler.js +98 -128
  130. package/cjs/core/Table/cells/DefaultCell.js +13 -48
  131. package/cjs/core/Table/cells/EditableCell.js +46 -75
  132. package/cjs/core/Table/cells/index.js +6 -16
  133. package/cjs/core/Table/columns/actionColumn.js +67 -97
  134. package/cjs/core/Table/columns/expanderColumn.js +32 -46
  135. package/cjs/core/Table/columns/index.js +11 -41
  136. package/cjs/core/Table/columns/selectionColumn.js +29 -57
  137. package/cjs/core/Table/filters/BaseFilter.js +13 -24
  138. package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.js +52 -120
  139. package/cjs/core/Table/filters/DateRangeFilter/DateRangeFilter.js +60 -120
  140. package/cjs/core/Table/filters/FilterButtonBar.js +16 -39
  141. package/cjs/core/Table/filters/FilterToggle.js +26 -62
  142. package/cjs/core/Table/filters/NumberRangeFilter/NumberRangeFilter.js +36 -58
  143. package/cjs/core/Table/filters/TextFilter/TextFilter.js +28 -40
  144. package/cjs/core/Table/filters/customFilterFunctions.js +14 -16
  145. package/cjs/core/Table/filters/defaultFilterFunctions.js +81 -86
  146. package/cjs/core/Table/filters/index.js +11 -35
  147. package/cjs/core/Table/filters/tableFilters.js +32 -44
  148. package/cjs/core/Table/filters/types.js +2 -2
  149. package/cjs/core/Table/hooks/index.js +19 -67
  150. package/cjs/core/Table/hooks/useColumnDragAndDrop.js +86 -101
  151. package/cjs/core/Table/hooks/useExpanderCell.js +25 -33
  152. package/cjs/core/Table/hooks/useResizeColumns.js +290 -362
  153. package/cjs/core/Table/hooks/useScrollToRow.js +38 -46
  154. package/cjs/core/Table/hooks/useSelectionCell.js +10 -17
  155. package/cjs/core/Table/hooks/useStickyColumns.js +62 -64
  156. package/cjs/core/Table/hooks/useSubRowFiltering.js +88 -95
  157. package/cjs/core/Table/hooks/useSubRowSelection.js +31 -32
  158. package/cjs/core/Table/index.js +18 -78
  159. package/cjs/core/Table/utils.js +40 -42
  160. package/cjs/core/Tabs/Tabs.js +232 -417
  161. package/cjs/core/Tag/Tag.js +15 -42
  162. package/cjs/core/Tag/TagContainer.js +11 -23
  163. package/cjs/core/Textarea/Textarea.js +6 -11
  164. package/cjs/core/ThemeProvider/ThemeContext.js +4 -4
  165. package/cjs/core/ThemeProvider/ThemeProvider.js +52 -105
  166. package/cjs/core/Tile/Tile.js +230 -410
  167. package/cjs/core/TimePicker/TimePicker.js +234 -458
  168. package/cjs/core/Toast/Toast.js +107 -204
  169. package/cjs/core/Toast/Toaster.js +77 -102
  170. package/cjs/core/ToggleSwitch/ToggleSwitch.js +23 -66
  171. package/cjs/core/Tooltip/Tooltip.js +91 -137
  172. package/cjs/core/TransferList/TransferList.js +103 -177
  173. package/cjs/core/Tree/Tree.js +129 -204
  174. package/cjs/core/Tree/TreeContext.js +9 -9
  175. package/cjs/core/Tree/TreeNode.js +104 -207
  176. package/cjs/core/Tree/TreeNodeExpander.js +12 -26
  177. package/cjs/core/Typography/Anchor.js +3 -3
  178. package/cjs/core/Typography/Blockquote.js +10 -18
  179. package/cjs/core/Typography/Code.js +3 -3
  180. package/cjs/core/Typography/Kbd.js +21 -30
  181. package/cjs/core/Typography/Text.js +13 -26
  182. package/cjs/core/VisuallyHidden/VisuallyHidden.js +8 -14
  183. package/cjs/core/utils/color/ColorValue.js +453 -535
  184. package/cjs/core/utils/color/index.js +4 -4
  185. package/cjs/core/utils/components/AutoclearingHiddenLiveRegion.js +13 -20
  186. package/cjs/core/utils/components/Box.js +3 -3
  187. package/cjs/core/utils/components/ButtonBase.js +20 -38
  188. package/cjs/core/utils/components/FocusTrap.js +38 -47
  189. package/cjs/core/utils/components/InputContainer.js +19 -58
  190. package/cjs/core/utils/components/InputFlexContainer.js +8 -24
  191. package/cjs/core/utils/components/MiddleTextTruncation.js +22 -32
  192. package/cjs/core/utils/components/Portal.js +20 -22
  193. package/cjs/core/utils/components/Resizer.js +196 -253
  194. package/cjs/core/utils/components/VirtualScroll.js +223 -304
  195. package/cjs/core/utils/components/WithCSSTransition.js +32 -49
  196. package/cjs/core/utils/components/index.js +14 -14
  197. package/cjs/core/utils/functions/colors.js +22 -25
  198. package/cjs/core/utils/functions/date.js +10 -10
  199. package/cjs/core/utils/functions/dev.js +14 -13
  200. package/cjs/core/utils/functions/dom.d.ts +2 -1
  201. package/cjs/core/utils/functions/dom.js +22 -25
  202. package/cjs/core/utils/functions/focusable.js +17 -26
  203. package/cjs/core/utils/functions/import.js +23 -46
  204. package/cjs/core/utils/functions/index.js +13 -13
  205. package/cjs/core/utils/functions/numbers.d.ts +7 -0
  206. package/cjs/core/utils/functions/numbers.js +21 -10
  207. package/cjs/core/utils/functions/polymorphic.js +30 -43
  208. package/cjs/core/utils/functions/react.js +24 -26
  209. package/cjs/core/utils/functions/supports.js +4 -5
  210. package/cjs/core/utils/hooks/index.js +17 -17
  211. package/cjs/core/utils/hooks/useContainerWidth.js +19 -26
  212. package/cjs/core/utils/hooks/useControlledState.js +12 -21
  213. package/cjs/core/utils/hooks/useDragAndDrop.js +87 -110
  214. package/cjs/core/utils/hooks/useEventListener.js +22 -22
  215. package/cjs/core/utils/hooks/useGlobals.js +27 -33
  216. package/cjs/core/utils/hooks/useId.js +8 -10
  217. package/cjs/core/utils/hooks/useIntersection.js +24 -30
  218. package/cjs/core/utils/hooks/useIsClient.js +9 -9
  219. package/cjs/core/utils/hooks/useIsomorphicLayoutEffect.js +5 -6
  220. package/cjs/core/utils/hooks/useLatestRef.js +9 -9
  221. package/cjs/core/utils/hooks/useMediaQuery.js +31 -31
  222. package/cjs/core/utils/hooks/useMergedRefs.js +16 -15
  223. package/cjs/core/utils/hooks/useOverflow.js +57 -70
  224. package/cjs/core/utils/hooks/useResizeObserver.js +17 -22
  225. package/cjs/core/utils/hooks/useSafeContext.js +9 -9
  226. package/cjs/core/utils/icons/StatusIconMap.js +12 -28
  227. package/cjs/core/utils/icons/Svg.js +3 -3
  228. package/cjs/core/utils/icons/SvgCalendar.js +7 -12
  229. package/cjs/core/utils/icons/SvgCaretDownSmall.js +7 -12
  230. package/cjs/core/utils/icons/SvgCaretRightSmall.js +7 -12
  231. package/cjs/core/utils/icons/SvgCaretUpSmall.js +7 -12
  232. package/cjs/core/utils/icons/SvgCheckmark.js +7 -10
  233. package/cjs/core/utils/icons/SvgCheckmarkSmall.js +7 -12
  234. package/cjs/core/utils/icons/SvgChevronLeft.js +7 -12
  235. package/cjs/core/utils/icons/SvgChevronLeftDouble.js +7 -12
  236. package/cjs/core/utils/icons/SvgChevronRight.js +7 -12
  237. package/cjs/core/utils/icons/SvgChevronRightDouble.js +7 -12
  238. package/cjs/core/utils/icons/SvgClose.js +7 -12
  239. package/cjs/core/utils/icons/SvgCloseSmall.js +7 -12
  240. package/cjs/core/utils/icons/SvgColumnManager.js +7 -12
  241. package/cjs/core/utils/icons/SvgDocument.js +7 -10
  242. package/cjs/core/utils/icons/SvgFilter.js +7 -10
  243. package/cjs/core/utils/icons/SvgFilterHollow.js +7 -12
  244. package/cjs/core/utils/icons/SvgImportantSmall.js +7 -12
  245. package/cjs/core/utils/icons/SvgInfoCircular.js +7 -12
  246. package/cjs/core/utils/icons/SvgMore.js +7 -12
  247. package/cjs/core/utils/icons/SvgMoreVertical.js +7 -12
  248. package/cjs/core/utils/icons/SvgNew.js +7 -12
  249. package/cjs/core/utils/icons/SvgSearch.js +7 -12
  250. package/cjs/core/utils/icons/SvgSmileyHappy.js +7 -12
  251. package/cjs/core/utils/icons/SvgSortDown.js +7 -12
  252. package/cjs/core/utils/icons/SvgSortUp.js +7 -12
  253. package/cjs/core/utils/icons/SvgStatusError.js +7 -12
  254. package/cjs/core/utils/icons/SvgStatusSuccess.js +7 -12
  255. package/cjs/core/utils/icons/SvgStatusWarning.js +7 -12
  256. package/cjs/core/utils/icons/SvgSwap.js +7 -12
  257. package/cjs/core/utils/icons/SvgUpload.js +7 -12
  258. package/cjs/core/utils/icons/index.js +34 -34
  259. package/cjs/core/utils/index.js +10 -10
  260. package/cjs/core/utils/props.js +2 -2
  261. package/cjs/core/utils/types.js +2 -2
  262. package/cjs/index.js +229 -949
  263. package/cjs/react-table/react-table.js +2 -2
  264. package/cjs/styles.js +412 -425
  265. package/esm/core/Alert/Alert.js +39 -106
  266. package/esm/core/Avatar/Avatar.js +14 -42
  267. package/esm/core/AvatarGroup/AvatarGroup.js +20 -58
  268. package/esm/core/Backdrop/Backdrop.js +2 -10
  269. package/esm/core/Badge/Badge.js +16 -31
  270. package/esm/core/Breadcrumbs/Breadcrumbs.js +55 -135
  271. package/esm/core/ButtonGroup/ButtonGroup.js +25 -61
  272. package/esm/core/Buttons/Button.js +5 -45
  273. package/esm/core/Buttons/DropdownButton.js +7 -37
  274. package/esm/core/Buttons/IconButton.js +5 -40
  275. package/esm/core/Buttons/IdeasButton.js +2 -12
  276. package/esm/core/Buttons/SplitButton.js +34 -101
  277. package/esm/core/Carousel/Carousel.js +43 -72
  278. package/esm/core/Carousel/CarouselDot.js +6 -17
  279. package/esm/core/Carousel/CarouselDotsList.js +85 -147
  280. package/esm/core/Carousel/CarouselNavigation.js +32 -68
  281. package/esm/core/Carousel/CarouselSlide.js +19 -41
  282. package/esm/core/Carousel/CarouselSlider.js +41 -65
  283. package/esm/core/Checkbox/Checkbox.js +25 -78
  284. package/esm/core/ColorPicker/ColorBuilder.js +167 -280
  285. package/esm/core/ColorPicker/ColorInputPanel.js +237 -395
  286. package/esm/core/ColorPicker/ColorPalette.js +14 -35
  287. package/esm/core/ColorPicker/ColorPicker.js +46 -79
  288. package/esm/core/ColorPicker/ColorPickerContext.js +5 -7
  289. package/esm/core/ColorPicker/ColorSwatch.js +7 -24
  290. package/esm/core/ComboBox/ComboBox.js +267 -396
  291. package/esm/core/ComboBox/ComboBoxEndIcon.js +5 -18
  292. package/esm/core/ComboBox/ComboBoxInput.js +125 -197
  293. package/esm/core/ComboBox/ComboBoxInputContainer.js +5 -20
  294. package/esm/core/ComboBox/ComboBoxMenu.js +37 -77
  295. package/esm/core/ComboBox/ComboBoxMenuItem.js +14 -61
  296. package/esm/core/ComboBox/ComboBoxMultipleContainer.js +2 -6
  297. package/esm/core/ComboBox/helpers.js +38 -38
  298. package/esm/core/DatePicker/DatePicker.js +326 -555
  299. package/esm/core/Dialog/Dialog.js +24 -53
  300. package/esm/core/Dialog/DialogBackdrop.js +19 -39
  301. package/esm/core/Dialog/DialogContent.js +12 -20
  302. package/esm/core/Dialog/DialogContext.js +1 -1
  303. package/esm/core/Dialog/DialogDragContext.js +4 -4
  304. package/esm/core/Dialog/DialogMain.js +128 -177
  305. package/esm/core/Dialog/DialogTitleBar.js +10 -45
  306. package/esm/core/Divider/Divider.js +2 -8
  307. package/esm/core/DropdownMenu/DropdownMenu.js +40 -75
  308. package/esm/core/ExpandableBlock/ExpandableBlock.js +92 -193
  309. package/esm/core/Fieldset/Fieldset.js +8 -19
  310. package/esm/core/FileUpload/FileEmptyCard.js +8 -19
  311. package/esm/core/FileUpload/FileUpload.js +36 -72
  312. package/esm/core/FileUpload/FileUploadCard.js +76 -153
  313. package/esm/core/FileUpload/FileUploadTemplate.js +9 -37
  314. package/esm/core/Flex/Flex.js +71 -87
  315. package/esm/core/Footer/Footer.js +55 -86
  316. package/esm/core/Footer/FooterSeparator.js +1 -1
  317. package/esm/core/Header/Header.js +14 -55
  318. package/esm/core/Header/HeaderBasicButton.js +7 -15
  319. package/esm/core/Header/HeaderBreadcrumbs.js +8 -32
  320. package/esm/core/Header/HeaderButton.js +14 -62
  321. package/esm/core/Header/HeaderDropdownButton.js +13 -42
  322. package/esm/core/Header/HeaderLogo.js +5 -36
  323. package/esm/core/Header/HeaderSplitButton.js +14 -61
  324. package/esm/core/Icon/Icon.js +12 -26
  325. package/esm/core/InformationPanel/InformationPanel.js +36 -71
  326. package/esm/core/InformationPanel/InformationPanelContent.js +3 -17
  327. package/esm/core/InformationPanel/InformationPanelHeader.js +8 -32
  328. package/esm/core/InformationPanel/InformationPanelWrapper.js +1 -3
  329. package/esm/core/Input/Input.js +4 -12
  330. package/esm/core/InputGrid/InputGrid.js +2 -11
  331. package/esm/core/InputGroup/InputGroup.js +16 -57
  332. package/esm/core/InputWithDecorations/InputWithDecorations.js +11 -42
  333. package/esm/core/Label/Label.js +5 -26
  334. package/esm/core/LabeledInput/LabeledInput.js +10 -63
  335. package/esm/core/LabeledSelect/LabeledSelect.js +18 -67
  336. package/esm/core/LabeledTextarea/LabeledTextarea.js +2 -8
  337. package/esm/core/List/ListItem.js +28 -46
  338. package/esm/core/Menu/Menu.js +48 -64
  339. package/esm/core/Menu/MenuDivider.js +1 -1
  340. package/esm/core/Menu/MenuExtraContent.js +1 -1
  341. package/esm/core/Menu/MenuItem.js +84 -164
  342. package/esm/core/Menu/MenuItemSkeleton.js +12 -43
  343. package/esm/core/Modal/Modal.js +6 -33
  344. package/esm/core/NonIdealState/ErrorPage.js +123 -173
  345. package/esm/core/NonIdealState/NonIdealState.js +6 -65
  346. package/esm/core/NotificationMarker/NotificationMarker.js +2 -20
  347. package/esm/core/Overlay/Overlay.d.ts +20 -24
  348. package/esm/core/Overlay/Overlay.js +45 -55
  349. package/esm/core/Popover/Popover.js +80 -172
  350. package/esm/core/ProgressIndicators/ProgressLinear.js +5 -40
  351. package/esm/core/ProgressIndicators/ProgressRadial.js +14 -40
  352. package/esm/core/Radio/Radio.js +6 -45
  353. package/esm/core/RadioTiles/RadioTile.js +8 -62
  354. package/esm/core/RadioTiles/RadioTileGroup.js +3 -10
  355. package/esm/core/SearchBox/SearchBox.js +97 -214
  356. package/esm/core/Select/Select.js +130 -265
  357. package/esm/core/Select/SelectTag.js +3 -15
  358. package/esm/core/Select/SelectTagContainer.js +7 -20
  359. package/esm/core/SideNavigation/SideNavigation.js +21 -118
  360. package/esm/core/SideNavigation/SidenavButton.js +2 -24
  361. package/esm/core/SideNavigation/SidenavSubmenu.js +3 -14
  362. package/esm/core/SideNavigation/SidenavSubmenuHeader.js +4 -20
  363. package/esm/core/SkipToContentLink/SkipToContentLink.js +2 -11
  364. package/esm/core/Slider/Slider.js +187 -340
  365. package/esm/core/Slider/Thumb.js +50 -97
  366. package/esm/core/Slider/Track.js +49 -74
  367. package/esm/core/StatusMessage/StatusMessage.js +5 -23
  368. package/esm/core/Stepper/Stepper.js +14 -70
  369. package/esm/core/Stepper/StepperStep.js +29 -92
  370. package/esm/core/Stepper/WorkflowDiagram.js +8 -21
  371. package/esm/core/Stepper/WorkflowDiagramStep.js +4 -22
  372. package/esm/core/Surface/Surface.js +48 -84
  373. package/esm/core/Table/SubRowExpander.js +9 -31
  374. package/esm/core/Table/Table.js +408 -763
  375. package/esm/core/Table/TableCell.js +53 -87
  376. package/esm/core/Table/TablePaginator.js +125 -306
  377. package/esm/core/Table/TableRowMemoized.js +58 -129
  378. package/esm/core/Table/actionHandlers/expandHandler.js +10 -10
  379. package/esm/core/Table/actionHandlers/filterHandler.js +15 -23
  380. package/esm/core/Table/actionHandlers/index.js +1 -5
  381. package/esm/core/Table/actionHandlers/resizeHandler.js +11 -11
  382. package/esm/core/Table/actionHandlers/selectHandler.js +95 -122
  383. package/esm/core/Table/cells/DefaultCell.js +7 -42
  384. package/esm/core/Table/cells/EditableCell.js +41 -70
  385. package/esm/core/Table/columns/actionColumn.js +55 -85
  386. package/esm/core/Table/columns/expanderColumn.js +25 -39
  387. package/esm/core/Table/columns/selectionColumn.js +23 -51
  388. package/esm/core/Table/filters/BaseFilter.js +7 -15
  389. package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.js +42 -107
  390. package/esm/core/Table/filters/DateRangeFilter/DateRangeFilter.js +52 -110
  391. package/esm/core/Table/filters/FilterButtonBar.js +9 -28
  392. package/esm/core/Table/filters/FilterToggle.js +18 -51
  393. package/esm/core/Table/filters/NumberRangeFilter/NumberRangeFilter.js +28 -50
  394. package/esm/core/Table/filters/TextFilter/TextFilter.js +20 -32
  395. package/esm/core/Table/filters/customFilterFunctions.js +12 -14
  396. package/esm/core/Table/filters/defaultFilterFunctions.js +79 -84
  397. package/esm/core/Table/filters/tableFilters.js +25 -34
  398. package/esm/core/Table/hooks/useColumnDragAndDrop.js +81 -88
  399. package/esm/core/Table/hooks/useExpanderCell.js +20 -26
  400. package/esm/core/Table/hooks/useResizeColumns.js +287 -353
  401. package/esm/core/Table/hooks/useScrollToRow.js +34 -42
  402. package/esm/core/Table/hooks/useSelectionCell.js +6 -10
  403. package/esm/core/Table/hooks/useStickyColumns.js +59 -61
  404. package/esm/core/Table/hooks/useSubRowFiltering.js +83 -90
  405. package/esm/core/Table/hooks/useSubRowSelection.js +27 -28
  406. package/esm/core/Table/index.js +1 -5
  407. package/esm/core/Table/utils.js +38 -40
  408. package/esm/core/Tabs/Tabs.js +226 -401
  409. package/esm/core/Tag/Tag.js +8 -35
  410. package/esm/core/Tag/TagContainer.js +5 -17
  411. package/esm/core/Textarea/Textarea.js +1 -6
  412. package/esm/core/ThemeProvider/ThemeProvider.js +44 -101
  413. package/esm/core/Tile/Tile.js +218 -386
  414. package/esm/core/TimePicker/TimePicker.js +228 -448
  415. package/esm/core/Toast/Toast.js +99 -193
  416. package/esm/core/Toast/Toaster.js +69 -82
  417. package/esm/core/ToggleSwitch/ToggleSwitch.js +17 -60
  418. package/esm/core/Tooltip/Tooltip.js +86 -151
  419. package/esm/core/TransferList/TransferList.js +93 -157
  420. package/esm/core/Tree/Tree.js +122 -196
  421. package/esm/core/Tree/TreeContext.js +5 -5
  422. package/esm/core/Tree/TreeNode.js +96 -195
  423. package/esm/core/Tree/TreeNodeExpander.js +5 -16
  424. package/esm/core/Typography/Blockquote.js +4 -12
  425. package/esm/core/Typography/Kbd.js +15 -24
  426. package/esm/core/Typography/Text.js +7 -20
  427. package/esm/core/VisuallyHidden/VisuallyHidden.js +2 -8
  428. package/esm/core/utils/color/ColorValue.js +449 -524
  429. package/esm/core/utils/components/AutoclearingHiddenLiveRegion.js +7 -11
  430. package/esm/core/utils/components/ButtonBase.js +13 -31
  431. package/esm/core/utils/components/FocusTrap.js +32 -41
  432. package/esm/core/utils/components/InputContainer.js +11 -50
  433. package/esm/core/utils/components/InputFlexContainer.js +2 -15
  434. package/esm/core/utils/components/MiddleTextTruncation.js +17 -27
  435. package/esm/core/utils/components/Portal.js +12 -12
  436. package/esm/core/utils/components/Resizer.js +192 -250
  437. package/esm/core/utils/components/VirtualScroll.js +218 -297
  438. package/esm/core/utils/components/WithCSSTransition.js +26 -43
  439. package/esm/core/utils/functions/colors.js +19 -19
  440. package/esm/core/utils/functions/date.js +8 -8
  441. package/esm/core/utils/functions/dev.js +12 -11
  442. package/esm/core/utils/functions/dom.d.ts +2 -1
  443. package/esm/core/utils/functions/dom.js +18 -18
  444. package/esm/core/utils/functions/focusable.js +15 -24
  445. package/esm/core/utils/functions/import.js +2 -4
  446. package/esm/core/utils/functions/numbers.d.ts +7 -0
  447. package/esm/core/utils/functions/numbers.js +17 -7
  448. package/esm/core/utils/functions/polymorphic.js +23 -32
  449. package/esm/core/utils/functions/react.js +19 -21
  450. package/esm/core/utils/functions/supports.js +1 -2
  451. package/esm/core/utils/hooks/useContainerWidth.js +13 -16
  452. package/esm/core/utils/hooks/useControlledState.js +8 -17
  453. package/esm/core/utils/hooks/useDragAndDrop.js +81 -100
  454. package/esm/core/utils/hooks/useEventListener.js +18 -18
  455. package/esm/core/utils/hooks/useGlobals.js +21 -27
  456. package/esm/core/utils/hooks/useId.js +3 -4
  457. package/esm/core/utils/hooks/useIntersection.js +19 -25
  458. package/esm/core/utils/hooks/useIsClient.js +5 -5
  459. package/esm/core/utils/hooks/useIsomorphicLayoutEffect.js +1 -2
  460. package/esm/core/utils/hooks/useLatestRef.js +5 -5
  461. package/esm/core/utils/hooks/useMediaQuery.js +25 -23
  462. package/esm/core/utils/hooks/useMergedRefs.js +12 -11
  463. package/esm/core/utils/hooks/useOverflow.js +51 -63
  464. package/esm/core/utils/hooks/useResizeObserver.js +12 -17
  465. package/esm/core/utils/hooks/useSafeContext.js +5 -5
  466. package/esm/core/utils/icons/StatusIconMap.js +4 -8
  467. package/esm/core/utils/icons/SvgCalendar.js +2 -7
  468. package/esm/core/utils/icons/SvgCaretDownSmall.js +2 -7
  469. package/esm/core/utils/icons/SvgCaretRightSmall.js +2 -7
  470. package/esm/core/utils/icons/SvgCaretUpSmall.js +2 -7
  471. package/esm/core/utils/icons/SvgCheckmark.js +2 -5
  472. package/esm/core/utils/icons/SvgCheckmarkSmall.js +2 -7
  473. package/esm/core/utils/icons/SvgChevronLeft.js +2 -7
  474. package/esm/core/utils/icons/SvgChevronLeftDouble.js +2 -7
  475. package/esm/core/utils/icons/SvgChevronRight.js +2 -7
  476. package/esm/core/utils/icons/SvgChevronRightDouble.js +2 -7
  477. package/esm/core/utils/icons/SvgClose.js +2 -7
  478. package/esm/core/utils/icons/SvgCloseSmall.js +2 -7
  479. package/esm/core/utils/icons/SvgColumnManager.js +2 -7
  480. package/esm/core/utils/icons/SvgDocument.js +2 -5
  481. package/esm/core/utils/icons/SvgFilter.js +2 -5
  482. package/esm/core/utils/icons/SvgFilterHollow.js +2 -7
  483. package/esm/core/utils/icons/SvgImportantSmall.js +2 -7
  484. package/esm/core/utils/icons/SvgInfoCircular.js +2 -7
  485. package/esm/core/utils/icons/SvgMore.js +2 -7
  486. package/esm/core/utils/icons/SvgMoreVertical.js +2 -7
  487. package/esm/core/utils/icons/SvgNew.js +2 -7
  488. package/esm/core/utils/icons/SvgSearch.js +2 -7
  489. package/esm/core/utils/icons/SvgSmileyHappy.js +2 -7
  490. package/esm/core/utils/icons/SvgSortDown.js +2 -7
  491. package/esm/core/utils/icons/SvgSortUp.js +2 -7
  492. package/esm/core/utils/icons/SvgStatusError.js +2 -7
  493. package/esm/core/utils/icons/SvgStatusSuccess.js +2 -7
  494. package/esm/core/utils/icons/SvgStatusWarning.js +2 -7
  495. package/esm/core/utils/icons/SvgSwap.js +2 -7
  496. package/esm/core/utils/icons/SvgUpload.js +2 -7
  497. package/esm/index.js +3 -21
  498. package/esm/styles.js +414 -425
  499. package/package.json +2 -2
  500. package/styles.css +6 -6
@@ -6,20 +6,9 @@ import * as React from 'react';
6
6
  import { MenuExtraContent } from '../Menu/MenuExtraContent.js';
7
7
  import { SelectTag } from '../Select/SelectTag.js';
8
8
  import { Text } from '../Typography/Text.js';
9
- import {
10
- getRandomValue,
11
- mergeRefs,
12
- useLatestRef,
13
- useIsomorphicLayoutEffect,
14
- AutoclearingHiddenLiveRegion,
15
- } from '../utils/index.js';
9
+ import { getRandomValue, mergeRefs, useLatestRef, useIsomorphicLayoutEffect, AutoclearingHiddenLiveRegion, } from '../utils/index.js';
16
10
  import { usePopover } from '../Popover/Popover.js';
17
- import {
18
- ComboBoxActionContext,
19
- comboBoxReducer,
20
- ComboBoxRefsContext,
21
- ComboBoxStateContext,
22
- } from './helpers.js';
11
+ import { ComboBoxActionContext, comboBoxReducer, ComboBoxRefsContext, ComboBoxStateContext, } from './helpers.js';
23
12
  import { ComboBoxEndIcon } from './ComboBoxEndIcon.js';
24
13
  import { ComboBoxInput } from './ComboBoxInput.js';
25
14
  import { ComboBoxInputContainer } from './ComboBoxInputContainer.js';
@@ -27,15 +16,15 @@ import { ComboBoxMenu } from './ComboBoxMenu.js';
27
16
  import { ComboBoxMenuItem } from './ComboBoxMenuItem.js';
28
17
  // Type guard for enabling multiple
29
18
  const isMultipleEnabled = (variable, multiple) => {
30
- return multiple && (Array.isArray(variable) || variable === undefined);
19
+ return multiple && (Array.isArray(variable) || variable === undefined);
31
20
  };
32
21
  // Type guard for user onChange
33
22
  const isSingleOnChange = (onChange, multiple) => {
34
- return !multiple;
23
+ return !multiple;
35
24
  };
36
25
  /** Returns either `option.id` or derives a stable id using `idPrefix` and `option.label` (without whitespace) */
37
26
  const getOptionId = (option, idPrefix) => {
38
- return option.id ?? `${idPrefix}-option-${option.label.replace(/\s/g, '-')}`;
27
+ return option.id ?? `${idPrefix}-option-${option.label.replace(/\s/g, '-')}`;
39
28
  };
40
29
  /**
41
30
  * ComboBox component that allows typing a value to filter the options in dropdown list.
@@ -51,272 +40,221 @@ const getOptionId = (option, idPrefix) => {
51
40
  * />
52
41
  */
53
42
  export const ComboBox = (props) => {
54
- const {
55
- options,
56
- value: valueProp,
57
- onChange,
58
- filterFunction,
59
- inputProps,
60
- endIconProps,
61
- dropdownMenuProps,
62
- emptyStateMessage = 'No options found',
63
- itemRenderer,
64
- enableVirtualization = false,
65
- multiple = false,
66
- onShow: onShowProp,
67
- onHide: onHideProp,
68
- ...rest
69
- } = props;
70
- // Generate a stateful random id if not specified
71
- const [id] = React.useState(
72
- () =>
73
- props.id ??
74
- (inputProps?.id && `${inputProps.id}-cb`) ??
75
- `iui-cb-${getRandomValue(10)}`,
76
- );
77
- // Refs get set in subcomponents
78
- const inputRef = React.useRef(null);
79
- const menuRef = React.useRef(null);
80
- const onChangeProp = useLatestRef(onChange);
81
- const optionsRef = useLatestRef(options);
82
- // Record to store all extra information (e.g. original indexes), where the key is the id of the option
83
- const optionsExtraInfoRef = React.useRef({});
84
- // Clear the extra info when the options change so that it can be reinitialized below
85
- React.useEffect(() => {
86
- optionsExtraInfoRef.current = {};
87
- }, [options]);
88
- // Initialize the extra info only if it is not already initialized
89
- if (
90
- options.length > 0 &&
91
- Object.keys(optionsExtraInfoRef.current).length === 0
92
- ) {
93
- options.forEach((option, index) => {
94
- optionsExtraInfoRef.current[getOptionId(option, id)] = {
95
- __originalIndex: index,
96
- };
43
+ const { options, value: valueProp, onChange, filterFunction, inputProps, endIconProps, dropdownMenuProps, emptyStateMessage = 'No options found', itemRenderer, enableVirtualization = false, multiple = false, onShow: onShowProp, onHide: onHideProp, ...rest } = props;
44
+ // Generate a stateful random id if not specified
45
+ const [id] = React.useState(() => props.id ??
46
+ (inputProps?.id && `${inputProps.id}-cb`) ??
47
+ `iui-cb-${getRandomValue(10)}`);
48
+ // Refs get set in subcomponents
49
+ const inputRef = React.useRef(null);
50
+ const menuRef = React.useRef(null);
51
+ const onChangeProp = useLatestRef(onChange);
52
+ const optionsRef = useLatestRef(options);
53
+ // Record to store all extra information (e.g. original indexes), where the key is the id of the option
54
+ const optionsExtraInfoRef = React.useRef({});
55
+ // Clear the extra info when the options change so that it can be reinitialized below
56
+ React.useEffect(() => {
57
+ optionsExtraInfoRef.current = {};
58
+ }, [options]);
59
+ // Initialize the extra info only if it is not already initialized
60
+ if (options.length > 0 &&
61
+ Object.keys(optionsExtraInfoRef.current).length === 0) {
62
+ options.forEach((option, index) => {
63
+ optionsExtraInfoRef.current[getOptionId(option, id)] = {
64
+ __originalIndex: index,
65
+ };
66
+ });
67
+ }
68
+ // Get indices of selected elements in options array when we have selected values.
69
+ const getSelectedIndexes = React.useCallback(() => {
70
+ if (isMultipleEnabled(valueProp, multiple)) {
71
+ const indexArray = [];
72
+ valueProp?.forEach((value) => {
73
+ const indexToAdd = options.findIndex((option) => option.value === value);
74
+ if (indexToAdd > -1) {
75
+ indexArray.push(indexToAdd);
76
+ }
77
+ });
78
+ return indexArray;
79
+ }
80
+ else {
81
+ return options.findIndex((option) => option.value === valueProp);
82
+ }
83
+ }, [multiple, options, valueProp]);
84
+ // Reducer where all the component-wide state is stored
85
+ const [{ isOpen, selected, focusedIndex }, dispatch] = React.useReducer(comboBoxReducer, {
86
+ isOpen: false,
87
+ selected: getSelectedIndexes(),
88
+ focusedIndex: -1,
97
89
  });
98
- }
99
- // Get indices of selected elements in options array when we have selected values.
100
- const getSelectedIndexes = React.useCallback(() => {
101
- if (isMultipleEnabled(valueProp, multiple)) {
102
- const indexArray = [];
103
- valueProp?.forEach((value) => {
104
- const indexToAdd = options.findIndex(
105
- (option) => option.value === value,
106
- );
107
- if (indexToAdd > -1) {
108
- indexArray.push(indexToAdd);
90
+ const onShowRef = useLatestRef(onShowProp);
91
+ const onHideRef = useLatestRef(onHideProp);
92
+ const show = React.useCallback(() => {
93
+ dispatch({ type: 'open' });
94
+ onShowRef.current?.();
95
+ }, [onShowRef]);
96
+ const hide = React.useCallback(() => {
97
+ dispatch({ type: 'close' });
98
+ onHideRef.current?.();
99
+ }, [onHideRef]);
100
+ useIsomorphicLayoutEffect(() => {
101
+ // When the dropdown opens
102
+ if (isOpen) {
103
+ inputRef.current?.focus(); // Focus the input
104
+ // Reset the filtered list (does not reset when multiple enabled)
105
+ if (!multiple) {
106
+ setFilteredOptions(optionsRef.current);
107
+ dispatch({ type: 'focus', value: undefined });
108
+ }
109
+ }
110
+ // When the dropdown closes
111
+ else {
112
+ // Reset the focused index
113
+ dispatch({ type: 'focus', value: undefined });
114
+ // Reset the input value if not multiple
115
+ if (!isMultipleEnabled(selected, multiple)) {
116
+ setInputValue(selected != undefined && selected >= 0
117
+ ? optionsRef.current[selected]?.label
118
+ : '');
119
+ }
120
+ }
121
+ }, [isOpen, multiple, optionsRef, selected]);
122
+ // Update filtered options to the latest value options according to input value
123
+ const [filteredOptions, setFilteredOptions] = React.useState(options);
124
+ React.useEffect(() => {
125
+ if (inputValue) {
126
+ setFilteredOptions(filterFunction?.(options, inputValue) ??
127
+ options.filter((option) => option.label.toLowerCase().includes(inputValue.toLowerCase())));
128
+ }
129
+ else {
130
+ setFilteredOptions(options);
109
131
  }
110
- });
111
- return indexArray;
112
- } else {
113
- return options.findIndex((option) => option.value === valueProp);
114
- }
115
- }, [multiple, options, valueProp]);
116
- // Reducer where all the component-wide state is stored
117
- const [{ isOpen, selected, focusedIndex }, dispatch] = React.useReducer(
118
- comboBoxReducer,
119
- {
120
- isOpen: false,
121
- selected: getSelectedIndexes(),
122
- focusedIndex: -1,
123
- },
124
- );
125
- const onShowRef = useLatestRef(onShowProp);
126
- const onHideRef = useLatestRef(onHideProp);
127
- const show = React.useCallback(() => {
128
- dispatch({ type: 'open' });
129
- onShowRef.current?.();
130
- }, [onShowRef]);
131
- const hide = React.useCallback(() => {
132
- dispatch({ type: 'close' });
133
- onHideRef.current?.();
134
- }, [onHideRef]);
135
- useIsomorphicLayoutEffect(() => {
136
- // When the dropdown opens
137
- if (isOpen) {
138
- inputRef.current?.focus(); // Focus the input
139
- // Reset the filtered list (does not reset when multiple enabled)
140
- if (!multiple) {
141
- setFilteredOptions(optionsRef.current);
142
132
  dispatch({ type: 'focus', value: undefined });
143
- }
144
- }
145
- // When the dropdown closes
146
- else {
147
- // Reset the focused index
148
- dispatch({ type: 'focus', value: undefined });
149
- // Reset the input value if not multiple
150
- if (!isMultipleEnabled(selected, multiple)) {
151
- setInputValue(
152
- selected != undefined && selected >= 0
153
- ? optionsRef.current[selected]?.label
154
- : '',
155
- );
156
- }
157
- }
158
- }, [isOpen, multiple, optionsRef, selected]);
159
- // Update filtered options to the latest value options according to input value
160
- const [filteredOptions, setFilteredOptions] = React.useState(options);
161
- React.useEffect(() => {
162
- if (inputValue) {
163
- setFilteredOptions(
164
- filterFunction?.(options, inputValue) ??
165
- options.filter((option) =>
166
- option.label.toLowerCase().includes(inputValue.toLowerCase()),
167
- ),
168
- );
169
- } else {
170
- setFilteredOptions(options);
171
- }
172
- dispatch({ type: 'focus', value: undefined });
173
- // Only need to call on options update
174
- // eslint-disable-next-line react-hooks/exhaustive-deps
175
- }, [options]);
176
- // Filter options based on input value
177
- const [inputValue, setInputValue] = React.useState(
178
- inputProps?.value?.toString() ?? '',
179
- );
180
- const [liveRegionSelection, setLiveRegionSelection] = React.useState('');
181
- const handleOnInput = React.useCallback(
182
- (event) => {
183
- const { value } = event.currentTarget;
184
- setInputValue(value);
185
- show(); // reopen when typing
186
- setFilteredOptions(
187
- filterFunction?.(optionsRef.current, value) ??
188
- optionsRef.current.filter((option) =>
189
- option.label.toLowerCase().includes(value.toLowerCase()),
190
- ),
191
- );
192
- if (focusedIndex != -1) {
193
- dispatch({ type: 'focus', value: -1 });
194
- }
195
- inputProps?.onChange?.(event);
196
- },
197
- [filterFunction, focusedIndex, inputProps, optionsRef, show],
198
- );
199
- // When the value prop changes, update the selected index/indices
200
- React.useEffect(() => {
201
- if (isMultipleEnabled(valueProp, multiple)) {
202
- if (valueProp) {
203
- // If user provided array of selected values
204
- const indexes = valueProp.map((value) => {
205
- return options.findIndex((option) => option.value === value);
206
- });
207
- dispatch({
208
- type: 'multiselect',
209
- value: indexes.filter((index) => index !== -1), // Add available options
210
- });
211
- } else {
212
- // if user provided one value or undefined
213
- dispatch({
214
- type: 'multiselect',
215
- value: [], // Add empty list
216
- });
217
- }
218
- } else {
219
- dispatch({
220
- type: 'select',
221
- value: options.findIndex((option) => option.value === valueProp),
222
- });
223
- }
224
- }, [valueProp, options, multiple]);
225
- const isMenuItemSelected = React.useCallback(
226
- (index) => {
227
- if (isMultipleEnabled(selected, multiple)) {
228
- return !!selected.includes(index);
229
- } else {
230
- return selected === index;
231
- }
232
- },
233
- [multiple, selected],
234
- );
235
- // Generates new array when item is added or removed
236
- const selectedChangeHandler = React.useCallback(
237
- (__originalIndex, action) => {
238
- if (action === 'added') {
239
- return [...selected, __originalIndex];
240
- } else {
241
- return selected.filter((index) => index !== __originalIndex);
242
- }
243
- },
244
- [selected],
245
- );
246
- // Calls user defined onChange
247
- const onChangeHandler = React.useCallback(
248
- (__originalIndex, actionType, newArray) => {
249
- if (isSingleOnChange(onChangeProp.current, multiple)) {
250
- onChangeProp.current?.(optionsRef.current[__originalIndex]?.value);
251
- } else {
252
- actionType &&
253
- newArray &&
254
- onChangeProp.current?.(
255
- newArray?.map((item) => optionsRef.current[item]?.value),
256
- {
257
- value: optionsRef.current[__originalIndex]?.value,
258
- type: actionType,
259
- },
260
- );
261
- }
262
- },
263
- [multiple, onChangeProp, optionsRef],
264
- );
265
- const onClickHandler = React.useCallback(
266
- (__originalIndex) => {
267
- inputRef.current?.focus({ preventScroll: true }); // return focus to input
268
- if (optionsRef.current[__originalIndex]?.disabled) {
269
- return;
270
- }
271
- if (isMultipleEnabled(selected, multiple)) {
272
- const actionType = isMenuItemSelected(__originalIndex)
273
- ? 'removed'
274
- : 'added';
275
- const newArray = selectedChangeHandler(__originalIndex, actionType);
276
- dispatch({ type: 'multiselect', value: newArray });
277
- onChangeHandler(__originalIndex, actionType, newArray);
278
- // update live region
279
- setLiveRegionSelection(
280
- newArray
281
- .map((item) => optionsRef.current[item]?.label)
282
- .filter(Boolean)
283
- .join(', '),
284
- );
285
- } else {
286
- dispatch({ type: 'select', value: __originalIndex });
287
- hide();
288
- onChangeHandler(__originalIndex);
289
- }
290
- },
291
- [
292
- selectedChangeHandler,
293
- isMenuItemSelected,
294
- multiple,
295
- onChangeHandler,
296
- selected,
297
- optionsRef,
298
- hide,
299
- ],
300
- );
301
- const getMenuItem = React.useCallback(
302
- (option, filteredIndex) => {
303
- const optionId = getOptionId(option, id);
304
- const { __originalIndex } = optionsExtraInfoRef.current[optionId];
305
- const { icon, startIcon: startIconProp, ...restOptions } = option;
306
- const startIcon = startIconProp ?? icon;
307
- const customItem = itemRenderer
308
- ? itemRenderer(option, {
309
- isFocused: focusedIndex === __originalIndex,
310
- isSelected: selected === __originalIndex,
311
- index: __originalIndex,
312
- id: optionId,
313
- })
314
- : null;
315
- return customItem
316
- ? React.cloneElement(customItem, {
133
+ // Only need to call on options update
134
+ // eslint-disable-next-line react-hooks/exhaustive-deps
135
+ }, [options]);
136
+ // Filter options based on input value
137
+ const [inputValue, setInputValue] = React.useState(inputProps?.value?.toString() ?? '');
138
+ const [liveRegionSelection, setLiveRegionSelection] = React.useState('');
139
+ const handleOnInput = React.useCallback((event) => {
140
+ const { value } = event.currentTarget;
141
+ setInputValue(value);
142
+ show(); // reopen when typing
143
+ setFilteredOptions(filterFunction?.(optionsRef.current, value) ??
144
+ optionsRef.current.filter((option) => option.label.toLowerCase().includes(value.toLowerCase())));
145
+ if (focusedIndex != -1) {
146
+ dispatch({ type: 'focus', value: -1 });
147
+ }
148
+ inputProps?.onChange?.(event);
149
+ }, [filterFunction, focusedIndex, inputProps, optionsRef, show]);
150
+ // When the value prop changes, update the selected index/indices
151
+ React.useEffect(() => {
152
+ if (isMultipleEnabled(valueProp, multiple)) {
153
+ if (valueProp) {
154
+ // If user provided array of selected values
155
+ const indexes = valueProp.map((value) => {
156
+ return options.findIndex((option) => option.value === value);
157
+ });
158
+ dispatch({
159
+ type: 'multiselect',
160
+ value: indexes.filter((index) => index !== -1), // Add available options
161
+ });
162
+ }
163
+ else {
164
+ // if user provided one value or undefined
165
+ dispatch({
166
+ type: 'multiselect',
167
+ value: [], // Add empty list
168
+ });
169
+ }
170
+ }
171
+ else {
172
+ dispatch({
173
+ type: 'select',
174
+ value: options.findIndex((option) => option.value === valueProp),
175
+ });
176
+ }
177
+ }, [valueProp, options, multiple]);
178
+ const isMenuItemSelected = React.useCallback((index) => {
179
+ if (isMultipleEnabled(selected, multiple)) {
180
+ return !!selected.includes(index);
181
+ }
182
+ else {
183
+ return selected === index;
184
+ }
185
+ }, [multiple, selected]);
186
+ // Generates new array when item is added or removed
187
+ const selectedChangeHandler = React.useCallback((__originalIndex, action) => {
188
+ if (action === 'added') {
189
+ return [...selected, __originalIndex];
190
+ }
191
+ else {
192
+ return selected.filter((index) => index !== __originalIndex);
193
+ }
194
+ }, [selected]);
195
+ // Calls user defined onChange
196
+ const onChangeHandler = React.useCallback((__originalIndex, actionType, newArray) => {
197
+ if (isSingleOnChange(onChangeProp.current, multiple)) {
198
+ onChangeProp.current?.(optionsRef.current[__originalIndex]?.value);
199
+ }
200
+ else {
201
+ actionType &&
202
+ newArray &&
203
+ onChangeProp.current?.(newArray?.map((item) => optionsRef.current[item]?.value), {
204
+ value: optionsRef.current[__originalIndex]?.value,
205
+ type: actionType,
206
+ });
207
+ }
208
+ }, [multiple, onChangeProp, optionsRef]);
209
+ const onClickHandler = React.useCallback((__originalIndex) => {
210
+ inputRef.current?.focus({ preventScroll: true }); // return focus to input
211
+ if (optionsRef.current[__originalIndex]?.disabled) {
212
+ return;
213
+ }
214
+ if (isMultipleEnabled(selected, multiple)) {
215
+ const actionType = isMenuItemSelected(__originalIndex)
216
+ ? 'removed'
217
+ : 'added';
218
+ const newArray = selectedChangeHandler(__originalIndex, actionType);
219
+ dispatch({ type: 'multiselect', value: newArray });
220
+ onChangeHandler(__originalIndex, actionType, newArray);
221
+ // update live region
222
+ setLiveRegionSelection(newArray
223
+ .map((item) => optionsRef.current[item]?.label)
224
+ .filter(Boolean)
225
+ .join(', '));
226
+ }
227
+ else {
228
+ dispatch({ type: 'select', value: __originalIndex });
229
+ hide();
230
+ onChangeHandler(__originalIndex);
231
+ }
232
+ }, [
233
+ selectedChangeHandler,
234
+ isMenuItemSelected,
235
+ multiple,
236
+ onChangeHandler,
237
+ selected,
238
+ optionsRef,
239
+ hide,
240
+ ]);
241
+ const getMenuItem = React.useCallback((option, filteredIndex) => {
242
+ const optionId = getOptionId(option, id);
243
+ const { __originalIndex } = optionsExtraInfoRef.current[optionId];
244
+ const { icon, startIcon: startIconProp, ...restOptions } = option;
245
+ const startIcon = startIconProp ?? icon;
246
+ const customItem = itemRenderer
247
+ ? itemRenderer(option, {
248
+ isFocused: focusedIndex === __originalIndex,
249
+ isSelected: selected === __originalIndex,
250
+ index: __originalIndex,
251
+ id: optionId,
252
+ })
253
+ : null;
254
+ return customItem ? (React.cloneElement(customItem, {
317
255
  onClick: (e) => {
318
- onClickHandler(__originalIndex);
319
- customItem.props.onClick?.(e);
256
+ onClickHandler(__originalIndex);
257
+ customItem.props.onClick?.(e);
320
258
  },
321
259
  // ComboBox.MenuItem handles scrollIntoView, data-iui-index and focused through context
322
260
  // but we still need to pass them here for backwards compatibility with MenuItem
@@ -324,125 +262,58 @@ export const ComboBox = (props) => {
324
262
  'data-iui-index': __originalIndex,
325
263
  'data-iui-filtered-index': filteredIndex,
326
264
  ref: mergeRefs(customItem.props.ref, (el) => {
327
- if (!enableVirtualization && focusedIndex === __originalIndex) {
328
- el?.scrollIntoView({ block: 'nearest' });
329
- }
265
+ if (!enableVirtualization && focusedIndex === __originalIndex) {
266
+ el?.scrollIntoView({ block: 'nearest' });
267
+ }
330
268
  }),
331
- })
332
- : React.createElement(
333
- ComboBoxMenuItem,
334
- {
335
- key: optionId,
336
- id: optionId,
337
- startIcon: startIcon,
338
- ...restOptions,
339
- isSelected: isMenuItemSelected(__originalIndex),
340
- onClick: () => {
269
+ })) : (React.createElement(ComboBoxMenuItem, { key: optionId, id: optionId, startIcon: startIcon, ...restOptions, isSelected: isMenuItemSelected(__originalIndex), onClick: () => {
341
270
  onClickHandler(__originalIndex);
342
- },
343
- index: __originalIndex,
344
- 'data-iui-filtered-index': filteredIndex,
345
- },
346
- option.label,
347
- );
348
- },
349
- [
350
- enableVirtualization,
351
- focusedIndex,
352
- id,
353
- isMenuItemSelected,
354
- itemRenderer,
355
- onClickHandler,
356
- selected,
357
- ],
358
- );
359
- const emptyContent = React.useMemo(
360
- () =>
361
- React.createElement(
362
- React.Fragment,
363
- null,
364
- React.isValidElement(emptyStateMessage)
365
- ? emptyStateMessage
366
- : React.createElement(
367
- MenuExtraContent,
368
- null,
369
- React.createElement(Text, { isMuted: true }, emptyStateMessage),
370
- ),
371
- ),
372
- [emptyStateMessage],
373
- );
374
- const popover = usePopover({
375
- visible: isOpen,
376
- onVisibleChange: (open) => (open ? show() : hide()),
377
- matchWidth: true,
378
- closeOnOutsideClick: true,
379
- trigger: { focus: true },
380
- });
381
- return React.createElement(
382
- ComboBoxRefsContext.Provider,
383
- { value: { inputRef, menuRef, optionsExtraInfoRef } },
384
- React.createElement(
385
- ComboBoxActionContext.Provider,
386
- { value: dispatch },
387
- React.createElement(
388
- ComboBoxStateContext.Provider,
389
- {
390
- value: {
391
- id,
392
- isOpen,
393
- focusedIndex,
394
- onClickHandler,
395
- enableVirtualization,
396
- filteredOptions,
397
- getMenuItem,
398
- multiple,
399
- popover,
400
- show,
401
- hide,
402
- },
403
- },
404
- React.createElement(
405
- ComboBoxInputContainer,
406
- { disabled: inputProps?.disabled, ...rest },
407
- React.createElement(
408
- React.Fragment,
409
- null,
410
- React.createElement(ComboBoxInput, {
411
- value: inputValue,
412
- disabled: inputProps?.disabled,
413
- ...inputProps,
414
- onChange: handleOnInput,
415
- selectTags: isMultipleEnabled(selected, multiple)
416
- ? selected.map((index) => {
417
- const item = optionsRef.current[index];
418
- return React.createElement(SelectTag, {
419
- key: item.label,
420
- label: item.label,
421
- });
422
- })
423
- : undefined,
424
- }),
425
- ),
426
- React.createElement(ComboBoxEndIcon, {
427
- ...endIconProps,
428
- disabled: inputProps?.disabled,
429
- isOpen: isOpen,
430
- }),
431
- multiple
432
- ? React.createElement(AutoclearingHiddenLiveRegion, {
433
- text: liveRegionSelection,
434
- })
435
- : null,
436
- ),
437
- React.createElement(
438
- ComboBoxMenu,
439
- { as: 'div', ...dropdownMenuProps },
440
- filteredOptions.length > 0 && !enableVirtualization
441
- ? filteredOptions.map(getMenuItem)
442
- : emptyContent,
443
- ),
444
- ),
445
- ),
446
- );
271
+ }, index: __originalIndex, "data-iui-filtered-index": filteredIndex }, option.label));
272
+ }, [
273
+ enableVirtualization,
274
+ focusedIndex,
275
+ id,
276
+ isMenuItemSelected,
277
+ itemRenderer,
278
+ onClickHandler,
279
+ selected,
280
+ ]);
281
+ const emptyContent = React.useMemo(() => (React.createElement(React.Fragment, null, React.isValidElement(emptyStateMessage) ? (emptyStateMessage) : (React.createElement(MenuExtraContent, null,
282
+ React.createElement(Text, { isMuted: true }, emptyStateMessage))))), [emptyStateMessage]);
283
+ const popover = usePopover({
284
+ visible: isOpen,
285
+ onVisibleChange: (open) => (open ? show() : hide()),
286
+ matchWidth: true,
287
+ closeOnOutsideClick: true,
288
+ trigger: { focus: true },
289
+ });
290
+ return (React.createElement(ComboBoxRefsContext.Provider, { value: { inputRef, menuRef, optionsExtraInfoRef } },
291
+ React.createElement(ComboBoxActionContext.Provider, { value: dispatch },
292
+ React.createElement(ComboBoxStateContext.Provider, { value: {
293
+ id,
294
+ isOpen,
295
+ focusedIndex,
296
+ onClickHandler,
297
+ enableVirtualization,
298
+ filteredOptions,
299
+ getMenuItem,
300
+ multiple,
301
+ popover,
302
+ show,
303
+ hide,
304
+ } },
305
+ React.createElement(ComboBoxInputContainer, { disabled: inputProps?.disabled, ...rest },
306
+ React.createElement(React.Fragment, null,
307
+ React.createElement(ComboBoxInput, { value: inputValue, disabled: inputProps?.disabled, ...inputProps, onChange: handleOnInput, selectTags: isMultipleEnabled(selected, multiple)
308
+ ? selected.map((index) => {
309
+ const item = optionsRef.current[index];
310
+ return (React.createElement(SelectTag, { key: item.label, label: item.label }));
311
+ })
312
+ : undefined })),
313
+ React.createElement(ComboBoxEndIcon, { ...endIconProps, disabled: inputProps?.disabled, isOpen: isOpen }),
314
+ multiple ? (React.createElement(AutoclearingHiddenLiveRegion, { text: liveRegionSelection })) : null),
315
+ React.createElement(ComboBoxMenu, { as: 'div', ...dropdownMenuProps }, filteredOptions.length > 0 && !enableVirtualization
316
+ ? filteredOptions.map(getMenuItem)
317
+ : emptyContent)))));
447
318
  };
448
319
  export default ComboBox;