@khanacademy/wonder-blocks-modal 7.1.11 → 7.1.13
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 +24 -0
- package/dist/es/index.js +19 -818
- package/dist/index.js +19 -819
- package/package.json +8 -9
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
8
8
|
var wonderBlocksTheming = require('@khanacademy/wonder-blocks-theming');
|
|
@@ -36,846 +36,46 @@ function _interopNamespace(e) {
|
|
|
36
36
|
return Object.freeze(n);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
|
|
40
39
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
41
40
|
var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
|
|
42
41
|
var xIcon__default = /*#__PURE__*/_interopDefaultLegacy(xIcon);
|
|
43
42
|
var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
|
|
44
43
|
|
|
45
|
-
const theme$1
|
|
46
|
-
root: {
|
|
47
|
-
color: {
|
|
48
|
-
inverse: {
|
|
49
|
-
background: wonderBlocksTokens.semanticColor.surface.inverse,
|
|
50
|
-
foreground: wonderBlocksTokens.semanticColor.text.inverse
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
border: {
|
|
54
|
-
radius: wonderBlocksTokens.border.radius.radius_040
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
backdrop: {
|
|
58
|
-
color: {
|
|
59
|
-
background: wonderBlocksTokens.semanticColor.surface.overlay
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
dialog: {
|
|
63
|
-
spacing: {
|
|
64
|
-
padding: wonderBlocksTokens.spacing.medium_16
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
footer: {
|
|
68
|
-
color: {
|
|
69
|
-
border: wonderBlocksTokens.semanticColor.border.primary
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
header: {
|
|
73
|
-
color: {
|
|
74
|
-
border: wonderBlocksTokens.semanticColor.border.primary,
|
|
75
|
-
secondary: wonderBlocksTokens.semanticColor.text.secondary
|
|
76
|
-
},
|
|
77
|
-
spacing: {
|
|
78
|
-
paddingBlockMd: wonderBlocksTokens.spacing.large_24,
|
|
79
|
-
paddingInlineMd: wonderBlocksTokens.spacing.xLarge_32,
|
|
80
|
-
paddingInlineSm: wonderBlocksTokens.spacing.medium_16,
|
|
81
|
-
gap: wonderBlocksTokens.spacing.xSmall_8,
|
|
82
|
-
titleGapMd: wonderBlocksTokens.spacing.medium_16,
|
|
83
|
-
titleGapSm: wonderBlocksTokens.spacing.xLarge_32
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
panel: {
|
|
87
|
-
spacing: {
|
|
88
|
-
gap: wonderBlocksTokens.spacing.xLarge_32
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
closeButton: {
|
|
92
|
-
spacing: {
|
|
93
|
-
gap: wonderBlocksTokens.spacing.xSmall_8
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
};
|
|
44
|
+
const theme$1={root:{color:{inverse:{background:wonderBlocksTokens.semanticColor.surface.inverse,foreground:wonderBlocksTokens.semanticColor.text.inverse}},border:{radius:wonderBlocksTokens.border.radius.radius_040}},backdrop:{color:{background:wonderBlocksTokens.semanticColor.surface.overlay}},dialog:{spacing:{padding:wonderBlocksTokens.spacing.medium_16}},footer:{color:{border:wonderBlocksTokens.semanticColor.border.primary}},header:{color:{border:wonderBlocksTokens.semanticColor.border.primary,secondary:wonderBlocksTokens.semanticColor.text.secondary},spacing:{paddingBlockMd:wonderBlocksTokens.spacing.large_24,paddingInlineMd:wonderBlocksTokens.spacing.xLarge_32,paddingInlineSm:wonderBlocksTokens.spacing.medium_16,gap:wonderBlocksTokens.spacing.xSmall_8,titleGapMd:wonderBlocksTokens.spacing.medium_16,titleGapSm:wonderBlocksTokens.spacing.xLarge_32}},panel:{spacing:{gap:wonderBlocksTokens.spacing.xLarge_32}},closeButton:{spacing:{gap:wonderBlocksTokens.spacing.xSmall_8}}};
|
|
97
45
|
|
|
98
|
-
const theme
|
|
99
|
-
root: {
|
|
100
|
-
color: {
|
|
101
|
-
inverse: {
|
|
102
|
-
background: wonderBlocksTokens.semanticColor.khanmigo.primary
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
});
|
|
46
|
+
const theme=wonderBlocksTheming.mergeTheme(theme$1,{root:{color:{inverse:{background:wonderBlocksTokens.semanticColor.khanmigo.primary}}}});
|
|
107
47
|
|
|
108
|
-
const themes = {
|
|
109
|
-
default: theme$1,
|
|
110
|
-
khanmigo: theme
|
|
111
|
-
};
|
|
112
|
-
const ModalDialogThemeContext = wonderBlocksTheming.createThemeContext(theme$1);
|
|
113
|
-
function ThemeModalDialog(props) {
|
|
114
|
-
const currentTheme = React__namespace.useContext(wonderBlocksTheming.ThemeSwitcherContext);
|
|
115
|
-
const theme = themes[currentTheme] || theme$1;
|
|
116
|
-
return React__namespace.createElement(ModalDialogThemeContext.Provider, {
|
|
117
|
-
value: theme
|
|
118
|
-
}, props.children);
|
|
119
|
-
}
|
|
48
|
+
const themes={default:theme$1,khanmigo:theme};const ModalDialogThemeContext=wonderBlocksTheming.createThemeContext(theme$1);function ThemeModalDialog(props){const currentTheme=React__namespace.useContext(wonderBlocksTheming.ThemeSwitcherContext);const theme=themes[currentTheme]||theme$1;return jsxRuntime.jsx(ModalDialogThemeContext.Provider,{value:theme,children:props.children})}
|
|
120
49
|
|
|
121
|
-
const ModalDialogCore = React__namespace.forwardRef(function
|
|
122
|
-
const {
|
|
123
|
-
above,
|
|
124
|
-
below,
|
|
125
|
-
role = "dialog",
|
|
126
|
-
style,
|
|
127
|
-
children,
|
|
128
|
-
testId,
|
|
129
|
-
"aria-labelledby": ariaLabelledBy,
|
|
130
|
-
"aria-describedby": ariaDescribedBy
|
|
131
|
-
} = props;
|
|
132
|
-
const {
|
|
133
|
-
theme
|
|
134
|
-
} = wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);
|
|
135
|
-
const styles = wonderBlocksTheming.useStyles(themedStylesFn$5, theme);
|
|
136
|
-
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
137
|
-
style: [styles.wrapper, style]
|
|
138
|
-
}, below && React__namespace.createElement(wonderBlocksCore.View, {
|
|
139
|
-
style: styles.below
|
|
140
|
-
}, below), React__namespace.createElement(wonderBlocksCore.View, {
|
|
141
|
-
role: role,
|
|
142
|
-
"aria-modal": "true",
|
|
143
|
-
"aria-labelledby": ariaLabelledBy,
|
|
144
|
-
"aria-describedby": ariaDescribedBy,
|
|
145
|
-
ref: ref,
|
|
146
|
-
style: styles.dialog,
|
|
147
|
-
testId: testId
|
|
148
|
-
}, children), above && React__namespace.createElement(wonderBlocksCore.View, {
|
|
149
|
-
style: styles.above
|
|
150
|
-
}, above));
|
|
151
|
-
});
|
|
152
|
-
const ModalDialog = React__namespace.forwardRef(function ModalDialog(props, ref) {
|
|
153
|
-
return React__namespace.createElement(ThemeModalDialog, null, React__namespace.createElement(ModalDialogCore, _extends__default["default"]({}, props, {
|
|
154
|
-
ref: ref
|
|
155
|
-
})));
|
|
156
|
-
});
|
|
157
|
-
const small$2 = "@media (max-width: 767px)";
|
|
158
|
-
const themedStylesFn$5 = theme => ({
|
|
159
|
-
wrapper: {
|
|
160
|
-
display: "flex",
|
|
161
|
-
flexDirection: "row",
|
|
162
|
-
alignItems: "stretch",
|
|
163
|
-
width: "100%",
|
|
164
|
-
height: "100%",
|
|
165
|
-
position: "relative",
|
|
166
|
-
[small$2]: {
|
|
167
|
-
padding: theme.dialog.spacing.padding,
|
|
168
|
-
flexDirection: "column"
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
dialog: {
|
|
172
|
-
width: "100%",
|
|
173
|
-
height: "100%",
|
|
174
|
-
borderRadius: theme.root.border.radius,
|
|
175
|
-
overflow: "hidden"
|
|
176
|
-
},
|
|
177
|
-
above: {
|
|
178
|
-
pointerEvents: "none",
|
|
179
|
-
position: "absolute",
|
|
180
|
-
top: 0,
|
|
181
|
-
left: 0,
|
|
182
|
-
bottom: 0,
|
|
183
|
-
right: 0,
|
|
184
|
-
zIndex: 1
|
|
185
|
-
},
|
|
186
|
-
below: {
|
|
187
|
-
pointerEvents: "none",
|
|
188
|
-
position: "absolute",
|
|
189
|
-
top: 0,
|
|
190
|
-
left: 0,
|
|
191
|
-
bottom: 0,
|
|
192
|
-
right: 0,
|
|
193
|
-
zIndex: -1
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
ModalDialog.displayName = "ModalDialog";
|
|
50
|
+
const ModalDialogCore=React__namespace.forwardRef(function ModalDialogCore(props,ref){const{above,below,role="dialog",style,children,testId,"aria-labelledby":ariaLabelledBy,"aria-describedby":ariaDescribedBy}=props;const{theme}=wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);const styles=wonderBlocksTheming.useStyles(themedStylesFn$5,theme);return jsxRuntime.jsxs(wonderBlocksCore.View,{style:[styles.wrapper,style],children:[below&&jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.below,children:below}),jsxRuntime.jsx(wonderBlocksCore.View,{role:role,"aria-modal":"true","aria-labelledby":ariaLabelledBy,"aria-describedby":ariaDescribedBy,ref:ref,style:styles.dialog,testId:testId,children:children}),above&&jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.above,children:above})]})});const ModalDialog=React__namespace.forwardRef(function ModalDialog(props,ref){return jsxRuntime.jsx(ThemeModalDialog,{children:jsxRuntime.jsx(ModalDialogCore,{...props,ref:ref})})});const small$2="@media (max-width: 767px)";const themedStylesFn$5=theme=>({wrapper:{display:"flex",flexDirection:"row",alignItems:"stretch",width:"100%",height:"100%",position:"relative",[small$2]:{padding:theme.dialog.spacing.padding,flexDirection:"column"}},dialog:{width:"100%",height:"100%",borderRadius:theme.root.border.radius,overflow:"hidden"},above:{pointerEvents:"none",position:"absolute",top:0,left:0,bottom:0,right:0,zIndex:1},below:{pointerEvents:"none",position:"absolute",top:0,left:0,bottom:0,right:0,zIndex:-1}});ModalDialog.displayName="ModalDialog";
|
|
197
51
|
|
|
198
|
-
function ModalFooter({
|
|
199
|
-
children
|
|
200
|
-
}) {
|
|
201
|
-
const {
|
|
202
|
-
theme
|
|
203
|
-
} = wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);
|
|
204
|
-
const styles = wonderBlocksTheming.useStyles(themedStylesFn$4, theme);
|
|
205
|
-
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
206
|
-
style: styles.footer
|
|
207
|
-
}, children);
|
|
208
|
-
}
|
|
209
|
-
ModalFooter.__IS_MODAL_FOOTER__ = true;
|
|
210
|
-
ModalFooter.isComponentOf = instance => {
|
|
211
|
-
return instance && instance.type && instance.type.__IS_MODAL_FOOTER__;
|
|
212
|
-
};
|
|
213
|
-
const themedStylesFn$4 = theme => ({
|
|
214
|
-
footer: {
|
|
215
|
-
flex: "0 0 auto",
|
|
216
|
-
boxSizing: "border-box",
|
|
217
|
-
minHeight: wonderBlocksTokens.spacing.xxxLarge_64,
|
|
218
|
-
paddingLeft: wonderBlocksTokens.spacing.medium_16,
|
|
219
|
-
paddingRight: wonderBlocksTokens.spacing.medium_16,
|
|
220
|
-
paddingTop: wonderBlocksTokens.spacing.xSmall_8,
|
|
221
|
-
paddingBottom: wonderBlocksTokens.spacing.xSmall_8,
|
|
222
|
-
display: "flex",
|
|
223
|
-
flexDirection: "row",
|
|
224
|
-
alignItems: "center",
|
|
225
|
-
justifyContent: "flex-end",
|
|
226
|
-
boxShadow: `0px -1px 0px ${theme.footer.color.border}`
|
|
227
|
-
}
|
|
228
|
-
});
|
|
52
|
+
function ModalFooter({children}){const{theme}=wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);const styles=wonderBlocksTheming.useStyles(themedStylesFn$4,theme);return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.footer,children:children})}ModalFooter.__IS_MODAL_FOOTER__=true;ModalFooter.isComponentOf=instance=>{return instance&&instance.type&&instance.type.__IS_MODAL_FOOTER__};const themedStylesFn$4=theme=>({footer:{flex:"0 0 auto",boxSizing:"border-box",minHeight:wonderBlocksTokens.spacing.xxxLarge_64,paddingLeft:wonderBlocksTokens.spacing.medium_16,paddingRight:wonderBlocksTokens.spacing.medium_16,paddingTop:wonderBlocksTokens.spacing.xSmall_8,paddingBottom:wonderBlocksTokens.spacing.xSmall_8,display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"flex-end",boxShadow:`0px -1px 0px ${theme.footer.color.border}`}});
|
|
229
53
|
|
|
230
|
-
function ModalHeader(props) {
|
|
231
|
-
const {
|
|
232
|
-
breadcrumbs = undefined,
|
|
233
|
-
light,
|
|
234
|
-
subtitle = undefined,
|
|
235
|
-
testId,
|
|
236
|
-
title,
|
|
237
|
-
titleId
|
|
238
|
-
} = props;
|
|
239
|
-
if (subtitle && breadcrumbs) {
|
|
240
|
-
throw new Error("'subtitle' and 'breadcrumbs' can't be used together");
|
|
241
|
-
}
|
|
242
|
-
const {
|
|
243
|
-
theme
|
|
244
|
-
} = wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);
|
|
245
|
-
const styles = wonderBlocksTheming.useStyles(themedStylesFn$3, theme);
|
|
246
|
-
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
247
|
-
style: [styles.header, !light && styles.dark],
|
|
248
|
-
testId: testId
|
|
249
|
-
}, breadcrumbs && React__namespace.createElement(wonderBlocksCore.View, {
|
|
250
|
-
style: styles.breadcrumbs
|
|
251
|
-
}, breadcrumbs), React__namespace.createElement(wonderBlocksTypography.HeadingMedium, {
|
|
252
|
-
tag: "h2",
|
|
253
|
-
style: styles.title,
|
|
254
|
-
id: titleId,
|
|
255
|
-
testId: testId && `${testId}-title`
|
|
256
|
-
}, title), subtitle && React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
|
|
257
|
-
style: light && styles.subtitle,
|
|
258
|
-
testId: testId && `${testId}-subtitle`
|
|
259
|
-
}, subtitle));
|
|
260
|
-
}
|
|
261
|
-
const small$1 = "@media (max-width: 767px)";
|
|
262
|
-
const themedStylesFn$3 = theme => ({
|
|
263
|
-
header: {
|
|
264
|
-
boxShadow: `0px 1px 0px ${theme.header.color.border}`,
|
|
265
|
-
display: "flex",
|
|
266
|
-
flexDirection: "column",
|
|
267
|
-
minHeight: 66,
|
|
268
|
-
paddingBlock: theme.header.spacing.paddingBlockMd,
|
|
269
|
-
paddingInline: theme.header.spacing.paddingInlineMd,
|
|
270
|
-
position: "relative",
|
|
271
|
-
width: "100%",
|
|
272
|
-
[small$1]: {
|
|
273
|
-
paddingInline: theme.header.spacing.paddingInlineSm
|
|
274
|
-
}
|
|
275
|
-
},
|
|
276
|
-
dark: {
|
|
277
|
-
background: theme.root.color.inverse.background,
|
|
278
|
-
color: theme.root.color.inverse.foreground
|
|
279
|
-
},
|
|
280
|
-
breadcrumbs: {
|
|
281
|
-
color: theme.header.color.secondary,
|
|
282
|
-
marginBottom: theme.header.spacing.gap
|
|
283
|
-
},
|
|
284
|
-
title: {
|
|
285
|
-
paddingRight: theme.header.spacing.titleGapMd,
|
|
286
|
-
[small$1]: {
|
|
287
|
-
paddingRight: theme.header.spacing.titleGapSm
|
|
288
|
-
}
|
|
289
|
-
},
|
|
290
|
-
subtitle: {
|
|
291
|
-
color: theme.header.color.secondary,
|
|
292
|
-
marginTop: theme.header.spacing.gap
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
ModalHeader.defaultProps = {
|
|
296
|
-
light: true
|
|
297
|
-
};
|
|
54
|
+
function ModalHeader(props){const{breadcrumbs=undefined,light,subtitle=undefined,testId,title,titleId}=props;if(subtitle&&breadcrumbs){throw new Error("'subtitle' and 'breadcrumbs' can't be used together")}const{theme}=wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);const styles=wonderBlocksTheming.useStyles(themedStylesFn$3,theme);return jsxRuntime.jsxs(wonderBlocksCore.View,{style:[styles.header,!light&&styles.dark],testId:testId,children:[breadcrumbs&&jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.breadcrumbs,children:breadcrumbs}),jsxRuntime.jsx(wonderBlocksTypography.HeadingMedium,{tag:"h2",style:styles.title,id:titleId,testId:testId&&`${testId}-title`,children:title}),subtitle&&jsxRuntime.jsx(wonderBlocksTypography.LabelSmall,{style:light&&styles.subtitle,testId:testId&&`${testId}-subtitle`,children:subtitle})]})}const small$1="@media (max-width: 767px)";const themedStylesFn$3=theme=>({header:{boxShadow:`0px 1px 0px ${theme.header.color.border}`,display:"flex",flexDirection:"column",minHeight:66,paddingBlock:theme.header.spacing.paddingBlockMd,paddingInline:theme.header.spacing.paddingInlineMd,position:"relative",width:"100%",[small$1]:{paddingInline:theme.header.spacing.paddingInlineSm}},dark:{background:theme.root.color.inverse.background,color:theme.root.color.inverse.foreground},breadcrumbs:{color:theme.header.color.secondary,marginBottom:theme.header.spacing.gap},title:{paddingRight:theme.header.spacing.titleGapMd,[small$1]:{paddingRight:theme.header.spacing.titleGapSm}},subtitle:{color:theme.header.color.secondary,marginTop:theme.header.spacing.gap}});ModalHeader.defaultProps={light:true};
|
|
298
55
|
|
|
299
|
-
const FOCUSABLE_ELEMENTS$1
|
|
300
|
-
class FocusTrap extends React__namespace.Component {
|
|
301
|
-
constructor(...args) {
|
|
302
|
-
super(...args);
|
|
303
|
-
this.modalRoot = void 0;
|
|
304
|
-
this.getModalRoot = node => {
|
|
305
|
-
if (!node) {
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
const modalRoot = ReactDOM__namespace.findDOMNode(node);
|
|
309
|
-
if (!modalRoot) {
|
|
310
|
-
throw new Error("Assertion error: modal root should exist after mount");
|
|
311
|
-
}
|
|
312
|
-
this.modalRoot = modalRoot;
|
|
313
|
-
};
|
|
314
|
-
this.handleFocusMoveToLast = () => {
|
|
315
|
-
this.focusElementIn(false);
|
|
316
|
-
};
|
|
317
|
-
this.handleFocusMoveToFirst = () => {
|
|
318
|
-
this.focusElementIn(true);
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
tryToFocus(node) {
|
|
322
|
-
if (node instanceof HTMLElement) {
|
|
323
|
-
try {
|
|
324
|
-
node.focus();
|
|
325
|
-
} catch (e) {}
|
|
326
|
-
return document.activeElement === node;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
focusElementIn(isLast) {
|
|
330
|
-
const modalRootAsHtmlEl = this.modalRoot;
|
|
331
|
-
const focusableNodes = Array.from(modalRootAsHtmlEl.querySelectorAll(FOCUSABLE_ELEMENTS$1));
|
|
332
|
-
const nodeIndex = !isLast ? focusableNodes.length - 1 : 0;
|
|
333
|
-
const focusableNode = focusableNodes[nodeIndex];
|
|
334
|
-
this.tryToFocus(focusableNode);
|
|
335
|
-
}
|
|
336
|
-
render() {
|
|
337
|
-
const {
|
|
338
|
-
style
|
|
339
|
-
} = this.props;
|
|
340
|
-
return React__namespace.createElement(React__namespace.Fragment, null, React__namespace.createElement("div", {
|
|
341
|
-
tabIndex: 0,
|
|
342
|
-
className: "modal-focus-trap-first",
|
|
343
|
-
onFocus: this.handleFocusMoveToLast,
|
|
344
|
-
style: {
|
|
345
|
-
position: "fixed"
|
|
346
|
-
}
|
|
347
|
-
}), React__namespace.createElement(wonderBlocksCore.View, {
|
|
348
|
-
style: style,
|
|
349
|
-
ref: this.getModalRoot
|
|
350
|
-
}, this.props.children), React__namespace.createElement("div", {
|
|
351
|
-
tabIndex: 0,
|
|
352
|
-
className: "modal-focus-trap-last",
|
|
353
|
-
onFocus: this.handleFocusMoveToFirst,
|
|
354
|
-
style: {
|
|
355
|
-
position: "fixed"
|
|
356
|
-
}
|
|
357
|
-
}));
|
|
358
|
-
}
|
|
359
|
-
}
|
|
56
|
+
const FOCUSABLE_ELEMENTS$1='button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';class FocusTrap extends React__namespace.Component{tryToFocus(node){if(node instanceof HTMLElement){try{node.focus();}catch(e){}return document.activeElement===node}}focusElementIn(isLast){const modalRootAsHtmlEl=this.modalRoot;const focusableNodes=Array.from(modalRootAsHtmlEl.querySelectorAll(FOCUSABLE_ELEMENTS$1));const nodeIndex=!isLast?focusableNodes.length-1:0;const focusableNode=focusableNodes[nodeIndex];this.tryToFocus(focusableNode);}render(){const{style}=this.props;return jsxRuntime.jsxs(React__namespace.Fragment,{children:[jsxRuntime.jsx("div",{tabIndex:0,className:"modal-focus-trap-first",onFocus:this.handleFocusMoveToLast,style:{position:"fixed"}}),jsxRuntime.jsx(wonderBlocksCore.View,{style:style,ref:this.getModalRoot,children:this.props.children}),jsxRuntime.jsx("div",{tabIndex:0,className:"modal-focus-trap-last",onFocus:this.handleFocusMoveToFirst,style:{position:"fixed"}})]})}constructor(...args){super(...args),this.getModalRoot=node=>{if(!node){return}const modalRoot=ReactDOM__namespace.findDOMNode(node);if(!modalRoot){throw new Error("Assertion error: modal root should exist after mount")}this.modalRoot=modalRoot;},this.handleFocusMoveToLast=()=>{this.focusElementIn(false);},this.handleFocusMoveToFirst=()=>{this.focusElementIn(true);};}}
|
|
360
57
|
|
|
361
|
-
const ModalLauncherPortalAttributeName
|
|
58
|
+
const ModalLauncherPortalAttributeName="data-modal-launcher-portal";
|
|
362
59
|
|
|
363
|
-
const FOCUSABLE_ELEMENTS
|
|
364
|
-
function findFocusableNodes(root) {
|
|
365
|
-
return Array.from(root.querySelectorAll(FOCUSABLE_ELEMENTS));
|
|
366
|
-
}
|
|
60
|
+
const FOCUSABLE_ELEMENTS="a[href], details, input, textarea, select, button";function findFocusableNodes(root){return Array.from(root.querySelectorAll(FOCUSABLE_ELEMENTS))}
|
|
367
61
|
|
|
368
|
-
class ModalBackdrop extends React__namespace.Component {
|
|
369
|
-
constructor(...args) {
|
|
370
|
-
super(...args);
|
|
371
|
-
this._mousePressedOutside = false;
|
|
372
|
-
this.handleMouseDown = e => {
|
|
373
|
-
this._mousePressedOutside = e.target === e.currentTarget;
|
|
374
|
-
};
|
|
375
|
-
this.handleMouseUp = e => {
|
|
376
|
-
if (e.target === e.currentTarget && this._mousePressedOutside) {
|
|
377
|
-
this.props.onCloseModal();
|
|
378
|
-
}
|
|
379
|
-
this._mousePressedOutside = false;
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
componentDidMount() {
|
|
383
|
-
const node = ReactDOM__namespace.findDOMNode(this);
|
|
384
|
-
if (!node) {
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
const firstFocusableElement = this._getInitialFocusElement(node) || this._getFirstFocusableElement(node) || this._getDialogElement(node);
|
|
388
|
-
setTimeout(() => {
|
|
389
|
-
firstFocusableElement.focus();
|
|
390
|
-
}, 0);
|
|
391
|
-
}
|
|
392
|
-
_getInitialFocusElement(node) {
|
|
393
|
-
const {
|
|
394
|
-
initialFocusId
|
|
395
|
-
} = this.props;
|
|
396
|
-
if (!initialFocusId) {
|
|
397
|
-
return null;
|
|
398
|
-
}
|
|
399
|
-
return ReactDOM__namespace.findDOMNode(node.querySelector(`#${initialFocusId}`));
|
|
400
|
-
}
|
|
401
|
-
_getFirstFocusableElement(node) {
|
|
402
|
-
const focusableElements = findFocusableNodes(node);
|
|
403
|
-
if (!focusableElements) {
|
|
404
|
-
return null;
|
|
405
|
-
}
|
|
406
|
-
return focusableElements[0];
|
|
407
|
-
}
|
|
408
|
-
_getDialogElement(node) {
|
|
409
|
-
const dialogElement = ReactDOM__namespace.findDOMNode(node.querySelector('[role="dialog"]'));
|
|
410
|
-
dialogElement.tabIndex = -1;
|
|
411
|
-
return dialogElement;
|
|
412
|
-
}
|
|
413
|
-
render() {
|
|
414
|
-
const {
|
|
415
|
-
children,
|
|
416
|
-
testId
|
|
417
|
-
} = this.props;
|
|
418
|
-
const backdropProps = {
|
|
419
|
-
[ModalLauncherPortalAttributeName]: true
|
|
420
|
-
};
|
|
421
|
-
return React__namespace.createElement(wonderBlocksCore.View, _extends__default["default"]({
|
|
422
|
-
style: this.props.wbThemeStyles.modalPositioner,
|
|
423
|
-
onMouseDown: this.handleMouseDown,
|
|
424
|
-
onMouseUp: this.handleMouseUp,
|
|
425
|
-
testId: testId
|
|
426
|
-
}, backdropProps), children);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
const themedStylesFn$2 = theme => ({
|
|
430
|
-
modalPositioner: {
|
|
431
|
-
position: "fixed",
|
|
432
|
-
left: 0,
|
|
433
|
-
top: 0,
|
|
434
|
-
width: "100%",
|
|
435
|
-
height: "100%",
|
|
436
|
-
alignItems: "center",
|
|
437
|
-
justifyContent: "center",
|
|
438
|
-
overflow: "auto",
|
|
439
|
-
background: theme.backdrop.color.background
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
var ModalBackdrop$1 = wonderBlocksTheming.withScopedTheme(themedStylesFn$2, ModalDialogThemeContext)(ModalBackdrop);
|
|
62
|
+
class ModalBackdrop extends React__namespace.Component{componentDidMount(){const node=ReactDOM__namespace.findDOMNode(this);if(!node){return}const firstFocusableElement=this._getInitialFocusElement(node)||this._getFirstFocusableElement(node)||this._getDialogElement(node);setTimeout(()=>{firstFocusableElement.focus();},0);}_getInitialFocusElement(node){const{initialFocusId}=this.props;if(!initialFocusId){return null}return ReactDOM__namespace.findDOMNode(node.querySelector(`#${initialFocusId}`))}_getFirstFocusableElement(node){const focusableElements=findFocusableNodes(node);if(!focusableElements){return null}return focusableElements[0]}_getDialogElement(node){const dialogElement=ReactDOM__namespace.findDOMNode(node.querySelector('[role="dialog"]'));dialogElement.tabIndex=-1;return dialogElement}render(){const{children,testId}=this.props;const backdropProps={[ModalLauncherPortalAttributeName]:true};return jsxRuntime.jsx(wonderBlocksCore.View,{style:this.props.wbThemeStyles.modalPositioner,onMouseDown:this.handleMouseDown,onMouseUp:this.handleMouseUp,testId:testId,...backdropProps,children:children})}constructor(...args){super(...args),this._mousePressedOutside=false,this.handleMouseDown=e=>{this._mousePressedOutside=e.target===e.currentTarget;},this.handleMouseUp=e=>{if(e.target===e.currentTarget&&this._mousePressedOutside){this.props.onCloseModal();}this._mousePressedOutside=false;};}}const themedStylesFn$2=theme=>({modalPositioner:{position:"fixed",left:0,top:0,width:"100%",height:"100%",alignItems:"center",justifyContent:"center",overflow:"auto",background:theme.backdrop.color.background}});var ModalBackdrop$1 = wonderBlocksTheming.withScopedTheme(themedStylesFn$2,ModalDialogThemeContext)(ModalBackdrop);
|
|
443
63
|
|
|
444
|
-
const needsHackyMobileSafariScrollDisabler = (()
|
|
445
|
-
if (typeof window === "undefined") {
|
|
446
|
-
return false;
|
|
447
|
-
}
|
|
448
|
-
const userAgent = window.navigator.userAgent;
|
|
449
|
-
return userAgent.indexOf("iPad") > -1 || userAgent.indexOf("iPhone") > -1;
|
|
450
|
-
})();
|
|
451
|
-
class ScrollDisabler extends React__namespace.Component {
|
|
452
|
-
componentDidMount() {
|
|
453
|
-
if (ScrollDisabler.numModalsOpened === 0) {
|
|
454
|
-
const body = document.body;
|
|
455
|
-
if (!body) {
|
|
456
|
-
throw new Error("couldn't find document.body");
|
|
457
|
-
}
|
|
458
|
-
ScrollDisabler.oldOverflow = body.style.overflow;
|
|
459
|
-
ScrollDisabler.oldScrollY = window.scrollY;
|
|
460
|
-
if (needsHackyMobileSafariScrollDisabler) {
|
|
461
|
-
ScrollDisabler.oldPosition = body.style.position;
|
|
462
|
-
ScrollDisabler.oldWidth = body.style.width;
|
|
463
|
-
ScrollDisabler.oldTop = body.style.top;
|
|
464
|
-
}
|
|
465
|
-
body.style.overflow = "hidden";
|
|
466
|
-
if (needsHackyMobileSafariScrollDisabler) {
|
|
467
|
-
body.style.position = "fixed";
|
|
468
|
-
body.style.width = "100%";
|
|
469
|
-
body.style.top = `${-ScrollDisabler.oldScrollY}px`;
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
ScrollDisabler.numModalsOpened++;
|
|
473
|
-
}
|
|
474
|
-
componentWillUnmount() {
|
|
475
|
-
ScrollDisabler.numModalsOpened--;
|
|
476
|
-
if (ScrollDisabler.numModalsOpened === 0) {
|
|
477
|
-
const body = document.body;
|
|
478
|
-
if (!body) {
|
|
479
|
-
throw new Error("couldn't find document.body");
|
|
480
|
-
}
|
|
481
|
-
body.style.overflow = ScrollDisabler.oldOverflow;
|
|
482
|
-
if (needsHackyMobileSafariScrollDisabler) {
|
|
483
|
-
body.style.position = ScrollDisabler.oldPosition;
|
|
484
|
-
body.style.width = ScrollDisabler.oldWidth;
|
|
485
|
-
body.style.top = ScrollDisabler.oldTop;
|
|
486
|
-
}
|
|
487
|
-
if (typeof window !== "undefined" && window.scrollTo) {
|
|
488
|
-
window.scrollTo(0, ScrollDisabler.oldScrollY);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
render() {
|
|
493
|
-
return null;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
ScrollDisabler.oldOverflow = void 0;
|
|
497
|
-
ScrollDisabler.oldPosition = void 0;
|
|
498
|
-
ScrollDisabler.oldScrollY = void 0;
|
|
499
|
-
ScrollDisabler.oldWidth = void 0;
|
|
500
|
-
ScrollDisabler.oldTop = void 0;
|
|
501
|
-
ScrollDisabler.numModalsOpened = 0;
|
|
64
|
+
const needsHackyMobileSafariScrollDisabler=(()=>{if(typeof window==="undefined"){return false}const userAgent=window.navigator.userAgent;return userAgent.indexOf("iPad")>-1||userAgent.indexOf("iPhone")>-1})();class ScrollDisabler extends React__namespace.Component{componentDidMount(){if(ScrollDisabler.numModalsOpened===0){const body=document.body;if(!body){throw new Error("couldn't find document.body")}ScrollDisabler.oldOverflow=body.style.overflow;ScrollDisabler.oldScrollY=window.scrollY;if(needsHackyMobileSafariScrollDisabler){ScrollDisabler.oldPosition=body.style.position;ScrollDisabler.oldWidth=body.style.width;ScrollDisabler.oldTop=body.style.top;}body.style.overflow="hidden";if(needsHackyMobileSafariScrollDisabler){body.style.position="fixed";body.style.width="100%";body.style.top=`${-ScrollDisabler.oldScrollY}px`;}}ScrollDisabler.numModalsOpened++;}componentWillUnmount(){ScrollDisabler.numModalsOpened--;if(ScrollDisabler.numModalsOpened===0){const body=document.body;if(!body){throw new Error("couldn't find document.body")}body.style.overflow=ScrollDisabler.oldOverflow;if(needsHackyMobileSafariScrollDisabler){body.style.position=ScrollDisabler.oldPosition;body.style.width=ScrollDisabler.oldWidth;body.style.top=ScrollDisabler.oldTop;}if(typeof window!=="undefined"&&window.scrollTo){window.scrollTo(0,ScrollDisabler.oldScrollY);}}}render(){return null}}ScrollDisabler.numModalsOpened=0;
|
|
502
65
|
|
|
503
|
-
const defaultContext =
|
|
504
|
-
closeModal: undefined
|
|
505
|
-
};
|
|
506
|
-
const ModalContext = React__namespace.createContext(defaultContext);
|
|
507
|
-
ModalContext.displayName = "ModalContext";
|
|
66
|
+
const defaultContext={closeModal:undefined};const ModalContext=React__namespace.createContext(defaultContext);ModalContext.displayName="ModalContext";
|
|
508
67
|
|
|
509
|
-
class ModalLauncher extends React__namespace.Component {
|
|
510
|
-
constructor(...args) {
|
|
511
|
-
super(...args);
|
|
512
|
-
this.lastElementFocusedOutsideModal = void 0;
|
|
513
|
-
this.state = {
|
|
514
|
-
opened: false
|
|
515
|
-
};
|
|
516
|
-
this._saveLastElementFocused = () => {
|
|
517
|
-
this.lastElementFocusedOutsideModal = document.activeElement;
|
|
518
|
-
};
|
|
519
|
-
this._openModal = () => {
|
|
520
|
-
this._saveLastElementFocused();
|
|
521
|
-
this.setState({
|
|
522
|
-
opened: true
|
|
523
|
-
});
|
|
524
|
-
};
|
|
525
|
-
this._returnFocus = () => {
|
|
526
|
-
const {
|
|
527
|
-
closedFocusId,
|
|
528
|
-
schedule
|
|
529
|
-
} = this.props;
|
|
530
|
-
const lastElement = this.lastElementFocusedOutsideModal;
|
|
531
|
-
if (closedFocusId) {
|
|
532
|
-
const focusElement = ReactDOM__namespace.findDOMNode(document.getElementById(closedFocusId));
|
|
533
|
-
if (focusElement) {
|
|
534
|
-
schedule.animationFrame(() => {
|
|
535
|
-
focusElement.focus();
|
|
536
|
-
});
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
if (lastElement != null) {
|
|
541
|
-
schedule.animationFrame(() => {
|
|
542
|
-
lastElement.focus();
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
this.handleCloseModal = () => {
|
|
547
|
-
this.setState({
|
|
548
|
-
opened: false
|
|
549
|
-
}, () => {
|
|
550
|
-
const {
|
|
551
|
-
onClose
|
|
552
|
-
} = this.props;
|
|
553
|
-
onClose == null || onClose();
|
|
554
|
-
this._returnFocus();
|
|
555
|
-
});
|
|
556
|
-
};
|
|
557
|
-
}
|
|
558
|
-
static getDerivedStateFromProps(props, state) {
|
|
559
|
-
if (typeof props.opened === "boolean" && props.children) {
|
|
560
|
-
console.warn("'children' and 'opened' can't be used together");
|
|
561
|
-
}
|
|
562
|
-
if (typeof props.opened === "boolean" && !props.onClose) {
|
|
563
|
-
console.warn("'onClose' should be used with 'opened'");
|
|
564
|
-
}
|
|
565
|
-
if (typeof props.opened !== "boolean" && !props.children) {
|
|
566
|
-
console.warn("either 'children' or 'opened' must be set");
|
|
567
|
-
}
|
|
568
|
-
return {
|
|
569
|
-
opened: typeof props.opened === "boolean" ? props.opened : state.opened
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
componentDidUpdate(prevProps) {
|
|
573
|
-
if (!prevProps.opened && this.props.opened) {
|
|
574
|
-
this._saveLastElementFocused();
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
_renderModal() {
|
|
578
|
-
if (typeof this.props.modal === "function") {
|
|
579
|
-
return this.props.modal({
|
|
580
|
-
closeModal: this.handleCloseModal
|
|
581
|
-
});
|
|
582
|
-
} else {
|
|
583
|
-
return this.props.modal;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
render() {
|
|
587
|
-
const renderedChildren = this.props.children ? this.props.children({
|
|
588
|
-
openModal: this._openModal
|
|
589
|
-
}) : null;
|
|
590
|
-
const {
|
|
591
|
-
body
|
|
592
|
-
} = document;
|
|
593
|
-
if (!body) {
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
596
|
-
return React__namespace.createElement(ModalContext.Provider, {
|
|
597
|
-
value: {
|
|
598
|
-
closeModal: this.handleCloseModal
|
|
599
|
-
}
|
|
600
|
-
}, renderedChildren, this.state.opened && ReactDOM__namespace.createPortal(React__namespace.createElement(FocusTrap, {
|
|
601
|
-
style: styles.container
|
|
602
|
-
}, React__namespace.createElement(ModalBackdrop$1, {
|
|
603
|
-
initialFocusId: this.props.initialFocusId,
|
|
604
|
-
testId: this.props.testId,
|
|
605
|
-
onCloseModal: this.props.backdropDismissEnabled ? this.handleCloseModal : () => {}
|
|
606
|
-
}, this._renderModal())), body), this.state.opened && React__namespace.createElement(ModalLauncherKeypressListener, {
|
|
607
|
-
onClose: this.handleCloseModal
|
|
608
|
-
}), this.state.opened && React__namespace.createElement(ScrollDisabler, null));
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
ModalLauncher.defaultProps = {
|
|
612
|
-
backdropDismissEnabled: true
|
|
613
|
-
};
|
|
614
|
-
class ModalLauncherKeypressListener extends React__namespace.Component {
|
|
615
|
-
constructor(...args) {
|
|
616
|
-
super(...args);
|
|
617
|
-
this._handleKeyup = e => {
|
|
618
|
-
if (e.key === "Escape") {
|
|
619
|
-
e.preventDefault();
|
|
620
|
-
e.stopPropagation();
|
|
621
|
-
this.props.onClose();
|
|
622
|
-
}
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
componentDidMount() {
|
|
626
|
-
window.addEventListener("keyup", this._handleKeyup);
|
|
627
|
-
}
|
|
628
|
-
componentWillUnmount() {
|
|
629
|
-
window.removeEventListener("keyup", this._handleKeyup);
|
|
630
|
-
}
|
|
631
|
-
render() {
|
|
632
|
-
return null;
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
const styles = aphrodite.StyleSheet.create({
|
|
636
|
-
container: {
|
|
637
|
-
zIndex: 1080
|
|
638
|
-
}
|
|
639
|
-
});
|
|
640
|
-
var modalLauncher = wonderBlocksTiming.withActionScheduler(ModalLauncher);
|
|
68
|
+
class ModalLauncher extends React__namespace.Component{static getDerivedStateFromProps(props,state){if(typeof props.opened==="boolean"&&props.children){console.warn("'children' and 'opened' can't be used together");}if(typeof props.opened==="boolean"&&!props.onClose){console.warn("'onClose' should be used with 'opened'");}if(typeof props.opened!=="boolean"&&!props.children){console.warn("either 'children' or 'opened' must be set");}return {opened:typeof props.opened==="boolean"?props.opened:state.opened}}componentDidUpdate(prevProps){if(!prevProps.opened&&this.props.opened){this._saveLastElementFocused();}}_renderModal(){if(typeof this.props.modal==="function"){return this.props.modal({closeModal:this.handleCloseModal})}else {return this.props.modal}}render(){const renderedChildren=this.props.children?this.props.children({openModal:this._openModal}):null;const{body}=document;if(!body){return null}return jsxRuntime.jsxs(ModalContext.Provider,{value:{closeModal:this.handleCloseModal},children:[renderedChildren,this.state.opened&&ReactDOM__namespace.createPortal(jsxRuntime.jsx(FocusTrap,{style:styles.container,children:jsxRuntime.jsx(ModalBackdrop$1,{initialFocusId:this.props.initialFocusId,testId:this.props.testId,onCloseModal:this.props.backdropDismissEnabled?this.handleCloseModal:()=>{},children:this._renderModal()})}),body),this.state.opened&&jsxRuntime.jsx(ModalLauncherKeypressListener,{onClose:this.handleCloseModal}),this.state.opened&&jsxRuntime.jsx(ScrollDisabler,{})]})}constructor(...args){super(...args),this.state={opened:false},this._saveLastElementFocused=()=>{this.lastElementFocusedOutsideModal=document.activeElement;},this._openModal=()=>{this._saveLastElementFocused();this.setState({opened:true});},this._returnFocus=()=>{const{closedFocusId,schedule}=this.props;const lastElement=this.lastElementFocusedOutsideModal;if(closedFocusId){const focusElement=ReactDOM__namespace.findDOMNode(document.getElementById(closedFocusId));if(focusElement){schedule.animationFrame(()=>{focusElement.focus();});return}}if(lastElement!=null){schedule.animationFrame(()=>{lastElement.focus();});}},this.handleCloseModal=()=>{this.setState({opened:false},()=>{const{onClose}=this.props;onClose?.();this._returnFocus();});};}}ModalLauncher.defaultProps={backdropDismissEnabled:true};class ModalLauncherKeypressListener extends React__namespace.Component{componentDidMount(){window.addEventListener("keyup",this._handleKeyup);}componentWillUnmount(){window.removeEventListener("keyup",this._handleKeyup);}render(){return null}constructor(...args){super(...args),this._handleKeyup=e=>{if(e.key==="Escape"){e.preventDefault();e.stopPropagation();this.props.onClose();}};}}const styles=aphrodite.StyleSheet.create({container:{zIndex:1080}});var modalLauncher = wonderBlocksTiming.withActionScheduler(ModalLauncher);
|
|
641
69
|
|
|
642
|
-
function ModalContent(props) {
|
|
643
|
-
const {
|
|
644
|
-
scrollOverflow,
|
|
645
|
-
style,
|
|
646
|
-
children
|
|
647
|
-
} = props;
|
|
648
|
-
const {
|
|
649
|
-
theme
|
|
650
|
-
} = wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);
|
|
651
|
-
const styles = wonderBlocksTheming.useStyles(themedStylesFn$1, theme);
|
|
652
|
-
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
653
|
-
style: [styles.wrapper, scrollOverflow && styles.scrollOverflow]
|
|
654
|
-
}, React__namespace.createElement(wonderBlocksCore.View, {
|
|
655
|
-
style: [styles.content, style]
|
|
656
|
-
}, children));
|
|
657
|
-
}
|
|
658
|
-
ModalContent.__IS_MODAL_CONTENT__ = true;
|
|
659
|
-
ModalContent.isComponentOf = instance => {
|
|
660
|
-
return instance && instance.type && instance.type.__IS_MODAL_CONTENT__;
|
|
661
|
-
};
|
|
662
|
-
const small = "@media (max-width: 767px)";
|
|
663
|
-
const themedStylesFn$1 = theme => ({
|
|
664
|
-
wrapper: {
|
|
665
|
-
flex: 1,
|
|
666
|
-
display: "block"
|
|
667
|
-
},
|
|
668
|
-
scrollOverflow: {
|
|
669
|
-
overflow: "auto"
|
|
670
|
-
},
|
|
671
|
-
content: {
|
|
672
|
-
flex: 1,
|
|
673
|
-
minHeight: "100%",
|
|
674
|
-
padding: wonderBlocksTokens.spacing.xLarge_32,
|
|
675
|
-
boxSizing: "border-box",
|
|
676
|
-
[small]: {
|
|
677
|
-
padding: `${wonderBlocksTokens.spacing.xLarge_32}px ${wonderBlocksTokens.spacing.medium_16}px`
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
});
|
|
681
|
-
ModalContent.defaultProps = {
|
|
682
|
-
scrollOverflow: true
|
|
683
|
-
};
|
|
70
|
+
function ModalContent(props){const{scrollOverflow,style,children}=props;const{theme}=wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);const styles=wonderBlocksTheming.useStyles(themedStylesFn$1,theme);return jsxRuntime.jsx(wonderBlocksCore.View,{style:[styles.wrapper,scrollOverflow&&styles.scrollOverflow],children:jsxRuntime.jsx(wonderBlocksCore.View,{style:[styles.content,style],children:children})})}ModalContent.__IS_MODAL_CONTENT__=true;ModalContent.isComponentOf=instance=>{return instance&&instance.type&&instance.type.__IS_MODAL_CONTENT__};const small="@media (max-width: 767px)";const themedStylesFn$1=theme=>({wrapper:{flex:1,display:"block"},scrollOverflow:{overflow:"auto"},content:{flex:1,minHeight:"100%",padding:wonderBlocksTokens.spacing.xLarge_32,boxSizing:"border-box",[small]:{padding:`${wonderBlocksTokens.spacing.xLarge_32}px ${wonderBlocksTokens.spacing.medium_16}px`}}});ModalContent.defaultProps={scrollOverflow:true};
|
|
684
71
|
|
|
685
|
-
class CloseButton extends React__namespace.Component {
|
|
686
|
-
render() {
|
|
687
|
-
const {
|
|
688
|
-
onClick,
|
|
689
|
-
style,
|
|
690
|
-
testId
|
|
691
|
-
} = this.props;
|
|
692
|
-
return React__namespace.createElement(ModalContext.Consumer, null, ({
|
|
693
|
-
closeModal
|
|
694
|
-
}) => {
|
|
695
|
-
if (closeModal && onClick) {
|
|
696
|
-
throw new Error("You've specified 'onClose' on a modal when using ModalLauncher. Please specify 'onClose' on the ModalLauncher instead");
|
|
697
|
-
}
|
|
698
|
-
return React__namespace.createElement(IconButton__default["default"], {
|
|
699
|
-
icon: xIcon__default["default"],
|
|
700
|
-
"aria-label": "Close modal",
|
|
701
|
-
onClick: onClick || closeModal,
|
|
702
|
-
kind: "tertiary",
|
|
703
|
-
actionType: "neutral",
|
|
704
|
-
style: style,
|
|
705
|
-
testId: testId
|
|
706
|
-
});
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
}
|
|
72
|
+
class CloseButton extends React__namespace.Component{render(){const{onClick,style,testId}=this.props;return jsxRuntime.jsx(ModalContext.Consumer,{children:({closeModal})=>{if(closeModal&&onClick){throw new Error("You've specified 'onClose' on a modal when using ModalLauncher. Please specify 'onClose' on the ModalLauncher instead")}return jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],"aria-label":"Close modal",onClick:onClick||closeModal,kind:"tertiary",actionType:"neutral",style:style,testId:testId})}})}}
|
|
710
73
|
|
|
711
|
-
function ModalPanel({
|
|
712
|
-
closeButtonVisible = true,
|
|
713
|
-
scrollOverflow = true,
|
|
714
|
-
light = true,
|
|
715
|
-
content,
|
|
716
|
-
footer,
|
|
717
|
-
header,
|
|
718
|
-
onClose,
|
|
719
|
-
style,
|
|
720
|
-
testId
|
|
721
|
-
}) {
|
|
722
|
-
const {
|
|
723
|
-
theme
|
|
724
|
-
} = wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);
|
|
725
|
-
const styles = wonderBlocksTheming.useStyles(themedStylesFn, theme);
|
|
726
|
-
const renderMainContent = React__namespace.useCallback(() => {
|
|
727
|
-
const mainContent = ModalContent.isComponentOf(content) ? content : React__namespace.createElement(ModalContent, null, content);
|
|
728
|
-
if (!mainContent) {
|
|
729
|
-
return mainContent;
|
|
730
|
-
}
|
|
731
|
-
return React__namespace.cloneElement(mainContent, {
|
|
732
|
-
scrollOverflow,
|
|
733
|
-
style: [!!footer && styles.hasFooter, mainContent.props.style]
|
|
734
|
-
});
|
|
735
|
-
}, [content, footer, scrollOverflow, styles.hasFooter]);
|
|
736
|
-
const mainContent = renderMainContent();
|
|
737
|
-
const isInverse = !light;
|
|
738
|
-
return React__namespace.createElement(wonderBlocksCore.View, {
|
|
739
|
-
style: [styles.wrapper, isInverse && styles.dark, style],
|
|
740
|
-
testId: testId && `${testId}-panel`
|
|
741
|
-
}, closeButtonVisible && React__namespace.createElement(CloseButton, {
|
|
742
|
-
onClick: onClose,
|
|
743
|
-
style: [styles.closeButton, isInverse && wonderBlocksStyles.actionStyles.inverse],
|
|
744
|
-
testId: testId && `${testId}-close`
|
|
745
|
-
}), header, mainContent, !footer || ModalFooter.isComponentOf(footer) ? footer : React__namespace.createElement(ModalFooter, null, footer));
|
|
746
|
-
}
|
|
747
|
-
ModalPanel.defaultProps = {
|
|
748
|
-
closeButtonVisible: true,
|
|
749
|
-
scrollOverflow: true,
|
|
750
|
-
light: true
|
|
751
|
-
};
|
|
752
|
-
const themedStylesFn = theme => ({
|
|
753
|
-
wrapper: {
|
|
754
|
-
flex: "1 1 auto",
|
|
755
|
-
position: "relative",
|
|
756
|
-
display: "flex",
|
|
757
|
-
flexDirection: "column",
|
|
758
|
-
background: "white",
|
|
759
|
-
boxSizing: "border-box",
|
|
760
|
-
overflow: "hidden",
|
|
761
|
-
height: "100%",
|
|
762
|
-
width: "100%"
|
|
763
|
-
},
|
|
764
|
-
closeButton: {
|
|
765
|
-
position: "absolute",
|
|
766
|
-
right: theme.closeButton.spacing.gap,
|
|
767
|
-
top: theme.closeButton.spacing.gap,
|
|
768
|
-
zIndex: 1,
|
|
769
|
-
":focus": _extends__default["default"]({}, wonderBlocksStyles.focusStyles.focus[":focus-visible"])
|
|
770
|
-
},
|
|
771
|
-
dark: {
|
|
772
|
-
background: theme.root.color.inverse.background,
|
|
773
|
-
color: theme.root.color.inverse.foreground
|
|
774
|
-
},
|
|
775
|
-
hasFooter: {
|
|
776
|
-
paddingBlockEnd: theme.panel.spacing.gap
|
|
777
|
-
}
|
|
778
|
-
});
|
|
74
|
+
function ModalPanel({closeButtonVisible=true,scrollOverflow=true,light=true,content,footer,header,onClose,style,testId}){const{theme}=wonderBlocksTheming.useScopedTheme(ModalDialogThemeContext);const styles=wonderBlocksTheming.useStyles(themedStylesFn,theme);const renderMainContent=React__namespace.useCallback(()=>{const mainContent=ModalContent.isComponentOf(content)?content:jsxRuntime.jsx(ModalContent,{children:content});if(!mainContent){return mainContent}return React__namespace.cloneElement(mainContent,{scrollOverflow,style:[!!footer&&styles.hasFooter,mainContent.props.style]})},[content,footer,scrollOverflow,styles.hasFooter]);const mainContent=renderMainContent();const isInverse=!light;return jsxRuntime.jsxs(wonderBlocksCore.View,{style:[styles.wrapper,isInverse&&styles.dark,style],testId:testId&&`${testId}-panel`,children:[closeButtonVisible&&jsxRuntime.jsx(CloseButton,{onClick:onClose,style:[styles.closeButton,isInverse&&wonderBlocksStyles.actionStyles.inverse],testId:testId&&`${testId}-close`}),header,mainContent,!footer||ModalFooter.isComponentOf(footer)?footer:jsxRuntime.jsx(ModalFooter,{children:footer})]})}ModalPanel.defaultProps={closeButtonVisible:true,scrollOverflow:true,light:true};const themedStylesFn=theme=>({wrapper:{flex:"1 1 auto",position:"relative",display:"flex",flexDirection:"column",background:"white",boxSizing:"border-box",overflow:"hidden",height:"100%",width:"100%"},closeButton:{position:"absolute",right:theme.closeButton.spacing.gap,top:theme.closeButton.spacing.gap,zIndex:1,":focus":{...wonderBlocksStyles.focusStyles.focus[":focus-visible"]}},dark:{background:theme.root.color.inverse.background,color:theme.root.color.inverse.foreground},hasFooter:{paddingBlockEnd:theme.panel.spacing.gap}});
|
|
779
75
|
|
|
780
|
-
class OnePaneDialog extends React__namespace.Component {
|
|
781
|
-
renderHeader(uniqueId) {
|
|
782
|
-
const {
|
|
783
|
-
title,
|
|
784
|
-
breadcrumbs = undefined,
|
|
785
|
-
subtitle = undefined,
|
|
786
|
-
testId
|
|
787
|
-
} = this.props;
|
|
788
|
-
if (breadcrumbs) {
|
|
789
|
-
return React__namespace.createElement(ModalHeader, {
|
|
790
|
-
title: title,
|
|
791
|
-
breadcrumbs: breadcrumbs,
|
|
792
|
-
titleId: uniqueId,
|
|
793
|
-
testId: testId && `${testId}-header`
|
|
794
|
-
});
|
|
795
|
-
} else if (subtitle) {
|
|
796
|
-
return React__namespace.createElement(ModalHeader, {
|
|
797
|
-
title: title,
|
|
798
|
-
subtitle: subtitle,
|
|
799
|
-
titleId: uniqueId,
|
|
800
|
-
testId: testId && `${testId}-header`
|
|
801
|
-
});
|
|
802
|
-
} else {
|
|
803
|
-
return React__namespace.createElement(ModalHeader, {
|
|
804
|
-
title: title,
|
|
805
|
-
titleId: uniqueId,
|
|
806
|
-
testId: testId && `${testId}-header`
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
render() {
|
|
811
|
-
const {
|
|
812
|
-
onClose,
|
|
813
|
-
footer,
|
|
814
|
-
content,
|
|
815
|
-
above,
|
|
816
|
-
below,
|
|
817
|
-
style,
|
|
818
|
-
closeButtonVisible,
|
|
819
|
-
testId,
|
|
820
|
-
titleId,
|
|
821
|
-
role,
|
|
822
|
-
"aria-describedby": ariaDescribedBy
|
|
823
|
-
} = this.props;
|
|
824
|
-
return React__namespace.createElement(wonderBlocksLayout.MediaLayout, {
|
|
825
|
-
styleSheets: styleSheets
|
|
826
|
-
}, ({
|
|
827
|
-
styles
|
|
828
|
-
}) => React__namespace.createElement(wonderBlocksCore.Id, {
|
|
829
|
-
id: titleId
|
|
830
|
-
}, uniqueId => React__namespace.createElement(ModalDialog, {
|
|
831
|
-
style: [styles.dialog, style],
|
|
832
|
-
above: above,
|
|
833
|
-
below: below,
|
|
834
|
-
testId: testId,
|
|
835
|
-
"aria-labelledby": uniqueId,
|
|
836
|
-
"aria-describedby": ariaDescribedBy,
|
|
837
|
-
role: role
|
|
838
|
-
}, React__namespace.createElement(ModalPanel, {
|
|
839
|
-
onClose: onClose,
|
|
840
|
-
header: this.renderHeader(uniqueId),
|
|
841
|
-
content: content,
|
|
842
|
-
footer: footer,
|
|
843
|
-
closeButtonVisible: closeButtonVisible,
|
|
844
|
-
testId: testId
|
|
845
|
-
}))));
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
OnePaneDialog.defaultProps = {
|
|
849
|
-
closeButtonVisible: true
|
|
850
|
-
};
|
|
851
|
-
const styleSheets = {
|
|
852
|
-
small: aphrodite.StyleSheet.create({
|
|
853
|
-
dialog: {
|
|
854
|
-
width: "100%",
|
|
855
|
-
height: "100%",
|
|
856
|
-
overflow: "hidden"
|
|
857
|
-
}
|
|
858
|
-
}),
|
|
859
|
-
mdOrLarger: aphrodite.StyleSheet.create({
|
|
860
|
-
dialog: {
|
|
861
|
-
width: "93.75%",
|
|
862
|
-
maxWidth: 576,
|
|
863
|
-
height: "81.25%",
|
|
864
|
-
maxHeight: 624
|
|
865
|
-
}
|
|
866
|
-
})
|
|
867
|
-
};
|
|
76
|
+
class OnePaneDialog extends React__namespace.Component{renderHeader(uniqueId){const{title,breadcrumbs=undefined,subtitle=undefined,testId}=this.props;if(breadcrumbs){return jsxRuntime.jsx(ModalHeader,{title:title,breadcrumbs:breadcrumbs,titleId:uniqueId,testId:testId&&`${testId}-header`})}else if(subtitle){return jsxRuntime.jsx(ModalHeader,{title:title,subtitle:subtitle,titleId:uniqueId,testId:testId&&`${testId}-header`})}else {return jsxRuntime.jsx(ModalHeader,{title:title,titleId:uniqueId,testId:testId&&`${testId}-header`})}}render(){const{onClose,footer,content,above,below,style,closeButtonVisible,testId,titleId,role,"aria-describedby":ariaDescribedBy}=this.props;return jsxRuntime.jsx(wonderBlocksLayout.MediaLayout,{styleSheets:styleSheets,children:({styles})=>jsxRuntime.jsx(wonderBlocksCore.Id,{id:titleId,children:uniqueId=>jsxRuntime.jsx(ModalDialog,{style:[styles.dialog,style],above:above,below:below,testId:testId,"aria-labelledby":uniqueId,"aria-describedby":ariaDescribedBy,role:role,children:jsxRuntime.jsx(ModalPanel,{onClose:onClose,header:this.renderHeader(uniqueId),content:content,footer:footer,closeButtonVisible:closeButtonVisible,testId:testId})})})})}}OnePaneDialog.defaultProps={closeButtonVisible:true};const styleSheets={small:aphrodite.StyleSheet.create({dialog:{width:"100%",height:"100%",overflow:"hidden"}}),mdOrLarger:aphrodite.StyleSheet.create({dialog:{width:"93.75%",maxWidth:576,height:"81.25%",maxHeight:624}})};
|
|
868
77
|
|
|
869
|
-
function maybeGetNextAncestorModalLauncherPortal(element) {
|
|
870
|
-
let candidateElement = element && element.parentElement;
|
|
871
|
-
while (candidateElement && !candidateElement.hasAttribute(ModalLauncherPortalAttributeName)) {
|
|
872
|
-
candidateElement = candidateElement.parentElement;
|
|
873
|
-
}
|
|
874
|
-
return candidateElement;
|
|
875
|
-
}
|
|
876
|
-
function maybeGetPortalMountedModalHostElement(element) {
|
|
877
|
-
return maybeGetNextAncestorModalLauncherPortal(element);
|
|
878
|
-
}
|
|
78
|
+
function maybeGetNextAncestorModalLauncherPortal(element){let candidateElement=element&&element.parentElement;while(candidateElement&&!candidateElement.hasAttribute(ModalLauncherPortalAttributeName)){candidateElement=candidateElement.parentElement;}return candidateElement}function maybeGetPortalMountedModalHostElement(element){return maybeGetNextAncestorModalLauncherPortal(element)}
|
|
879
79
|
|
|
880
80
|
exports.ModalDialog = ModalDialog;
|
|
881
81
|
exports.ModalFooter = ModalFooter;
|