@itwin/itwinui-react 3.0.0-dev.7 → 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 (189) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/cjs/core/Alert/Alert.d.ts +20 -9
  3. package/cjs/core/Alert/Alert.js +48 -10
  4. package/cjs/core/ButtonGroup/ButtonGroup.js +41 -36
  5. package/cjs/core/Buttons/IconButton/IconButton.js +27 -44
  6. package/cjs/core/Buttons/SplitButton/SplitButton.js +3 -0
  7. package/cjs/core/ColorPicker/ColorInputPanel.js +172 -231
  8. package/cjs/core/ComboBox/ComboBox.js +3 -3
  9. package/cjs/core/ComboBox/ComboBoxDropdown.js +4 -9
  10. package/cjs/core/ComboBox/ComboBoxEndIcon.js +3 -22
  11. package/cjs/core/ComboBox/ComboBoxMenu.d.ts +2 -2
  12. package/cjs/core/ComboBox/ComboBoxMenuItem.d.ts +1 -1
  13. package/cjs/core/ComboBox/ComboBoxMenuItem.js +8 -6
  14. package/cjs/core/ComboBox/helpers.d.ts +1 -2
  15. package/cjs/core/DatePicker/DatePicker.d.ts +30 -8
  16. package/cjs/core/DatePicker/DatePicker.js +40 -5
  17. package/cjs/core/Dialog/Dialog.js +10 -16
  18. package/cjs/core/Dialog/DialogContext.d.ts +3 -4
  19. package/cjs/core/ExpandableBlock/ExpandableBlock.d.ts +20 -14
  20. package/cjs/core/ExpandableBlock/ExpandableBlock.js +38 -15
  21. package/cjs/core/Header/HeaderSplitButton.js +1 -0
  22. package/cjs/core/Input/Input.d.ts +4 -0
  23. package/cjs/core/Input/Input.js +2 -1
  24. package/cjs/core/InputGrid/InputGrid.d.ts +25 -0
  25. package/cjs/core/InputGrid/InputGrid.js +39 -0
  26. package/cjs/core/InputGrid/index.d.ts +3 -0
  27. package/cjs/core/InputGrid/index.js +15 -0
  28. package/cjs/core/InputGroup/InputGroup.d.ts +13 -0
  29. package/cjs/core/InputGroup/InputGroup.js +35 -9
  30. package/cjs/core/InputWithDecorations/InputWithDecorations.d.ts +39 -0
  31. package/cjs/core/InputWithDecorations/InputWithDecorations.js +81 -0
  32. package/cjs/core/InputWithDecorations/index.d.ts +3 -0
  33. package/cjs/core/InputWithDecorations/index.js +15 -0
  34. package/cjs/core/Label/Label.d.ts +5 -0
  35. package/cjs/core/Label/Label.js +2 -0
  36. package/cjs/core/LabeledInput/LabeledInput.d.ts +22 -16
  37. package/cjs/core/LabeledInput/LabeledInput.js +52 -29
  38. package/cjs/core/LabeledSelect/LabeledSelect.d.ts +17 -7
  39. package/cjs/core/LabeledSelect/LabeledSelect.js +36 -17
  40. package/cjs/core/LabeledTextarea/LabeledTextarea.d.ts +15 -5
  41. package/cjs/core/LabeledTextarea/LabeledTextarea.js +12 -45
  42. package/cjs/core/Menu/Menu.d.ts +1 -1
  43. package/cjs/core/Menu/Menu.js +1 -1
  44. package/cjs/core/Menu/MenuDivider.d.ts +2 -1
  45. package/cjs/core/Menu/MenuDivider.js +1 -1
  46. package/cjs/core/Menu/MenuItem.d.ts +1 -1
  47. package/cjs/core/Menu/MenuItem.js +1 -0
  48. package/cjs/core/Menu/MenuItemSkeleton.d.ts +1 -1
  49. package/cjs/core/Menu/MenuItemSkeleton.js +0 -1
  50. package/cjs/core/SearchBox/SearchBox.js +1 -1
  51. package/cjs/core/Select/Select.d.ts +4 -0
  52. package/cjs/core/Select/Select.js +10 -9
  53. package/cjs/core/SideNavigation/SideNavigation.js +2 -0
  54. package/cjs/core/Slider/Thumb.js +1 -0
  55. package/cjs/core/StatusMessage/StatusMessage.d.ts +12 -2
  56. package/cjs/core/StatusMessage/StatusMessage.js +23 -9
  57. package/cjs/core/Table/SubRowExpander.js +2 -0
  58. package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.d.ts +6 -1
  59. package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.js +46 -18
  60. package/cjs/core/Table/filters/DateRangeFilter/DateRangeFilter.d.ts +2 -0
  61. package/cjs/core/Table/filters/DateRangeFilter/DateRangeFilter.js +2 -0
  62. package/cjs/core/Textarea/Textarea.d.ts +7 -1
  63. package/cjs/core/Textarea/Textarea.js +6 -11
  64. package/cjs/core/ThemeProvider/ThemeProvider.js +1 -1
  65. package/cjs/core/Tile/Tile.d.ts +139 -15
  66. package/cjs/core/Tile/Tile.js +107 -16
  67. package/cjs/core/Toast/Toast.d.ts +12 -4
  68. package/cjs/core/Toast/Toast.js +20 -4
  69. package/cjs/core/Tooltip/Tooltip.d.ts +35 -28
  70. package/cjs/core/Tooltip/Tooltip.js +116 -117
  71. package/cjs/core/TransferList/TransferList.js +4 -12
  72. package/cjs/core/index.d.ts +2 -0
  73. package/cjs/core/index.js +20 -4
  74. package/cjs/core/utils/components/Icon.d.ts +5 -0
  75. package/cjs/core/utils/components/Icon.js +8 -1
  76. package/cjs/core/utils/components/InputContainer.d.ts +0 -1
  77. package/cjs/core/utils/components/InputContainer.js +14 -34
  78. package/cjs/core/utils/components/InputFlexContainer.d.ts +1 -0
  79. package/cjs/core/utils/components/InputFlexContainer.js +3 -1
  80. package/cjs/core/utils/components/Portal.d.ts +27 -0
  81. package/cjs/core/utils/components/Portal.js +43 -0
  82. package/cjs/core/utils/components/index.d.ts +1 -0
  83. package/cjs/core/utils/components/index.js +1 -0
  84. package/cjs/core/utils/functions/index.d.ts +1 -0
  85. package/cjs/core/utils/functions/index.js +1 -0
  86. package/cjs/core/utils/functions/react.d.ts +8 -0
  87. package/cjs/core/utils/functions/react.js +40 -0
  88. package/cjs/core/utils/hooks/index.d.ts +1 -1
  89. package/cjs/core/utils/hooks/index.js +1 -1
  90. package/cjs/core/utils/hooks/useControlledState.d.ts +13 -0
  91. package/cjs/core/utils/hooks/useControlledState.js +39 -0
  92. package/cjs/styles.js +10 -28
  93. package/esm/core/Alert/Alert.d.ts +20 -9
  94. package/esm/core/Alert/Alert.js +49 -10
  95. package/esm/core/ButtonGroup/ButtonGroup.js +41 -36
  96. package/esm/core/Buttons/IconButton/IconButton.js +25 -40
  97. package/esm/core/Buttons/SplitButton/SplitButton.js +9 -1
  98. package/esm/core/ColorPicker/ColorInputPanel.js +173 -232
  99. package/esm/core/ComboBox/ComboBox.js +3 -3
  100. package/esm/core/ComboBox/ComboBoxDropdown.js +4 -9
  101. package/esm/core/ComboBox/ComboBoxEndIcon.js +4 -25
  102. package/esm/core/ComboBox/ComboBoxMenu.d.ts +2 -2
  103. package/esm/core/ComboBox/ComboBoxMenuItem.d.ts +1 -1
  104. package/esm/core/ComboBox/ComboBoxMenuItem.js +9 -7
  105. package/esm/core/ComboBox/helpers.d.ts +1 -2
  106. package/esm/core/DatePicker/DatePicker.d.ts +30 -8
  107. package/esm/core/DatePicker/DatePicker.js +25 -5
  108. package/esm/core/Dialog/Dialog.js +11 -23
  109. package/esm/core/Dialog/DialogContext.d.ts +3 -4
  110. package/esm/core/ExpandableBlock/ExpandableBlock.d.ts +20 -14
  111. package/esm/core/ExpandableBlock/ExpandableBlock.js +39 -17
  112. package/esm/core/Header/HeaderSplitButton.js +1 -0
  113. package/esm/core/Input/Input.d.ts +4 -0
  114. package/esm/core/Input/Input.js +2 -1
  115. package/esm/core/InputGrid/InputGrid.d.ts +25 -0
  116. package/esm/core/InputGrid/InputGrid.js +35 -0
  117. package/esm/core/InputGrid/index.d.ts +3 -0
  118. package/esm/core/InputGrid/index.js +6 -0
  119. package/esm/core/InputGroup/InputGroup.d.ts +13 -0
  120. package/esm/core/InputGroup/InputGroup.js +34 -10
  121. package/esm/core/InputWithDecorations/InputWithDecorations.d.ts +39 -0
  122. package/esm/core/InputWithDecorations/InputWithDecorations.js +80 -0
  123. package/esm/core/InputWithDecorations/index.d.ts +3 -0
  124. package/esm/core/InputWithDecorations/index.js +6 -0
  125. package/esm/core/Label/Label.d.ts +5 -0
  126. package/esm/core/Label/Label.js +2 -0
  127. package/esm/core/LabeledInput/LabeledInput.d.ts +22 -16
  128. package/esm/core/LabeledInput/LabeledInput.js +53 -29
  129. package/esm/core/LabeledSelect/LabeledSelect.d.ts +17 -7
  130. package/esm/core/LabeledSelect/LabeledSelect.js +37 -18
  131. package/esm/core/LabeledTextarea/LabeledTextarea.d.ts +15 -5
  132. package/esm/core/LabeledTextarea/LabeledTextarea.js +14 -45
  133. package/esm/core/Menu/Menu.d.ts +1 -1
  134. package/esm/core/Menu/Menu.js +1 -1
  135. package/esm/core/Menu/MenuDivider.d.ts +2 -1
  136. package/esm/core/Menu/MenuDivider.js +1 -1
  137. package/esm/core/Menu/MenuItem.d.ts +1 -1
  138. package/esm/core/Menu/MenuItem.js +1 -0
  139. package/esm/core/Menu/MenuItemSkeleton.d.ts +1 -1
  140. package/esm/core/Menu/MenuItemSkeleton.js +0 -1
  141. package/esm/core/SearchBox/SearchBox.js +1 -1
  142. package/esm/core/Select/Select.d.ts +4 -0
  143. package/esm/core/Select/Select.js +10 -9
  144. package/esm/core/SideNavigation/SideNavigation.js +2 -0
  145. package/esm/core/Slider/Thumb.js +1 -0
  146. package/esm/core/StatusMessage/StatusMessage.d.ts +12 -2
  147. package/esm/core/StatusMessage/StatusMessage.js +23 -16
  148. package/esm/core/Table/SubRowExpander.js +2 -0
  149. package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.d.ts +6 -1
  150. package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.js +45 -17
  151. package/esm/core/Table/filters/DateRangeFilter/DateRangeFilter.d.ts +2 -0
  152. package/esm/core/Table/filters/DateRangeFilter/DateRangeFilter.js +2 -0
  153. package/esm/core/Textarea/Textarea.d.ts +7 -1
  154. package/esm/core/Textarea/Textarea.js +6 -11
  155. package/esm/core/ThemeProvider/ThemeProvider.js +4 -3
  156. package/esm/core/Tile/Tile.d.ts +139 -15
  157. package/esm/core/Tile/Tile.js +107 -16
  158. package/esm/core/Toast/Toast.d.ts +12 -4
  159. package/esm/core/Toast/Toast.js +21 -4
  160. package/esm/core/Tooltip/Tooltip.d.ts +35 -28
  161. package/esm/core/Tooltip/Tooltip.js +119 -116
  162. package/esm/core/TransferList/TransferList.js +4 -9
  163. package/esm/core/index.d.ts +2 -0
  164. package/esm/core/index.js +2 -0
  165. package/esm/core/utils/components/Icon.d.ts +5 -0
  166. package/esm/core/utils/components/Icon.js +8 -1
  167. package/esm/core/utils/components/InputContainer.d.ts +0 -1
  168. package/esm/core/utils/components/InputContainer.js +14 -30
  169. package/esm/core/utils/components/InputFlexContainer.d.ts +1 -0
  170. package/esm/core/utils/components/InputFlexContainer.js +3 -1
  171. package/esm/core/utils/components/Portal.d.ts +27 -0
  172. package/esm/core/utils/components/Portal.js +36 -0
  173. package/esm/core/utils/components/index.d.ts +1 -0
  174. package/esm/core/utils/components/index.js +1 -0
  175. package/esm/core/utils/functions/index.d.ts +1 -0
  176. package/esm/core/utils/functions/index.js +1 -0
  177. package/esm/core/utils/functions/react.d.ts +8 -0
  178. package/esm/core/utils/functions/react.js +35 -0
  179. package/esm/core/utils/hooks/index.d.ts +1 -1
  180. package/esm/core/utils/hooks/index.js +1 -1
  181. package/esm/core/utils/hooks/useControlledState.d.ts +13 -0
  182. package/esm/core/utils/hooks/useControlledState.js +34 -0
  183. package/esm/styles.js +10 -28
  184. package/package.json +3 -3
  185. package/styles.css +22 -19
  186. package/cjs/core/utils/hooks/useUncontrolledState.d.ts +0 -6
  187. package/cjs/core/utils/hooks/useUncontrolledState.js +0 -18
  188. package/esm/core/utils/hooks/useUncontrolledState.d.ts +0 -6
  189. package/esm/core/utils/hooks/useUncontrolledState.js +0 -13
