@itwin/itwinui-react 3.0.0-dev.5 → 3.0.0-dev.7

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 (172) hide show
  1. package/CHANGELOG.md +98 -1
  2. package/cjs/core/Avatar/Avatar.d.ts +3 -2
  3. package/cjs/core/Avatar/Avatar.js +21 -19
  4. package/cjs/core/AvatarGroup/AvatarGroup.js +3 -8
  5. package/cjs/core/Buttons/Button/Button.d.ts +15 -2
  6. package/cjs/core/Buttons/Button/Button.js +23 -9
  7. package/cjs/core/Buttons/DropdownButton/DropdownButton.d.ts +1 -1
  8. package/cjs/core/Buttons/DropdownButton/DropdownButton.js +1 -1
  9. package/cjs/core/Buttons/IconButton/IconButton.d.ts +5 -1
  10. package/cjs/core/Buttons/IconButton/IconButton.js +11 -5
  11. package/cjs/core/Buttons/SplitButton/SplitButton.d.ts +9 -0
  12. package/cjs/core/Buttons/SplitButton/SplitButton.js +22 -13
  13. package/cjs/core/Carousel/Carousel.d.ts +6 -4
  14. package/cjs/core/Carousel/Carousel.js +2 -2
  15. package/cjs/core/Carousel/CarouselDot.js +1 -3
  16. package/cjs/core/Carousel/CarouselNavigation.d.ts +6 -4
  17. package/cjs/core/ColorPicker/ColorBuilder.js +2 -1
  18. package/cjs/core/ComboBox/ComboBoxInput.js +1 -1
  19. package/cjs/core/ComboBox/ComboBoxMenu.js +5 -5
  20. package/cjs/core/DatePicker/DatePicker.js +7 -1
  21. package/cjs/core/Dialog/Dialog.js +1 -2
  22. package/cjs/core/Dialog/DialogContent.d.ts +2 -1
  23. package/cjs/core/Dialog/DialogContent.js +25 -1
  24. package/cjs/core/Dialog/DialogMain.js +5 -6
  25. package/cjs/core/ExpandableBlock/ExpandableBlock.js +1 -3
  26. package/cjs/core/FileUpload/FileUpload.d.ts +4 -0
  27. package/cjs/core/FileUpload/FileUpload.js +24 -3
  28. package/cjs/core/Header/HeaderBasicButton.js +3 -16
  29. package/cjs/core/Header/HeaderButton.d.ts +4 -0
  30. package/cjs/core/Header/HeaderButton.js +2 -0
  31. package/cjs/core/Header/HeaderDropdownButton.js +1 -1
  32. package/cjs/core/Header/HeaderSplitButton.js +2 -4
  33. package/cjs/core/Input/Input.d.ts +5 -0
  34. package/cjs/core/Input/Input.js +2 -1
  35. package/cjs/core/ProgressIndicators/ProgressLinear.d.ts +4 -0
  36. package/cjs/core/ProgressIndicators/ProgressLinear.js +9 -1
  37. package/cjs/core/Radio/Radio.d.ts +8 -0
  38. package/cjs/core/Radio/Radio.js +22 -9
  39. package/cjs/core/RadioTiles/RadioTile.d.ts +16 -0
  40. package/cjs/core/RadioTiles/RadioTile.js +61 -27
  41. package/cjs/core/Select/Select.js +2 -2
  42. package/cjs/core/SideNavigation/SideNavigation.d.ts +16 -0
  43. package/cjs/core/SideNavigation/SideNavigation.js +40 -9
  44. package/cjs/core/Slider/Slider.d.ts +24 -0
  45. package/cjs/core/Slider/Slider.js +58 -10
  46. package/cjs/core/Slider/Thumb.js +2 -2
  47. package/cjs/core/Slider/Track.d.ts +1 -1
  48. package/cjs/core/Slider/Track.js +17 -6
  49. package/cjs/core/Stepper/Stepper.d.ts +26 -1
  50. package/cjs/core/Stepper/Stepper.js +35 -6
  51. package/cjs/core/Stepper/StepperStep.d.ts +17 -0
  52. package/cjs/core/Stepper/StepperStep.js +33 -8
  53. package/cjs/core/Stepper/WorkflowDiagram.d.ts +11 -1
  54. package/cjs/core/Stepper/WorkflowDiagram.js +23 -10
  55. package/cjs/core/Stepper/WorkflowDiagramStep.d.ts +6 -1
  56. package/cjs/core/Stepper/WorkflowDiagramStep.js +9 -2
  57. package/cjs/core/Table/SubRowExpander.js +1 -1
  58. package/cjs/core/Table/Table.d.ts +16 -0
  59. package/cjs/core/Table/Table.js +50 -9
  60. package/cjs/core/Table/TableCell.js +1 -1
  61. package/cjs/core/Table/TablePaginator.js +1 -3
  62. package/cjs/core/Tabs/Tab.js +1 -2
  63. package/cjs/core/ThemeProvider/ThemeContext.d.ts +1 -1
  64. package/cjs/core/ThemeProvider/ThemeProvider.d.ts +23 -3
  65. package/cjs/core/ThemeProvider/ThemeProvider.js +56 -23
  66. package/cjs/core/Tile/Tile.d.ts +3 -2
  67. package/cjs/core/Toast/Toast.js +4 -9
  68. package/cjs/core/Tooltip/Tooltip.d.ts +1 -1
  69. package/cjs/core/Tooltip/Tooltip.js +1 -2
  70. package/cjs/core/Tree/TreeNode.js +1 -1
  71. package/cjs/core/utils/components/ButtonBase.d.ts +14 -0
  72. package/cjs/core/utils/components/ButtonBase.js +46 -0
  73. package/cjs/core/utils/components/Popover.js +5 -3
  74. package/cjs/core/utils/components/Resizer.js +21 -13
  75. package/cjs/core/utils/components/VirtualScroll.js +4 -4
  76. package/cjs/core/utils/components/index.d.ts +1 -0
  77. package/cjs/core/utils/components/index.js +1 -0
  78. package/cjs/core/utils/functions/colors.d.ts +1 -1
  79. package/cjs/core/utils/functions/colors.js +1 -13
  80. package/cjs/core/utils/hooks/index.d.ts +1 -0
  81. package/cjs/core/utils/hooks/index.js +1 -0
  82. package/cjs/core/utils/hooks/useGlobals.d.ts +1 -1
  83. package/cjs/core/utils/hooks/useUncontrolledState.d.ts +6 -0
  84. package/cjs/core/utils/hooks/useUncontrolledState.js +18 -0
  85. package/cjs/styles.js +4 -11
  86. package/esm/core/Avatar/Avatar.d.ts +3 -2
  87. package/esm/core/Avatar/Avatar.js +21 -17
  88. package/esm/core/AvatarGroup/AvatarGroup.js +3 -8
  89. package/esm/core/Buttons/Button/Button.d.ts +15 -2
  90. package/esm/core/Buttons/Button/Button.js +18 -10
  91. package/esm/core/Buttons/DropdownButton/DropdownButton.d.ts +1 -1
  92. package/esm/core/Buttons/DropdownButton/DropdownButton.js +1 -1
  93. package/esm/core/Buttons/IconButton/IconButton.d.ts +5 -1
  94. package/esm/core/Buttons/IconButton/IconButton.js +9 -6
  95. package/esm/core/Buttons/SplitButton/SplitButton.d.ts +9 -0
  96. package/esm/core/Buttons/SplitButton/SplitButton.js +22 -13
  97. package/esm/core/Carousel/Carousel.d.ts +6 -4
  98. package/esm/core/Carousel/Carousel.js +8 -3
  99. package/esm/core/Carousel/CarouselDot.js +2 -4
  100. package/esm/core/Carousel/CarouselNavigation.d.ts +6 -4
  101. package/esm/core/ColorPicker/ColorBuilder.js +2 -1
  102. package/esm/core/ComboBox/ComboBoxInput.js +1 -1
  103. package/esm/core/ComboBox/ComboBoxMenu.js +5 -5
  104. package/esm/core/DatePicker/DatePicker.js +8 -1
  105. package/esm/core/Dialog/Dialog.js +1 -1
  106. package/esm/core/Dialog/DialogContent.d.ts +2 -1
  107. package/esm/core/Dialog/DialogContent.js +25 -2
  108. package/esm/core/Dialog/DialogMain.js +5 -6
  109. package/esm/core/ExpandableBlock/ExpandableBlock.js +2 -3
  110. package/esm/core/FileUpload/FileUpload.d.ts +4 -0
  111. package/esm/core/FileUpload/FileUpload.js +26 -3
  112. package/esm/core/Header/HeaderBasicButton.js +4 -17
  113. package/esm/core/Header/HeaderButton.d.ts +4 -0
  114. package/esm/core/Header/HeaderButton.js +2 -0
  115. package/esm/core/Header/HeaderDropdownButton.js +1 -1
  116. package/esm/core/Header/HeaderSplitButton.js +8 -5
  117. package/esm/core/Input/Input.d.ts +5 -0
  118. package/esm/core/Input/Input.js +2 -1
  119. package/esm/core/ProgressIndicators/ProgressLinear.d.ts +4 -0
  120. package/esm/core/ProgressIndicators/ProgressLinear.js +9 -1
  121. package/esm/core/Radio/Radio.d.ts +8 -0
  122. package/esm/core/Radio/Radio.js +19 -6
  123. package/esm/core/RadioTiles/RadioTile.d.ts +16 -0
  124. package/esm/core/RadioTiles/RadioTile.js +52 -22
  125. package/esm/core/Select/Select.js +2 -2
  126. package/esm/core/SideNavigation/SideNavigation.d.ts +16 -0
  127. package/esm/core/SideNavigation/SideNavigation.js +31 -9
  128. package/esm/core/Slider/Slider.d.ts +24 -0
  129. package/esm/core/Slider/Slider.js +43 -10
  130. package/esm/core/Slider/Thumb.js +2 -2
  131. package/esm/core/Slider/Track.d.ts +1 -1
  132. package/esm/core/Slider/Track.js +14 -6
  133. package/esm/core/Stepper/Stepper.d.ts +26 -1
  134. package/esm/core/Stepper/Stepper.js +32 -6
  135. package/esm/core/Stepper/StepperStep.d.ts +17 -0
  136. package/esm/core/Stepper/StepperStep.js +27 -8
  137. package/esm/core/Stepper/WorkflowDiagram.d.ts +11 -1
  138. package/esm/core/Stepper/WorkflowDiagram.js +10 -7
  139. package/esm/core/Stepper/WorkflowDiagramStep.d.ts +6 -1
  140. package/esm/core/Stepper/WorkflowDiagramStep.js +6 -2
  141. package/esm/core/Table/SubRowExpander.js +1 -1
  142. package/esm/core/Table/Table.d.ts +16 -0
  143. package/esm/core/Table/Table.js +47 -9
  144. package/esm/core/Table/TableCell.js +1 -1
  145. package/esm/core/Table/TablePaginator.js +2 -3
  146. package/esm/core/Tabs/Tab.js +2 -3
  147. package/esm/core/ThemeProvider/ThemeContext.d.ts +1 -1
  148. package/esm/core/ThemeProvider/ThemeProvider.d.ts +23 -3
  149. package/esm/core/ThemeProvider/ThemeProvider.js +64 -24
  150. package/esm/core/Tile/Tile.d.ts +3 -2
  151. package/esm/core/Toast/Toast.js +5 -9
  152. package/esm/core/Tooltip/Tooltip.d.ts +1 -1
  153. package/esm/core/Tooltip/Tooltip.js +1 -1
  154. package/esm/core/Tree/TreeNode.js +1 -1
  155. package/esm/core/utils/components/ButtonBase.d.ts +14 -0
  156. package/esm/core/utils/components/ButtonBase.js +42 -0
  157. package/esm/core/utils/components/Popover.js +5 -3
  158. package/esm/core/utils/components/Resizer.js +21 -13
  159. package/esm/core/utils/components/VirtualScroll.js +4 -4
  160. package/esm/core/utils/components/index.d.ts +1 -0
  161. package/esm/core/utils/components/index.js +1 -0
  162. package/esm/core/utils/functions/colors.d.ts +1 -1
  163. package/esm/core/utils/functions/colors.js +1 -13
  164. package/esm/core/utils/functions/import.js +2 -1
  165. package/esm/core/utils/hooks/index.d.ts +1 -0
  166. package/esm/core/utils/hooks/index.js +1 -0
  167. package/esm/core/utils/hooks/useGlobals.d.ts +1 -1
  168. package/esm/core/utils/hooks/useUncontrolledState.d.ts +6 -0
  169. package/esm/core/utils/hooks/useUncontrolledState.js +13 -0
  170. package/esm/styles.js +4 -11
  171. package/package.json +2 -2
  172. package/styles.css +723 -1566
