@itwin/itwinui-react 3.7.4 → 3.8.1

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 (55) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/cjs/core/Carousel/Carousel.d.ts +4 -4
  3. package/cjs/core/Carousel/CarouselNavigation.d.ts +4 -4
  4. package/cjs/core/InformationPanel/InformationPanel.js +10 -5
  5. package/cjs/core/LabeledSelect/LabeledSelect.d.ts +2 -2
  6. package/cjs/core/Popover/Popover.d.ts +2 -2
  7. package/cjs/core/Table/Table.js +1 -1
  8. package/cjs/core/Table/cells/DefaultCell.d.ts +2 -1
  9. package/cjs/core/Table/cells/DefaultCell.js +6 -1
  10. package/cjs/core/Table/utils.d.ts +3 -1
  11. package/cjs/core/Table/utils.js +30 -1
  12. package/cjs/core/ThemeProvider/ThemeProvider.js +8 -7
  13. package/cjs/core/Tile/Tile.d.ts +2 -2
  14. package/cjs/core/VisuallyHidden/VisuallyHidden.js +2 -2
  15. package/cjs/core/utils/components/ShadowRoot.js +26 -24
  16. package/cjs/core/utils/hooks/index.d.ts +1 -0
  17. package/cjs/core/utils/hooks/index.js +1 -0
  18. package/cjs/core/utils/hooks/useMediaQuery.d.ts +1 -1
  19. package/cjs/core/utils/hooks/useMediaQuery.js +11 -26
  20. package/cjs/core/utils/hooks/useSyncExternalStore.d.ts +5 -0
  21. package/cjs/core/utils/hooks/useSyncExternalStore.js +68 -0
  22. package/cjs/core/utils/index.d.ts +1 -0
  23. package/cjs/core/utils/index.js +1 -0
  24. package/cjs/core/utils/providers/HydrationProvider.d.ts +16 -0
  25. package/cjs/core/utils/providers/HydrationProvider.js +75 -0
  26. package/cjs/core/utils/providers/index.d.ts +1 -0
  27. package/cjs/core/utils/providers/index.js +21 -0
  28. package/esm/core/Carousel/Carousel.d.ts +4 -4
  29. package/esm/core/Carousel/CarouselNavigation.d.ts +4 -4
  30. package/esm/core/InformationPanel/InformationPanel.js +10 -5
  31. package/esm/core/LabeledSelect/LabeledSelect.d.ts +2 -2
  32. package/esm/core/Popover/Popover.d.ts +2 -2
  33. package/esm/core/Table/Table.js +2 -2
  34. package/esm/core/Table/cells/DefaultCell.d.ts +2 -1
  35. package/esm/core/Table/cells/DefaultCell.js +6 -1
  36. package/esm/core/Table/utils.d.ts +3 -1
  37. package/esm/core/Table/utils.js +6 -0
  38. package/esm/core/ThemeProvider/ThemeProvider.js +9 -8
  39. package/esm/core/Tile/Tile.d.ts +2 -2
  40. package/esm/core/VisuallyHidden/VisuallyHidden.js +3 -3
  41. package/esm/core/utils/components/ShadowRoot.js +26 -24
  42. package/esm/core/utils/hooks/index.d.ts +1 -0
  43. package/esm/core/utils/hooks/index.js +1 -0
  44. package/esm/core/utils/hooks/useMediaQuery.d.ts +1 -1
  45. package/esm/core/utils/hooks/useMediaQuery.js +11 -26
  46. package/esm/core/utils/hooks/useSyncExternalStore.d.ts +5 -0
  47. package/esm/core/utils/hooks/useSyncExternalStore.js +42 -0
  48. package/esm/core/utils/index.d.ts +1 -0
  49. package/esm/core/utils/index.js +1 -0
  50. package/esm/core/utils/providers/HydrationProvider.d.ts +16 -0
  51. package/esm/core/utils/providers/HydrationProvider.js +47 -0
  52. package/esm/core/utils/providers/index.d.ts +1 -0
  53. package/esm/core/utils/providers/index.js +5 -0
  54. package/package.json +2 -2
  55. package/styles.css +1 -677
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1964](https://github.com/iTwin/iTwinUI/pull/1964): Fixed a bug with `InformationPanel` where changing orientation after resizing the panel would cause the panel to maintain it's resized width/height.
8
+
9
+ ## 3.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#1957](https://github.com/iTwin/iTwinUI/pull/1957): Bumped the minimum required version of `@floating-ui/react` from `^0.26.3` to `^0.26.10`. (Make sure to also update transitive deps!)
14
+
15
+ ### Patch Changes
16
+
17
+ - [#1962](https://github.com/iTwin/iTwinUI/pull/1962): Hydration checks have been added in some components to facilitate showing pure client-rendered content more eagerly.
18
+ - [#1968](https://github.com/iTwin/iTwinUI/pull/1968): Fixed a regression in `Table` where the layout of a custom `Cell` unexpectedly changed from horizontal to vertical.
19
+
3
20
  ## 3.7.4
4
21
 
5
22
  ### Patch Changes
@@ -48,7 +48,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
48
48
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
49
49
  ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
50
50
  }, "as" | "children" | "content" | "portal" | keyof {
51
- placement?: import("@floating-ui/core").Placement | undefined;
51
+ placement?: import("@floating-ui/utils").Placement | undefined;
52
52
  visible?: boolean | undefined;
53
53
  onVisibleChange?: ((visible: boolean) => void) | undefined;
54
54
  autoUpdateOptions?: {
@@ -74,7 +74,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
74
74
  content: React.ReactNode;
75
75
  children?: React.ReactNode;
76
76
  } & import("../utils/index.js").PortalProps & {
77
- placement?: import("@floating-ui/core").Placement | undefined;
77
+ placement?: import("@floating-ui/utils").Placement | undefined;
78
78
  visible?: boolean | undefined;
79
79
  onVisibleChange?: ((visible: boolean) => void) | undefined;
80
80
  autoUpdateOptions?: {
@@ -111,7 +111,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
111
111
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
112
112
  ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
113
113
  }, "as" | "children" | "content" | "portal" | keyof {
114
- placement?: import("@floating-ui/core").Placement | undefined;
114
+ placement?: import("@floating-ui/utils").Placement | undefined;
115
115
  visible?: boolean | undefined;
116
116
  onVisibleChange?: ((visible: boolean) => void) | undefined;
117
117
  autoUpdateOptions?: {
@@ -137,7 +137,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
137
137
  content: React.ReactNode;
138
138
  children?: React.ReactNode;
139
139
  } & import("../utils/index.js").PortalProps & {
140
- placement?: import("@floating-ui/core").Placement | undefined;
140
+ placement?: import("@floating-ui/utils").Placement | undefined;
141
141
  visible?: boolean | undefined;
142
142
  onVisibleChange?: ((visible: boolean) => void) | undefined;
143
143
  autoUpdateOptions?: {
@@ -15,7 +15,7 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
15
15
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
16
16
  ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
17
17
  }, "as" | "children" | "content" | "portal" | keyof {
18
- placement?: import("@floating-ui/core").Placement | undefined;
18
+ placement?: import("@floating-ui/utils").Placement | undefined;
19
19
  visible?: boolean | undefined;
20
20
  onVisibleChange?: ((visible: boolean) => void) | undefined;
21
21
  autoUpdateOptions?: {
@@ -41,7 +41,7 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
41
41
  content: React.ReactNode;
42
42
  children?: React.ReactNode;
43
43
  } & import("../utils/index.js").PortalProps & {
44
- placement?: import("@floating-ui/core").Placement | undefined;
44
+ placement?: import("@floating-ui/utils").Placement | undefined;
45
45
  visible?: boolean | undefined;
46
46
  onVisibleChange?: ((visible: boolean) => void) | undefined;
47
47
  autoUpdateOptions?: {
@@ -78,7 +78,7 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
78
78
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
79
79
  ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
80
80
  }, "as" | "children" | "content" | "portal" | keyof {
81
- placement?: import("@floating-ui/core").Placement | undefined;
81
+ placement?: import("@floating-ui/utils").Placement | undefined;
82
82
  visible?: boolean | undefined;
83
83
  onVisibleChange?: ((visible: boolean) => void) | undefined;
84
84
  autoUpdateOptions?: {
@@ -104,7 +104,7 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
104
104
  content: React.ReactNode;
105
105
  children?: React.ReactNode;
106
106
  } & import("../utils/index.js").PortalProps & {
107
- placement?: import("@floating-ui/core").Placement | undefined;
107
+ placement?: import("@floating-ui/utils").Placement | undefined;
108
108
  visible?: boolean | undefined;
109
109
  onVisibleChange?: ((visible: boolean) => void) | undefined;
110
110
  autoUpdateOptions?: {
@@ -55,10 +55,11 @@ const index_js_1 = require("../utils/index.js");
55
55
  * </InformationPanel>
56
56
  * </InformationPanelWrapper>
57
57
  */
58
- exports.InformationPanel = React.forwardRef((props, ref) => {
58
+ exports.InformationPanel = React.forwardRef((props, forwardedRef) => {
59
59
  const { className, isOpen = false, orientation = 'vertical', resizable = true, children, ...rest } = props;
60
+ const [infoPanelSize, setInfoPanelSize] = React.useState({ width: undefined, height: undefined });
60
61
  const infoPanelRef = React.useRef(null);
61
- const refs = (0, index_js_1.useMergedRefs)(ref, infoPanelRef);
62
+ const refs = (0, index_js_1.useMergedRefs)(forwardedRef, infoPanelRef);
62
63
  const startResize = (e) => {
63
64
  if (!infoPanelRef.current) {
64
65
  return;
@@ -78,17 +79,21 @@ exports.InformationPanel = React.forwardRef((props, ref) => {
78
79
  }
79
80
  const { right, bottom } = infoPanelRef.current.getBoundingClientRect();
80
81
  if (orientation === 'vertical') {
81
- infoPanelRef.current.style.width = `${right - e.clientX}px`;
82
+ setInfoPanelSize({ width: right - e.clientX, height: undefined });
82
83
  }
83
84
  else {
84
- infoPanelRef.current.style.height = `${bottom - e.clientY}px`;
85
+ setInfoPanelSize({ height: bottom - e.clientY, width: undefined });
85
86
  }
86
87
  }, [orientation]);
87
88
  return (React.createElement(index_js_1.Box, { className: (0, classnames_1.default)('iui-information-panel', {
88
89
  'iui-right': orientation === 'vertical',
89
90
  'iui-bottom': orientation === 'horizontal',
90
91
  'iui-visible': isOpen,
91
- }, className), ref: refs, ...rest },
92
+ }, className), ref: refs, ...rest, style: {
93
+ width: orientation === 'vertical' ? infoPanelSize.width : undefined,
94
+ height: orientation === 'horizontal' ? infoPanelSize.height : undefined,
95
+ ...props.style,
96
+ } },
92
97
  resizable && (React.createElement(index_js_1.Box, { className: 'iui-resizer', onPointerDown: startResize },
93
98
  React.createElement(index_js_1.Box, { className: 'iui-resizer-bar' }))),
94
99
  children));
@@ -297,7 +297,7 @@ export declare const LabeledSelect: <T>(props: ({
297
297
  menuClassName?: string | undefined;
298
298
  menuStyle?: React.CSSProperties | undefined;
299
299
  popoverProps?: Pick<{
300
- placement?: import("@floating-ui/core").Placement | undefined;
300
+ placement?: import("@floating-ui/utils").Placement | undefined;
301
301
  visible?: boolean | undefined;
302
302
  onVisibleChange?: ((visible: boolean) => void) | undefined;
303
303
  closeOnOutsideClick?: boolean | undefined;
@@ -427,7 +427,7 @@ export declare const LabeledSelect: <T>(props: ({
427
427
  menuClassName?: string | undefined;
428
428
  menuStyle?: React.CSSProperties | undefined;
429
429
  popoverProps?: Pick<{
430
- placement?: import("@floating-ui/core").Placement | undefined;
430
+ placement?: import("@floating-ui/utils").Placement | undefined;
431
431
  visible?: boolean | undefined;
432
432
  onVisibleChange?: ((visible: boolean) => void) | undefined;
433
433
  closeOnOutsideClick?: boolean | undefined;
@@ -71,7 +71,7 @@ type PopoverInternalProps = {
71
71
  };
72
72
  export declare const usePopover: (options: PopoverOptions & PopoverInternalProps) => {
73
73
  placement: Placement;
74
- strategy: import("@floating-ui/react").Strategy;
74
+ strategy: import("@floating-ui/utils").Strategy;
75
75
  middlewareData: import("@floating-ui/core").MiddlewareData;
76
76
  x: number;
77
77
  y: number;
@@ -92,7 +92,7 @@ export declare const usePopover: (options: PopoverOptions & PopoverInternalProps
92
92
  x: number;
93
93
  y: number;
94
94
  placement: Placement;
95
- strategy: import("@floating-ui/react").Strategy;
95
+ strategy: import("@floating-ui/utils").Strategy;
96
96
  middlewareData: import("@floating-ui/core").MiddlewareData;
97
97
  isPositioned: boolean;
98
98
  update: () => void;
@@ -413,7 +413,7 @@ const Table = (props) => {
413
413
  // eslint-disable-next-line react-hooks/exhaustive-deps
414
414
  }, []);
415
415
  const isHeaderDirectClick = React.useRef(false);
416
- return (React.createElement(React.Fragment, null,
416
+ return (React.createElement(utils_js_1.TableColumnsContext.Provider, { value: columns },
417
417
  React.createElement(index_js_1.Box, { ref: (0, index_js_1.useMergedRefs)(tableRef, (element) => {
418
418
  ownerDocument.current = element?.ownerDocument;
419
419
  resizeRef(element);
@@ -16,7 +16,8 @@ export type DefaultCellProps<T extends Record<string, unknown>> = {
16
16
  /**
17
17
  * Should the contents of the cell be clamped after a certain number of lines?
18
18
  *
19
- * Will be enabled by default if the cell content is a string.
19
+ * Will be enabled by default if the cell content is a string and a custom `Cell`
20
+ * is not specified in the column object.
20
21
  */
21
22
  clamp?: boolean;
22
23
  } & CellRendererProps<T> & React.ComponentPropsWithoutRef<'div'>;
@@ -34,6 +34,7 @@ exports.DefaultCell = void 0;
34
34
  const React = __importStar(require("react"));
35
35
  const classnames_1 = __importDefault(require("classnames"));
36
36
  const index_js_1 = require("../../utils/index.js");
37
+ const utils_js_1 = require("../utils.js");
37
38
  /**
38
39
  * Default cell.
39
40
  * It should be passed to `cellRenderer`.
@@ -46,7 +47,11 @@ const index_js_1 = require("../../utils/index.js");
46
47
  * }
47
48
  */
48
49
  const DefaultCell = (props) => {
49
- const { cellElementProps: { className: cellElementClassName, style: cellElementStyle, ...cellElementProps }, children, startIcon, endIcon, cellProps, isDisabled, className, style, status, clamp = typeof cellProps.value === 'string', ...rest } = props;
50
+ const columnsProp = React.useContext(utils_js_1.TableColumnsContext);
51
+ const isCustomCell = React.useMemo(() => columnsProp
52
+ .find(({ id }) => props.cellProps.column.id === id)
53
+ ?.hasOwnProperty('Cell'), [props.cellProps.column.id, columnsProp]);
54
+ const { cellElementProps: { className: cellElementClassName, style: cellElementStyle, ...cellElementProps }, children, startIcon, endIcon, cellProps, isDisabled, className, style, status, clamp = typeof cellProps.value === 'string' && !isCustomCell, ...rest } = props;
50
55
  return (React.createElement(index_js_1.Box, { ...cellElementProps, ...rest, className: (0, classnames_1.default)(cellElementClassName, className), "aria-disabled": isDisabled?.(cellProps.row.original) || undefined, "data-iui-status": status, style: { ...cellElementStyle, ...style } },
51
56
  React.createElement(index_js_1.ShadowRoot, null,
52
57
  React.createElement("slot", { name: 'start' }),
@@ -1,4 +1,5 @@
1
- import type { ColumnInstance } from '../../react-table/react-table.js';
1
+ import * as React from 'react';
2
+ import type { ColumnInstance, Column } from '../../react-table/react-table.js';
2
3
  export declare const getCellStyle: <T extends Record<string, unknown>>(column: ColumnInstance<T>, isTableResizing: boolean) => React.CSSProperties | undefined;
3
4
  export declare const getStickyStyle: <T extends Record<string, unknown>>(column: ColumnInstance<T>, columnList: ColumnInstance<T>[]) => React.CSSProperties;
4
5
  export declare const getSubRowStyle: ({ density, depth }: {
@@ -7,3 +8,4 @@ export declare const getSubRowStyle: ({ density, depth }: {
7
8
  }) => {
8
9
  paddingInlineStart: number;
9
10
  };
11
+ export declare const TableColumnsContext: React.Context<Column[]>;
@@ -1,6 +1,34 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSubRowStyle = exports.getStickyStyle = exports.getCellStyle = void 0;
26
+ exports.TableColumnsContext = exports.getSubRowStyle = exports.getStickyStyle = exports.getCellStyle = void 0;
27
+ /*---------------------------------------------------------------------------------------------
28
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
29
+ * See LICENSE.md in the project root for license terms and full copyright notice.
30
+ *--------------------------------------------------------------------------------------------*/
31
+ const React = __importStar(require("react"));
4
32
  const getCellStyle = (column, isTableResizing) => {
5
33
  const style = {};
6
34
  style.flex = `1 1 145px`;
@@ -65,3 +93,4 @@ const getSubRowStyle = ({ density = 'default', depth = 1 }) => {
65
93
  };
66
94
  };
67
95
  exports.getSubRowStyle = getSubRowStyle;
96
+ exports.TableColumnsContext = React.createContext([]);
@@ -85,13 +85,14 @@ exports.ThemeProvider = React.forwardRef((props, forwardedRef) => {
85
85
  // we do include all dependencies below, but we want to stringify the objects as they could be different on each render
86
86
  // eslint-disable-next-line react-hooks/exhaustive-deps
87
87
  [theme, JSON.stringify(themeOptions), portalContainer]);
88
- return (React.createElement(ThemeContext_js_1.ThemeContext.Provider, { value: contextValue },
89
- includeCss && rootElement ? React.createElement(FallbackStyles, { root: rootElement }) : null,
90
- React.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: (0, index_js_1.useMergedRefs)(forwardedRef, setRootElement), ...rest },
91
- React.createElement(Toaster_js_1.ToastProvider, null,
92
- children,
93
- portaledPortalContainer ? (ReactDOM.createPortal(React.createElement(Toaster_js_1.Toaster, null), portaledPortalContainer)) : (React.createElement("div", { ref: setPortalContainer, style: { display: 'contents' } },
94
- React.createElement(Toaster_js_1.Toaster, null)))))));
88
+ return (React.createElement(index_js_1.HydrationProvider, null,
89
+ React.createElement(ThemeContext_js_1.ThemeContext.Provider, { value: contextValue },
90
+ includeCss && rootElement ? (React.createElement(FallbackStyles, { root: rootElement })) : null,
91
+ React.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: (0, index_js_1.useMergedRefs)(forwardedRef, setRootElement), ...rest },
92
+ React.createElement(Toaster_js_1.ToastProvider, null,
93
+ children,
94
+ portaledPortalContainer ? (ReactDOM.createPortal(React.createElement(Toaster_js_1.Toaster, null), portaledPortalContainer)) : (React.createElement("div", { ref: setPortalContainer, style: { display: 'contents' } },
95
+ React.createElement(Toaster_js_1.Toaster, null))))))));
95
96
  });
96
97
  // ----------------------------------------------------------------------------
97
98
  const Root = React.forwardRef((props, forwardedRef) => {
@@ -255,7 +255,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
255
255
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
256
256
  ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
257
257
  }, "as" | "children" | "content" | "portal" | keyof {
258
- placement?: import("@floating-ui/core").Placement | undefined;
258
+ placement?: import("@floating-ui/utils").Placement | undefined;
259
259
  visible?: boolean | undefined;
260
260
  onVisibleChange?: ((visible: boolean) => void) | undefined;
261
261
  autoUpdateOptions?: {
@@ -281,7 +281,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
281
281
  content: React.ReactNode;
282
282
  children?: React.ReactNode;
283
283
  } & import("../utils/index.js").PortalProps & {
284
- placement?: import("@floating-ui/core").Placement | undefined;
284
+ placement?: import("@floating-ui/utils").Placement | undefined;
285
285
  visible?: boolean | undefined;
286
286
  onVisibleChange?: ((visible: boolean) => void) | undefined;
287
287
  autoUpdateOptions?: {
@@ -46,12 +46,12 @@ const index_js_1 = require("../utils/index.js");
46
46
  */
47
47
  exports.VisuallyHidden = React.forwardRef((props, ref) => {
48
48
  const { as: asProp = 'span', className, unhideOnFocus = true, children: childrenProp, ...rest } = props;
49
- const isMounted = (0, index_js_1.useIsClient)();
49
+ const isHydrated = (0, index_js_1.useHydration)() === 'hydrated';
50
50
  // ShadowRoot is not supported on all elements, so we only use it for few common ones.
51
51
  const children = !['div', 'span', 'p'].includes(asProp) ? (childrenProp) : (React.createElement(React.Fragment, null,
52
52
  React.createElement(index_js_1.ShadowRoot, { css: css },
53
53
  React.createElement("slot", null)),
54
- isMounted && childrenProp));
54
+ isHydrated && childrenProp));
55
55
  return (React.createElement(index_js_1.Box, { as: asProp, className: (0, classnames_1.default)('iui-visually-hidden', className), "data-iui-unhide-on-focus": unhideOnFocus ? true : undefined, ref: ref, ...rest }, children));
56
56
  });
57
57
  // ----------------------------------------------------------------------------
@@ -31,6 +31,7 @@ exports.ShadowRoot = void 0;
31
31
  const React = __importStar(require("react"));
32
32
  const ReactDOM = __importStar(require("react-dom"));
33
33
  const index_js_1 = require("../hooks/index.js");
34
+ const index_js_2 = require("../providers/index.js");
34
35
  const isBrowser = typeof document !== 'undefined';
35
36
  const supportsDSD = isBrowser && 'shadowRootMode' in HTMLTemplateElement.prototype;
36
37
  const supportsAdoptedStylesheets = isBrowser && 'adoptedStyleSheets' in Document.prototype;
@@ -41,7 +42,7 @@ const supportsAdoptedStylesheets = isBrowser && 'adoptedStyleSheets' in Document
41
42
  * @private
42
43
  */
43
44
  const ShadowRoot = ({ children, css }) => {
44
- const isFirstRender = useIsFirstRender();
45
+ const isHydrating = (0, index_js_2.useHydration)() === 'hydrating';
45
46
  if (!isBrowser) {
46
47
  return (React.createElement("template", { shadowrootmode: 'open' },
47
48
  css && React.createElement("style", null, css),
@@ -49,7 +50,7 @@ const ShadowRoot = ({ children, css }) => {
49
50
  }
50
51
  // In browsers that support DSD, the template will be automatically removed as soon as it's parsed.
51
52
  // To pass hydration, the first client render needs to emulate this browser behavior and return null.
52
- if (supportsDSD && isFirstRender) {
53
+ if (supportsDSD && isHydrating) {
53
54
  return null;
54
55
  }
55
56
  return React.createElement(ClientShadowRoot, { css: css }, children);
@@ -75,31 +76,38 @@ function useShadowRoot(templateRef, { css = '' }) {
75
76
  const [shadowRoot, setShadowRoot] = React.useState(null);
76
77
  const styleSheet = React.useRef();
77
78
  const latestCss = (0, index_js_1.useLatestRef)(css);
79
+ const latestShadowRoot = (0, index_js_1.useLatestRef)(shadowRoot);
78
80
  (0, index_js_1.useLayoutEffect)(() => {
79
81
  const parent = templateRef.current?.parentElement;
80
82
  if (!parent) {
81
83
  return;
82
84
  }
83
- if (parent.shadowRoot) {
84
- parent.shadowRoot.replaceChildren(); // Remove previous shadowroot content
85
- }
86
- const shadow = parent.shadowRoot || parent.attachShadow({ mode: 'open' });
87
- if (supportsAdoptedStylesheets) {
88
- // create an empty stylesheet and add it to the shadowRoot
89
- const currentWindow = shadow.ownerDocument.defaultView || globalThis;
90
- styleSheet.current = new currentWindow.CSSStyleSheet();
91
- shadow.adoptedStyleSheets = [styleSheet.current];
92
- // add the CSS immediately to avoid FOUC (one-time)
93
- if (latestCss.current) {
94
- styleSheet.current.replaceSync(latestCss.current);
85
+ const setupOrReuseShadowRoot = () => {
86
+ if (parent.shadowRoot && latestShadowRoot.current === null) {
87
+ parent.shadowRoot.replaceChildren(); // Remove previous shadowroot content
95
88
  }
96
- }
97
- queueMicrotask(() => {
98
- // Flush the state immediately to ensure layout measurements in parent component are correct
89
+ const shadow = parent.shadowRoot || parent.attachShadow({ mode: 'open' });
90
+ if (supportsAdoptedStylesheets) {
91
+ // create an empty stylesheet and add it to the shadowRoot
92
+ const currentWindow = shadow.ownerDocument.defaultView || globalThis;
93
+ styleSheet.current = new currentWindow.CSSStyleSheet();
94
+ shadow.adoptedStyleSheets = [styleSheet.current];
95
+ // add the CSS immediately to avoid FOUC (one-time)
96
+ if (latestCss.current) {
97
+ styleSheet.current.replaceSync(latestCss.current);
98
+ }
99
+ }
100
+ // Flush the state immediately after shadow-root is attached, to ensure that layout
101
+ // measurements in parent component are correct.
102
+ // Without this, the parent component may end up measuring the layout when the shadow-root
103
+ // is attached in the DOM but React hasn't rendered any slots or content into it yet.
99
104
  ReactDOM.flushSync(() => setShadowRoot(shadow));
105
+ };
106
+ queueMicrotask(() => {
107
+ setupOrReuseShadowRoot();
100
108
  });
101
109
  return () => void setShadowRoot(null);
102
- }, [templateRef, latestCss]);
110
+ }, [templateRef, latestCss, latestShadowRoot]);
103
111
  // Synchronize `css` with contents of the existing stylesheet
104
112
  (0, index_js_1.useLayoutEffect)(() => {
105
113
  if (css && supportsAdoptedStylesheets) {
@@ -108,9 +116,3 @@ function useShadowRoot(templateRef, { css = '' }) {
108
116
  }, [css]);
109
117
  return shadowRoot;
110
118
  }
111
- // ----------------------------------------------------------------------------
112
- function useIsFirstRender() {
113
- const [isFirstRender, setIsFirstRender] = React.useState(true);
114
- React.useEffect(() => setIsFirstRender(false), []);
115
- return isFirstRender;
116
- }
@@ -12,3 +12,4 @@ export * from './useIsomorphicLayoutEffect.js';
12
12
  export * from './useIsClient.js';
13
13
  export * from './useId.js';
14
14
  export * from './useControlledState.js';
15
+ export * from './useSyncExternalStore.js';
@@ -32,3 +32,4 @@ __exportStar(require("./useIsomorphicLayoutEffect.js"), exports);
32
32
  __exportStar(require("./useIsClient.js"), exports);
33
33
  __exportStar(require("./useId.js"), exports);
34
34
  __exportStar(require("./useControlledState.js"), exports);
35
+ __exportStar(require("./useSyncExternalStore.js"), exports);
@@ -1 +1 @@
1
- export declare const useMediaQuery: (queryString: string) => boolean;
1
+ export declare const useMediaQuery: (queryString: string) => boolean | undefined;
@@ -29,33 +29,18 @@ exports.useMediaQuery = void 0;
29
29
  * See LICENSE.md in the project root for license terms and full copyright notice.
30
30
  *--------------------------------------------------------------------------------------------*/
31
31
  const React = __importStar(require("react"));
32
- const index_js_1 = require("../functions/index.js");
33
- const useIsomorphicLayoutEffect_js_1 = require("./useIsomorphicLayoutEffect.js");
32
+ const useSyncExternalStore_js_1 = require("./useSyncExternalStore.js");
34
33
  const useMediaQuery = (queryString) => {
35
- const [matches, setMatches] = React.useState();
36
- (0, useIsomorphicLayoutEffect_js_1.useLayoutEffect)(() => {
37
- const mediaQueryList = (0, index_js_1.getWindow)()?.matchMedia?.(queryString);
38
- const handleChange = ({ matches }) => setMatches(matches);
39
- if (mediaQueryList != undefined) {
40
- setMatches(mediaQueryList.matches);
41
- try {
42
- mediaQueryList.addEventListener('change', handleChange);
43
- }
44
- catch {
45
- // Safari 13 fallback
46
- mediaQueryList.addListener?.(handleChange);
47
- }
48
- }
49
- return () => {
50
- try {
51
- mediaQueryList?.removeEventListener('change', handleChange);
52
- }
53
- catch {
54
- // Safari 13 fallback
55
- mediaQueryList?.removeListener?.(handleChange);
56
- }
57
- };
34
+ const getSnapshot = React.useCallback(() => {
35
+ return typeof window !== 'undefined'
36
+ ? window.matchMedia?.(queryString).matches
37
+ : undefined;
58
38
  }, [queryString]);
59
- return !!matches;
39
+ const subscribe = React.useCallback((onChange) => {
40
+ const mediaQueryList = window.matchMedia?.(queryString);
41
+ mediaQueryList?.addEventListener?.('change', onChange);
42
+ return () => mediaQueryList?.removeEventListener?.('change', onChange);
43
+ }, [queryString]);
44
+ return (0, useSyncExternalStore_js_1.useSyncExternalStore)(subscribe, getSnapshot, () => undefined);
60
45
  };
61
46
  exports.useMediaQuery = useMediaQuery;
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Wrapper around `React.useSyncExternalStore` that uses a shim for React 17.
4
+ */
5
+ export declare const useSyncExternalStore: typeof React.useSyncExternalStore;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.useSyncExternalStore = void 0;
27
+ /*---------------------------------------------------------------------------------------------
28
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
29
+ * See LICENSE.md in the project root for license terms and full copyright notice.
30
+ *--------------------------------------------------------------------------------------------*/
31
+ const React = __importStar(require("react"));
32
+ const _React = React; // prevent bundlers from stripping the namespace import
33
+ /**
34
+ * Wrapper around `React.useSyncExternalStore` that uses a shim for React 17.
35
+ */
36
+ exports.useSyncExternalStore = _React.useSyncExternalStore || useSyncExternalStoreShim;
37
+ // ----------------------------------------------------------------------------
38
+ /**
39
+ * The shim below is adapted from React's source to make it ESM-compatible.
40
+ *
41
+ * Note: This does not use `getServerSnapshot` at all, because there is
42
+ * apparently no way to check "hydrating" state in pre-18.
43
+ *
44
+ * @see https://github.com/facebook/react/tree/main/packages/use-sync-external-store
45
+ */
46
+ function useSyncExternalStoreShim(subscribe, getSnapshot) {
47
+ const value = getSnapshot();
48
+ const [{ instance }, forceUpdate] = React.useState({
49
+ instance: { value, getSnapshot },
50
+ });
51
+ React.useLayoutEffect(() => {
52
+ instance.value = value;
53
+ instance.getSnapshot = getSnapshot;
54
+ if (!Object.is(value, getSnapshot())) {
55
+ forceUpdate({ instance });
56
+ }
57
+ }, [subscribe, value, getSnapshot]); // eslint-disable-line
58
+ React.useEffect(() => {
59
+ const synchronize = () => {
60
+ if (!Object.is(instance.value, instance.getSnapshot())) {
61
+ forceUpdate({ instance });
62
+ }
63
+ };
64
+ synchronize();
65
+ return subscribe(synchronize);
66
+ }, [subscribe]); // eslint-disable-line
67
+ return value;
68
+ }
@@ -5,3 +5,4 @@ export * from './props.js';
5
5
  export * from './color/index.js';
6
6
  export * from './icons/index.js';
7
7
  export * from './types.js';
8
+ export * from './providers/index.js';
@@ -25,3 +25,4 @@ __exportStar(require("./props.js"), exports);
25
25
  __exportStar(require("./color/index.js"), exports);
26
26
  __exportStar(require("./icons/index.js"), exports);
27
27
  __exportStar(require("./types.js"), exports);
28
+ __exportStar(require("./providers/index.js"), exports);
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Hook that returns the hydration status of the app.
4
+ *
5
+ * @returns one of the following values:
6
+ * - `"hydrated"` after hydration is *definitely* complete (or is a pure client render)
7
+ * - `"hydrating"` if we know for sure that hydration is happening (in React 18)
8
+ * - `undefined` if the hydration status is unknown
9
+ *
10
+ * @private
11
+ */
12
+ export declare const useHydration: () => "hydrated" | "hydrating" | undefined;
13
+ /** @private */
14
+ export declare const HydrationProvider: ({ children, }: {
15
+ children: React.ReactNode;
16
+ }) => React.JSX.Element;