@@ -14,7 +14,7 @@ const index_js_3 = require('../Buttons/index.js');
14
14
  const index_js_4 = require('../ProgressIndicators/index.js');
15
15
  const TileContext = React.createContext(undefined);
16
16
  TileContext.displayName = 'TileContext';
17
- const TileComponent = React.forwardRef((props, forwardedRef) => {
17
+ const TileWrapper = React.forwardRef((props, forwardedRef) => {
18
18
  const {
19
19
  className,
20
20
  status,
@@ -60,7 +60,7 @@ const TileComponent = React.forwardRef((props, forwardedRef) => {
60
60
  }),
61
61
  );
62
62
  });
63
- TileComponent.displayName = 'Tile';
63
+ TileWrapper.displayName = 'Tile.Wrapper';
64
64
  // ----------------------------------------------------------------------------
65
65
  // Tile.Action component
66
66
  const TileAction = React.forwardRef((props, forwardedRef) => {
@@ -272,10 +272,84 @@ TileMoreOptions.displayName = 'Tile.MoreOptions';
272
272
  // Tile.Buttons component
273
273
  const TileButtons = (0, index_js_1.polymorphic)('iui-tile-buttons');
274
274
  TileButtons.displayName = 'Tile.Buttons';
275
+ const TileComponent = React.forwardRef((props, forwardedRef) => {
276
+ const {
277
+ name,
278
+ description,
279
+ status,
280
+ isNew,
281
+ isLoading,
282
+ isSelected,
283
+ thumbnail,
284
+ badge,
285
+ leftIcon,
286
+ rightIcon,
287
+ buttons,
288
+ metadata,
289
+ moreOptions,
290
+ children,
291
+ isActionable,
292
+ isDisabled,
293
+ onClick,
294
+ ...rest
295
+ } = props;
296
+ return React.createElement(
297
+ TileWrapper,
298
+ {
299
+ ref: forwardedRef,
300
+ isNew: isNew,
301
+ isSelected: isSelected,
302
+ isLoading: isLoading,
303
+ status: status,
304
+ isDisabled: isDisabled,
305
+ ...rest,
306
+ },
307
+ React.createElement(
308
+ TileName,
309
+ null,
310
+ (status || isNew || isLoading || isSelected) &&
311
+ React.createElement(TileNameIcon, null),
312
+ React.createElement(
313
+ TileNameLabel,
314
+ null,
315
+ isActionable
316
+ ? React.createElement(
317
+ TileAction,
318
+ {
319
+ onClick: !isDisabled ? onClick : undefined,
320
+ 'aria-disabled': isDisabled,
321
+ },
322
+ name,
323
+ )
324
+ : name,
325
+ ),
326
+ ),
327
+ React.createElement(
328
+ TileThumbnailArea,
329
+ null,
330
+ typeof thumbnail !== 'string'
331
+ ? React.createElement(TileThumbnailPicture, null, thumbnail)
332
+ : React.createElement(TileThumbnailPicture, { url: thumbnail }),
333
+ badge && React.createElement(TileBadgeContainer, null, badge),
334
+ leftIcon && React.createElement(TileTypeIndicator, null, leftIcon),
335
+ rightIcon && React.createElement(TileQuickAction, null, rightIcon),
336
+ ),
337
+ React.createElement(
338
+ TileContentArea,
339
+ null,
340
+ description && React.createElement(TileDescription, null, description),
341
+ moreOptions && React.createElement(TileMoreOptions, null, moreOptions),
342
+ metadata && React.createElement(TileMetadata, null, metadata),
343
+ children,
344
+ ),
345
+ buttons && React.createElement(TileButtons, null, buttons),
346
+ );
347
+ });
348
+ TileComponent.displayName = 'Tile';
275
349
  /**
276
350
  * Tile with customizable Thumbnail, Name, Content and Buttons subcomponents
277
351
  * @example
278
- * <Tile>
352
+ * <Tile.Wrapper>
279
353
  * <Tile.ThumbnailArea>
280
354
  * <Tile.ThumbnailPicture/>
281
355
  * <Tile.Badge/>
@@ -285,23 +359,40 @@ TileButtons.displayName = 'Tile.Buttons';
285
359
  * <Tile.Name>
286
360
  * <Tile.NameIcon/>
287
361
  * <Tile.NameLabel/>
288
- * <Tile.Name/>
362
+ * </Tile.Name>
289
363
  * <Tile.ContentArea>
290
364
  * <Tile.Description />
291
365
  * <Tile.Metadata/>
292
366
  * <Tile.MoreOptions/>
293
367
  * </Tile.ContentArea>
294
368
  * <Tile.Buttons/>
295
- * </Tile>
369
+ * </Tile.Wrapper>
370
+ *
371
+ * @example
372
+ * <Tile
373
+ * name='Tile name'
374
+ * description='Tile description that takes upto 3 lines'
375
+ * metadata={<TagContainer><Tag variant='basic'>Tag 1</Tag></TagContainer>}
376
+ * thumbnail='/url/to/image.jpg'
377
+ * badge={<Badge backgroundColor='blue'>Badge label</Badge>}
378
+ * buttons={[<Button>Button 1</Button>, <Button>Button 2</Button>]}
379
+ * moreOptions={[<MenuItem>Item 1</MenuItem>, <MenuItem>Item 2</MenuItem>]}
380
+ * leftIcon={<IconButton><SvgInfo /></IconButton>}
381
+ * rightIcon={<IconButton><SvgStar /></IconButton>}
382
+ * isSelected={true}
383
+ * isNew={false}
384
+ * />
296
385
  */
297
386
  exports.Tile = Object.assign(TileComponent, {
387
+ /**
388
+ * Wrapper subcomponent for fully customisable Tile.
389
+ */
390
+ Wrapper: TileWrapper,
298
391
  /**
299
392
  * ThumbnailArea subcomponent that contains `ThumbnailPicture`, `QuickAction`, `TypeIndicator` or `BadgeContainer`
300
393
  * @example
301
394
  * <Tile.ThumbnailArea>
302
395
  * <Tile.ThumbnailPicture/>
303
- * // or
304
- * <Tile.ThumbnailAvatar/>
305
396
  * <Tile.QuickAction/>
306
397
  * <Tile.TypeIndicator/>
307
398
  * <Tile.BadgeContainer/>
@@ -311,14 +402,14 @@ exports.Tile = Object.assign(TileComponent, {
311
402
  /**
312
403
  * Thumbnail image url, a custom component or an svg for thumbnail avatar.
313
404
  * @example
314
- * <Tile>
405
+ * <Tile.Wrapper>
315
406
  * // ...
316
407
  * <Tile.ThumbnailArea>
317
408
  * <Tile.ThumbnailPicture url = '/url/to/image.jpg'/>
318
409
  * </Tile.ThumbnailArea>
319
- * </Tile>
410
+ * </Tile.Wrapper>
320
411
  * or
321
- * <Tile>
412
+ * <Tile.Wrapper>
322
413
  * // ...
323
414
  * <Tile.ThumbnailArea>
324
415
  * <Tile.ThumbnailPicture>
@@ -355,21 +446,21 @@ exports.Tile = Object.assign(TileComponent, {
355
446
  /**
356
447
  * `NameIcon` next to name of the tile. Goes under <Tile.Name>
357
448
  * @example
358
- * <Tile>
449
+ * <Tile.Wrapper>
359
450
  * <Tile.Name>
360
451
  * <Tile.NameIcon/>
361
452
  * </Tile.Name>
362
- * <Tile/>
453
+ * </Tile.Wrapper>
363
454
  */
364
455
  NameIcon: TileNameIcon,
365
456
  /*
366
457
  * `NameLabel` of the tile
367
458
  * @example
368
- * <Tile>
459
+ * <Tile.Wrapper>
369
460
  * <Tile.Name>
370
461
  * <Tile.NameLabel> Tile Name <Tile.NameLabel/>
371
462
  * </Tile.Name/>
372
- * <Tile/>
463
+ * </Tile.Wrapper>
373
464
  */
374
465
  NameLabel: TileNameLabel,
375
466
  /**
@@ -386,13 +477,13 @@ exports.Tile = Object.assign(TileComponent, {
386
477
  /**
387
478
  * Tile content area that contains `Description`, `Metadata` and `MoreOptions` Tile subcomponents
388
479
  * @example
389
- * <Tile>
480
+ * <Tile.Wrapper>
390
481
  * <Tile.ContentArea>
391
482
  * <Tile.Description/>
392
483
  * <Tile.Metadata/>
393
484
  * <Tile.MoreOptions/>
394
485
  * </Tile.ContentArea>
395
- * </Tile>
486
+ * </Tile.Wrapper>
396
487
  */
397
488
  ContentArea: TileContentArea,
398
489
  /**
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { CommonProps } from '../utils/index.js';
2
+ import type { PolymorphicForwardRefComponent } from '../utils/index.js';
3
3
  export type ToastCategory = 'informational' | 'negative' | 'positive' | 'warning';
4
4
  export type ToastProps = {
5
5
  /**
@@ -10,6 +10,13 @@ export type ToastProps = {
10
10
  * Content of the Toast message
11
11
  */
12
12
  content: React.ReactNode;
13
+ /**
14
+ * Passes props to toast and content
15
+ */
16
+ domProps?: {
17
+ toastProps?: React.ComponentProps<'div'>;
18
+ contentProps?: React.ComponentProps<'div'>;
19
+ };
13
20
  /**
14
21
  * Category of the Toast, which controls the border color, as well as the category icon.
15
22
  */
@@ -60,12 +67,13 @@ export type ToastProps = {
60
67
  * <Toast type='persisting' content='Job processing error.' category='negative' />
61
68
  */
62
69
  export declare const Toast: (props: ToastProps) => React.JSX.Element;
63
- export type ToastPresentationProps = Omit<ToastProps, 'duration' | 'id' | 'isVisible' | 'onRemove'> & {
70
+ export type ToastPresentationProps = Omit<ToastProps, 'duration' | 'id' | 'isVisible' | 'onRemove' | 'domProps'> & {
64
71
  onClose?: () => void;
65
- } & CommonProps;
72
+ contentProps?: React.ComponentProps<'div'>;
73
+ };
66
74
  /**
67
75
  * The presentational part of a toast, without any animation or logic.
68
76
  * @private
69
77
  */
70
- export declare const ToastPresentation: (props: ToastPresentationProps) => React.JSX.Element;
78
+ export declare const ToastPresentation: PolymorphicForwardRefComponent<"div", ToastPresentationProps>;
71
79
  export default Toast;
@@ -35,6 +35,7 @@ const Toast = (props) => {
35
35
  hasCloseButton,
36
36
  onRemove,
37
37
  animateOutTo,
38
+ domProps,
38
39
  } = props;
39
40
  const closeTimeout = React.useRef(0);
40
41
  const { placement } = (0, index_js_1.useSafeContext)(
@@ -149,12 +150,15 @@ const Toast = (props) => {
149
150
  'div',
150
151
  { ref: onRef },
151
152
  React.createElement(exports.ToastPresentation, {
153
+ as: 'div',
152
154
  category: category,
153
155
  content: content,
154
156
  link: link,
155
157
  type: type,
156
158
  hasCloseButton: hasCloseButton,
157
159
  onClose: close,
160
+ ...domProps?.toastProps,
161
+ contentProps: domProps?.contentProps,
158
162
  }),
159
163
  ),
160
164
  ),
@@ -165,7 +169,7 @@ exports.Toast = Toast;
165
169
  * The presentational part of a toast, without any animation or logic.
166
170
  * @private
167
171
  */
168
- const ToastPresentation = (props) => {
172
+ exports.ToastPresentation = React.forwardRef((props, forwardedRef) => {
169
173
  const {
170
174
  content,
171
175
  category,
@@ -174,6 +178,7 @@ const ToastPresentation = (props) => {
174
178
  hasCloseButton,
175
179
  onClose,
176
180
  className,
181
+ contentProps,
177
182
  ...rest
178
183
  } = props;
179
184
  const StatusIcon = index_js_1.StatusIconMap[category];
@@ -184,6 +189,7 @@ const ToastPresentation = (props) => {
184
189
  `iui-toast iui-${category}`,
185
190
  className,
186
191
  ),
192
+ ref: forwardedRef,
187
193
  ...rest,
188
194
  },
189
195
  React.createElement(
@@ -191,7 +197,18 @@ const ToastPresentation = (props) => {
191
197
  { className: 'iui-status-area' },
192
198
  React.createElement(StatusIcon, { className: 'iui-icon' }),
193
199
  ),
194
- React.createElement(index_js_1.Box, { className: 'iui-message' }, content),
200
+ React.createElement(
201
+ index_js_1.Box,
202
+ {
203
+ as: 'div',
204
+ ...contentProps,
205
+ className: (0, classnames_1.default)(
206
+ 'iui-message',
207
+ contentProps?.className,
208
+ ),
209
+ },
210
+ content,
211
+ ),
195
212
  link &&
196
213
  React.createElement(
197
214
  index_js_1.ButtonBase,
@@ -210,6 +227,5 @@ const ToastPresentation = (props) => {
210
227
  React.createElement(index_js_1.SvgCloseSmall, null),
211
228
  ),
212
229
  );
213
- };
214
- exports.ToastPresentation = ToastPresentation;
230
+ });
215
231
  exports.default = exports.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 portalContainer 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;
@@ -10,31 +10,30 @@ const React = tslib_1.__importStar(require('react'));
10
10
  const classnames_1 = tslib_1.__importDefault(require('classnames'));
11
11
  const react_1 = require('@floating-ui/react');
12
12
  const index_js_1 = require('../utils/index.js');
13
- const react_dom_1 = tslib_1.__importDefault(require('react-dom'));
14
13
  const useTooltip = (options = {}) => {
14
+ const uniqueId = (0, index_js_1.useId)();
15
15
  const {
16
- placement,
17
- visible: controlledOpen,
18
- middleware = {
19
- flip: true,
20
- shift: true,
21
- },
16
+ placement = 'top',
17
+ visible,
18
+ onVisibleChange,
19
+ middleware = { flip: true, shift: true },
22
20
  autoUpdateOptions = {},
21
+ reference,
22
+ ariaStrategy = 'description',
23
+ id = uniqueId,
24
+ ...props
23
25
  } = options;
24
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
25
- const open = controlledOpen ?? uncontrolledOpen;
26
- const data = (0, react_1.useFloating)({
26
+ const [open, onOpenChange] = (0, index_js_1.useControlledState)(
27
+ false,
28
+ visible,
29
+ onVisibleChange,
30
+ );
31
+ const floating = (0, react_1.useFloating)({
27
32
  placement,
28
33
  open,
29
- onOpenChange: setUncontrolledOpen,
30
- whileElementsMounted: (referenceEl, floatingEl, update) =>
31
- (0, react_1.autoUpdate)(referenceEl, floatingEl, update, {
32
- animationFrame: autoUpdateOptions.animationFrame,
33
- ancestorScroll: autoUpdateOptions.ancestorScroll,
34
- ancestorResize: autoUpdateOptions.ancestorResize,
35
- elementResize: autoUpdateOptions.elementResize,
36
- layoutShift: autoUpdateOptions.layoutShift,
37
- }),
34
+ onOpenChange,
35
+ whileElementsMounted: (...args) =>
36
+ (0, react_1.autoUpdate)(...args, autoUpdateOptions),
38
37
  middleware: [
39
38
  middleware.offset !== undefined
40
39
  ? (0, react_1.offset)(middleware.offset)
@@ -46,41 +45,81 @@ const useTooltip = (options = {}) => {
46
45
  middleware.inline && (0, react_1.inline)(),
47
46
  middleware.hide && (0, react_1.hide)(),
48
47
  ].filter(Boolean),
48
+ ...(reference && { elements: { reference } }),
49
49
  });
50
- const context = data.context;
51
- const hover = (0, react_1.useHover)(context, {
52
- enabled: controlledOpen == null,
53
- delay: {
54
- open: 50,
55
- close: 250,
56
- },
57
- handleClose: (0, react_1.safePolygon)({ buffer: -Infinity }),
58
- });
59
- const focus = (0, react_1.useFocus)(context, {
60
- enabled: controlledOpen == null,
61
- });
62
- const click = (0, react_1.useClick)(context, {
63
- enabled: controlledOpen == null,
64
- });
65
- const dismiss = (0, react_1.useDismiss)(context, {
66
- enabled: controlledOpen == null,
67
- });
68
- const role = (0, react_1.useRole)(context, { role: 'tooltip' });
50
+ const ariaProps = React.useMemo(
51
+ () =>
52
+ ariaStrategy === 'description'
53
+ ? { 'aria-describedby': id }
54
+ : ariaStrategy === 'label'
55
+ ? { 'aria-labelledby': id }
56
+ : {},
57
+ [ariaStrategy, id],
58
+ );
59
+ const { delay } = (0, react_1.useDelayGroupContext)();
60
+ (0, react_1.useDelayGroup)(floating.context, { id: (0, index_js_1.useId)() });
69
61
  const interactions = (0, react_1.useInteractions)([
70
- click,
71
- hover,
72
- focus,
73
- dismiss,
74
- role,
62
+ (0, react_1.useHover)(floating.context, {
63
+ delay: delay ?? { open: 50, close: 250 },
64
+ handleClose: (0, react_1.safePolygon)({ buffer: -Infinity }),
65
+ }),
66
+ (0, react_1.useFocus)(floating.context),
67
+ (0, react_1.useClick)(floating.context),
68
+ (0, react_1.useDismiss)(floating.context),
75
69
  ]);
70
+ // Manually add attributes and event handlers to external reference element,
71
+ // because we cannot spread getReferenceProps onto it.
72
+ React.useEffect(() => {
73
+ if (!reference) {
74
+ return;
75
+ }
76
+ /** e.g. onPointerDown --> pointerdown */
77
+ const domEventName = (e) => e.toLowerCase().substring(2);
78
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
+ const cleanupValues = {};
80
+ Object.entries({
81
+ ...ariaProps,
82
+ ...interactions.getReferenceProps(),
83
+ }).forEach(([key, value]) => {
84
+ if (typeof value === 'function') {
85
+ reference.addEventListener(domEventName(key), value);
86
+ cleanupValues[key] = value;
87
+ } else if (value) {
88
+ cleanupValues[key] = reference.getAttribute(key);
89
+ reference.setAttribute(key, value);
90
+ }
91
+ });
92
+ return () => {
93
+ Object.entries(cleanupValues).forEach(([key, value]) => {
94
+ if (typeof value === 'function') {
95
+ reference.removeEventListener(domEventName(key), value);
96
+ } else if (value) {
97
+ reference.setAttribute(key, value);
98
+ } else {
99
+ reference.removeAttribute(key);
100
+ }
101
+ });
102
+ };
103
+ }, [ariaProps, reference, interactions]);
104
+ const getReferenceProps = React.useCallback(
105
+ (userProps) => {
106
+ return interactions.getReferenceProps({ ...userProps, ...ariaProps });
107
+ },
108
+ [interactions, ariaProps],
109
+ );
110
+ const floatingProps = React.useMemo(
111
+ () =>
112
+ interactions.getFloatingProps({
113
+ hidden: !open,
114
+ 'aria-hidden': 'true',
115
+ ...props,
116
+ id,
117
+ }),
118
+ [interactions, props, id, open],
119
+ );
76
120
  return React.useMemo(
77
- () => ({
78
- open,
79
- setUncontrolledOpen,
80
- ...interactions,
81
- ...data,
82
- }),
83
- [open, interactions, data],
121
+ () => ({ getReferenceProps, floatingProps, ...floating }),
122
+ [getReferenceProps, floatingProps, floating],
84
123
  );
85
124
  };
86
125
  /**
@@ -89,78 +128,38 @@ const useTooltip = (options = {}) => {
89
128
  * @example
90
129
  * <Tooltip content='tooltip text' placement='top'>Hover here</Tooltip>
91
130
  * @example
92
- * const buttonRef = React.useRef();
131
+ * const [trigger, setTrigger] = React.useState(null);
93
132
  * ...
94
- * <Button ref={buttonRef} />
95
- * <Tooltip content='tooltip text' reference={buttonRef} />
133
+ * <Button ref={setTrigger} />
134
+ * <Tooltip content='tooltip text' reference={trigger} />
96
135
  */
97
- exports.Tooltip = React.forwardRef((props, forwardRef) => {
98
- const {
99
- content,
100
- children,
101
- portal = true,
102
- placement = 'top',
103
- autoUpdateOptions,
104
- middleware,
105
- style,
106
- className,
107
- visible,
108
- reference,
109
- ...rest
110
- } = props;
111
- const tooltip = useTooltip({
112
- placement,
113
- visible,
114
- autoUpdateOptions,
115
- middleware,
116
- });
117
- const context = (0, index_js_1.useGlobals)();
118
- React.useEffect(() => {
119
- if (reference) {
120
- tooltip.refs.setReference(reference.current);
121
- }
122
- }, [reference, tooltip.refs]);
123
- const portalTo =
124
- typeof portal !== 'boolean'
125
- ? portal.to
126
- : portal
127
- ? context?.portalContainer || (0, index_js_1.getDocument)()?.body
128
- : null;
129
- const contentBox = React.createElement(
130
- index_js_1.Box,
131
- {
132
- className: (0, classnames_1.default)('iui-tooltip', className),
133
- ref: (0, index_js_1.useMergedRefs)(tooltip.refs.setFloating, forwardRef),
134
- style: { ...tooltip.floatingStyles, ...style },
135
- ...tooltip.getFloatingProps(),
136
- ...rest,
137
- },
138
- content,
139
- );
140
- const childrenRef =
141
- React.isValidElement(children) &&
142
- (0, index_js_1.mergeRefs)(
143
- tooltip.refs.setReference,
144
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
145
- children.ref,
146
- );
136
+ exports.Tooltip = React.forwardRef((props, forwardedRef) => {
137
+ const { content, children, portal = true, className, style, ...rest } = props;
138
+ const tooltip = useTooltip(rest);
147
139
  return React.createElement(
148
140
  React.Fragment,
149
141
  null,
150
- React.isValidElement(children)
151
- ? React.cloneElement(
152
- children,
153
- tooltip.getReferenceProps({
154
- ref: childrenRef,
155
- ...children.props,
156
- }),
157
- )
158
- : null,
159
- tooltip.open
160
- ? portalTo
161
- ? react_dom_1.default.createPortal(contentBox, portalTo)
162
- : contentBox
163
- : null,
142
+ (0, index_js_1.cloneElementWithRef)(children, (children) => ({
143
+ ...tooltip.getReferenceProps(children.props),
144
+ ref: tooltip.refs.setReference,
145
+ })),
146
+ React.createElement(
147
+ index_js_1.Portal,
148
+ { portal: portal },
149
+ React.createElement(
150
+ index_js_1.Box,
151
+ {
152
+ className: (0, classnames_1.default)('iui-tooltip', className),
153
+ ref: (0, index_js_1.useMergedRefs)(
154
+ tooltip.refs.setFloating,
155
+ forwardedRef,
156
+ ),
157
+ style: { ...tooltip.floatingStyles, ...style },
158
+ ...tooltip.floatingProps,
159
+ },
160
+ content,
161
+ ),
162
+ ),
164
163
  );
165
164
  });
166
165
  exports.default = exports.Tooltip;