@@ -3,14 +3,23 @@
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
+ import * as ReactDOM from 'react-dom';
6
7
  import cx from 'classnames';
7
- import { useMediaQuery, useMergedRefs, Box } from '../utils/index.js';
8
+ import {
9
+ useMediaQuery,
10
+ useMergedRefs,
11
+ Box,
12
+ useIsomorphicLayoutEffect,
13
+ useUncontrolledState,
14
+ } from '../utils/index.js';
8
15
  import { ThemeContext } from './ThemeContext.js';
9
16
  import { ToastProvider, Toaster } from '../Toast/Toaster.js';
10
17
  /**
11
- * This component provides global styles and applies theme to the entire tree
12
- * that it is wrapping around. The `theme` prop is optional and defaults to the
13
- * light theme.
18
+ * This component provides global state and applies theme to the entire tree
19
+ * that it is wrapping around.
20
+ *
21
+ * The `theme` prop defaults to "inherit", which looks upwards for closest ThemeProvider
22
+ * and falls back to "light" theme if one is not found.
14
23
  *
15
24
  * If you want to theme the entire app, you should use this component at the root. You can also
16
25
  * use this component to apply a different theme to only a part of the tree.
@@ -33,18 +42,23 @@ import { ToastProvider, Toaster } from '../Toast/Toaster.js';
33
42
  * <App />
34
43
  * </ThemeProvider>
35
44
  */
