@itwin/itwinui-react 3.0.0-dev.6 → 3.0.0-dev.8

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 (283) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/cjs/core/Alert/Alert.d.ts +20 -9
  3. package/cjs/core/Alert/Alert.js +48 -10
  4. package/cjs/core/Avatar/Avatar.d.ts +3 -2
  5. package/cjs/core/Avatar/Avatar.js +21 -19
  6. package/cjs/core/AvatarGroup/AvatarGroup.js +3 -8
  7. package/cjs/core/ButtonGroup/ButtonGroup.js +41 -36
  8. package/cjs/core/Buttons/Button/Button.d.ts +15 -2
  9. package/cjs/core/Buttons/Button/Button.js +23 -9
  10. package/cjs/core/Buttons/DropdownButton/DropdownButton.js +1 -1
  11. package/cjs/core/Buttons/IconButton/IconButton.d.ts +5 -1
  12. package/cjs/core/Buttons/IconButton/IconButton.js +27 -38
  13. package/cjs/core/Buttons/SplitButton/SplitButton.d.ts +9 -0
  14. package/cjs/core/Buttons/SplitButton/SplitButton.js +25 -13
  15. package/cjs/core/Carousel/Carousel.d.ts +6 -4
  16. package/cjs/core/Carousel/Carousel.js +2 -2
  17. package/cjs/core/Carousel/CarouselDot.js +1 -3
  18. package/cjs/core/Carousel/CarouselNavigation.d.ts +6 -4
  19. package/cjs/core/ColorPicker/ColorBuilder.js +2 -1
  20. package/cjs/core/ColorPicker/ColorInputPanel.js +172 -231
  21. package/cjs/core/ComboBox/ComboBox.js +3 -3
  22. package/cjs/core/ComboBox/ComboBoxDropdown.js +4 -9
  23. package/cjs/core/ComboBox/ComboBoxEndIcon.js +3 -22
  24. package/cjs/core/ComboBox/ComboBoxInput.js +1 -1
  25. package/cjs/core/ComboBox/ComboBoxMenu.d.ts +2 -2
  26. package/cjs/core/ComboBox/ComboBoxMenu.js +5 -5
  27. package/cjs/core/ComboBox/ComboBoxMenuItem.d.ts +1 -1
  28. package/cjs/core/ComboBox/ComboBoxMenuItem.js +8 -6
  29. package/cjs/core/ComboBox/helpers.d.ts +1 -2
  30. package/cjs/core/DatePicker/DatePicker.d.ts +30 -8
  31. package/cjs/core/DatePicker/DatePicker.js +47 -6
  32. package/cjs/core/Dialog/Dialog.js +10 -17
  33. package/cjs/core/Dialog/DialogContext.d.ts +3 -4
  34. package/cjs/core/Dialog/DialogMain.js +5 -5
  35. package/cjs/core/ExpandableBlock/ExpandableBlock.d.ts +20 -14
  36. package/cjs/core/ExpandableBlock/ExpandableBlock.js +39 -18
  37. package/cjs/core/FileUpload/FileUpload.d.ts +4 -0
  38. package/cjs/core/FileUpload/FileUpload.js +24 -3
  39. package/cjs/core/Header/HeaderBasicButton.js +3 -16
  40. package/cjs/core/Header/HeaderDropdownButton.js +1 -1
  41. package/cjs/core/Header/HeaderSplitButton.js +3 -4
  42. package/cjs/core/Input/Input.d.ts +4 -0
  43. package/cjs/core/Input/Input.js +2 -1
  44. package/cjs/core/InputGrid/InputGrid.d.ts +25 -0
  45. package/cjs/core/InputGrid/InputGrid.js +39 -0
  46. package/cjs/core/InputGrid/index.d.ts +3 -0
  47. package/cjs/core/InputGrid/index.js +15 -0
  48. package/cjs/core/InputGroup/InputGroup.d.ts +13 -0
  49. package/cjs/core/InputGroup/InputGroup.js +35 -9
  50. package/cjs/core/InputWithDecorations/InputWithDecorations.d.ts +39 -0
  51. package/cjs/core/InputWithDecorations/InputWithDecorations.js +81 -0
  52. package/cjs/core/InputWithDecorations/index.d.ts +3 -0
  53. package/cjs/core/InputWithDecorations/index.js +15 -0
  54. package/cjs/core/Label/Label.d.ts +5 -0
  55. package/cjs/core/Label/Label.js +2 -0
  56. package/cjs/core/LabeledInput/LabeledInput.d.ts +22 -16
  57. package/cjs/core/LabeledInput/LabeledInput.js +52 -29
  58. package/cjs/core/LabeledSelect/LabeledSelect.d.ts +17 -7
  59. package/cjs/core/LabeledSelect/LabeledSelect.js +36 -17
  60. package/cjs/core/LabeledTextarea/LabeledTextarea.d.ts +15 -5
  61. package/cjs/core/LabeledTextarea/LabeledTextarea.js +12 -45
  62. package/cjs/core/Menu/Menu.d.ts +1 -1
  63. package/cjs/core/Menu/Menu.js +1 -1
  64. package/cjs/core/Menu/MenuDivider.d.ts +2 -1
  65. package/cjs/core/Menu/MenuDivider.js +1 -1
  66. package/cjs/core/Menu/MenuItem.d.ts +1 -1
  67. package/cjs/core/Menu/MenuItem.js +1 -0
  68. package/cjs/core/Menu/MenuItemSkeleton.d.ts +1 -1
  69. package/cjs/core/Menu/MenuItemSkeleton.js +0 -1
  70. package/cjs/core/ProgressIndicators/ProgressLinear.d.ts +4 -0
  71. package/cjs/core/ProgressIndicators/ProgressLinear.js +9 -1
  72. package/cjs/core/SearchBox/SearchBox.js +1 -1
  73. package/cjs/core/Select/Select.d.ts +4 -0
  74. package/cjs/core/Select/Select.js +12 -11
  75. package/cjs/core/SideNavigation/SideNavigation.d.ts +16 -0
  76. package/cjs/core/SideNavigation/SideNavigation.js +42 -9
  77. package/cjs/core/Slider/Slider.d.ts +24 -0
  78. package/cjs/core/Slider/Slider.js +58 -10
  79. package/cjs/core/Slider/Thumb.js +3 -2
  80. package/cjs/core/Slider/Track.d.ts +1 -1
  81. package/cjs/core/Slider/Track.js +17 -6
  82. package/cjs/core/StatusMessage/StatusMessage.d.ts +12 -2
  83. package/cjs/core/StatusMessage/StatusMessage.js +23 -9
  84. package/cjs/core/Stepper/Stepper.d.ts +26 -1
  85. package/cjs/core/Stepper/Stepper.js +35 -6
  86. package/cjs/core/Stepper/StepperStep.d.ts +17 -0
  87. package/cjs/core/Stepper/StepperStep.js +33 -8
  88. package/cjs/core/Stepper/WorkflowDiagram.d.ts +11 -1
  89. package/cjs/core/Stepper/WorkflowDiagram.js +23 -10
  90. package/cjs/core/Stepper/WorkflowDiagramStep.d.ts +6 -1
  91. package/cjs/core/Stepper/WorkflowDiagramStep.js +9 -2
  92. package/cjs/core/Table/SubRowExpander.js +3 -1
  93. package/cjs/core/Table/Table.js +0 -1
  94. package/cjs/core/Table/TableCell.js +1 -1
  95. package/cjs/core/Table/TablePaginator.js +1 -3
  96. package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.d.ts +6 -1
  97. package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.js +46 -18
  98. package/cjs/core/Table/filters/DateRangeFilter/DateRangeFilter.d.ts +2 -0
  99. package/cjs/core/Table/filters/DateRangeFilter/DateRangeFilter.js +2 -0
  100. package/cjs/core/Tabs/Tab.js +1 -2
  101. package/cjs/core/Textarea/Textarea.d.ts +7 -1
  102. package/cjs/core/Textarea/Textarea.js +6 -11
  103. package/cjs/core/ThemeProvider/ThemeContext.d.ts +1 -1
  104. package/cjs/core/ThemeProvider/ThemeProvider.d.ts +23 -3
  105. package/cjs/core/ThemeProvider/ThemeProvider.js +56 -23
  106. package/cjs/core/Tile/Tile.d.ts +142 -17
  107. package/cjs/core/Tile/Tile.js +107 -16
  108. package/cjs/core/Toast/Toast.d.ts +12 -4
  109. package/cjs/core/Toast/Toast.js +24 -13
  110. package/cjs/core/Tooltip/Tooltip.d.ts +35 -28
  111. package/cjs/core/Tooltip/Tooltip.js +116 -118
  112. package/cjs/core/TransferList/TransferList.js +4 -12
  113. package/cjs/core/Tree/TreeNode.js +1 -1
  114. package/cjs/core/index.d.ts +2 -0
  115. package/cjs/core/index.js +20 -4
  116. package/cjs/core/utils/components/ButtonBase.d.ts +14 -0
  117. package/cjs/core/utils/components/ButtonBase.js +46 -0
  118. package/cjs/core/utils/components/Icon.d.ts +5 -0
  119. package/cjs/core/utils/components/Icon.js +8 -1
  120. package/cjs/core/utils/components/InputContainer.d.ts +0 -1
  121. package/cjs/core/utils/components/InputContainer.js +14 -34
  122. package/cjs/core/utils/components/InputFlexContainer.d.ts +1 -0
  123. package/cjs/core/utils/components/InputFlexContainer.js +3 -1
  124. package/cjs/core/utils/components/Popover.js +5 -3
  125. package/cjs/core/utils/components/Portal.d.ts +27 -0
  126. package/cjs/core/utils/components/Portal.js +43 -0
  127. package/cjs/core/utils/components/VirtualScroll.js +4 -4
  128. package/cjs/core/utils/components/index.d.ts +2 -0
  129. package/cjs/core/utils/components/index.js +2 -0
  130. package/cjs/core/utils/functions/colors.d.ts +1 -1
  131. package/cjs/core/utils/functions/colors.js +1 -13
  132. package/cjs/core/utils/functions/index.d.ts +1 -0
  133. package/cjs/core/utils/functions/index.js +1 -0
  134. package/cjs/core/utils/functions/react.d.ts +8 -0
  135. package/cjs/core/utils/functions/react.js +40 -0
  136. package/cjs/core/utils/hooks/index.d.ts +1 -0
  137. package/cjs/core/utils/hooks/index.js +1 -0
  138. package/cjs/core/utils/hooks/useControlledState.d.ts +13 -0
  139. package/cjs/core/utils/hooks/useControlledState.js +39 -0
  140. package/cjs/core/utils/hooks/useGlobals.d.ts +1 -1
  141. package/cjs/styles.js +11 -35
  142. package/esm/core/Alert/Alert.d.ts +20 -9
  143. package/esm/core/Alert/Alert.js +49 -10
  144. package/esm/core/Avatar/Avatar.d.ts +3 -2
  145. package/esm/core/Avatar/Avatar.js +21 -17
  146. package/esm/core/AvatarGroup/AvatarGroup.js +3 -8
  147. package/esm/core/ButtonGroup/ButtonGroup.js +41 -36
  148. package/esm/core/Buttons/Button/Button.d.ts +15 -2
  149. package/esm/core/Buttons/Button/Button.js +18 -10
  150. package/esm/core/Buttons/DropdownButton/DropdownButton.js +1 -1
  151. package/esm/core/Buttons/IconButton/IconButton.d.ts +5 -1
  152. package/esm/core/Buttons/IconButton/IconButton.js +25 -37
  153. package/esm/core/Buttons/SplitButton/SplitButton.d.ts +9 -0
  154. package/esm/core/Buttons/SplitButton/SplitButton.js +31 -14
  155. package/esm/core/Carousel/Carousel.d.ts +6 -4
  156. package/esm/core/Carousel/Carousel.js +8 -3
  157. package/esm/core/Carousel/CarouselDot.js +2 -4
  158. package/esm/core/Carousel/CarouselNavigation.d.ts +6 -4
  159. package/esm/core/ColorPicker/ColorBuilder.js +2 -1
  160. package/esm/core/ColorPicker/ColorInputPanel.js +173 -232
  161. package/esm/core/ComboBox/ComboBox.js +3 -3
  162. package/esm/core/ComboBox/ComboBoxDropdown.js +4 -9
  163. package/esm/core/ComboBox/ComboBoxEndIcon.js +4 -25
  164. package/esm/core/ComboBox/ComboBoxInput.js +1 -1
  165. package/esm/core/ComboBox/ComboBoxMenu.d.ts +2 -2
  166. package/esm/core/ComboBox/ComboBoxMenu.js +5 -5
  167. package/esm/core/ComboBox/ComboBoxMenuItem.d.ts +1 -1
  168. package/esm/core/ComboBox/ComboBoxMenuItem.js +9 -7
  169. package/esm/core/ComboBox/helpers.d.ts +1 -2
  170. package/esm/core/DatePicker/DatePicker.d.ts +30 -8
  171. package/esm/core/DatePicker/DatePicker.js +33 -6
  172. package/esm/core/Dialog/Dialog.js +11 -23
  173. package/esm/core/Dialog/DialogContext.d.ts +3 -4
  174. package/esm/core/Dialog/DialogMain.js +5 -5
  175. package/esm/core/ExpandableBlock/ExpandableBlock.d.ts +20 -14
  176. package/esm/core/ExpandableBlock/ExpandableBlock.js +41 -20
  177. package/esm/core/FileUpload/FileUpload.d.ts +4 -0
  178. package/esm/core/FileUpload/FileUpload.js +26 -3
  179. package/esm/core/Header/HeaderBasicButton.js +4 -17
  180. package/esm/core/Header/HeaderDropdownButton.js +1 -1
  181. package/esm/core/Header/HeaderSplitButton.js +9 -5
  182. package/esm/core/Input/Input.d.ts +4 -0
  183. package/esm/core/Input/Input.js +2 -1
  184. package/esm/core/InputGrid/InputGrid.d.ts +25 -0
  185. package/esm/core/InputGrid/InputGrid.js +35 -0
  186. package/esm/core/InputGrid/index.d.ts +3 -0
  187. package/esm/core/InputGrid/index.js +6 -0
  188. package/esm/core/InputGroup/InputGroup.d.ts +13 -0
  189. package/esm/core/InputGroup/InputGroup.js +34 -10
  190. package/esm/core/InputWithDecorations/InputWithDecorations.d.ts +39 -0
  191. package/esm/core/InputWithDecorations/InputWithDecorations.js +80 -0
  192. package/esm/core/InputWithDecorations/index.d.ts +3 -0
  193. package/esm/core/InputWithDecorations/index.js +6 -0
  194. package/esm/core/Label/Label.d.ts +5 -0
  195. package/esm/core/Label/Label.js +2 -0
  196. package/esm/core/LabeledInput/LabeledInput.d.ts +22 -16
  197. package/esm/core/LabeledInput/LabeledInput.js +53 -29
  198. package/esm/core/LabeledSelect/LabeledSelect.d.ts +17 -7
  199. package/esm/core/LabeledSelect/LabeledSelect.js +37 -18
  200. package/esm/core/LabeledTextarea/LabeledTextarea.d.ts +15 -5
  201. package/esm/core/LabeledTextarea/LabeledTextarea.js +14 -45
  202. package/esm/core/Menu/Menu.d.ts +1 -1
  203. package/esm/core/Menu/Menu.js +1 -1
  204. package/esm/core/Menu/MenuDivider.d.ts +2 -1
  205. package/esm/core/Menu/MenuDivider.js +1 -1
  206. package/esm/core/Menu/MenuItem.d.ts +1 -1
  207. package/esm/core/Menu/MenuItem.js +1 -0
  208. package/esm/core/Menu/MenuItemSkeleton.d.ts +1 -1
  209. package/esm/core/Menu/MenuItemSkeleton.js +0 -1
  210. package/esm/core/ProgressIndicators/ProgressLinear.d.ts +4 -0
  211. package/esm/core/ProgressIndicators/ProgressLinear.js +9 -1
  212. package/esm/core/SearchBox/SearchBox.js +1 -1
  213. package/esm/core/Select/Select.d.ts +4 -0
  214. package/esm/core/Select/Select.js +12 -11
  215. package/esm/core/SideNavigation/SideNavigation.d.ts +16 -0
  216. package/esm/core/SideNavigation/SideNavigation.js +33 -9
  217. package/esm/core/Slider/Slider.d.ts +24 -0
  218. package/esm/core/Slider/Slider.js +43 -10
  219. package/esm/core/Slider/Thumb.js +3 -2
  220. package/esm/core/Slider/Track.d.ts +1 -1
  221. package/esm/core/Slider/Track.js +14 -6
  222. package/esm/core/StatusMessage/StatusMessage.d.ts +12 -2
  223. package/esm/core/StatusMessage/StatusMessage.js +23 -16
  224. package/esm/core/Stepper/Stepper.d.ts +26 -1
  225. package/esm/core/Stepper/Stepper.js +32 -6
  226. package/esm/core/Stepper/StepperStep.d.ts +17 -0
  227. package/esm/core/Stepper/StepperStep.js +27 -8
  228. package/esm/core/Stepper/WorkflowDiagram.d.ts +11 -1
  229. package/esm/core/Stepper/WorkflowDiagram.js +10 -7
  230. package/esm/core/Stepper/WorkflowDiagramStep.d.ts +6 -1
  231. package/esm/core/Stepper/WorkflowDiagramStep.js +6 -2
  232. package/esm/core/Table/SubRowExpander.js +3 -1
  233. package/esm/core/Table/Table.js +0 -1
  234. package/esm/core/Table/TableCell.js +1 -1
  235. package/esm/core/Table/TablePaginator.js +2 -3
  236. package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.d.ts +6 -1
  237. package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.js +45 -17
  238. package/esm/core/Table/filters/DateRangeFilter/DateRangeFilter.d.ts +2 -0
  239. package/esm/core/Table/filters/DateRangeFilter/DateRangeFilter.js +2 -0
  240. package/esm/core/Tabs/Tab.js +2 -3
  241. package/esm/core/Textarea/Textarea.d.ts +7 -1
  242. package/esm/core/Textarea/Textarea.js +6 -11
  243. package/esm/core/ThemeProvider/ThemeContext.d.ts +1 -1
  244. package/esm/core/ThemeProvider/ThemeProvider.d.ts +23 -3
  245. package/esm/core/ThemeProvider/ThemeProvider.js +65 -24
  246. package/esm/core/Tile/Tile.d.ts +142 -17
  247. package/esm/core/Tile/Tile.js +107 -16
  248. package/esm/core/Toast/Toast.d.ts +12 -4
  249. package/esm/core/Toast/Toast.js +26 -13
  250. package/esm/core/Tooltip/Tooltip.d.ts +35 -28
  251. package/esm/core/Tooltip/Tooltip.js +119 -116
  252. package/esm/core/TransferList/TransferList.js +4 -9
  253. package/esm/core/Tree/TreeNode.js +1 -1
  254. package/esm/core/index.d.ts +2 -0
  255. package/esm/core/index.js +2 -0
  256. package/esm/core/utils/components/ButtonBase.d.ts +14 -0
  257. package/esm/core/utils/components/ButtonBase.js +42 -0
  258. package/esm/core/utils/components/Icon.d.ts +5 -0
  259. package/esm/core/utils/components/Icon.js +8 -1
  260. package/esm/core/utils/components/InputContainer.d.ts +0 -1
  261. package/esm/core/utils/components/InputContainer.js +14 -30
  262. package/esm/core/utils/components/InputFlexContainer.d.ts +1 -0
  263. package/esm/core/utils/components/InputFlexContainer.js +3 -1
  264. package/esm/core/utils/components/Popover.js +5 -3
  265. package/esm/core/utils/components/Portal.d.ts +27 -0
  266. package/esm/core/utils/components/Portal.js +36 -0
  267. package/esm/core/utils/components/VirtualScroll.js +4 -4
  268. package/esm/core/utils/components/index.d.ts +2 -0
  269. package/esm/core/utils/components/index.js +2 -0
  270. package/esm/core/utils/functions/colors.d.ts +1 -1
  271. package/esm/core/utils/functions/colors.js +1 -13
  272. package/esm/core/utils/functions/index.d.ts +1 -0
  273. package/esm/core/utils/functions/index.js +1 -0
  274. package/esm/core/utils/functions/react.d.ts +8 -0
  275. package/esm/core/utils/functions/react.js +35 -0
  276. package/esm/core/utils/hooks/index.d.ts +1 -0
  277. package/esm/core/utils/hooks/index.js +1 -0
  278. package/esm/core/utils/hooks/useControlledState.d.ts +13 -0
  279. package/esm/core/utils/hooks/useControlledState.js +34 -0
  280. package/esm/core/utils/hooks/useGlobals.d.ts +1 -1
  281. package/esm/styles.js +11 -35
  282. package/package.json +3 -3
  283. package/styles.css +49 -46
