@itwin/itwinui-react 3.11.1 → 3.11.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.11.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#2084](https://github.com/iTwin/iTwinUI/pull/2084): Fixed an issue where a portaled `ThemeProvider` would try to re-render infinitely.
8
+ - [#2083](https://github.com/iTwin/iTwinUI/pull/2083): Removed the accidentally added no-op `loading` prop in `IconButton`.
9
+ - [#2083](https://github.com/iTwin/iTwinUI/pull/2083): Fixed a visual bug where elements like `startIcon` and `endIcon` inside the `Button` (or its derivatives) were not hidden when the button was in a loading state. Now,`loading={true}` on `Button` hides _all_ its children except the `ProgressRadial`.
10
+
3
11
  ## 3.11.1
4
12
 
5
13
  ### Patch Changes
@@ -21,7 +21,7 @@ export type IconButtonProps = {
21
21
  * Passes props to IconButton icon.
22
22
  */
23
23
  iconProps?: React.ComponentProps<'span'>;
24
- } & Omit<ButtonProps, 'startIcon' | 'endIcon' | 'startIconProps' | 'endIconProps' | 'labelProps'>;
24
+ } & Omit<ButtonProps, 'startIcon' | 'endIcon' | 'startIconProps' | 'endIconProps' | 'labelProps' | 'loading'>;
25
25
  /**
26
26
  * Icon button
27
27
  * @example
@@ -42,7 +42,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
42
42
  Navigation: PolymorphicForwardRefComponent<"div", {}> & {
43
43
  PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
44
44
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
45
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
45
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
46
46
  isActive?: boolean | undefined;
47
47
  label?: React.ReactNode;
48
48
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -100,12 +100,12 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
100
100
  as?: "div" | undefined;
101
101
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
102
102
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
103
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
103
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
104
104
  as?: "button" | undefined;
105
105
  }>;
106
106
  NextButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
107
107
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
108
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
108
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
109
109
  isActive?: boolean | undefined;
110
110
  label?: React.ReactNode;
111
111
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -163,7 +163,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
163
163
  as?: "div" | undefined;
164
164
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
165
165
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
166
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
166
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
167
167
  as?: "button" | undefined;
168
168
  }>;
169
169
  };
@@ -9,7 +9,7 @@ import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
9
9
  export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {}> & {
10
10
  PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
11
11
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
12
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
12
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
13
13
  isActive?: boolean | undefined;
14
14
  label?: React.ReactNode;
15
15
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -67,12 +67,12 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
67
67
  as?: "div" | undefined;
68
68
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
69
69
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
70
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
70
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
71
71
  as?: "button" | undefined;
72
72
  }>;
73
73
  NextButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
74
74
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
75
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
75
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
76
76
  isActive?: boolean | undefined;
77
77
  label?: React.ReactNode;
78
78
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -130,7 +130,7 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
130
130
  as?: "div" | undefined;
131
131
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
132
132
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
133
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
133
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
134
134
  as?: "button" | undefined;
135
135
  }>;
136
136
  };
@@ -71,7 +71,7 @@ type HeaderProps = {
71
71
  * appLogo={<HeaderLogo logo={<SvgImodelHollow />}>iTwin Application</HeaderLogo>}
72
72
  * breadcrumbs={
73
73
  * <HeaderBreadcrumbs items={[
74
- * <HeaderButton key='project' name='Project A' />
74
+ * <HeaderButton key='project' name='Project A' />,
75
75
  * <HeaderButton key='imodel' name='IModel X' />
76
76
  * ]} />
77
77
  * }
@@ -82,9 +82,9 @@ type HeaderProps = {
82
82
  * <SvgHelpCircularHollow />
83
83
  * </IconButton>
84
84
  * </DropdownMenu>,
85
- * <DropdownMenu menuItems={...}>
85
+ * <DropdownMenu menuItems={}>
86
86
  * <IconButton styleType='borderless'>
87
- * <Avatar ... />
87
+ * <Avatar />
88
88
  * </IconButton>
89
89
  * </DropdownMenu>
90
90
  * ]}
@@ -46,7 +46,7 @@ const defaultTranslations = {
46
46
  * appLogo={<HeaderLogo logo={<SvgImodelHollow />}>iTwin Application</HeaderLogo>}
47
47
  * breadcrumbs={
48
48
  * <HeaderBreadcrumbs items={[
49
- * <HeaderButton key='project' name='Project A' />
49
+ * <HeaderButton key='project' name='Project A' />,
50
50
  * <HeaderButton key='imodel' name='IModel X' />
51
51
  * ]} />
52
52
  * }
@@ -57,9 +57,9 @@ const defaultTranslations = {
57
57
  * <SvgHelpCircularHollow />
58
58
  * </IconButton>
59
59
  * </DropdownMenu>,
60
- * <DropdownMenu menuItems={...}>
60
+ * <DropdownMenu menuItems={}>
61
61
  * <IconButton styleType='borderless'>
62
- * <Avatar ... />
62
+ * <Avatar />
63
63
  * </IconButton>
64
64
  * </DropdownMenu>
65
65
  * ]}
@@ -32,7 +32,7 @@ export declare const InputWithDecorations: PolymorphicForwardRefComponent<"div",
32
32
  */
33
33
  Button: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
34
34
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
35
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & Omit<import("../Buttons/IconButton.js").IconButtonProps, "styleType"> & {
35
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & Omit<import("../Buttons/IconButton.js").IconButtonProps, "styleType"> & {
36
36
  styleType?: "default" | "cta" | "high-visibility" | "borderless" | undefined;
37
37
  } & {
38
38
  as?: "button" | undefined;
@@ -101,10 +101,13 @@ const Root = React.forwardRef((props, forwardedRef) => {
101
101
  const shouldApplyDark = theme === 'dark' || (theme === 'os' && prefersDark);
102
102
  const shouldApplyHC = themeOptions?.highContrast ?? prefersHighContrast;
103
103
  const shouldApplyBackground = themeOptions?.applyBackground;
104
- const setOwnerDocument = (0, index_js_1.useScopedSetAtom)(ownerDocumentAtom);
105
- return (React.createElement(index_js_1.Box, { className: (0, classnames_1.default)('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: (0, index_js_1.useMergedRefs)(forwardedRef, (el) => {
106
- setOwnerDocument(el?.ownerDocument);
107
- }), ...rest }, children));
104
+ const [ownerDocument, setOwnerDocument] = (0, index_js_1.useScopedAtom)(ownerDocumentAtom);
105
+ const findOwnerDocumentFromRef = React.useCallback((el) => {
106
+ if (el && el.ownerDocument !== ownerDocument) {
107
+ setOwnerDocument(el.ownerDocument);
108
+ }
109
+ }, [ownerDocument, setOwnerDocument]);
110
+ return (React.createElement(index_js_1.Box, { className: (0, classnames_1.default)('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: (0, index_js_1.useMergedRefs)(forwardedRef, findOwnerDocumentFromRef), ...rest }, children));
108
111
  });
109
112
  // ----------------------------------------------------------------------------
110
113
  /**
@@ -159,33 +162,40 @@ const useParentThemeAndContext = (rootElement) => {
159
162
  */
160
163
  const PortalContainer = React.memo(({ portalContainerProp, portalContainerFromParent, isInheritingTheme, }) => {
161
164
  const [ownerDocument] = (0, index_js_1.useScopedAtom)(ownerDocumentAtom);
162
- const [portalContainer, setPortalContainer] = (0, index_js_1.useScopedAtom)(index_js_1.portalContainerAtom);
165
+ const setPortalContainer = (0, index_js_1.useScopedSetAtom)(index_js_1.portalContainerAtom);
163
166
  // bail if not hydrated, because portals don't work on server
164
167
  const isHydrated = (0, index_js_1.useHydration)() === 'hydrated';
165
168
  if (!isHydrated) {
166
169
  return null;
167
170
  }
171
+ if (portalContainerProp) {
172
+ return React.createElement(PortaledToaster, { target: portalContainerProp });
173
+ }
168
174
  // Create a new portal container only if necessary:
169
175
  // - not inheriting theme
170
176
  // - no parent portal container to portal into
171
177
  // - parent portal container is in a different window (#2006)
172
- if (!portalContainerProp && // bail if portalContainerProp is set, because it takes precedence
173
- (!isInheritingTheme ||
174
- !portalContainerFromParent ||
178
+ if (!isInheritingTheme ||
179
+ !portalContainerFromParent ||
180
+ (!!ownerDocument &&
175
181
  portalContainerFromParent.ownerDocument !== ownerDocument)) {
176
182
  return (React.createElement("div", { style: { display: 'contents' }, ref: setPortalContainer },
177
183
  React.createElement(Toaster_js_1.Toaster, null)));
178
184
  }
179
- const portalTarget = portalContainerProp || portalContainerFromParent;
180
- // Synchronize atom with the correct portal container if necessary.
181
- if (portalTarget && portalTarget !== portalContainer) {
182
- setPortalContainer(portalTarget);
183
- }
184
- return portalTarget
185
- ? ReactDOM.createPortal(React.createElement(Toaster_js_1.Toaster, null), portalTarget)
186
- : null;
185
+ return React.createElement(PortaledToaster, { target: portalContainerFromParent });
187
186
  });
188
187
  // ----------------------------------------------------------------------------
188
+ const PortaledToaster = ({ target }) => {
189
+ const [portalContainer, setPortalContainer] = (0, index_js_1.useScopedAtom)(index_js_1.portalContainerAtom);
190
+ // Synchronize atom with the correct portal target if necessary.
191
+ React.useEffect(() => {
192
+ if (target && target !== portalContainer) {
193
+ setPortalContainer(target);
194
+ }
195
+ });
196
+ return target ? ReactDOM.createPortal(React.createElement(Toaster_js_1.Toaster, null), target) : null;
197
+ };
198
+ // ----------------------------------------------------------------------------
189
199
  /**
190
200
  * When `@itwin/itwinui-react/styles.css` is not imported, we will attempt to
191
201
  * dynamically import it (if possible) and fallback to loading it from a CDN.
@@ -249,7 +249,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
249
249
  */
250
250
  IconButton: PolymorphicForwardRefComponent<"button", Omit<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
251
251
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
252
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
252
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
253
253
  isActive?: boolean | undefined;
254
254
  label?: React.ReactNode;
255
255
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -323,7 +323,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
323
323
  as?: "div" | undefined;
324
324
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
325
325
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
326
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
326
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
327
327
  as?: "button" | undefined;
328
328
  }, "ref">>;
329
329
  /**
@@ -60,9 +60,11 @@ const useScopedAtom = (atom) => {
60
60
  const setAtom = (0, exports.useScopedSetAtom)(atom);
61
61
  const value = (0, jotai_1.useAtomValue)(atom, { store });
62
62
  const inheritedValue = (0, jotai_1.useAtomValue)(atom, { store: parentStore || store });
63
- if (value == undefined && inheritedValue != undefined) {
64
- setAtom(inheritedValue);
65
- }
63
+ React.useEffect(() => {
64
+ if (value == undefined && inheritedValue != undefined) {
65
+ setAtom(inheritedValue);
66
+ }
67
+ });
66
68
  return [value, setAtom];
67
69
  };
68
70
  exports.useScopedAtom = useScopedAtom;
@@ -21,7 +21,7 @@ export type IconButtonProps = {
21
21
  * Passes props to IconButton icon.
22
22
  */
23
23
  iconProps?: React.ComponentProps<'span'>;
24
- } & Omit<ButtonProps, 'startIcon' | 'endIcon' | 'startIconProps' | 'endIconProps' | 'labelProps'>;
24
+ } & Omit<ButtonProps, 'startIcon' | 'endIcon' | 'startIconProps' | 'endIconProps' | 'labelProps' | 'loading'>;
25
25
  /**
26
26
  * Icon button
27
27
  * @example
@@ -42,7 +42,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
42
42
  Navigation: PolymorphicForwardRefComponent<"div", {}> & {
43
43
  PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
44
44
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
45
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
45
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
46
46
  isActive?: boolean | undefined;
47
47
  label?: React.ReactNode;
48
48
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -100,12 +100,12 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
100
100
  as?: "div" | undefined;
101
101
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
102
102
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
103
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
103
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
104
104
  as?: "button" | undefined;
105
105
  }>;
106
106
  NextButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
107
107
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
108
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
108
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
109
109
  isActive?: boolean | undefined;
110
110
  label?: React.ReactNode;
111
111
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -163,7 +163,7 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
163
163
  as?: "div" | undefined;
164
164
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
165
165
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
166
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
166
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
167
167
  as?: "button" | undefined;
168
168
  }>;
169
169
  };
@@ -9,7 +9,7 @@ import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
9
9
  export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {}> & {
10
10
  PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
11
11
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
12
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
12
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
13
13
  isActive?: boolean | undefined;
14
14
  label?: React.ReactNode;
15
15
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -67,12 +67,12 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
67
67
  as?: "div" | undefined;
68
68
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
69
69
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
70
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
70
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
71
71
  as?: "button" | undefined;
72
72
  }>;
73
73
  NextButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
74
74
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
75
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
75
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
76
76
  isActive?: boolean | undefined;
77
77
  label?: React.ReactNode;
78
78
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -130,7 +130,7 @@ export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {
130
130
  as?: "div" | undefined;
131
131
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
132
132
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
133
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
133
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
134
134
  as?: "button" | undefined;
135
135
  }>;
136
136
  };
@@ -71,7 +71,7 @@ type HeaderProps = {
71
71
  * appLogo={<HeaderLogo logo={<SvgImodelHollow />}>iTwin Application</HeaderLogo>}
72
72
  * breadcrumbs={
73
73
  * <HeaderBreadcrumbs items={[
74
- * <HeaderButton key='project' name='Project A' />
74
+ * <HeaderButton key='project' name='Project A' />,
75
75
  * <HeaderButton key='imodel' name='IModel X' />
76
76
  * ]} />
77
77
  * }
@@ -82,9 +82,9 @@ type HeaderProps = {
82
82
  * <SvgHelpCircularHollow />
83
83
  * </IconButton>
84
84
  * </DropdownMenu>,
85
- * <DropdownMenu menuItems={...}>
85
+ * <DropdownMenu menuItems={}>
86
86
  * <IconButton styleType='borderless'>
87
- * <Avatar ... />
87
+ * <Avatar />
88
88
  * </IconButton>
89
89
  * </DropdownMenu>
90
90
  * ]}
@@ -17,7 +17,7 @@ const defaultTranslations = {
17
17
  * appLogo={<HeaderLogo logo={<SvgImodelHollow />}>iTwin Application</HeaderLogo>}
18
18
  * breadcrumbs={
19
19
  * <HeaderBreadcrumbs items={[
20
- * <HeaderButton key='project' name='Project A' />
20
+ * <HeaderButton key='project' name='Project A' />,
21
21
  * <HeaderButton key='imodel' name='IModel X' />
22
22
  * ]} />
23
23
  * }
@@ -28,9 +28,9 @@ const defaultTranslations = {
28
28
  * <SvgHelpCircularHollow />
29
29
  * </IconButton>
30
30
  * </DropdownMenu>,
31
- * <DropdownMenu menuItems={...}>
31
+ * <DropdownMenu menuItems={}>
32
32
  * <IconButton styleType='borderless'>
33
- * <Avatar ... />
33
+ * <Avatar />
34
34
  * </IconButton>
35
35
  * </DropdownMenu>
36
36
  * ]}
@@ -32,7 +32,7 @@ export declare const InputWithDecorations: PolymorphicForwardRefComponent<"div",
32
32
  */
33
33
  Button: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
34
34
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
35
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & Omit<import("../Buttons/IconButton.js").IconButtonProps, "styleType"> & {
35
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & Omit<import("../Buttons/IconButton.js").IconButtonProps, "styleType"> & {
36
36
  styleType?: "default" | "cta" | "high-visibility" | "borderless" | undefined;
37
37
  } & {
38
38
  as?: "button" | undefined;
@@ -72,10 +72,13 @@ const Root = React.forwardRef((props, forwardedRef) => {
72
72
  const shouldApplyDark = theme === 'dark' || (theme === 'os' && prefersDark);
73
73
  const shouldApplyHC = themeOptions?.highContrast ?? prefersHighContrast;
74
74
  const shouldApplyBackground = themeOptions?.applyBackground;
75
- const setOwnerDocument = useScopedSetAtom(ownerDocumentAtom);
76
- return (React.createElement(Box, { className: cx('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: useMergedRefs(forwardedRef, (el) => {
77
- setOwnerDocument(el?.ownerDocument);
78
- }), ...rest }, children));
75
+ const [ownerDocument, setOwnerDocument] = useScopedAtom(ownerDocumentAtom);
76
+ const findOwnerDocumentFromRef = React.useCallback((el) => {
77
+ if (el && el.ownerDocument !== ownerDocument) {
78
+ setOwnerDocument(el.ownerDocument);
79
+ }
80
+ }, [ownerDocument, setOwnerDocument]);
81
+ return (React.createElement(Box, { className: cx('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: useMergedRefs(forwardedRef, findOwnerDocumentFromRef), ...rest }, children));
79
82
  });
80
83
  // ----------------------------------------------------------------------------
81
84
  /**
@@ -130,33 +133,40 @@ const useParentThemeAndContext = (rootElement) => {
130
133
  */
131
134
  const PortalContainer = React.memo(({ portalContainerProp, portalContainerFromParent, isInheritingTheme, }) => {
132
135
  const [ownerDocument] = useScopedAtom(ownerDocumentAtom);
133
- const [portalContainer, setPortalContainer] = useScopedAtom(portalContainerAtom);
136
+ const setPortalContainer = useScopedSetAtom(portalContainerAtom);
134
137
  // bail if not hydrated, because portals don't work on server
135
138
  const isHydrated = useHydration() === 'hydrated';
136
139
  if (!isHydrated) {
137
140
  return null;
138
141
  }
142
+ if (portalContainerProp) {
143
+ return React.createElement(PortaledToaster, { target: portalContainerProp });
144
+ }
139
145
  // Create a new portal container only if necessary:
140
146
  // - not inheriting theme
141
147
  // - no parent portal container to portal into
142
148
  // - parent portal container is in a different window (#2006)
143
- if (!portalContainerProp && // bail if portalContainerProp is set, because it takes precedence
144
- (!isInheritingTheme ||
145
- !portalContainerFromParent ||
149
+ if (!isInheritingTheme ||
150
+ !portalContainerFromParent ||
151
+ (!!ownerDocument &&
146
152
  portalContainerFromParent.ownerDocument !== ownerDocument)) {
147
153
  return (React.createElement("div", { style: { display: 'contents' }, ref: setPortalContainer },
148
154
  React.createElement(Toaster, null)));
149
155
  }
150
- const portalTarget = portalContainerProp || portalContainerFromParent;
151
- // Synchronize atom with the correct portal container if necessary.
152
- if (portalTarget && portalTarget !== portalContainer) {
153
- setPortalContainer(portalTarget);
154
- }
155
- return portalTarget
156
- ? ReactDOM.createPortal(React.createElement(Toaster, null), portalTarget)
157
- : null;
156
+ return React.createElement(PortaledToaster, { target: portalContainerFromParent });
158
157
  });
159
158
  // ----------------------------------------------------------------------------
159
+ const PortaledToaster = ({ target }) => {
160
+ const [portalContainer, setPortalContainer] = useScopedAtom(portalContainerAtom);
161
+ // Synchronize atom with the correct portal target if necessary.
162
+ React.useEffect(() => {
163
+ if (target && target !== portalContainer) {
164
+ setPortalContainer(target);
165
+ }
166
+ });
167
+ return target ? ReactDOM.createPortal(React.createElement(Toaster, null), target) : null;
168
+ };
169
+ // ----------------------------------------------------------------------------
160
170
  /**
161
171
  * When `@itwin/itwinui-react/styles.css` is not imported, we will attempt to
162
172
  * dynamically import it (if possible) and fallback to loading it from a CDN.
@@ -249,7 +249,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
249
249
  */
250
250
  IconButton: PolymorphicForwardRefComponent<"button", Omit<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
251
251
  ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
252
- }, "label" | "as" | "loading" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
252
+ }, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "labelProps" | "stretched" | "isActive" | "iconProps"> & {
253
253
  isActive?: boolean | undefined;
254
254
  label?: React.ReactNode;
255
255
  labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
@@ -323,7 +323,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
323
323
  as?: "div" | undefined;
324
324
  }, "ref">, "children" | "content" | "reference" | "ariaStrategy"> | undefined;
325
325
  iconProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> | undefined;
326
- } & Omit<import("../Buttons/Button.js").ButtonProps, "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
326
+ } & Omit<import("../Buttons/Button.js").ButtonProps, "loading" | "startIcon" | "endIcon" | "labelProps" | "startIconProps" | "endIconProps"> & {
327
327
  as?: "button" | undefined;
328
328
  }, "ref">>;
329
329
  /**
@@ -33,9 +33,11 @@ export const useScopedAtom = (atom) => {
33
33
  const setAtom = useScopedSetAtom(atom);
34
34
  const value = useAtomValue(atom, { store });
35
35
  const inheritedValue = useAtomValue(atom, { store: parentStore || store });
36
- if (value == undefined && inheritedValue != undefined) {
37
- setAtom(inheritedValue);
38
- }
36
+ React.useEffect(() => {
37
+ if (value == undefined && inheritedValue != undefined) {
38
+ setAtom(inheritedValue);
39
+ }
40
+ });
39
41
  return [value, setAtom];
40
42
  };
41
43
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "3.11.1",
3
+ "version": "3.11.2",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "type": "module",