36
- export const ThemeProvider = React.forwardRef((props, ref) => {
37
- const { theme: themeProp, children, themeOptions, ...rest } = props;
38
- const portalContainerRef = React.useRef(null);
39
- const parentContext = React.useContext(ThemeContext);
40
- const theme =
41
- themeProp === 'inherit' ? parentContext?.theme ?? 'light' : themeProp;
42
- const shouldApplyBackground =
43
- themeOptions?.applyBackground ??
44
- (themeProp === 'inherit' ? false : !parentContext);
45
+ export const ThemeProvider = React.forwardRef((props, forwardedRef) => {
46
+ const {
47
+ theme: themeProp = 'inherit',
48
+ children,
49
+ themeOptions,
50
+ portalContainer: portalContainerProp,
51
+ ...rest
52
+ } = props;
53
+ const [portalContainer, setPortalContainer] = useUncontrolledState(
54
+ portalContainerProp || null,
55
+ );
56
+ const [parentTheme, rootRef] = useParentTheme();
57
+ const theme = themeProp === 'inherit' ? parentTheme || 'light' : themeProp;
58
+ const shouldApplyBackground = themeOptions?.applyBackground ?? !parentTheme;
45
59
  const contextValue = React.useMemo(
46
- () => ({ theme, themeOptions, portalContainerRef }),
47
- [theme, themeOptions],
60
+ () => ({ theme, themeOptions, portalContainer }),
61
+ [theme, themeOptions, portalContainer],
48
62
  );
49
63
  return React.createElement(
50
64
  ThemeContext.Provider,
@@ -55,23 +69,29 @@ export const ThemeProvider = React.forwardRef((props, ref) => {
55
69
  theme: theme,
56
70
  shouldApplyBackground: shouldApplyBackground,
57
71
  themeOptions: themeOptions,
58
- ref: ref,
72
+ ref: useMergedRefs(forwardedRef, rootRef),
59
73
  ...rest,
60
74
  },
61
75
  React.createElement(
62
76
  ToastProvider,
63
77
  null,
64
78
  children,
65
- React.createElement(
66
- 'div',
67
- { ref: portalContainerRef },
68
- React.createElement(Toaster, null),
69
- ),
79
+ portalContainerProp
80
+ ? ReactDOM.createPortal(
81
+ React.createElement(Toaster, null),
82
+ portalContainerProp,
83
+ )
84
+ : React.createElement(
85
+ 'div',
86
+ { ref: setPortalContainer },
87
+ React.createElement(Toaster, null),
88
+ ),
70
89
  ),
71
90
  ),
72
91
  );
73
92
  });
74
93
  export default ThemeProvider;
94
+ // ----------------------------------------------------------------------------
75
95
  const Root = React.forwardRef((props, forwardedRef) => {
76
96
  const {
77
97
  theme,
@@ -81,8 +101,6 @@ const Root = React.forwardRef((props, forwardedRef) => {
81
101
  className,
82
102
  ...rest
83
103
  } = props;
84
- const ref = React.useRef(null);
85
- const mergedRefs = useMergedRefs(ref, forwardedRef);
86
104
  const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
87
105
  const prefersHighContrast = useMediaQuery('(prefers-contrast: more)');
88
106
  const shouldApplyDark = theme === 'dark' || (theme === 'os' && prefersDark);
@@ -97,9 +115,31 @@ const Root = React.forwardRef((props, forwardedRef) => {
97
115
  ),
98
116
  'data-iui-theme': shouldApplyDark ? 'dark' : 'light',
99
117
  'data-iui-contrast': shouldApplyHC ? 'high' : 'default',
100
- ref: mergedRefs,
118
+ ref: forwardedRef,
101
119
  ...rest,
102
120
  },
103
121
  children,
104
122
  );
105
123
  });
124
+ // ----------------------------------------------------------------------------
125
+ /**
126
+ * Returns theme from either parent context or by reading the closest
127
+ * data-iui-theme attribute if context is not found.
128
+ */
129
+ const useParentTheme = () => {
130
+ const parentContext = React.useContext(ThemeContext);
131
+ const rootRef = React.useRef(null);
132
+ const [parentThemeState, setParentTheme] = React.useState(
133
+ parentContext?.theme,
134
+ );
135
+ useIsomorphicLayoutEffect(() => {
136
+ setParentTheme(
137
+ (old) =>
138
+ old ||
139
+ rootRef.current?.parentElement
140
+ ?.closest('[data-iui-theme]')
141
+ ?.getAttribute('data-iui-theme'),
142
+ );
143
+ }, []);
144
+ return [parentContext?.theme ?? parentThemeState, rootRef];
145
+ };
@@ -125,10 +125,11 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileOwnProps> &
125
125
  */
126
126
  IconButton: PolymorphicForwardRefComponent<"button", Omit<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
127
127
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
128
- }, "label" | "as" | "size" | "styleType" | "isActive"> & {
128
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
129
129
  isActive?: boolean | undefined;
130
130
  label?: React.ReactNode;
131
- } & Omit<import("../Buttons/Button/Button.js").ButtonProps, "startIcon" | "endIcon"> & {
131
+ iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
132
+ } & Omit<import("../Buttons/Button/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
132
133
  as?: "button" | undefined;
133
134
  }, "ref">>;
134
135
  /**
@@ -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';
@@ -46,9 +47,9 @@ export const Toast = (props) => {
46
47
  const [margin, setMargin] = React.useState(0);
47
48
  const marginStyle = () => {
48
49
  if (placementPosition === 'top') {
49
- return { marginBottom: margin };
50
+ return { marginBlockEnd: margin };
50
51
  }
51
- return { marginTop: margin };
52
+ return { marginBlockStart: margin };
52
53
  };
53
54
  React.useEffect(() => {
54
55
  if (type === 'temporary') {
@@ -185,13 +186,8 @@ export const ToastPresentation = (props) => {
185
186
  React.createElement(Box, { className: 'iui-message' }, content),
186
187
  link &&
187
188
  React.createElement(
188
- Box,
189
- {
190
- as: 'button',
191
- className: 'iui-toast-anchor',
192
- ...link,
193
- title: undefined,
194
- },
189
+ ButtonBase,
190
+ { className: 'iui-toast-anchor', ...link, title: undefined },
195
191
  link.title,
196
192
  ),
197
193
  (type === 'persisting' || hasCloseButton) &&
@@ -55,7 +55,7 @@ type TooltipOwnProps = {
55
55
  children?: React.ReactNode;
56
56
  /**
57
57
  * Element to portal tooltip to.
58
- * Portals to ThemeProvider portalContainerRef by default.
58
+ * Portals to ThemeProvider portalContainer by default.
59
59
  * @default true;
60
60
  */
61
61
  portal?: boolean | {
@@ -135,7 +135,7 @@ export const Tooltip = React.forwardRef((props, forwardRef) => {
135
135
  typeof portal !== 'boolean'
136
136
  ? portal.to
137
137
  : portal
138
- ? context?.portalContainerRef?.current ?? getDocument()?.body
138
+ ? context?.portalContainer || getDocument()?.body
139
139
  : null;
140
140
  const contentBox = React.createElement(
141
141
  Box,
@@ -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
  };
@@ -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';
@@ -36,8 +36,7 @@ export const Popover = React.forwardRef((props, ref) => {
36
36
  const computedProps = {
37
37
  allowHTML: true,
38
38
  animation: false,
39
- appendTo: (el) =>
40
- themeInfo?.portalContainerRef?.current || el.ownerDocument.body,
39
+ appendTo: (el) => themeInfo?.portalContainer || el.ownerDocument.body,
41
40
  arrow: false,
42
41
  duration: 0,
43
42
  interactive: true,
@@ -62,7 +61,10 @@ export const Popover = React.forwardRef((props, ref) => {
62
61
  ...props.popperOptions,
63
62
  modifiers: [
64
63
  { name: 'flip' },
65
- { name: 'preventOverflow', options: { padding: 0 } },
64
+ {
65
+ name: 'preventOverflow',
66
+ options: { padding: 0 },
67
+ },
66
68
  ...(props.popperOptions?.modifiers || []),
67
69
  ],
68
70
  },
@@ -34,7 +34,10 @@ export const Resizer = (props) => {
34
34
  let height = `${initialHeight}px`;
35
35
  let translateX = initialTranslateX;
36
36
  let translateY = initialTranslateY;
37
- const minWidth = parseFloat(getComputedStyle(elementRef.current).minWidth);
37
+ let minWidth = parseFloat(getComputedStyle(elementRef.current).minWidth);
38
+ if (Number.isNaN(minWidth)) {
39
+ minWidth = 380;
40
+ }
38
41
  const minHeight = parseFloat(
39
42
  getComputedStyle(elementRef.current).minHeight,
40
43
  );
@@ -102,6 +105,8 @@ export const Resizer = (props) => {
102
105
  }
103
106
  case 'right': {
104
107
  width = elementRef.current.style.width = `${initialWidth - diffX}px`;
108
+ height = elementRef.current.style.height = `${initialHeight}px`;
109
+ elementRef.current.style.transform = `translate(${translateX}px, ${translateY}px)`;
105
110
  break;
106
111
  }
107
112
  case 'bottom-right': {
@@ -109,12 +114,14 @@ export const Resizer = (props) => {
109
114
  height = elementRef.current.style.height = `${
110
115
  initialHeight - diffY
111
116
  }px`;
117
+ elementRef.current.style.transform = `translate(${translateX}px, ${translateY}px)`;
112
118
  break;
113
119
  }
114
120
  case 'bottom': {
115
121
  height = elementRef.current.style.height = `${
116
122
  initialHeight - diffY
117
123
  }px`;
124
+ elementRef.current.style.transform = `translate(${translateX}px, ${translateY}px)`;
118
125
  break;
119
126
  }
120
127
  case 'bottom-left': {
@@ -135,6 +142,7 @@ export const Resizer = (props) => {
135
142
  break;
136
143
  }
137
144
  width = elementRef.current.style.width = `${newWidth}px`;
145
+ height = elementRef.current.style.height = `${initialHeight}px`;
138
146
  translateX = initialTranslateX - diffX;
139
147
  elementRef.current.style.transform = `translate(${translateX}px, ${translateY}px)`;
140
148
  break;
@@ -169,8 +177,8 @@ export const Resizer = (props) => {
169
177
  onPointerDown: onResizePointerDown,
170
178
  style: {
171
179
  position: 'absolute',
172
- top: -4,
173
- left: -4,
180
+ top: 0,
181
+ left: 0,
174
182
  width: 12,
175
183
  height: 12,
176
184
  cursor: 'nw-resize',
@@ -181,7 +189,7 @@ export const Resizer = (props) => {
181
189
  onPointerDown: onResizePointerDown,
182
190
  style: {
183
191
  position: 'absolute',
184
- top: -4,
192
+ top: 0,
185
193
  left: 8,
186
194
  right: 8,
187
195
  height: 8,
@@ -193,8 +201,8 @@ export const Resizer = (props) => {
193
201
  onPointerDown: onResizePointerDown,
194
202
  style: {
195
203
  position: 'absolute',
196
- top: -4,
197
- right: -4,
204
+ top: 0,
205
+ right: 0,
198
206
  width: 12,
199
207
  height: 12,
200
208
  cursor: 'ne-resize',
@@ -206,7 +214,7 @@ export const Resizer = (props) => {
206
214
  style: {
207
215
  position: 'absolute',
208
216
  top: 8,
209
- right: -4,
217
+ right: 0,
210
218
  bottom: 8,
211
219
  width: 8,
212
220
  cursor: 'e-resize',
@@ -217,8 +225,8 @@ export const Resizer = (props) => {
217
225
  onPointerDown: onResizePointerDown,
218
226
  style: {
219
227
  position: 'absolute',
220
- bottom: -4,
221
- right: -4,
228
+ bottom: 0,
229
+ right: 0,
222
230
  width: 12,
223
231
  height: 12,
224
232
  cursor: 'se-resize',
@@ -229,7 +237,7 @@ export const Resizer = (props) => {
229
237
  onPointerDown: onResizePointerDown,
230
238
  style: {
231
239
  position: 'absolute',
232
- bottom: -4,
240
+ bottom: 0,
233
241
  left: 8,
234
242
  right: 8,
235
243
  height: 8,
@@ -241,8 +249,8 @@ export const Resizer = (props) => {
241
249
  onPointerDown: onResizePointerDown,
242
250
  style: {
243
251
  position: 'absolute',
244
- bottom: -4,
245
- left: -4,
252
+ bottom: 0,
253
+ left: 0,
246
254
  width: 12,
247
255
  height: 12,
248
256
  cursor: 'sw-resize',
@@ -254,7 +262,7 @@ export const Resizer = (props) => {
254
262
  style: {
255
263
  position: 'absolute',
256
264
  top: 8,
257
- left: -4,
265
+ left: 0,
258
266
  bottom: 8,
259
267
  width: 8,
260
268
  cursor: 'w-resize',
@@ -36,8 +36,8 @@ const getElementHeightWithMargins = (element) => {
36
36
  return undefined;
37
37
  }
38
38
  const margin =
39
- parseFloat(getElementStyle(element, 'margin-top')) +
40
- parseFloat(getElementStyle(element, 'margin-bottom'));
39
+ parseFloat(getElementStyle(element, 'margin-block-start')) +
40
+ parseFloat(getElementStyle(element, 'margin-block-end'));
41
41
  return getElementHeight(element) + (isNaN(margin) ? 0 : margin);
42
42
  };
43
43
  const getNumberOfNodesInHeight = (childHeight, totalHeight) => {
@@ -344,13 +344,13 @@ export const useVirtualization = (props) => {
344
344
  return {
345
345
  outerProps: {
346
346
  style: {
347
- minHeight:
347
+ minBlockSize:
348
348
  itemsLength > 1
349
349
  ? Math.max(itemsLength - 2, 0) * childHeight.current.middle +
350
350
  childHeight.current.first +
351
351
  childHeight.current.last
352
352
  : childHeight.current.middle,
353
- minWidth: '100%',
353
+ minInlineSize: '100%',
354
354
  ...style,
355
355
  },
356
356
  ...rest,
@@ -13,3 +13,4 @@ export * from './Divider.js';
13
13
  export * from './LinkAction.js';
14
14
  export * from './AutoclearingHiddenLiveRegion.js';
15
15
  export * from './Box.js';
16
+ export * from './ButtonBase.js';
@@ -17,3 +17,4 @@ export * from './Divider.js';
17
17
  export * from './LinkAction.js';
18
18
  export * from './AutoclearingHiddenLiveRegion.js';
19
19
  export * from './Box.js';
20
+ export * from './ButtonBase.js';
@@ -17,4 +17,4 @@ export declare const isSoftBackground: (value: string) => value is "skyblue" | "
17
17
  * Generate color from user name or email.
18
18
  * Recommended to use for `backgroundColor` in `Avatar` component.
19
19
  */
20
- export declare const getUserColor: (emailOrName: string) => string;
20
+ export declare const getUserColor: (emailOrName: string) => "var(--iui-color-background-skyblue)" | "var(--iui-color-background-celery)" | "var(--iui-color-background-froly)" | "var(--iui-color-background-steelblue)" | "var(--iui-color-background-sunglow)" | "var(--iui-color-background-seabuckthorn)" | "var(--iui-color-background-montecarlo)" | "var(--iui-color-background-poloblue)" | "var(--iui-color-background-bouquet)" | "var(--iui-color-background-ash)" | "var(--iui-color-background-oak)";
@@ -19,19 +19,7 @@ export const SoftBackgrounds = {
19
19
  export const isSoftBackground = (value) => {
20
20
  return Object.keys(SoftBackgrounds).includes(value);
21
21
  };
22
- const USER_COLORS = [
23
- '#6AB9EC',
24
- '#B1C854',
25
- '#F7706C',
26
- '#4585A5',
27
- '#FFC335',
28
- '#F7963E',
29
- '#73C7C1',
30
- '#85A9CF',
31
- '#A3779F',
32
- '#C8C2B4',
33
- '#A47854',
34
- ];
22
+ const USER_COLORS = Object.values(SoftBackgrounds);
35
23
  /**
36
24
  * Generate color from user name or email.
37
25
  * Recommended to use for `backgroundColor` in `Avatar` component.
@@ -10,4 +10,5 @@
10
10
  export const dynamicImport =
11
11
  typeof jest === undefined
12
12
  ? new Function('specifier', 'return import(specifier)')
13
- : (specifier) => import(specifier);
13
+ : (specifier) =>
14
+ import(/* webpackIgnore: true */ /* @vite-ignore */ specifier);
@@ -11,3 +11,4 @@ export * from './useLatestRef.js';
11
11
  export * from './useIsomorphicLayoutEffect.js';
12
12
  export * from './useIsClient.js';
13
13
  export * from './useId.js';
14
+ export * from './useUncontrolledState.js';
@@ -15,3 +15,4 @@ export * from './useLatestRef.js';
15
15
  export * from './useIsomorphicLayoutEffect.js';
16
16
  export * from './useIsClient.js';
17
17
  export * from './useId.js';
18
+ export * from './useUncontrolledState.js';
@@ -9,7 +9,7 @@ import { ThemeContext } from '../../ThemeProvider/ThemeContext.js';
9
9
  export declare const useGlobals: () => {
10
10
  theme?: import("../../index.js").ThemeType | undefined;
11
11
  themeOptions?: import("../../ThemeProvider/ThemeProvider.js").ThemeOptions | undefined;
12
- portalContainerRef?: React.RefObject<HTMLElement> | undefined;
12
+ portalContainer?: HTMLElement | null | undefined;
13
13
  } | undefined;
14
14
  /** Shows console error if ThemeProvider is not used */
15
15
  export declare const useThemeProviderWarning: (themeContext: React.ContextType<typeof ThemeContext>) => void;
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Wrapper over `useState` that always gives preference to the
4
+ * uncontrolled state (which often comes from a prop).
5
+ */
6
+ export declare const useUncontrolledState: <T>(uncontrolledState: T) => readonly [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>];
@@ -0,0 +1,13 @@
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
+ /**
7
+ * Wrapper over `useState` that always gives preference to the
8
+ * uncontrolled state (which often comes from a prop).
9
+ */
10
+ export const useUncontrolledState = (uncontrolledState) => {
11
+ const [controlledState, setControlledState] = React.useState();
12
+ return [uncontrolledState ?? controlledState, setControlledState];
13
+ };
package/esm/styles.js CHANGED
@@ -10,13 +10,6 @@ const styles = {
10
10
  'iui-anchor': '_iui3-anchor',
11
11
  'iui-anchor-external': '_iui3-anchor-external',
12
12
  'iui-avatar': '_iui3-avatar',
13
- 'iui-stroke': '_iui3-stroke',
14
- 'iui-initials': '_iui3-initials',
15
- 'iui-status': '_iui3-status',
16
- 'iui-online': '_iui3-online',
17
- 'iui-away': '_iui3-away',
18
- 'iui-busy': '_iui3-busy',
19
- 'iui-offline': '_iui3-offline',
20
13
  'iui-avatar-count': '_iui3-avatar-count',
21
14
  'iui-small': '_iui3-small',
22
15
  'iui-large': '_iui3-large',
@@ -107,6 +100,7 @@ const styles = {
107
100
  'iui-calendar-day-range-today': '_iui3-calendar-day-range-today',
108
101
  'iui-dialog-wrapper': '_iui3-dialog-wrapper',
109
102
  'iui-dialog': '_iui3-dialog',
103
+ 'iui-dialog-content': '_iui3-dialog-content',
110
104
  'iui-dialog-visible': '_iui3-dialog-visible',
111
105
  'iui-dialog-default': '_iui3-dialog-default',
112
106
  'iui-dialog-full-page': '_iui3-dialog-full-page',
@@ -116,7 +110,6 @@ const styles = {
116
110
  'iui-dialog-title': '_iui3-dialog-title',
117
111
  'iui-dialog-title-bar': '_iui3-dialog-title-bar',
118
112
  'iui-dialog-title-bar-filled': '_iui3-dialog-title-bar-filled',
119
- 'iui-dialog-content': '_iui3-dialog-content',
120
113
  'iui-dialog-button-bar': '_iui3-dialog-button-bar',
121
114
  'iui-expandable-block': '_iui3-expandable-block',
122
115
  'iui-expandable-header': '_iui3-expandable-header',
@@ -242,13 +235,12 @@ const styles = {
242
235
  'iui-overlay-exiting': '_iui3-overlay-exiting',
243
236
  closeAnimation,
244
237
  'iui-progress-indicator-radial': '_iui3-progress-indicator-radial',
245
- 'iui-u4ca3ko': '_iui3-u4ca3ko',
238
+ 'iui-u8bwhh6': '_iui3-u8bwhh6',
246
239
  'iui-progress-indicator-linear-label':
247
240
  '_iui3-progress-indicator-linear-label',
248
- 'iui-u4ca3lg': '_iui3-u4ca3lg',
241
+ 'iui-u8bwhhv': '_iui3-u8bwhhv',
249
242
  'iui-radio': '_iui3-radio',
250
243
  'iui-radio-tile': '_iui3-radio-tile',
251
- 'iui-radio-tile-content': '_iui3-radio-tile-content',
252
244
  'iui-radio-tile-icon': '_iui3-radio-tile-icon',
253
245
  'iui-radio-tile-container': '_iui3-radio-tile-container',
254
246
  'iui-radio-tile-input': '_iui3-radio-tile-input',
@@ -438,6 +430,7 @@ const styles = {
438
430
  'iui-tree-node-content-label': '_iui3-tree-node-content-label',
439
431
  'iui-tree-node-content-title': '_iui3-tree-node-content-title',
440
432
  'iui-tree-node-content-caption': '_iui3-tree-node-content-caption',
433
+ 'iui-button-base': '_iui3-button-base',
441
434
  'iui-svg-icon': '_iui3-svg-icon',
442
435
  'iui-notification-marker': '_iui3-notification-marker',
443
436
  pulse,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "3.0.0-dev.5",
3
+ "version": "3.0.0-dev.7",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -83,7 +83,7 @@
83
83
  "tslib": "^2.6.0"
84
84
  },
85
85
  "devDependencies": {
86
- "@itwin/itwinui-css": "^2.0.0-dev.5",
86
+ "@itwin/itwinui-css": "^2.0.0-dev.7",
87
87
  "@itwin/itwinui-illustrations-react": "^2.1.0",
88
88
  "@itwin/itwinui-variables": "3.0.0-dev.1",
89
89
  "@swc/cli": "^0.1.62",