@@ -11,6 +11,7 @@ import {
11
11
  SvgCloseSmall,
12
12
  Box,
13
13
  useSafeContext,
14
+ ButtonBase,
14
15
  } from '../utils/index.js';
15
16
  import { IconButton } from '../Buttons/index.js';
16
17
  import { ToasterStateContext } from './Toaster.js';
@@ -35,6 +36,7 @@ export const Toast = (props) => {
35
36
  hasCloseButton,
36
37
  onRemove,
37
38
  animateOutTo,
39
+ domProps,
38
40
  } = props;
39
41
  const closeTimeout = React.useRef(0);
40
42
  const { placement } = useSafeContext(ToasterStateContext).settings;
@@ -46,9 +48,9 @@ export const Toast = (props) => {
46
48
  const [margin, setMargin] = React.useState(0);
47
49
  const marginStyle = () => {
48
50
  if (placementPosition === 'top') {
49
- return { marginBottom: margin };
51
+ return { marginBlockEnd: margin };
50
52
  }
51
- return { marginTop: margin };
53
+ return { marginBlockStart: margin };
52
54
  };
53
55
  React.useEffect(() => {
54
56
  if (type === 'temporary') {
@@ -147,12 +149,15 @@ export const Toast = (props) => {
147
149
  'div',
148
150
  { ref: onRef },
149
151
  React.createElement(ToastPresentation, {
152
+ as: 'div',
150
153
  category: category,
151
154
  content: content,
152
155
  link: link,
153
156
  type: type,
154
157
  hasCloseButton: hasCloseButton,
155
158
  onClose: close,
159
+ ...domProps?.toastProps,
160
+ contentProps: domProps?.contentProps,
156
161
  }),
157
162
  ),
158
163
  ),
@@ -162,7 +167,7 @@ export const Toast = (props) => {
162
167
  * The presentational part of a toast, without any animation or logic.
163
168
  * @private
164
169
  */
165
- export const ToastPresentation = (props) => {
170
+ export const ToastPresentation = React.forwardRef((props, forwardedRef) => {
166
171
  const {
167
172
  content,
168
173
  category,
@@ -171,27 +176,35 @@ export const ToastPresentation = (props) => {
171
176
  hasCloseButton,
172
177
  onClose,
173
178
  className,
179
+ contentProps,
174
180
  ...rest
175
181
  } = props;
176
182
  const StatusIcon = StatusIconMap[category];
177
183
  return React.createElement(
178
184
  Box,
179
- { className: cx(`iui-toast iui-${category}`, className), ...rest },
185
+ {
186
+ className: cx(`iui-toast iui-${category}`, className),
187
+ ref: forwardedRef,
188
+ ...rest,
189
+ },
180
190
  React.createElement(
181
191
  Box,
182
192
  { className: 'iui-status-area' },
183
193
  React.createElement(StatusIcon, { className: 'iui-icon' }),
184
194
  ),
185
- React.createElement(Box, { className: 'iui-message' }, content),
195
+ React.createElement(
196
+ Box,
197
+ {
198
+ as: 'div',
199
+ ...contentProps,
200
+ className: cx('iui-message', contentProps?.className),
201
+ },
202
+ content,
203
+ ),
186
204
  link &&
187
205
  React.createElement(
188
- Box,
189
- {
190
- as: 'button',
191
- className: 'iui-toast-anchor',
192
- ...link,
193
- title: undefined,
194
- },
206
+ ButtonBase,
207
+ { className: 'iui-toast-anchor', ...link, title: undefined },
195
208
  link.title,
196
209
  ),
197
210
  (type === 'persisting' || hasCloseButton) &&
@@ -206,5 +219,5 @@ export const ToastPresentation = (props) => {
206
219
  React.createElement(SvgCloseSmall, null),
207
220
  ),
208
221
  );
209
- };
222
+ });
210
223
  export default Toast;
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { Placement } from '@floating-ui/react';
3
- import type { PolymorphicForwardRefComponent } from '../utils/index.js';
3
+ import type { PolymorphicForwardRefComponent, PortalProps } from '../utils/index.js';
4
4
  type TooltipOptions = {
5
5
  /**
6
6
  * Placement of the Tooltip
@@ -11,6 +11,11 @@ type TooltipOptions = {
11
11
  * Property for manual visibility control
12
12
  */
13
13
  visible?: boolean;
14
+ /**
15
+ * Callback invoked every time the tooltip visibility changes as a result
16
+ * of internal logic. Should be used alongside `visible` prop.
17
+ */
18
+ onVisibleChange?: (visible: boolean) => void;
14
19
  /**
15
20
  * autoUpdate options that recalculates position
16
21
  * to ensure the floating element remains anchored
@@ -42,34 +47,26 @@ type TooltipOptions = {
42
47
  hide?: boolean;
43
48
  inline?: boolean;
44
49
  };
45
- };
46
- type TooltipOwnProps = {
47
- /**
48
- * Content of the tooltip.
49
- */
50
- content: React.ReactNode;
51
- /**
52
- * Element to have tooltip on. Has to be a valid JSX element and needs to forward its ref.
53
- * If not specified, the `reference` prop should be used instead.
54
- */
55
- children?: React.ReactNode;
56
- /**
57
- * Element to portal tooltip to.
58
- * Portals to ThemeProvider portalContainerRef by default.
59
- * @default true;
60
- */
61
- portal?: boolean | {
62
- to: HTMLElement;
63
- };
64
50
  /**
65
51
  * Sets reference point to user provided element.
66
52
  * @example
67
- * const buttonRef = React.useRef();
53
+ * const [trigger, setTrigger] = React.useState(null);
68
54
  * ...
69
- * <Button ref={buttonRef} />
70
- * <Tooltip content='tooltip text' reference={buttonRef} />
55
+ * <Button ref={setTrigger} />
56
+ * <Tooltip content='tooltip text' reference={trigger} />
71
57
  */
72
- reference?: React.RefObject<HTMLElement>;
58
+ reference?: HTMLElement | null;
59
+ /**
60
+ * By default, the tooltip will be associated with the reference element
61
+ * using `aria-describedby`.
62
+ *
63
+ * Pass "label" if you want to use `aria-labelledby` instead, or pass "none"
64
+ * if you don't want any association.
65
+ *
66
+ * @default 'description'
67
+ */
68
+ ariaStrategy?: 'description' | 'label' | 'none';
69
+ id?: string;
73
70
  };
74
71
  /**
75
72
  * Basic tooltip component to display informative content when an element is hovered or focused.
@@ -77,10 +74,20 @@ type TooltipOwnProps = {
77
74
  * @example
78
75
  * <Tooltip content='tooltip text' placement='top'>Hover here</Tooltip>
79
76
  * @example
80
- * const buttonRef = React.useRef();
77
+ * const [trigger, setTrigger] = React.useState(null);
81
78
  * ...
82
- * <Button ref={buttonRef} />
83
- * <Tooltip content='tooltip text' reference={buttonRef} />
79
+ * <Button ref={setTrigger} />
80
+ * <Tooltip content='tooltip text' reference={trigger} />
84
81
  */
85
- export declare const Tooltip: PolymorphicForwardRefComponent<"div", TooltipOwnProps & TooltipOptions>;
82
+ export declare const Tooltip: PolymorphicForwardRefComponent<"div", {
83
+ /**
84
+ * Content of the tooltip.
85
+ */
86
+ content: React.ReactNode;
87
+ /**
88
+ * Element to have tooltip on. Has to be a valid JSX element and needs to forward its ref.
89
+ * If not specified, the `reference` prop should be used instead.
90
+ */
91
+ children?: React.ReactNode;
92
+ } & PortalProps & TooltipOptions>;
86
93
  export default Tooltip;
@@ -14,46 +14,46 @@ import {
14
14
  useHover,
15
15
  useFocus,
16
16
  useDismiss,
17
- useRole,
18
17
  useInteractions,
19
18
  safePolygon,
20
19
  size,
21
20
  autoPlacement,
22
21
  hide,
23
22
  inline,
23
+ useDelayGroupContext,
24
+ useDelayGroup,
24
25
  } from '@floating-ui/react';
25
26
  import {
26
27
  Box,
27
- getDocument,
28
- mergeRefs,
29
- useGlobals,
28
+ Portal,
29
+ cloneElementWithRef,
30
+ useControlledState,
31
+ useId,
30
32
  useMergedRefs,
31
33
  } from '../utils/index.js';
32
- import ReactDOM from 'react-dom';
33
34
  const useTooltip = (options = {}) => {
35
+ const uniqueId = useId();
34
36
  const {
35
- placement,
36
- visible: controlledOpen,
37
- middleware = {
38
- flip: true,
39
- shift: true,
40
- },
37
+ placement = 'top',
38
+ visible,
39
+ onVisibleChange,
40
+ middleware = { flip: true, shift: true },
41
41
  autoUpdateOptions = {},
42
+ reference,
43
+ ariaStrategy = 'description',
44
+ id = uniqueId,
45
+ ...props
42
46
  } = options;
43
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
44
- const open = controlledOpen ?? uncontrolledOpen;
45
- const data = useFloating({
47
+ const [open, onOpenChange] = useControlledState(
48
+ false,
49
+ visible,
50
+ onVisibleChange,
51
+ );
52
+ const floating = useFloating({
46
53
  placement,
47
54
  open,
48
- onOpenChange: setUncontrolledOpen,
49
- whileElementsMounted: (referenceEl, floatingEl, update) =>
50
- autoUpdate(referenceEl, floatingEl, update, {
51
- animationFrame: autoUpdateOptions.animationFrame,
52
- ancestorScroll: autoUpdateOptions.ancestorScroll,
53
- ancestorResize: autoUpdateOptions.ancestorResize,
54
- elementResize: autoUpdateOptions.elementResize,
55
- layoutShift: autoUpdateOptions.layoutShift,
56
- }),
55
+ onOpenChange,
56
+ whileElementsMounted: (...args) => autoUpdate(...args, autoUpdateOptions),
57
57
  middleware: [
58
58
  middleware.offset !== undefined ? offset(middleware.offset) : offset(4),
59
59
  middleware.flip && flip(),
@@ -63,35 +63,81 @@ const useTooltip = (options = {}) => {
63
63
  middleware.inline && inline(),
64
64
  middleware.hide && hide(),
65
65
  ].filter(Boolean),
66
+ ...(reference && { elements: { reference } }),
66
67
  });
67
- const context = data.context;
68
- const hover = useHover(context, {
69
- enabled: controlledOpen == null,
70
- delay: {
71
- open: 50,
72
- close: 250,
68
+ const ariaProps = React.useMemo(
69
+ () =>
70
+ ariaStrategy === 'description'
71
+ ? { 'aria-describedby': id }
72
+ : ariaStrategy === 'label'
73
+ ? { 'aria-labelledby': id }
74
+ : {},
75
+ [ariaStrategy, id],
76
+ );
77
+ const { delay } = useDelayGroupContext();
78
+ useDelayGroup(floating.context, { id: useId() });
79
+ const interactions = useInteractions([
80
+ useHover(floating.context, {
81
+ delay: delay ?? { open: 50, close: 250 },
82
+ handleClose: safePolygon({ buffer: -Infinity }),
83
+ }),
84
+ useFocus(floating.context),
85
+ useClick(floating.context),
86
+ useDismiss(floating.context),
87
+ ]);
88
+ // Manually add attributes and event handlers to external reference element,
89
+ // because we cannot spread getReferenceProps onto it.
90
+ React.useEffect(() => {
91
+ if (!reference) {
92
+ return;
93
+ }
94
+ /** e.g. onPointerDown --> pointerdown */
95
+ const domEventName = (e) => e.toLowerCase().substring(2);
96
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
+ const cleanupValues = {};
98
+ Object.entries({
99
+ ...ariaProps,
100
+ ...interactions.getReferenceProps(),
101
+ }).forEach(([key, value]) => {
102
+ if (typeof value === 'function') {
103
+ reference.addEventListener(domEventName(key), value);
104
+ cleanupValues[key] = value;
105
+ } else if (value) {
106
+ cleanupValues[key] = reference.getAttribute(key);
107
+ reference.setAttribute(key, value);
108
+ }
109
+ });
110
+ return () => {
111
+ Object.entries(cleanupValues).forEach(([key, value]) => {
112
+ if (typeof value === 'function') {
113
+ reference.removeEventListener(domEventName(key), value);
114
+ } else if (value) {
115
+ reference.setAttribute(key, value);
116
+ } else {
117
+ reference.removeAttribute(key);
118
+ }
119
+ });
120
+ };
121
+ }, [ariaProps, reference, interactions]);
122
+ const getReferenceProps = React.useCallback(
123
+ (userProps) => {
124
+ return interactions.getReferenceProps({ ...userProps, ...ariaProps });
73
125
  },
74
- handleClose: safePolygon({ buffer: -Infinity }),
75
- });
76
- const focus = useFocus(context, {
77
- enabled: controlledOpen == null,
78
- });
79
- const click = useClick(context, {
80
- enabled: controlledOpen == null,
81
- });
82
- const dismiss = useDismiss(context, {
83
- enabled: controlledOpen == null,
84
- });
85
- const role = useRole(context, { role: 'tooltip' });
86
- const interactions = useInteractions([click, hover, focus, dismiss, role]);
126
+ [interactions, ariaProps],
127
+ );
128
+ const floatingProps = React.useMemo(
129
+ () =>
130
+ interactions.getFloatingProps({
131
+ hidden: !open,
132
+ 'aria-hidden': 'true',
133
+ ...props,
134
+ id,
135
+ }),
136
+ [interactions, props, id, open],
137
+ );
87
138
  return React.useMemo(
88
- () => ({
89
- open,
90
- setUncontrolledOpen,
91
- ...interactions,
92
- ...data,
93
- }),
94
- [open, interactions, data],
139
+ () => ({ getReferenceProps, floatingProps, ...floating }),
140
+ [getReferenceProps, floatingProps, floating],
95
141
  );
96
142
  };
97
143
  /**
@@ -100,78 +146,35 @@ const useTooltip = (options = {}) => {
100
146
  * @example
101
147
  * <Tooltip content='tooltip text' placement='top'>Hover here</Tooltip>
102
148
  * @example
103
- * const buttonRef = React.useRef();
149
+ * const [trigger, setTrigger] = React.useState(null);
104
150
  * ...
105
- * <Button ref={buttonRef} />
106
- * <Tooltip content='tooltip text' reference={buttonRef} />
151
+ * <Button ref={setTrigger} />
152
+ * <Tooltip content='tooltip text' reference={trigger} />
107
153
  */
108
- export const Tooltip = React.forwardRef((props, forwardRef) => {
109
- const {
110
- content,
111
- children,
112
- portal = true,
113
- placement = 'top',
114
- autoUpdateOptions,
115
- middleware,
116
- style,
117
- className,
118
- visible,
119
- reference,
120
- ...rest
121
- } = props;
122
- const tooltip = useTooltip({
123
- placement,
124
- visible,
125
- autoUpdateOptions,
126
- middleware,
127
- });
128
- const context = useGlobals();
129
- React.useEffect(() => {
130
- if (reference) {
131
- tooltip.refs.setReference(reference.current);
132
- }
133
- }, [reference, tooltip.refs]);
134
- const portalTo =
135
- typeof portal !== 'boolean'
136
- ? portal.to
137
- : portal
138
- ? context?.portalContainerRef?.current ?? getDocument()?.body
139
- : null;
140
- const contentBox = React.createElement(
141
- Box,
142
- {
143
- className: cx('iui-tooltip', className),
144
- ref: useMergedRefs(tooltip.refs.setFloating, forwardRef),
145
- style: { ...tooltip.floatingStyles, ...style },
146
- ...tooltip.getFloatingProps(),
147
- ...rest,
148
- },
149
- content,
150
- );
151
- const childrenRef =
152
- React.isValidElement(children) &&
153
- mergeRefs(
154
- tooltip.refs.setReference,
155
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
156
- children.ref,
157
- );
154
+ export const Tooltip = React.forwardRef((props, forwardedRef) => {
155
+ const { content, children, portal = true, className, style, ...rest } = props;
156
+ const tooltip = useTooltip(rest);
158
157
  return React.createElement(
159
158
  React.Fragment,
160
159
  null,
161
- React.isValidElement(children)
162
- ? React.cloneElement(
163
- children,
164
- tooltip.getReferenceProps({
165
- ref: childrenRef,
166
- ...children.props,
167
- }),
168
- )
169
- : null,
170
- tooltip.open
171
- ? portalTo
172
- ? ReactDOM.createPortal(contentBox, portalTo)
173
- : contentBox
174
- : null,
160
+ cloneElementWithRef(children, (children) => ({
161
+ ...tooltip.getReferenceProps(children.props),
162
+ ref: tooltip.refs.setReference,
163
+ })),
164
+ React.createElement(
165
+ Portal,
166
+ { portal: portal },
167
+ React.createElement(
168
+ Box,
169
+ {
170
+ className: cx('iui-tooltip', className),
171
+ ref: useMergedRefs(tooltip.refs.setFloating, forwardedRef),
172
+ style: { ...tooltip.floatingStyles, ...style },
173
+ ...tooltip.floatingProps,
174
+ },
175
+ content,
176
+ ),
177
+ ),
175
178
  );
176
179
  });
177
180
  export default Tooltip;
@@ -13,6 +13,7 @@ import {
13
13
  polymorphic,
14
14
  } from '../utils/index.js';
15
15
  import { List, ListItem } from '../List/index.js';
16
+ import { Label } from '../Label/index.js';
16
17
  // ----------------------------------------------------------------------------
17
18
  // TransferListComponent
18
19
  const TransferListComponent = polymorphic('iui-transfer-list-wrapper');
@@ -143,7 +144,7 @@ const TransferListItem = React.forwardRef((props, ref) => {
143
144
  });
144
145
  TransferListItem.displayName = 'TransferList.Item';
145
146
  const TransferListListboxLabel = React.forwardRef((props, ref) => {
146
- const { children, className, id, ...rest } = props;
147
+ const { children, id, ...rest } = props;
147
148
  const { labelId, setLabelId } = useSafeContext(TransferListContext);
148
149
  React.useEffect(() => {
149
150
  if (id && id !== labelId) {
@@ -151,14 +152,8 @@ const TransferListListboxLabel = React.forwardRef((props, ref) => {
151
152
  }
152
153
  }, [id, labelId, setLabelId]);
153
154
  return React.createElement(
154
- Box,
155
- {
156
- as: 'div',
157
- className: cx('iui-transfer-list-listbox-label', className),
158
- id: labelId,
159
- ref: ref,
160
- ...rest,
161
- },
155
+ Label,
156
+ { as: 'div', id: labelId, ref: ref, ...rest },
162
157
  children,
163
158
  );
164
159
  });
@@ -221,7 +221,7 @@ export const TreeNode = (props) => {
221
221
  as: 'ul',
222
222
  className: 'iui-sub-tree',
223
223
  role: 'group',
224
- 'aria-owns': subNodeIds.join(','),
224
+ 'aria-owns': subNodeIds.join(' '),
225
225
  }),
226
226
  );
227
227
  };
@@ -26,6 +26,8 @@ export { TransferList } from './TransferList/index.js';
26
26
  export { Tabs, Tab } from './Tabs/index.js';
27
27
  export { InformationPanel, InformationPanelWrapper, InformationPanelHeader, InformationPanelBody, InformationPanelContent, } from './InformationPanel/index.js';
28
28
  export { Input } from './Input/index.js';
29
+ export { InputWithDecorations } from './InputWithDecorations/InputWithDecorations.js';
30
+ export { InputGrid } from './InputGrid/InputGrid.js';
29
31
  export { Label } from './Label/index.js';
30
32
  export { LabeledInput } from './LabeledInput/index.js';
31
33
  export { InputGroup } from './InputGroup/index.js';
package/esm/core/index.js CHANGED
@@ -56,6 +56,8 @@ export {
56
56
  InformationPanelContent,
57
57
  } from './InformationPanel/index.js';
58
58
  export { Input } from './Input/index.js';
59
+ export { InputWithDecorations } from './InputWithDecorations/InputWithDecorations.js';
60
+ export { InputGrid } from './InputGrid/InputGrid.js';
59
61
  export { Label } from './Label/index.js';
60
62
  export { LabeledInput } from './LabeledInput/index.js';
61
63
  export { InputGroup } from './InputGroup/index.js';
@@ -0,0 +1,14 @@
1
+ import type { PolymorphicForwardRefComponent } from '../props.js';
2
+ export declare const ButtonBase: PolymorphicForwardRefComponent<"button", ButtonBaseProps>;
3
+ type ButtonBaseProps = {
4
+ /**
5
+ * Custom `disabled` prop that keeps the button focusable, prevents
6
+ * clicks, applied disabled styling, and adds `aria-disabled`.
7
+ */
8
+ disabled?: boolean;
9
+ /**
10
+ * Built-in html `disabled` attribute
11
+ */
12
+ htmlDisabled?: boolean;
13
+ };
14
+ export {};
@@ -0,0 +1,42 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as React from 'react';
6
+ import cx from 'classnames';
7
+ import { Box } from './Box.js';
8
+ import { useIsClient } from '../hooks/useIsClient.js';
9
+ export const ButtonBase = React.forwardRef((props, forwardedRef) => {
10
+ const {
11
+ as: asProp = 'button',
12
+ disabled: disabledProp,
13
+ htmlDisabled,
14
+ ...rest
15
+ } = props;
16
+ const isClient = useIsClient();
17
+ const ariaDisabled =
18
+ disabledProp &&
19
+ !htmlDisabled && // htmlDisabled prop takes preference
20
+ isClient && // progressively enhance after first render
21
+ asProp === 'button'; // ignore if not button, e.g. links
22
+ const handleIfEnabled = (handler) => (e) => {
23
+ if (disabledProp) {
24
+ return;
25
+ }
26
+ handler?.(e);
27
+ };
28
+ return React.createElement(Box, {
29
+ as: asProp,
30
+ type: asProp === 'button' ? 'button' : undefined,
31
+ ref: forwardedRef,
32
+ 'aria-disabled': ariaDisabled ? 'true' : undefined,
33
+ 'data-iui-disabled': disabledProp ? 'true' : undefined,
34
+ disabled: htmlDisabled ?? (!isClient && disabledProp) ? true : undefined,
35
+ ...rest,
36
+ className: cx('iui-button-base', props.className),
37
+ onClick: handleIfEnabled(props.onClick),
38
+ onPointerDown: handleIfEnabled(props.onPointerDown),
39
+ onPointerUp: handleIfEnabled(props.onPointerUp),
40
+ });
41
+ });
42
+ ButtonBase.displayName = 'ButtonBase';
@@ -24,6 +24,11 @@ export type IconProps = {
24
24
  * @default 'default'
25
25
  */
26
26
  fill?: 'default' | 'positive' | 'informational' | 'negative' | 'warning' | AnyString;
27
+ /**
28
+ * Option to add padding to the icon.
29
+ * @default false
30
+ */
31
+ padded?: boolean;
27
32
  } & React.ComponentPropsWithoutRef<'span'>;
28
33
  /**
29
34
  * A utility component to provide size and fill to svgs.
@@ -32,12 +32,19 @@ const getSizeValue = (size) => {
32
32
  * </Icon>
33
33
  */
34
34
  export const Icon = React.forwardRef((props, ref) => {
35
- const { size = 'medium', fill = 'default', className, ...rest } = props;
35
+ const {
36
+ size = 'medium',
37
+ fill = 'default',
38
+ className,
39
+ padded = false,
40
+ ...rest
41
+ } = props;
36
42
  return React.createElement(Box, {
37
43
  as: 'span',
38
44
  className: cx('iui-svg-icon', className),
39
45
  'data-iui-icon-size': getSizeValue(size),
40
46
  'data-iui-icon-color': fill,
47
+ 'data-iui-padded': padded ? 'true' : undefined,
41
48
  ref: ref,
42
49
  ...rest,
43
50
  });
@@ -8,7 +8,6 @@ export type InputContainerProps<T extends React.ElementType = 'div'> = {
8
8
  message?: React.ReactNode;
9
9
  icon?: JSX.Element;
10
10
  isLabelInline?: boolean;
11
- isIconInline?: boolean;
12
11
  statusMessage?: React.ReactNode;
13
12
  inputId?: string;
14
13
  labelId?: string;