@itwin/itwinui-react 3.17.0-dev.0 → 3.17.0-dev.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 +28 -0
- package/DEV-cjs/core/Dialog/Dialog.js +35 -42
- package/DEV-cjs/core/Dialog/DialogBackdrop.js +6 -1
- package/DEV-cjs/core/Dialog/DialogMain.js +42 -34
- package/DEV-cjs/core/Dialog/DialogMainContext.js +23 -0
- package/DEV-cjs/core/Dialog/DialogTitleBar.js +10 -1
- package/DEV-cjs/core/Panels/Panels.js +1 -1
- package/DEV-cjs/core/SideNavigation/SideNavigation.js +1 -11
- package/DEV-cjs/core/Table/actionHandlers/selectHandler.js +7 -8
- package/DEV-cjs/core/Tabs/Tabs.js +9 -1
- package/DEV-cjs/core/ThemeProvider/ThemeProvider.js +12 -9
- package/DEV-cjs/core/Toast/Toast.js +132 -77
- package/DEV-cjs/core/Toast/Toaster.js +11 -3
- package/DEV-cjs/styles.js +1 -1
- package/DEV-cjs/utils/components/index.js +0 -1
- package/DEV-esm/core/Dialog/Dialog.js +32 -42
- package/DEV-esm/core/Dialog/DialogBackdrop.js +6 -1
- package/DEV-esm/core/Dialog/DialogMain.js +42 -34
- package/DEV-esm/core/Dialog/DialogMainContext.js +3 -0
- package/DEV-esm/core/Dialog/DialogTitleBar.js +10 -1
- package/DEV-esm/core/Panels/Panels.js +2 -1
- package/DEV-esm/core/SideNavigation/SideNavigation.js +2 -17
- package/DEV-esm/core/Table/actionHandlers/selectHandler.js +7 -8
- package/DEV-esm/core/Tabs/Tabs.js +9 -1
- package/DEV-esm/core/ThemeProvider/ThemeProvider.js +12 -9
- package/DEV-esm/core/Toast/Toast.js +131 -75
- package/DEV-esm/core/Toast/Toaster.js +11 -3
- package/DEV-esm/styles.js +1 -1
- package/DEV-esm/utils/components/index.js +0 -1
- package/LICENSE.md +1 -1
- package/cjs/core/Dialog/Dialog.d.ts +1 -1
- package/cjs/core/Dialog/Dialog.js +35 -42
- package/cjs/core/Dialog/DialogBackdrop.d.ts +1 -1
- package/cjs/core/Dialog/DialogBackdrop.js +6 -1
- package/cjs/core/Dialog/DialogMain.js +42 -34
- package/cjs/core/Dialog/DialogMainContext.d.ts +7 -0
- package/cjs/core/Dialog/DialogMainContext.js +23 -0
- package/cjs/core/Dialog/DialogTitleBar.js +10 -1
- package/cjs/core/Panels/Panels.js +1 -1
- package/cjs/core/SideNavigation/SideNavigation.d.ts +2 -2
- package/cjs/core/SideNavigation/SideNavigation.js +1 -11
- package/cjs/core/Table/actionHandlers/selectHandler.js +7 -8
- package/cjs/core/Tabs/Tabs.js +9 -1
- package/cjs/core/ThemeProvider/ThemeContext.d.ts +2 -1
- package/cjs/core/ThemeProvider/ThemeProvider.d.ts +13 -5
- package/cjs/core/ThemeProvider/ThemeProvider.js +12 -9
- package/cjs/core/Toast/Toast.d.ts +1 -1
- package/cjs/core/Toast/Toast.js +132 -77
- package/cjs/core/Toast/Toaster.d.ts +1 -1
- package/cjs/core/Toast/Toaster.js +11 -3
- package/cjs/styles.js +1 -1
- package/cjs/utils/components/index.d.ts +0 -1
- package/cjs/utils/components/index.js +0 -1
- package/cjs/utils/hooks/useGlobals.d.ts +1 -0
- package/esm/core/Dialog/Dialog.d.ts +1 -1
- package/esm/core/Dialog/Dialog.js +32 -42
- package/esm/core/Dialog/DialogBackdrop.d.ts +1 -1
- package/esm/core/Dialog/DialogBackdrop.js +6 -1
- package/esm/core/Dialog/DialogMain.js +42 -34
- package/esm/core/Dialog/DialogMainContext.d.ts +7 -0
- package/esm/core/Dialog/DialogMainContext.js +3 -0
- package/esm/core/Dialog/DialogTitleBar.js +10 -1
- package/esm/core/Panels/Panels.js +2 -1
- package/esm/core/SideNavigation/SideNavigation.d.ts +2 -2
- package/esm/core/SideNavigation/SideNavigation.js +2 -17
- package/esm/core/Table/actionHandlers/selectHandler.js +7 -8
- package/esm/core/Tabs/Tabs.js +9 -1
- package/esm/core/ThemeProvider/ThemeContext.d.ts +2 -1
- package/esm/core/ThemeProvider/ThemeProvider.d.ts +13 -5
- package/esm/core/ThemeProvider/ThemeProvider.js +12 -9
- package/esm/core/Toast/Toast.d.ts +1 -1
- package/esm/core/Toast/Toast.js +131 -75
- package/esm/core/Toast/Toaster.d.ts +1 -1
- package/esm/core/Toast/Toaster.js +11 -3
- package/esm/styles.js +1 -1
- package/esm/utils/components/index.d.ts +0 -1
- package/esm/utils/components/index.js +0 -1
- package/esm/utils/hooks/useGlobals.d.ts +1 -0
- package/package.json +5 -7
- package/styles.css +10 -10
- package/DEV-cjs/utils/components/WithCSSTransition.js +0 -60
- package/DEV-esm/utils/components/WithCSSTransition.js +0 -49
- package/cjs/utils/components/WithCSSTransition.d.ts +0 -6
- package/cjs/utils/components/WithCSSTransition.js +0 -60
- package/esm/utils/components/WithCSSTransition.d.ts +0 -6
- package/esm/utils/components/WithCSSTransition.js +0 -49
|
@@ -23,13 +23,14 @@ import { meta } from '../../utils/meta.js';
|
|
|
23
23
|
let versionWithoutDots = meta.version.replace(/\./g, '');
|
|
24
24
|
let ownerDocumentAtom = atom(void 0);
|
|
25
25
|
export const ThemeProvider = React.forwardRef((props, forwardedRef) => {
|
|
26
|
-
var _themeOptions, _themeOptions1,
|
|
26
|
+
var _themeOptions, _themeOptions1, _future;
|
|
27
27
|
let {
|
|
28
28
|
theme: themeProp = 'inherit',
|
|
29
29
|
children,
|
|
30
30
|
themeOptions = {},
|
|
31
31
|
portalContainer: portalContainerProp,
|
|
32
32
|
includeCss = 'inherit' === themeProp,
|
|
33
|
+
future = {},
|
|
33
34
|
...rest
|
|
34
35
|
} = props;
|
|
35
36
|
useInertPolyfill();
|
|
@@ -41,18 +42,16 @@ export const ThemeProvider = React.forwardRef((props, forwardedRef) => {
|
|
|
41
42
|
(_themeOptions1 = themeOptions).highContrast ??
|
|
42
43
|
(_themeOptions1.highContrast =
|
|
43
44
|
'inherit' === themeProp ? parent.highContrast : void 0);
|
|
44
|
-
(
|
|
45
|
-
(
|
|
46
|
-
'inherit' === themeProp
|
|
47
|
-
? parent.context?.themeOptions?.bridgeToFutureVersions
|
|
48
|
-
: void 0);
|
|
45
|
+
(_future = future).themeBridge ??
|
|
46
|
+
(_future.themeBridge = parent.context?.future?.themeBridge);
|
|
49
47
|
let [portalContainerFromParent] = useScopedAtom(portalContainerAtom);
|
|
50
48
|
let contextValue = React.useMemo(
|
|
51
49
|
() => ({
|
|
52
50
|
theme,
|
|
53
51
|
themeOptions,
|
|
52
|
+
future,
|
|
54
53
|
}),
|
|
55
|
-
[theme, JSON.stringify(themeOptions)],
|
|
54
|
+
[theme, JSON.stringify(themeOptions), JSON.stringify(future)],
|
|
56
55
|
);
|
|
57
56
|
return React.createElement(
|
|
58
57
|
ScopeProvider,
|
|
@@ -80,6 +79,7 @@ export const ThemeProvider = React.forwardRef((props, forwardedRef) => {
|
|
|
80
79
|
{
|
|
81
80
|
theme: theme,
|
|
82
81
|
themeOptions: themeOptions,
|
|
82
|
+
future: future,
|
|
83
83
|
ref: useMergedRefs(forwardedRef, setRootElement, useIuiDebugRef),
|
|
84
84
|
...rest,
|
|
85
85
|
},
|
|
@@ -87,6 +87,7 @@ export const ThemeProvider = React.forwardRef((props, forwardedRef) => {
|
|
|
87
87
|
React.createElement(PortalContainer, {
|
|
88
88
|
theme: theme,
|
|
89
89
|
themeOptions: themeOptions,
|
|
90
|
+
future: future,
|
|
90
91
|
portalContainerProp: portalContainerProp,
|
|
91
92
|
portalContainerFromParent: portalContainerFromParent,
|
|
92
93
|
isInheritingTheme: 'inherit' === themeProp,
|
|
@@ -113,7 +114,7 @@ let MainRoot = React.forwardRef((props, forwardedRef) => {
|
|
|
113
114
|
});
|
|
114
115
|
});
|
|
115
116
|
let Root = React.forwardRef((props, forwardedRef) => {
|
|
116
|
-
let { theme, children, themeOptions, className, ...rest } = props;
|
|
117
|
+
let { theme, children, themeOptions, className, future, ...rest } = props;
|
|
117
118
|
let prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
|
|
118
119
|
let prefersHighContrast = useMediaQuery('(prefers-contrast: more)');
|
|
119
120
|
let shouldApplyDark = 'dark' === theme || ('os' === theme && prefersDark);
|
|
@@ -131,7 +132,7 @@ let Root = React.forwardRef((props, forwardedRef) => {
|
|
|
131
132
|
),
|
|
132
133
|
'data-iui-theme': shouldApplyDark ? 'dark' : 'light',
|
|
133
134
|
'data-iui-contrast': shouldApplyHC ? 'high' : 'default',
|
|
134
|
-
'data-iui-bridge': !!
|
|
135
|
+
'data-iui-bridge': !!future?.themeBridge || void 0,
|
|
135
136
|
ref: forwardedRef,
|
|
136
137
|
...rest,
|
|
137
138
|
},
|
|
@@ -179,6 +180,7 @@ let PortalContainer = React.memo(
|
|
|
179
180
|
isInheritingTheme,
|
|
180
181
|
theme,
|
|
181
182
|
themeOptions,
|
|
183
|
+
future,
|
|
182
184
|
}) => {
|
|
183
185
|
let [ownerDocument] = useScopedAtom(ownerDocumentAtom);
|
|
184
186
|
let [portalContainer, setPortalContainer] =
|
|
@@ -208,6 +210,7 @@ let PortalContainer = React.memo(
|
|
|
208
210
|
...themeOptions,
|
|
209
211
|
applyBackground: false,
|
|
210
212
|
},
|
|
213
|
+
future: future,
|
|
211
214
|
'data-iui-portal': true,
|
|
212
215
|
style: {
|
|
213
216
|
display: 'contents',
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { Transition } from 'react-transition-group';
|
|
3
2
|
import cx from 'classnames';
|
|
4
3
|
import {
|
|
5
4
|
getWindow,
|
|
@@ -9,6 +8,7 @@ import {
|
|
|
9
8
|
useSafeContext,
|
|
10
9
|
ButtonBase,
|
|
11
10
|
useMediaQuery,
|
|
11
|
+
useLatestRef,
|
|
12
12
|
} from '../../utils/index.js';
|
|
13
13
|
import { IconButton } from '../Buttons/IconButton.js';
|
|
14
14
|
import { ToasterStateContext } from './Toaster.js';
|
|
@@ -33,7 +33,6 @@ export const Toast = (props) => {
|
|
|
33
33
|
let [height, setHeight] = React.useState(0);
|
|
34
34
|
let thisElement = React.useRef(null);
|
|
35
35
|
let [margin, setMargin] = React.useState(0);
|
|
36
|
-
let motionOk = useMediaQuery('(prefers-reduced-motion: no-preference)');
|
|
37
36
|
let marginStyle = () => {
|
|
38
37
|
if ('top' === placementPosition)
|
|
39
38
|
return {
|
|
@@ -73,81 +72,41 @@ export const Toast = (props) => {
|
|
|
73
72
|
setHeight(height);
|
|
74
73
|
}
|
|
75
74
|
};
|
|
76
|
-
let
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
translateX,
|
|
87
|
-
translateY,
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
return React.createElement(
|
|
91
|
-
Transition,
|
|
92
|
-
{
|
|
93
|
-
timeout: {
|
|
94
|
-
enter: 240,
|
|
95
|
-
exit: animateOutTo ? 400 : 120,
|
|
96
|
-
},
|
|
97
|
-
in: isVisible,
|
|
98
|
-
appear: true,
|
|
99
|
-
unmountOnExit: true,
|
|
100
|
-
onEnter: (node) => {
|
|
101
|
-
if (motionOk) {
|
|
102
|
-
node.style.transform = 'translateY(15%)';
|
|
103
|
-
node.style.transitionTimingFunction = 'ease';
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
onEntered: (node) => {
|
|
107
|
-
if (motionOk) node.style.transform = 'translateY(0)';
|
|
108
|
-
},
|
|
109
|
-
onExiting: (node) => {
|
|
110
|
-
if (motionOk) {
|
|
111
|
-
let { translateX, translateY } = calculateOutAnimation(node);
|
|
112
|
-
node.style.transform = animateOutTo
|
|
113
|
-
? `scale(0.9) translate(${translateX}px,${translateY}px)`
|
|
114
|
-
: 'scale(0.9)';
|
|
115
|
-
node.style.opacity = '0';
|
|
116
|
-
node.style.transitionDuration = animateOutTo ? '400ms' : '120ms';
|
|
117
|
-
node.style.transitionTimingFunction = 'cubic-bezier(0.4, 0, 1, 1)';
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
onExited: onRemove,
|
|
121
|
-
},
|
|
122
|
-
React.createElement(
|
|
123
|
-
Box,
|
|
124
|
-
{
|
|
125
|
-
ref: thisElement,
|
|
126
|
-
className: 'iui-toast-all',
|
|
127
|
-
style: {
|
|
128
|
-
height,
|
|
129
|
-
...marginStyle(),
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
React.createElement(
|
|
133
|
-
'div',
|
|
75
|
+
let shouldBeMounted = useAnimateToastBasedOnVisibility(isVisible, {
|
|
76
|
+
thisElement,
|
|
77
|
+
animateOutTo,
|
|
78
|
+
onRemove,
|
|
79
|
+
});
|
|
80
|
+
return shouldBeMounted
|
|
81
|
+
? React.createElement(
|
|
82
|
+
Box,
|
|
134
83
|
{
|
|
135
|
-
ref:
|
|
84
|
+
ref: thisElement,
|
|
85
|
+
className: 'iui-toast-all',
|
|
86
|
+
style: {
|
|
87
|
+
height,
|
|
88
|
+
...marginStyle(),
|
|
89
|
+
},
|
|
136
90
|
},
|
|
137
|
-
React.createElement(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
91
|
+
React.createElement(
|
|
92
|
+
'div',
|
|
93
|
+
{
|
|
94
|
+
ref: onRef,
|
|
95
|
+
},
|
|
96
|
+
React.createElement(ToastPresentation, {
|
|
97
|
+
as: 'div',
|
|
98
|
+
category: category,
|
|
99
|
+
content: content,
|
|
100
|
+
link: link,
|
|
101
|
+
type: type,
|
|
102
|
+
hasCloseButton: hasCloseButton,
|
|
103
|
+
onClose: close,
|
|
104
|
+
...domProps?.toastProps,
|
|
105
|
+
contentProps: domProps?.contentProps,
|
|
106
|
+
}),
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
: null;
|
|
151
110
|
};
|
|
152
111
|
export const ToastPresentation = React.forwardRef((props, forwardedRef) => {
|
|
153
112
|
let {
|
|
@@ -212,3 +171,100 @@ export const ToastPresentation = React.forwardRef((props, forwardedRef) => {
|
|
|
212
171
|
),
|
|
213
172
|
);
|
|
214
173
|
});
|
|
174
|
+
let useAnimateToastBasedOnVisibility = (isVisible, args) => {
|
|
175
|
+
let { thisElement, animateOutTo, onRemove } = args;
|
|
176
|
+
let [shouldBeMounted, setShouldBeMounted] = React.useState(isVisible);
|
|
177
|
+
let motionOk = useMediaQuery('(prefers-reduced-motion: no-preference)');
|
|
178
|
+
let onRemoveRef = useLatestRef(onRemove);
|
|
179
|
+
let [prevIsVisible, setPrevIsVisible] = React.useState(void 0);
|
|
180
|
+
React.useEffect(() => {
|
|
181
|
+
if (prevIsVisible !== isVisible) {
|
|
182
|
+
setPrevIsVisible(isVisible);
|
|
183
|
+
if (isVisible) safeAnimateIn();
|
|
184
|
+
else safeAnimateOut();
|
|
185
|
+
}
|
|
186
|
+
function calculateOutAnimation(node) {
|
|
187
|
+
let translateX = 0;
|
|
188
|
+
let translateY = 0;
|
|
189
|
+
if (animateOutTo && node) {
|
|
190
|
+
let { x: startX, y: startY } = node.getBoundingClientRect();
|
|
191
|
+
let { x: endX, y: endY } = animateOutTo.getBoundingClientRect();
|
|
192
|
+
translateX = endX - startX;
|
|
193
|
+
translateY = endY - startY;
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
translateX,
|
|
197
|
+
translateY,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function safeAnimateIn() {
|
|
201
|
+
setShouldBeMounted(true);
|
|
202
|
+
queueMicrotask(() => {
|
|
203
|
+
animateIn();
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
function safeAnimateOut() {
|
|
207
|
+
if (motionOk) {
|
|
208
|
+
let animation = animateOut();
|
|
209
|
+
animation?.addEventListener('finish', () => {
|
|
210
|
+
setShouldBeMounted(false);
|
|
211
|
+
onRemoveRef.current?.();
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
setShouldBeMounted(false);
|
|
215
|
+
onRemoveRef.current?.();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function animateIn() {
|
|
219
|
+
if (!motionOk) return;
|
|
220
|
+
thisElement.current?.animate?.(
|
|
221
|
+
[
|
|
222
|
+
{
|
|
223
|
+
transform: 'translateY(15%)',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
transform: 'translateY(0)',
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
{
|
|
230
|
+
duration: 240,
|
|
231
|
+
fill: 'forwards',
|
|
232
|
+
},
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
function animateOut() {
|
|
236
|
+
if (null == thisElement.current || !motionOk) return;
|
|
237
|
+
let { translateX, translateY } = calculateOutAnimation(
|
|
238
|
+
thisElement.current,
|
|
239
|
+
);
|
|
240
|
+
let animationDuration = animateOutTo ? 400 : 120;
|
|
241
|
+
let animation = thisElement.current?.animate?.(
|
|
242
|
+
[
|
|
243
|
+
{
|
|
244
|
+
transform: animateOutTo
|
|
245
|
+
? `scale(0.9) translate(${translateX}px,${translateY}px)`
|
|
246
|
+
: 'scale(0.9)',
|
|
247
|
+
opacity: 0,
|
|
248
|
+
transitionDuration: `${animationDuration}ms`,
|
|
249
|
+
transitionTimingFunction: 'cubic-bezier(0.4, 0, 1, 1)',
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
{
|
|
253
|
+
duration: animationDuration,
|
|
254
|
+
iterations: 1,
|
|
255
|
+
fill: 'forwards',
|
|
256
|
+
},
|
|
257
|
+
);
|
|
258
|
+
return animation;
|
|
259
|
+
}
|
|
260
|
+
}, [
|
|
261
|
+
isVisible,
|
|
262
|
+
prevIsVisible,
|
|
263
|
+
animateOutTo,
|
|
264
|
+
motionOk,
|
|
265
|
+
thisElement,
|
|
266
|
+
setShouldBeMounted,
|
|
267
|
+
onRemoveRef,
|
|
268
|
+
]);
|
|
269
|
+
return shouldBeMounted;
|
|
270
|
+
};
|
|
@@ -66,16 +66,24 @@ export const ToastProvider = ({ children, inherit = false }) => {
|
|
|
66
66
|
placement: 'top',
|
|
67
67
|
},
|
|
68
68
|
});
|
|
69
|
-
|
|
69
|
+
let toasterDispatchContext = React.useContext(ToasterDispatchContext);
|
|
70
|
+
let toasterStateContext = React.useContext(ToasterStateContext);
|
|
71
|
+
let shouldReuse = toasterStateContext && inherit;
|
|
72
|
+
let toasterDispatchContextValue = shouldReuse
|
|
73
|
+
? toasterDispatchContext
|
|
74
|
+
: dispatch;
|
|
75
|
+
let toasterStateContextValue = shouldReuse
|
|
76
|
+
? toasterStateContext
|
|
77
|
+
: toasterState;
|
|
70
78
|
return React.createElement(
|
|
71
79
|
ToasterDispatchContext.Provider,
|
|
72
80
|
{
|
|
73
|
-
value:
|
|
81
|
+
value: toasterDispatchContextValue,
|
|
74
82
|
},
|
|
75
83
|
React.createElement(
|
|
76
84
|
ToasterStateContext.Provider,
|
|
77
85
|
{
|
|
78
|
-
value:
|
|
86
|
+
value: toasterStateContextValue,
|
|
79
87
|
},
|
|
80
88
|
children,
|
|
81
89
|
),
|
package/DEV-esm/styles.js
CHANGED
|
@@ -3,7 +3,6 @@ export * from './FocusTrap.js';
|
|
|
3
3
|
export * from './InputContainer.js';
|
|
4
4
|
export * from './InputFlexContainer.js';
|
|
5
5
|
export * from './InputWithIcon.js';
|
|
6
|
-
export * from './WithCSSTransition.js';
|
|
7
6
|
export * from './MiddleTextTruncation.js';
|
|
8
7
|
export * from './AutoclearingHiddenLiveRegion.js';
|
|
9
8
|
export * from './Box.js';
|
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MIT License
|
|
2
2
|
|
|
3
|
-
Copyright © 2021-
|
|
3
|
+
Copyright © 2021-2025 Bentley Systems, Incorporated. All rights reserved.
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
|
@@ -19,7 +19,6 @@ const _DialogContext = require('./DialogContext.js');
|
|
|
19
19
|
const _DialogButtonBar = require('./DialogButtonBar.js');
|
|
20
20
|
const _DialogMain = require('./DialogMain.js');
|
|
21
21
|
const _index = require('../../utils/index.js');
|
|
22
|
-
const _reacttransitiongroup = require('react-transition-group');
|
|
23
22
|
const DialogComponent = _react.forwardRef((props, ref) => {
|
|
24
23
|
let {
|
|
25
24
|
trapFocus = false,
|
|
@@ -39,49 +38,43 @@ const DialogComponent = _react.forwardRef((props, ref) => {
|
|
|
39
38
|
...rest
|
|
40
39
|
} = props;
|
|
41
40
|
let dialogRootRef = _react.useRef(null);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
timeout: {
|
|
47
|
-
exit: 600,
|
|
48
|
-
},
|
|
49
|
-
mountOnEnter: true,
|
|
50
|
-
unmountOnExit: true,
|
|
51
|
-
},
|
|
52
|
-
_react.createElement(
|
|
53
|
-
_DialogContext.DialogContext.Provider,
|
|
54
|
-
{
|
|
55
|
-
value: {
|
|
56
|
-
isOpen,
|
|
57
|
-
onClose,
|
|
58
|
-
closeOnEsc,
|
|
59
|
-
closeOnExternalClick,
|
|
60
|
-
isDismissible,
|
|
61
|
-
preventDocumentScroll,
|
|
62
|
-
trapFocus,
|
|
63
|
-
setFocus,
|
|
64
|
-
isDraggable,
|
|
65
|
-
isResizable,
|
|
66
|
-
relativeTo,
|
|
67
|
-
dialogRootRef,
|
|
68
|
-
placement,
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
_react.createElement(
|
|
72
|
-
_index.Portal,
|
|
41
|
+
let mergedRefs = (0, _index.useMergedRefs)(ref, dialogRootRef);
|
|
42
|
+
return isOpen
|
|
43
|
+
? _react.createElement(
|
|
44
|
+
_DialogContext.DialogContext.Provider,
|
|
73
45
|
{
|
|
74
|
-
|
|
46
|
+
value: {
|
|
47
|
+
isOpen,
|
|
48
|
+
onClose,
|
|
49
|
+
closeOnEsc,
|
|
50
|
+
closeOnExternalClick,
|
|
51
|
+
isDismissible,
|
|
52
|
+
preventDocumentScroll,
|
|
53
|
+
trapFocus,
|
|
54
|
+
setFocus,
|
|
55
|
+
isDraggable,
|
|
56
|
+
isResizable,
|
|
57
|
+
relativeTo,
|
|
58
|
+
placement,
|
|
59
|
+
},
|
|
75
60
|
},
|
|
76
|
-
_react.createElement(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
61
|
+
_react.createElement(
|
|
62
|
+
_index.Portal,
|
|
63
|
+
{
|
|
64
|
+
portal: portal,
|
|
65
|
+
},
|
|
66
|
+
_react.createElement(_index.Box, {
|
|
67
|
+
className: (0, _classnames.default)(
|
|
68
|
+
'iui-dialog-wrapper',
|
|
69
|
+
className,
|
|
70
|
+
),
|
|
71
|
+
'data-iui-relative': 'container' === relativeTo,
|
|
72
|
+
ref: mergedRefs,
|
|
73
|
+
...rest,
|
|
74
|
+
}),
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
: null;
|
|
85
78
|
});
|
|
86
79
|
const Dialog = Object.assign(DialogComponent, {
|
|
87
80
|
Backdrop: _DialogBackdrop.DialogBackdrop,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BackdropProps } from '../Backdrop/Backdrop.js';
|
|
2
2
|
import type { PolymorphicForwardRefComponent } from '../../utils/index.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type DialogContextProps } from './DialogContext.js';
|
|
4
4
|
type DialogBackdropProps = BackdropProps & Pick<DialogContextProps, 'onClose' | 'isDismissible' | 'closeOnExternalClick' | 'relativeTo'>;
|
|
5
5
|
/**
|
|
6
6
|
* Backdrop component for dialog. Recommended to be used with `Dialog`
|
|
@@ -14,9 +14,11 @@ const _react = _interop_require_wildcard._(require('react'));
|
|
|
14
14
|
const _Backdrop = require('../Backdrop/Backdrop.js');
|
|
15
15
|
const _index = require('../../utils/index.js');
|
|
16
16
|
const _DialogContext = require('./DialogContext.js');
|
|
17
|
+
const _DialogMainContext = require('./DialogMainContext.js');
|
|
17
18
|
const _classnames = _interop_require_default._(require('classnames'));
|
|
18
19
|
const DialogBackdrop = _react.forwardRef((props, ref) => {
|
|
19
20
|
let dialogContext = (0, _DialogContext.useDialogContext)();
|
|
21
|
+
let dialogMainContext = (0, _DialogMainContext.useDialogMainContext)();
|
|
20
22
|
let {
|
|
21
23
|
isVisible = dialogContext.isOpen,
|
|
22
24
|
isDismissible = dialogContext.isDismissible,
|
|
@@ -33,7 +35,10 @@ const DialogBackdrop = _react.forwardRef((props, ref) => {
|
|
|
33
35
|
let handleMouseDown = (event) => {
|
|
34
36
|
event.persist();
|
|
35
37
|
if (event.target !== backdropRef.current) return;
|
|
36
|
-
if (isDismissible && closeOnExternalClick && onClose)
|
|
38
|
+
if (isDismissible && closeOnExternalClick && onClose) {
|
|
39
|
+
dialogMainContext?.beforeClose();
|
|
40
|
+
onClose(event);
|
|
41
|
+
}
|
|
37
42
|
onMouseDown?.(event);
|
|
38
43
|
};
|
|
39
44
|
return _react.createElement(_Backdrop.Backdrop, {
|
|
@@ -14,9 +14,9 @@ const _react = _interop_require_wildcard._(require('react'));
|
|
|
14
14
|
const _classnames = _interop_require_default._(require('classnames'));
|
|
15
15
|
const _index = require('../../utils/index.js');
|
|
16
16
|
const _DialogContext = require('./DialogContext.js');
|
|
17
|
-
const _reacttransitiongroup = require('react-transition-group');
|
|
18
17
|
const _DialogDragContext = require('./DialogDragContext.js');
|
|
19
18
|
const _useDragAndDrop = require('../../utils/hooks/useDragAndDrop.js');
|
|
19
|
+
const _DialogMainContext = require('./DialogMainContext.js');
|
|
20
20
|
const DialogMain = _react.forwardRef((props, ref) => {
|
|
21
21
|
let dialogContext = (0, _DialogContext.useDialogContext)();
|
|
22
22
|
let {
|
|
@@ -37,12 +37,13 @@ const DialogMain = _react.forwardRef((props, ref) => {
|
|
|
37
37
|
placement = dialogContext.placement,
|
|
38
38
|
...rest
|
|
39
39
|
} = props;
|
|
40
|
-
let
|
|
40
|
+
let { dialogRootRef } = dialogContext;
|
|
41
41
|
let dialogRef = _react.useRef(null);
|
|
42
|
-
let hasBeenResized = _react.useRef(false);
|
|
43
42
|
let previousFocusedElement = _react.useRef();
|
|
43
|
+
let [style, setStyle] = _react.useState();
|
|
44
|
+
let hasBeenResized = _react.useRef(false);
|
|
44
45
|
let originalBodyOverflow = _react.useRef('');
|
|
45
|
-
|
|
46
|
+
(0, _index.useLayoutEffect)(() => {
|
|
46
47
|
if (isOpen) originalBodyOverflow.current = document.body.style.overflow;
|
|
47
48
|
}, [isOpen]);
|
|
48
49
|
_react.useEffect(() => {
|
|
@@ -58,17 +59,19 @@ const DialogMain = _react.forwardRef((props, ref) => {
|
|
|
58
59
|
return () => {
|
|
59
60
|
ownerDocument.body.style.overflow = originalBodyOverflow.current;
|
|
60
61
|
};
|
|
61
|
-
}, [isOpen, preventDocumentScroll]);
|
|
62
|
+
}, [dialogRef, isOpen, preventDocumentScroll]);
|
|
62
63
|
let handleKeyDown = (event) => {
|
|
63
64
|
if (event.altKey) return;
|
|
64
65
|
event.persist();
|
|
65
|
-
if (isDismissible && closeOnEsc && 'Escape' === event.key && onClose)
|
|
66
|
+
if (isDismissible && closeOnEsc && 'Escape' === event.key && onClose) {
|
|
67
|
+
beforeClose();
|
|
66
68
|
onClose(event);
|
|
69
|
+
}
|
|
67
70
|
onKeyDown?.(event);
|
|
68
71
|
};
|
|
69
72
|
let { onPointerDown, transform } = (0, _useDragAndDrop.useDragAndDrop)(
|
|
70
73
|
dialogRef,
|
|
71
|
-
|
|
74
|
+
dialogRootRef,
|
|
72
75
|
isDraggable,
|
|
73
76
|
);
|
|
74
77
|
let handlePointerDown = _react.useCallback(
|
|
@@ -88,13 +91,35 @@ const DialogMain = _react.forwardRef((props, ref) => {
|
|
|
88
91
|
insetBlockStart: dialogRef.current?.offsetTop,
|
|
89
92
|
transform: `translate(${translateX}px,${translateY}px)`,
|
|
90
93
|
}));
|
|
91
|
-
}, [isDraggable, isOpen]);
|
|
94
|
+
}, [dialogRef, isDraggable, isOpen]);
|
|
92
95
|
let setResizeStyle = _react.useCallback((newStyle) => {
|
|
93
96
|
setStyle((oldStyle) => ({
|
|
94
97
|
...oldStyle,
|
|
95
98
|
...newStyle,
|
|
96
99
|
}));
|
|
97
100
|
}, []);
|
|
101
|
+
let onEnter = _react.useCallback(() => {
|
|
102
|
+
previousFocusedElement.current =
|
|
103
|
+
dialogRef.current?.ownerDocument.activeElement;
|
|
104
|
+
if (setFocus)
|
|
105
|
+
dialogRef.current?.focus({
|
|
106
|
+
preventScroll: true,
|
|
107
|
+
});
|
|
108
|
+
}, [dialogRef, previousFocusedElement, setFocus]);
|
|
109
|
+
let beforeClose = _react.useCallback(() => {
|
|
110
|
+
if (
|
|
111
|
+
dialogRef.current?.contains(
|
|
112
|
+
dialogRef.current?.ownerDocument.activeElement,
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
previousFocusedElement.current?.focus();
|
|
116
|
+
}, [dialogRef, previousFocusedElement]);
|
|
117
|
+
let mountRef = _react.useCallback(
|
|
118
|
+
(element) => {
|
|
119
|
+
if (element) onEnter();
|
|
120
|
+
},
|
|
121
|
+
[onEnter],
|
|
122
|
+
);
|
|
98
123
|
let content = _react.createElement(
|
|
99
124
|
_index.Box,
|
|
100
125
|
{
|
|
@@ -109,7 +134,7 @@ const DialogMain = _react.forwardRef((props, ref) => {
|
|
|
109
134
|
className,
|
|
110
135
|
),
|
|
111
136
|
role: 'dialog',
|
|
112
|
-
ref: (0, _index.useMergedRefs)(dialogRef, ref),
|
|
137
|
+
ref: (0, _index.useMergedRefs)(dialogRef, mountRef, ref),
|
|
113
138
|
onKeyDown: handleKeyDown,
|
|
114
139
|
tabIndex: -1,
|
|
115
140
|
'data-iui-placement': placement,
|
|
@@ -127,7 +152,7 @@ const DialogMain = _react.forwardRef((props, ref) => {
|
|
|
127
152
|
isResizable &&
|
|
128
153
|
_react.createElement(_index.Resizer, {
|
|
129
154
|
elementRef: dialogRef,
|
|
130
|
-
containerRef:
|
|
155
|
+
containerRef: dialogRootRef,
|
|
131
156
|
onResizeStart: () => {
|
|
132
157
|
if (!hasBeenResized.current) {
|
|
133
158
|
hasBeenResized.current = true;
|
|
@@ -142,31 +167,14 @@ const DialogMain = _react.forwardRef((props, ref) => {
|
|
|
142
167
|
children,
|
|
143
168
|
);
|
|
144
169
|
return _react.createElement(
|
|
145
|
-
|
|
170
|
+
_DialogMainContext.DialogMainContext.Provider,
|
|
146
171
|
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
previousFocusedElement.current =
|
|
154
|
-
dialogRef.current?.ownerDocument.activeElement;
|
|
155
|
-
setFocus &&
|
|
156
|
-
dialogRef.current?.focus({
|
|
157
|
-
preventScroll: true,
|
|
158
|
-
});
|
|
159
|
-
},
|
|
160
|
-
onExit: () => {
|
|
161
|
-
if (
|
|
162
|
-
dialogRef.current?.contains(
|
|
163
|
-
dialogRef.current?.ownerDocument.activeElement,
|
|
164
|
-
)
|
|
165
|
-
)
|
|
166
|
-
previousFocusedElement.current?.focus();
|
|
167
|
-
},
|
|
168
|
-
unmountOnExit: true,
|
|
169
|
-
nodeRef: dialogRef,
|
|
172
|
+
value: _react.useMemo(
|
|
173
|
+
() => ({
|
|
174
|
+
beforeClose,
|
|
175
|
+
}),
|
|
176
|
+
[beforeClose],
|
|
177
|
+
),
|
|
170
178
|
},
|
|
171
179
|
_react.createElement(
|
|
172
180
|
_DialogDragContext.DialogDragContext.Provider,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
type DialogMainContextProps = {
|
|
3
|
+
beforeClose: () => void;
|
|
4
|
+
};
|
|
5
|
+
export declare const DialogMainContext: React.Context<DialogMainContextProps | null>;
|
|
6
|
+
export declare const useDialogMainContext: () => DialogMainContextProps | null;
|
|
7
|
+
export {};
|