@khanacademy/wonder-blocks-modal 2.1.42 → 2.2.0
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 +10 -0
- package/dist/es/index.js +96 -85
- package/dist/index.js +913 -757
- package/package.json +15 -16
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +11 -11
- package/src/components/__tests__/close-button.test.js +1 -0
- package/src/components/__tests__/modal-backdrop.test.js +115 -57
- package/src/components/__tests__/modal-header.test.js +1 -0
- package/src/components/__tests__/modal-launcher.test.js +37 -6
- package/src/components/__tests__/modal-panel.test.js +1 -0
- package/src/components/__tests__/one-pane-dialog.test.js +1 -0
- package/src/components/modal-backdrop.js +17 -13
- package/src/components/one-pane-dialog.stories.js +11 -13
- package/src/util/find-focusable-nodes.js +14 -0
- package/src/util/maybe-get-portal-mounted-modal-host-element.test.js +3 -3
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -82,7 +82,7 @@ module.exports =
|
|
|
82
82
|
/******/
|
|
83
83
|
/******/
|
|
84
84
|
/******/ // Load entry module and return exports
|
|
85
|
-
/******/ return __webpack_require__(__webpack_require__.s =
|
|
85
|
+
/******/ return __webpack_require__(__webpack_require__.s = 25);
|
|
86
86
|
/******/ })
|
|
87
87
|
/************************************************************************/
|
|
88
88
|
/******/ ([
|
|
@@ -129,82 +129,232 @@ module.exports = require("react-dom");
|
|
|
129
129
|
|
|
130
130
|
/***/ }),
|
|
131
131
|
/* 7 */
|
|
132
|
-
/***/ (function(module,
|
|
132
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
"use strict";
|
|
135
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalHeader; });
|
|
136
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
137
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
138
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
139
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
|
|
140
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
|
|
141
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__);
|
|
142
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
|
|
143
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
|
|
144
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5);
|
|
145
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__);
|
|
146
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1);
|
|
147
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5__);
|
|
148
|
+
/* harmony import */ var _khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(13);
|
|
149
|
+
/* harmony import */ var _khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__);
|
|
135
150
|
|
|
136
|
-
/***/ }),
|
|
137
|
-
/* 8 */
|
|
138
|
-
/***/ (function(module, exports) {
|
|
139
151
|
|
|
140
|
-
function _extends() {
|
|
141
|
-
module.exports = _extends = Object.assign || function (target) {
|
|
142
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
143
|
-
var source = arguments[i];
|
|
144
152
|
|
|
145
|
-
for (var key in source) {
|
|
146
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
147
|
-
target[key] = source[key];
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
153
|
|
|
152
|
-
return target;
|
|
153
|
-
};
|
|
154
154
|
|
|
155
|
-
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|
156
|
-
return _extends.apply(this, arguments);
|
|
157
|
-
}
|
|
158
155
|
|
|
159
|
-
module.exports = _extends;
|
|
160
|
-
module.exports["default"] = module.exports, module.exports.__esModule = true;
|
|
161
156
|
|
|
162
|
-
/***/ }),
|
|
163
|
-
/* 9 */
|
|
164
|
-
/***/ (function(module, exports) {
|
|
165
157
|
|
|
166
|
-
|
|
158
|
+
/**
|
|
159
|
+
* This is a helper component that is never rendered by itself. It is always
|
|
160
|
+
* pinned to the top of the dialog, is responsive using the same behavior as its
|
|
161
|
+
* parent dialog, and has the following properties:
|
|
162
|
+
* - title
|
|
163
|
+
* - breadcrumb OR subtitle, but not both.
|
|
164
|
+
*
|
|
165
|
+
* **Accessibility notes:**
|
|
166
|
+
*
|
|
167
|
+
* - By default (e.g. using [OnePaneDialog](/#onepanedialog)), `titleId` is
|
|
168
|
+
* populated automatically by the parent container.
|
|
169
|
+
* - If there is a custom Dialog implementation (e.g. `TwoPaneDialog`), the
|
|
170
|
+
* ModalHeader doesn’t have to have the `titleId` prop however this is
|
|
171
|
+
* recommended. It should match the `aria-labelledby` prop of the
|
|
172
|
+
* [ModalDialog](/#modaldialog) component. If you want to see an example of
|
|
173
|
+
* how to generate this ID, check [IDProvider](/#idprovider).
|
|
174
|
+
*
|
|
175
|
+
* **Implementation notes:**
|
|
176
|
+
*
|
|
177
|
+
* If you are creating a custom Dialog, make sure to follow these guidelines:
|
|
178
|
+
* - Make sure to include it as part of [ModalPanel](/#modalpanel) by using the
|
|
179
|
+
* `header` prop.
|
|
180
|
+
* - Add a title (required).
|
|
181
|
+
* - Optionally add a subtitle or breadcrumbs.
|
|
182
|
+
* - We encourage you to add `titleId` (see Accessibility notes).
|
|
183
|
+
* - If the `ModalPanel` has a dark background, make sure to set `light` to
|
|
184
|
+
* `false`.
|
|
185
|
+
* - If you need to create e2e tests, make sure to pass a `testId` prop and
|
|
186
|
+
* add a sufix to scope the testId to this component: e.g.
|
|
187
|
+
* `some-random-id-ModalHeader`. This scope will also be passed to the title
|
|
188
|
+
* and subtitle elements: e.g. `some-random-id-ModalHeader-title`.
|
|
189
|
+
*
|
|
190
|
+
* Example:
|
|
191
|
+
*
|
|
192
|
+
* ```js
|
|
193
|
+
* <ModalHeader
|
|
194
|
+
* title="Sidebar using ModalHeader"
|
|
195
|
+
* subtitle="subtitle"
|
|
196
|
+
* titleId="uniqueTitleId"
|
|
197
|
+
* light={false}
|
|
198
|
+
* />
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
class ModalHeader extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
202
|
+
render() {
|
|
203
|
+
const {
|
|
204
|
+
breadcrumbs = undefined,
|
|
205
|
+
light,
|
|
206
|
+
subtitle = undefined,
|
|
207
|
+
testId,
|
|
208
|
+
title,
|
|
209
|
+
titleId
|
|
210
|
+
} = this.props;
|
|
167
211
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
212
|
+
if (subtitle && breadcrumbs) {
|
|
213
|
+
throw new Error("'subtitle' and 'breadcrumbs' can't be used together");
|
|
214
|
+
}
|
|
171
215
|
|
|
172
|
-
|
|
216
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__["MediaLayout"], {
|
|
217
|
+
styleSheets: styleSheets
|
|
218
|
+
}, ({
|
|
219
|
+
styles
|
|
220
|
+
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
221
|
+
style: [styles.header, !light && styles.dark],
|
|
222
|
+
testId: testId
|
|
223
|
+
}, breadcrumbs && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
224
|
+
style: styles.breadcrumbs
|
|
225
|
+
}, breadcrumbs), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["HeadingMedium"], {
|
|
226
|
+
style: styles.title,
|
|
227
|
+
id: titleId,
|
|
228
|
+
testId: testId && `${testId}-title`
|
|
229
|
+
}, title), subtitle && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["LabelSmall"], {
|
|
230
|
+
style: light && styles.subtitle,
|
|
231
|
+
testId: testId && `${testId}-subtitle`
|
|
232
|
+
}, subtitle)));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
}
|
|
236
|
+
ModalHeader.defaultProps = {
|
|
237
|
+
light: true
|
|
238
|
+
};
|
|
239
|
+
const styleSheets = {
|
|
240
|
+
all: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
241
|
+
header: {
|
|
242
|
+
boxShadow: `0px 1px 0px ${_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.offBlack16}`,
|
|
243
|
+
display: "flex",
|
|
244
|
+
flexDirection: "column",
|
|
245
|
+
minHeight: 66,
|
|
246
|
+
padding: `${_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.large_24}px ${_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.xLarge_32}px`,
|
|
247
|
+
position: "relative",
|
|
248
|
+
width: "100%"
|
|
249
|
+
},
|
|
250
|
+
dark: {
|
|
251
|
+
background: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.darkBlue,
|
|
252
|
+
color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.white
|
|
253
|
+
},
|
|
254
|
+
breadcrumbs: {
|
|
255
|
+
color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.offBlack64,
|
|
256
|
+
marginBottom: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.xSmall_8
|
|
257
|
+
},
|
|
258
|
+
title: {
|
|
259
|
+
// Prevent title from overlapping the close button
|
|
260
|
+
paddingRight: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.medium_16
|
|
261
|
+
},
|
|
262
|
+
subtitle: {
|
|
263
|
+
color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.offBlack64,
|
|
264
|
+
marginTop: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.xSmall_8
|
|
265
|
+
}
|
|
266
|
+
}),
|
|
267
|
+
small: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
268
|
+
header: {
|
|
269
|
+
paddingLeft: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.medium_16,
|
|
270
|
+
paddingRight: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.medium_16
|
|
271
|
+
},
|
|
272
|
+
title: {
|
|
273
|
+
paddingRight: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.xLarge_32
|
|
274
|
+
}
|
|
275
|
+
})
|
|
276
|
+
};
|
|
173
277
|
|
|
174
278
|
/***/ }),
|
|
175
|
-
/*
|
|
279
|
+
/* 8 */
|
|
176
280
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
177
281
|
|
|
178
282
|
"use strict";
|
|
179
|
-
|
|
180
|
-
__webpack_require__
|
|
283
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalFooter; });
|
|
284
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
285
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
286
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
287
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
|
|
288
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
|
|
289
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__);
|
|
290
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
|
|
291
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
|
|
292
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1);
|
|
293
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__);
|
|
294
|
+
|
|
295
|
+
|
|
181
296
|
|
|
182
|
-
// EXPORTS
|
|
183
|
-
__webpack_require__.d(__webpack_exports__, "ModalHeader", function() { return /* reexport */ modal_header_ModalHeader; });
|
|
184
|
-
__webpack_require__.d(__webpack_exports__, "ModalFooter", function() { return /* reexport */ modal_footer_ModalFooter; });
|
|
185
|
-
__webpack_require__.d(__webpack_exports__, "ModalDialog", function() { return /* reexport */ modal_dialog_ModalDialog; });
|
|
186
|
-
__webpack_require__.d(__webpack_exports__, "ModalPanel", function() { return /* reexport */ modal_panel_ModalPanel; });
|
|
187
|
-
__webpack_require__.d(__webpack_exports__, "ModalLauncher", function() { return /* reexport */ modal_launcher_ModalLauncher; });
|
|
188
|
-
__webpack_require__.d(__webpack_exports__, "OnePaneDialog", function() { return /* reexport */ one_pane_dialog_OnePaneDialog; });
|
|
189
|
-
__webpack_require__.d(__webpack_exports__, "maybeGetPortalMountedModalHostElement", function() { return /* reexport */ maybeGetPortalMountedModalHostElement; });
|
|
190
297
|
|
|
191
|
-
// EXTERNAL MODULE: external "react"
|
|
192
|
-
var external_react_ = __webpack_require__(0);
|
|
193
298
|
|
|
194
|
-
// EXTERNAL MODULE: external "aphrodite"
|
|
195
|
-
var external_aphrodite_ = __webpack_require__(3);
|
|
196
299
|
|
|
197
|
-
|
|
198
|
-
|
|
300
|
+
/**
|
|
301
|
+
* Modal footer included after the content.
|
|
302
|
+
*
|
|
303
|
+
* **Implementation notes**:
|
|
304
|
+
*
|
|
305
|
+
* If you are creating a custom Dialog, make sure to follow these guidelines:
|
|
306
|
+
* - Make sure to include it as part of [ModalPanel](/#modalpanel) by using the `footer` prop.
|
|
307
|
+
* - The footer is completely flexible. Meaning the developer needs to add its own custom layout to match design specs.
|
|
308
|
+
*/
|
|
309
|
+
class ModalFooter extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
310
|
+
static isClassOf(instance) {
|
|
311
|
+
return instance && instance.type && instance.type.__IS_MODAL_FOOTER__;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
render() {
|
|
315
|
+
const {
|
|
316
|
+
children
|
|
317
|
+
} = this.props;
|
|
318
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
319
|
+
style: styles.footer
|
|
320
|
+
}, children);
|
|
321
|
+
}
|
|
199
322
|
|
|
200
|
-
|
|
201
|
-
|
|
323
|
+
}
|
|
324
|
+
ModalFooter.__IS_MODAL_FOOTER__ = true;
|
|
325
|
+
const styles = aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
326
|
+
footer: {
|
|
327
|
+
flex: "0 0 auto",
|
|
328
|
+
boxSizing: "border-box",
|
|
329
|
+
minHeight: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xxxLarge_64,
|
|
330
|
+
paddingLeft: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
|
|
331
|
+
paddingRight: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
|
|
332
|
+
paddingTop: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xSmall_8,
|
|
333
|
+
paddingBottom: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xSmall_8,
|
|
334
|
+
display: "flex",
|
|
335
|
+
flexDirection: "row",
|
|
336
|
+
alignItems: "center",
|
|
337
|
+
justifyContent: "flex-end",
|
|
338
|
+
boxShadow: `0px -1px 0px ${_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.offBlack16}`
|
|
339
|
+
}
|
|
340
|
+
});
|
|
202
341
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
342
|
+
/***/ }),
|
|
343
|
+
/* 9 */
|
|
344
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
206
345
|
|
|
207
|
-
|
|
346
|
+
"use strict";
|
|
347
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalDialog; });
|
|
348
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
349
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
350
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
351
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
|
|
352
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
|
|
353
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__);
|
|
354
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
|
|
355
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
|
|
356
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1);
|
|
357
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__);
|
|
208
358
|
|
|
209
359
|
|
|
210
360
|
|
|
@@ -221,7 +371,7 @@ var wonder_blocks_spacing_default = /*#__PURE__*/__webpack_require__.n(wonder_bl
|
|
|
221
371
|
* - If there is a custom Dialog implementation (e.g. `TwoPaneDialog`), the dialog element doesn’t have to have
|
|
222
372
|
* the `aria-labelledby` attribute however this is recommended. It should match the `id` of the dialog title.
|
|
223
373
|
*/
|
|
224
|
-
class
|
|
374
|
+
class ModalDialog extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
225
375
|
render() {
|
|
226
376
|
const {
|
|
227
377
|
above,
|
|
@@ -234,35 +384,35 @@ class modal_dialog_ModalDialog extends external_react_["Component"] {
|
|
|
234
384
|
} = this.props;
|
|
235
385
|
const contextValue = {
|
|
236
386
|
ssrSize: "large",
|
|
237
|
-
mediaSpec:
|
|
387
|
+
mediaSpec: _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MEDIA_MODAL_SPEC"]
|
|
238
388
|
};
|
|
239
|
-
return /*#__PURE__*/
|
|
389
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MediaLayoutContext"].Provider, {
|
|
240
390
|
value: contextValue
|
|
241
|
-
}, /*#__PURE__*/
|
|
391
|
+
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MediaLayout"], {
|
|
242
392
|
styleSheets: styleSheets
|
|
243
393
|
}, ({
|
|
244
394
|
styles
|
|
245
|
-
}) => /*#__PURE__*/
|
|
395
|
+
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
246
396
|
style: [styles.wrapper, style]
|
|
247
|
-
}, below && /*#__PURE__*/
|
|
397
|
+
}, below && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
248
398
|
style: styles.below
|
|
249
|
-
}, below), /*#__PURE__*/
|
|
399
|
+
}, below), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
250
400
|
role: role,
|
|
251
401
|
"aria-modal": "true",
|
|
252
402
|
"aria-labelledby": ariaLabelledBy,
|
|
253
403
|
style: styles.dialog,
|
|
254
404
|
testId: testId
|
|
255
|
-
}, children), above && /*#__PURE__*/
|
|
405
|
+
}, children), above && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
256
406
|
style: styles.above
|
|
257
407
|
}, above))));
|
|
258
408
|
}
|
|
259
409
|
|
|
260
410
|
}
|
|
261
|
-
|
|
411
|
+
ModalDialog.defaultProps = {
|
|
262
412
|
role: "dialog"
|
|
263
413
|
};
|
|
264
414
|
const styleSheets = {
|
|
265
|
-
all:
|
|
415
|
+
all: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
266
416
|
wrapper: {
|
|
267
417
|
display: "flex",
|
|
268
418
|
flexDirection: "row",
|
|
@@ -300,18 +450,38 @@ const styleSheets = {
|
|
|
300
450
|
zIndex: -1
|
|
301
451
|
}
|
|
302
452
|
}),
|
|
303
|
-
small:
|
|
453
|
+
small: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
304
454
|
wrapper: {
|
|
305
|
-
padding:
|
|
455
|
+
padding: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
|
|
306
456
|
flexDirection: "column"
|
|
307
457
|
}
|
|
308
458
|
})
|
|
309
459
|
};
|
|
310
|
-
// EXTERNAL MODULE: external "@khanacademy/wonder-blocks-color"
|
|
311
|
-
var wonder_blocks_color_ = __webpack_require__(4);
|
|
312
|
-
var wonder_blocks_color_default = /*#__PURE__*/__webpack_require__.n(wonder_blocks_color_);
|
|
313
460
|
|
|
314
|
-
|
|
461
|
+
/***/ }),
|
|
462
|
+
/* 10 */
|
|
463
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
464
|
+
|
|
465
|
+
"use strict";
|
|
466
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalPanel; });
|
|
467
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
468
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
469
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
470
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
|
|
471
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
|
|
472
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__);
|
|
473
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
|
|
474
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
|
|
475
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1);
|
|
476
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__);
|
|
477
|
+
/* harmony import */ var _modal_content_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(14);
|
|
478
|
+
/* harmony import */ var _modal_header_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7);
|
|
479
|
+
/* harmony import */ var _modal_footer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(8);
|
|
480
|
+
/* harmony import */ var _close_button_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(22);
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
315
485
|
|
|
316
486
|
|
|
317
487
|
|
|
@@ -319,52 +489,153 @@ var wonder_blocks_color_default = /*#__PURE__*/__webpack_require__.n(wonder_bloc
|
|
|
319
489
|
|
|
320
490
|
|
|
321
491
|
/**
|
|
322
|
-
*
|
|
492
|
+
* ModalPanel is the content container.
|
|
323
493
|
*
|
|
324
|
-
* **Implementation notes
|
|
494
|
+
* **Implementation notes:**
|
|
325
495
|
*
|
|
326
496
|
* If you are creating a custom Dialog, make sure to follow these guidelines:
|
|
327
|
-
* - Make sure to
|
|
328
|
-
* -
|
|
497
|
+
* - Make sure to add this component inside the [ModalDialog](/#modaldialog).
|
|
498
|
+
* - If needed, you can also add a [ModalHeader](/#modalheader) using the
|
|
499
|
+
* `header` prop. Same goes for [ModalFooter](/#modalfooter).
|
|
500
|
+
* - If you need to create e2e tests, make sure to pass a `testId` prop. This
|
|
501
|
+
* will be passed down to this component using a sufix: e.g.
|
|
502
|
+
* `some-random-id-ModalPanel`. This scope will be propagated to the
|
|
503
|
+
* CloseButton element as well: e.g. `some-random-id-CloseButton`.
|
|
504
|
+
*
|
|
505
|
+
* ```js
|
|
506
|
+
* <ModalDialog>
|
|
507
|
+
* <ModalPanel content={"custom content goes here"} />
|
|
508
|
+
* </ModalDialog>
|
|
509
|
+
* ```
|
|
329
510
|
*/
|
|
330
|
-
class
|
|
331
|
-
|
|
332
|
-
|
|
511
|
+
class ModalPanel extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
512
|
+
renderMainContent() {
|
|
513
|
+
const {
|
|
514
|
+
content,
|
|
515
|
+
footer,
|
|
516
|
+
scrollOverflow
|
|
517
|
+
} = this.props;
|
|
518
|
+
const mainContent = _modal_content_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].isClassOf(content) ? content : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_content_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"], null, content);
|
|
519
|
+
|
|
520
|
+
if (!mainContent) {
|
|
521
|
+
return mainContent;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["cloneElement"](mainContent, {
|
|
525
|
+
// Pass the scrollOverflow and header in to the main content
|
|
526
|
+
scrollOverflow,
|
|
527
|
+
// We override the styling of the main content to help position
|
|
528
|
+
// it if there is a footer or close button being
|
|
529
|
+
// shown. We have to do this here as the ModalContent doesn't
|
|
530
|
+
// know about things being positioned around it.
|
|
531
|
+
style: [!!footer && styles.hasFooter, mainContent.props.style]
|
|
532
|
+
});
|
|
333
533
|
}
|
|
334
534
|
|
|
335
535
|
render() {
|
|
336
536
|
const {
|
|
337
|
-
|
|
537
|
+
closeButtonVisible,
|
|
538
|
+
footer,
|
|
539
|
+
header,
|
|
540
|
+
light,
|
|
541
|
+
onClose,
|
|
542
|
+
style,
|
|
543
|
+
testId
|
|
338
544
|
} = this.props;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
545
|
+
const mainContent = this.renderMainContent();
|
|
546
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
|
|
547
|
+
style: [styles.wrapper, !light && styles.dark, style],
|
|
548
|
+
testId: testId && `${testId}-panel`
|
|
549
|
+
}, closeButtonVisible && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_close_button_js__WEBPACK_IMPORTED_MODULE_8__[/* default */ "a"], {
|
|
550
|
+
light: !light,
|
|
551
|
+
onClick: onClose,
|
|
552
|
+
style: styles.closeButton,
|
|
553
|
+
testId: testId && `${testId}-close`
|
|
554
|
+
}), header, mainContent, !footer || _modal_footer_js__WEBPACK_IMPORTED_MODULE_7__[/* default */ "a"].isClassOf(footer) ? footer : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_footer_js__WEBPACK_IMPORTED_MODULE_7__[/* default */ "a"], null, footer));
|
|
342
555
|
}
|
|
343
556
|
|
|
344
557
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
paddingBottom: wonder_blocks_spacing_default.a.xSmall_8,
|
|
558
|
+
ModalPanel.defaultProps = {
|
|
559
|
+
closeButtonVisible: true,
|
|
560
|
+
scrollOverflow: true,
|
|
561
|
+
light: true
|
|
562
|
+
};
|
|
563
|
+
const styles = aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
564
|
+
wrapper: {
|
|
565
|
+
flex: "1 1 auto",
|
|
566
|
+
position: "relative",
|
|
355
567
|
display: "flex",
|
|
356
|
-
flexDirection: "
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
568
|
+
flexDirection: "column",
|
|
569
|
+
background: "white",
|
|
570
|
+
boxSizing: "border-box",
|
|
571
|
+
overflow: "hidden",
|
|
572
|
+
height: "100%",
|
|
573
|
+
width: "100%"
|
|
574
|
+
},
|
|
575
|
+
closeButton: {
|
|
576
|
+
position: "absolute",
|
|
577
|
+
right: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
|
|
578
|
+
top: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
|
|
579
|
+
// This is to allow the button to be tab-ordered before the modal
|
|
580
|
+
// content but still be above the header and content.
|
|
581
|
+
zIndex: 1
|
|
582
|
+
},
|
|
583
|
+
dark: {
|
|
584
|
+
background: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.darkBlue,
|
|
585
|
+
color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.white
|
|
586
|
+
},
|
|
587
|
+
hasFooter: {
|
|
588
|
+
paddingBottom: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xLarge_32
|
|
360
589
|
}
|
|
361
590
|
});
|
|
362
|
-
// EXTERNAL MODULE: external "@khanacademy/wonder-blocks-typography"
|
|
363
|
-
var wonder_blocks_typography_ = __webpack_require__(7);
|
|
364
|
-
|
|
365
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/components/modal-header.js
|
|
366
591
|
|
|
592
|
+
/***/ }),
|
|
593
|
+
/* 11 */
|
|
594
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
367
595
|
|
|
596
|
+
"use strict";
|
|
597
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalLauncherPortalAttributeName; });
|
|
598
|
+
/**
|
|
599
|
+
* The attribute used to identify a modal launcher portal.
|
|
600
|
+
*/
|
|
601
|
+
const ModalLauncherPortalAttributeName = "data-modal-launcher-portal";
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
/***/ }),
|
|
605
|
+
/* 12 */
|
|
606
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
607
|
+
|
|
608
|
+
"use strict";
|
|
609
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
610
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
611
|
+
|
|
612
|
+
const defaultContext = {
|
|
613
|
+
closeModal: undefined
|
|
614
|
+
};
|
|
615
|
+
/* harmony default export */ __webpack_exports__["a"] = (/*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createContext"](defaultContext));
|
|
616
|
+
|
|
617
|
+
/***/ }),
|
|
618
|
+
/* 13 */
|
|
619
|
+
/***/ (function(module, exports) {
|
|
620
|
+
|
|
621
|
+
module.exports = require("@khanacademy/wonder-blocks-typography");
|
|
622
|
+
|
|
623
|
+
/***/ }),
|
|
624
|
+
/* 14 */
|
|
625
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
626
|
+
|
|
627
|
+
"use strict";
|
|
628
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalContent; });
|
|
629
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
630
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
631
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
632
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
|
|
633
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
|
|
634
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__);
|
|
635
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
|
|
636
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3__);
|
|
637
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1);
|
|
638
|
+
/* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__);
|
|
368
639
|
|
|
369
640
|
|
|
370
641
|
|
|
@@ -372,132 +643,441 @@ var wonder_blocks_typography_ = __webpack_require__(7);
|
|
|
372
643
|
|
|
373
644
|
|
|
374
645
|
/**
|
|
375
|
-
*
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
646
|
+
* The Modal content included after the header
|
|
647
|
+
*/
|
|
648
|
+
class ModalContent extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
649
|
+
static isClassOf(instance) {
|
|
650
|
+
return instance && instance.type && instance.type.__IS_MODAL_CONTENT__;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
render() {
|
|
654
|
+
const {
|
|
655
|
+
scrollOverflow,
|
|
656
|
+
style,
|
|
657
|
+
children
|
|
658
|
+
} = this.props;
|
|
659
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3__["MediaLayout"], {
|
|
660
|
+
styleSheets: styleSheets
|
|
661
|
+
}, ({
|
|
662
|
+
styles
|
|
663
|
+
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__["View"], {
|
|
664
|
+
style: [styles.wrapper, scrollOverflow && styles.scrollOverflow]
|
|
665
|
+
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__["View"], {
|
|
666
|
+
style: [styles.content, style]
|
|
667
|
+
}, children)));
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
}
|
|
671
|
+
ModalContent.defaultProps = {
|
|
672
|
+
scrollOverflow: true
|
|
673
|
+
};
|
|
674
|
+
ModalContent.__IS_MODAL_CONTENT__ = true;
|
|
675
|
+
const styleSheets = {
|
|
676
|
+
all: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
677
|
+
wrapper: {
|
|
678
|
+
flex: 1,
|
|
679
|
+
// This helps to ensure that the paddingBottom is preserved when
|
|
680
|
+
// the contents start to overflow, this goes away on display: flex
|
|
681
|
+
display: "block"
|
|
682
|
+
},
|
|
683
|
+
scrollOverflow: {
|
|
684
|
+
overflow: "auto"
|
|
685
|
+
},
|
|
686
|
+
content: {
|
|
687
|
+
flex: 1,
|
|
688
|
+
minHeight: "100%",
|
|
689
|
+
padding: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xLarge_32,
|
|
690
|
+
boxSizing: "border-box"
|
|
691
|
+
}
|
|
692
|
+
}),
|
|
693
|
+
small: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
694
|
+
content: {
|
|
695
|
+
padding: `${_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xLarge_32}px ${_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16}px`
|
|
696
|
+
}
|
|
697
|
+
})
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
/***/ }),
|
|
701
|
+
/* 15 */
|
|
702
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
703
|
+
|
|
704
|
+
"use strict";
|
|
705
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalLauncher; });
|
|
706
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
707
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
708
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
|
|
709
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
|
710
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
|
711
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_2__);
|
|
712
|
+
/* harmony import */ var _focus_trap_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(18);
|
|
713
|
+
/* harmony import */ var _modal_backdrop_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(19);
|
|
714
|
+
/* harmony import */ var _scroll_disabler_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21);
|
|
715
|
+
/* harmony import */ var _modal_context_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(12);
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* This component enables you to launch a modal, covering the screen.
|
|
405
726
|
*
|
|
406
|
-
*
|
|
727
|
+
* Children have access to `openModal` function via the function-as-children
|
|
728
|
+
* pattern, so one common use case is for this component to wrap a button:
|
|
407
729
|
*
|
|
408
730
|
* ```js
|
|
409
|
-
* <
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
* titleId="uniqueTitleId"
|
|
413
|
-
* light={false}
|
|
414
|
-
* />
|
|
731
|
+
* <ModalLauncher modal={<TwoColumnModal ... />}>
|
|
732
|
+
* {({openModal}) => <button onClick={openModal}>Learn more</button>}
|
|
733
|
+
* </ModalLauncher>
|
|
415
734
|
* ```
|
|
735
|
+
*
|
|
736
|
+
* The actual modal itself is constructed separately, using a layout component
|
|
737
|
+
* like OnePaneDialog and is provided via
|
|
738
|
+
* the `modal` prop.
|
|
416
739
|
*/
|
|
417
|
-
class
|
|
740
|
+
class ModalLauncher extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
741
|
+
constructor(...args) {
|
|
742
|
+
super(...args);
|
|
743
|
+
this.state = {
|
|
744
|
+
opened: false
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
this._saveLastElementFocused = () => {
|
|
748
|
+
// keep a reference of the element that triggers the modal
|
|
749
|
+
this.lastElementFocusedOutsideModal = document.activeElement;
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
this._openModal = () => {
|
|
753
|
+
this._saveLastElementFocused();
|
|
754
|
+
|
|
755
|
+
this.setState({
|
|
756
|
+
opened: true
|
|
757
|
+
});
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
this.handleCloseModal = () => {
|
|
761
|
+
this.setState({
|
|
762
|
+
opened: false
|
|
763
|
+
}, () => {
|
|
764
|
+
this.props.onClose && this.props.onClose();
|
|
765
|
+
|
|
766
|
+
if (this.lastElementFocusedOutsideModal != null) {
|
|
767
|
+
// return focus to the element that triggered the modal
|
|
768
|
+
this.lastElementFocusedOutsideModal.focus();
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
static getDerivedStateFromProps(props, state) {
|
|
775
|
+
if (typeof props.opened === "boolean" && props.children) {
|
|
776
|
+
// eslint-disable-next-line no-console
|
|
777
|
+
console.warn("'children' and 'opened' can't be used together");
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (typeof props.opened === "boolean" && !props.onClose) {
|
|
781
|
+
// eslint-disable-next-line no-console
|
|
782
|
+
console.warn("'onClose' should be used with 'opened'");
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
if (typeof props.opened !== "boolean" && !props.children) {
|
|
786
|
+
// eslint-disable-next-line no-console
|
|
787
|
+
console.warn("either 'children' or 'opened' must be set");
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
return {
|
|
791
|
+
opened: typeof props.opened === "boolean" ? props.opened : state.opened
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
componentDidUpdate(prevProps) {
|
|
796
|
+
// ensures the element is stored only when the modal is opened
|
|
797
|
+
if (!prevProps.opened && this.props.opened) {
|
|
798
|
+
this._saveLastElementFocused();
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
_renderModal() {
|
|
803
|
+
if (typeof this.props.modal === "function") {
|
|
804
|
+
return this.props.modal({
|
|
805
|
+
closeModal: this.handleCloseModal
|
|
806
|
+
});
|
|
807
|
+
} else {
|
|
808
|
+
return this.props.modal;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
render() {
|
|
813
|
+
const renderedChildren = this.props.children ? this.props.children({
|
|
814
|
+
openModal: this._openModal
|
|
815
|
+
}) : null;
|
|
816
|
+
const {
|
|
817
|
+
body
|
|
818
|
+
} = document;
|
|
819
|
+
|
|
820
|
+
if (!body) {
|
|
821
|
+
return null;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
return (
|
|
825
|
+
/*#__PURE__*/
|
|
826
|
+
// This flow check is valid, it's the babel plugin which is broken,
|
|
827
|
+
// see modal-context.js for details.
|
|
828
|
+
// $FlowFixMe
|
|
829
|
+
react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_context_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"].Provider, {
|
|
830
|
+
value: {
|
|
831
|
+
closeModal: this.handleCloseModal
|
|
832
|
+
}
|
|
833
|
+
}, renderedChildren, this.state.opened && /*#__PURE__*/react_dom__WEBPACK_IMPORTED_MODULE_1__["createPortal"](
|
|
834
|
+
/*#__PURE__*/
|
|
835
|
+
|
|
836
|
+
/* We need the container View that FocusTrap creates to be at the
|
|
837
|
+
correct z-index so that it'll be above the global nav in webapp. */
|
|
838
|
+
react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_focus_trap_js__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"], {
|
|
839
|
+
style: styles.container
|
|
840
|
+
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_backdrop_js__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"], {
|
|
841
|
+
initialFocusId: this.props.initialFocusId,
|
|
842
|
+
testId: this.props.testId,
|
|
843
|
+
onCloseModal: this.props.backdropDismissEnabled ? this.handleCloseModal : () => {}
|
|
844
|
+
}, this._renderModal())), body), this.state.opened && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](ModalLauncherKeypressListener, {
|
|
845
|
+
onClose: this.handleCloseModal
|
|
846
|
+
}), this.state.opened && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_scroll_disabler_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"], null))
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
}
|
|
851
|
+
/** A component that, when mounted, calls `onClose` when Escape is pressed. */
|
|
852
|
+
|
|
853
|
+
ModalLauncher.defaultProps = {
|
|
854
|
+
backdropDismissEnabled: true
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
class ModalLauncherKeypressListener extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
858
|
+
constructor(...args) {
|
|
859
|
+
super(...args);
|
|
860
|
+
|
|
861
|
+
this._handleKeyup = e => {
|
|
862
|
+
// We check the key as that's keyboard layout agnostic and also avoids
|
|
863
|
+
// the minefield of deprecated number type properties like keyCode and
|
|
864
|
+
// which, with the replacement code, which uses a string instead.
|
|
865
|
+
if (e.key === "Escape") {
|
|
866
|
+
// Stop the event going any further.
|
|
867
|
+
// For cancellation events, like the Escape key, we generally should
|
|
868
|
+
// air on the side of caution and only allow it to cancel one thing.
|
|
869
|
+
// So, it's polite for us to stop propagation of the event.
|
|
870
|
+
// Otherwise, we end up with UX where one Escape key press
|
|
871
|
+
// unexpectedly cancels multiple things.
|
|
872
|
+
e.preventDefault();
|
|
873
|
+
e.stopPropagation();
|
|
874
|
+
this.props.onClose();
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
componentDidMount() {
|
|
880
|
+
window.addEventListener("keyup", this._handleKeyup);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
componentWillUnmount() {
|
|
884
|
+
window.removeEventListener("keyup", this._handleKeyup);
|
|
885
|
+
}
|
|
886
|
+
|
|
418
887
|
render() {
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
const styles = aphrodite__WEBPACK_IMPORTED_MODULE_2__["StyleSheet"].create({
|
|
894
|
+
container: {
|
|
895
|
+
// This z-index is copied from the Khan Academy webapp.
|
|
896
|
+
//
|
|
897
|
+
// TODO(mdr): Should we keep this in a constants file somewhere? Or
|
|
898
|
+
// not hardcode it at all, and provide it to Wonder Blocks via
|
|
899
|
+
// configuration?
|
|
900
|
+
zIndex: 1080
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
/***/ }),
|
|
905
|
+
/* 16 */
|
|
906
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
907
|
+
|
|
908
|
+
"use strict";
|
|
909
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return OnePaneDialog; });
|
|
910
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
911
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
912
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
913
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
|
|
914
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
|
|
915
|
+
/* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__);
|
|
916
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
|
|
917
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
|
|
918
|
+
/* harmony import */ var _modal_dialog_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9);
|
|
919
|
+
/* harmony import */ var _modal_panel_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(10);
|
|
920
|
+
/* harmony import */ var _modal_header_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7);
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* This is the standard layout for most straightforward modal experiences.
|
|
931
|
+
*
|
|
932
|
+
* The ModalHeader is required, but the ModalFooter is optional.
|
|
933
|
+
* The content of the dialog itself is fully customizable, but the left/right/top/bottom padding is fixed.
|
|
934
|
+
*/
|
|
935
|
+
class OnePaneDialog extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
936
|
+
renderHeader(uniqueId) {
|
|
419
937
|
const {
|
|
938
|
+
title,
|
|
420
939
|
breadcrumbs = undefined,
|
|
421
|
-
light,
|
|
422
940
|
subtitle = undefined,
|
|
423
|
-
testId
|
|
424
|
-
title,
|
|
425
|
-
titleId
|
|
941
|
+
testId
|
|
426
942
|
} = this.props;
|
|
427
943
|
|
|
428
|
-
if (
|
|
429
|
-
|
|
944
|
+
if (breadcrumbs) {
|
|
945
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_header_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"], {
|
|
946
|
+
title: title,
|
|
947
|
+
breadcrumbs: breadcrumbs,
|
|
948
|
+
titleId: uniqueId,
|
|
949
|
+
testId: testId && `${testId}-header`
|
|
950
|
+
});
|
|
951
|
+
} else if (subtitle) {
|
|
952
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_header_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"], {
|
|
953
|
+
title: title,
|
|
954
|
+
subtitle: subtitle,
|
|
955
|
+
titleId: uniqueId,
|
|
956
|
+
testId: testId && `${testId}-header`
|
|
957
|
+
});
|
|
958
|
+
} else {
|
|
959
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_header_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"], {
|
|
960
|
+
title: title,
|
|
961
|
+
titleId: uniqueId,
|
|
962
|
+
testId: testId && `${testId}-header`
|
|
963
|
+
});
|
|
430
964
|
}
|
|
965
|
+
}
|
|
431
966
|
|
|
432
|
-
|
|
433
|
-
|
|
967
|
+
render() {
|
|
968
|
+
const {
|
|
969
|
+
onClose,
|
|
970
|
+
footer,
|
|
971
|
+
content,
|
|
972
|
+
above,
|
|
973
|
+
below,
|
|
974
|
+
style,
|
|
975
|
+
closeButtonVisible,
|
|
976
|
+
testId,
|
|
977
|
+
titleId,
|
|
978
|
+
role
|
|
979
|
+
} = this.props;
|
|
980
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MediaLayout"], {
|
|
981
|
+
styleSheets: styleSheets
|
|
434
982
|
}, ({
|
|
435
983
|
styles
|
|
436
|
-
}) => /*#__PURE__*/
|
|
437
|
-
style: [styles.header, !light && styles.dark],
|
|
438
|
-
testId: testId
|
|
439
|
-
}, breadcrumbs && /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
|
|
440
|
-
style: styles.breadcrumbs
|
|
441
|
-
}, breadcrumbs), /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["HeadingMedium"], {
|
|
442
|
-
style: styles.title,
|
|
984
|
+
}) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["IDProvider"], {
|
|
443
985
|
id: titleId,
|
|
444
|
-
|
|
445
|
-
},
|
|
446
|
-
style:
|
|
447
|
-
|
|
448
|
-
|
|
986
|
+
scope: "modal"
|
|
987
|
+
}, uniqueId => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_dialog_js__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"], {
|
|
988
|
+
style: [styles.dialog, style],
|
|
989
|
+
above: above,
|
|
990
|
+
below: below,
|
|
991
|
+
testId: testId,
|
|
992
|
+
"aria-labelledby": uniqueId,
|
|
993
|
+
role: role
|
|
994
|
+
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_panel_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"], {
|
|
995
|
+
onClose: onClose,
|
|
996
|
+
header: this.renderHeader(uniqueId),
|
|
997
|
+
content: content,
|
|
998
|
+
footer: footer,
|
|
999
|
+
closeButtonVisible: closeButtonVisible,
|
|
1000
|
+
testId: testId
|
|
1001
|
+
}))));
|
|
449
1002
|
}
|
|
450
1003
|
|
|
451
1004
|
}
|
|
452
|
-
|
|
453
|
-
|
|
1005
|
+
OnePaneDialog.defaultProps = {
|
|
1006
|
+
closeButtonVisible: true
|
|
454
1007
|
};
|
|
455
|
-
const
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
minHeight: 66,
|
|
462
|
-
padding: `${wonder_blocks_spacing_default.a.large_24}px ${wonder_blocks_spacing_default.a.xLarge_32}px`,
|
|
463
|
-
position: "relative",
|
|
464
|
-
width: "100%"
|
|
465
|
-
},
|
|
466
|
-
dark: {
|
|
467
|
-
background: wonder_blocks_color_default.a.darkBlue,
|
|
468
|
-
color: wonder_blocks_color_default.a.white
|
|
469
|
-
},
|
|
470
|
-
breadcrumbs: {
|
|
471
|
-
color: wonder_blocks_color_default.a.offBlack64,
|
|
472
|
-
marginBottom: wonder_blocks_spacing_default.a.xSmall_8
|
|
473
|
-
},
|
|
474
|
-
title: {
|
|
475
|
-
// Prevent title from overlapping the close button
|
|
476
|
-
paddingRight: wonder_blocks_spacing_default.a.medium_16
|
|
477
|
-
},
|
|
478
|
-
subtitle: {
|
|
479
|
-
color: wonder_blocks_color_default.a.offBlack64,
|
|
480
|
-
marginTop: wonder_blocks_spacing_default.a.xSmall_8
|
|
1008
|
+
const styleSheets = {
|
|
1009
|
+
small: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
1010
|
+
dialog: {
|
|
1011
|
+
width: "100%",
|
|
1012
|
+
height: "100%",
|
|
1013
|
+
overflow: "hidden"
|
|
481
1014
|
}
|
|
482
1015
|
}),
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
paddingRight: wonder_blocks_spacing_default.a.xLarge_32
|
|
1016
|
+
mdOrLarger: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
|
|
1017
|
+
dialog: {
|
|
1018
|
+
width: "93.75%",
|
|
1019
|
+
maxWidth: 576,
|
|
1020
|
+
height: "81.25%",
|
|
1021
|
+
maxHeight: 624
|
|
490
1022
|
}
|
|
491
1023
|
})
|
|
492
1024
|
};
|
|
493
|
-
// EXTERNAL MODULE: external "react-dom"
|
|
494
|
-
var external_react_dom_ = __webpack_require__(6);
|
|
495
1025
|
|
|
496
|
-
|
|
1026
|
+
/***/ }),
|
|
1027
|
+
/* 17 */
|
|
1028
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1029
|
+
|
|
1030
|
+
"use strict";
|
|
1031
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return maybeGetPortalMountedModalHostElement; });
|
|
1032
|
+
/* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* From a given element, finds its next ancestor that is a modal launcher portal
|
|
1036
|
+
* element.
|
|
1037
|
+
* @param {?(Element | Text)} element The element whose ancestors are to be
|
|
1038
|
+
* walked.
|
|
1039
|
+
* @returns {?Element} The nearest parent modal launcher portal.
|
|
1040
|
+
*/
|
|
1041
|
+
|
|
1042
|
+
function maybeGetNextAncestorModalLauncherPortal(element) {
|
|
1043
|
+
let candidateElement = element && element.parentElement;
|
|
1044
|
+
|
|
1045
|
+
while (candidateElement && !candidateElement.hasAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_0__[/* ModalLauncherPortalAttributeName */ "a"])) {
|
|
1046
|
+
candidateElement = candidateElement.parentElement;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
return candidateElement;
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* From a given element, finds the next modal host that has been mounted in
|
|
1053
|
+
* a modal portal.
|
|
1054
|
+
* @param {?(Element | Text)} element The element whose ancestors are to be
|
|
1055
|
+
* walked.
|
|
1056
|
+
* @returns {?Element} The next portal-mounted modal host element.
|
|
1057
|
+
* TODO(kevinb): look into getting rid of this
|
|
1058
|
+
*/
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
function maybeGetPortalMountedModalHostElement(element) {
|
|
1062
|
+
return maybeGetNextAncestorModalLauncherPortal(element);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/***/ }),
|
|
1066
|
+
/* 18 */
|
|
1067
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1068
|
+
|
|
1069
|
+
"use strict";
|
|
1070
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return FocusTrap; });
|
|
1071
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
1072
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
1073
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
|
|
1074
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
|
1075
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
|
|
1076
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__);
|
|
497
1077
|
|
|
498
1078
|
|
|
499
1079
|
|
|
500
|
-
class
|
|
1080
|
+
class FocusTrap extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
501
1081
|
/** The most recent node _inside this component_ to receive focus. */
|
|
502
1082
|
|
|
503
1083
|
/**
|
|
@@ -517,7 +1097,7 @@ class focus_trap_FocusTrap extends external_react_["Component"] {
|
|
|
517
1097
|
return;
|
|
518
1098
|
}
|
|
519
1099
|
|
|
520
|
-
const modalRoot =
|
|
1100
|
+
const modalRoot = react_dom__WEBPACK_IMPORTED_MODULE_1__["findDOMNode"](node);
|
|
521
1101
|
|
|
522
1102
|
if (!modalRoot) {
|
|
523
1103
|
throw new Error("Assertion error: modal root should exist after mount");
|
|
@@ -646,15 +1226,15 @@ class focus_trap_FocusTrap extends external_react_["Component"] {
|
|
|
646
1226
|
const {
|
|
647
1227
|
style
|
|
648
1228
|
} = this.props;
|
|
649
|
-
return /*#__PURE__*/
|
|
1229
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](react__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("div", {
|
|
650
1230
|
tabIndex: "0",
|
|
651
1231
|
style: {
|
|
652
1232
|
position: "fixed"
|
|
653
1233
|
}
|
|
654
|
-
}), /*#__PURE__*/
|
|
1234
|
+
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__["View"], {
|
|
655
1235
|
style: style,
|
|
656
1236
|
ref: this.getModalRoot
|
|
657
|
-
}, this.props.children), /*#__PURE__*/
|
|
1237
|
+
}, this.props.children), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("div", {
|
|
658
1238
|
tabIndex: "0",
|
|
659
1239
|
style: {
|
|
660
1240
|
position: "fixed"
|
|
@@ -663,17 +1243,27 @@ class focus_trap_FocusTrap extends external_react_["Component"] {
|
|
|
663
1243
|
}
|
|
664
1244
|
|
|
665
1245
|
}
|
|
666
|
-
// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/extends.js
|
|
667
|
-
var helpers_extends = __webpack_require__(8);
|
|
668
|
-
var extends_default = /*#__PURE__*/__webpack_require__.n(helpers_extends);
|
|
669
1246
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
1247
|
+
/***/ }),
|
|
1248
|
+
/* 19 */
|
|
1249
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1250
|
+
|
|
1251
|
+
"use strict";
|
|
1252
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalBackdrop; });
|
|
1253
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
1254
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
1255
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
|
|
1256
|
+
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
|
|
1257
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
|
|
1258
|
+
/* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_2__);
|
|
1259
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
|
|
1260
|
+
/* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3__);
|
|
1261
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2);
|
|
1262
|
+
/* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__);
|
|
1263
|
+
/* harmony import */ var _util_constants_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(11);
|
|
1264
|
+
/* harmony import */ var _util_find_focusable_nodes_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(20);
|
|
1265
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
675
1266
|
|
|
676
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/components/modal-backdrop.js
|
|
677
1267
|
|
|
678
1268
|
|
|
679
1269
|
|
|
@@ -682,11 +1272,6 @@ const ModalLauncherPortalAttributeName = "data-modal-launcher-portal";
|
|
|
682
1272
|
|
|
683
1273
|
|
|
684
1274
|
|
|
685
|
-
/**
|
|
686
|
-
* List of elements that can be focused
|
|
687
|
-
* @see https://www.w3.org/TR/html5/editing.html#can-be-focused
|
|
688
|
-
*/
|
|
689
|
-
const FOCUSABLE_ELEMENTS = 'a[href], details, input, textarea, select, button:not([aria-label^="Close"])';
|
|
690
1275
|
/**
|
|
691
1276
|
* A private component used by ModalLauncher. This is the fixed-position
|
|
692
1277
|
* container element that gets mounted outside the DOM. It overlays the modal
|
|
@@ -697,22 +1282,29 @@ const FOCUSABLE_ELEMENTS = 'a[href], details, input, textarea, select, button:no
|
|
|
697
1282
|
* and adding an `onClose` prop that will call `onCloseModal`. If an
|
|
698
1283
|
* `onClose` prop is already provided, the two are merged.
|
|
699
1284
|
*/
|
|
700
|
-
|
|
701
|
-
class modal_backdrop_ModalBackdrop extends external_react_["Component"] {
|
|
1285
|
+
class ModalBackdrop extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
702
1286
|
constructor(...args) {
|
|
703
1287
|
super(...args);
|
|
1288
|
+
this._mousePressedOutside = false;
|
|
1289
|
+
|
|
1290
|
+
this.handleMouseDown = e => {
|
|
1291
|
+
// Confirm that it is the backdrop that is being clicked, not the child
|
|
1292
|
+
this._mousePressedOutside = e.target === e.currentTarget;
|
|
1293
|
+
};
|
|
704
1294
|
|
|
705
|
-
this.
|
|
706
|
-
//
|
|
707
|
-
//
|
|
708
|
-
if (e.target === e.currentTarget) {
|
|
1295
|
+
this.handleMouseUp = e => {
|
|
1296
|
+
// Confirm that it is the backdrop that is being clicked, not the child
|
|
1297
|
+
// and that the mouse was pressed in the backdrop first.
|
|
1298
|
+
if (e.target === e.currentTarget && this._mousePressedOutside) {
|
|
709
1299
|
this.props.onCloseModal();
|
|
710
1300
|
}
|
|
1301
|
+
|
|
1302
|
+
this._mousePressedOutside = false;
|
|
711
1303
|
};
|
|
712
1304
|
}
|
|
713
1305
|
|
|
714
1306
|
componentDidMount() {
|
|
715
|
-
const node =
|
|
1307
|
+
const node = react_dom__WEBPACK_IMPORTED_MODULE_1__["findDOMNode"](this);
|
|
716
1308
|
|
|
717
1309
|
if (!node) {
|
|
718
1310
|
return;
|
|
@@ -728,11 +1320,10 @@ class modal_backdrop_ModalBackdrop extends external_react_["Component"] {
|
|
|
728
1320
|
firstFocusableElement.focus();
|
|
729
1321
|
}, 0);
|
|
730
1322
|
}
|
|
1323
|
+
|
|
731
1324
|
/**
|
|
732
1325
|
* Returns an element specified by the user
|
|
733
1326
|
*/
|
|
734
|
-
|
|
735
|
-
|
|
736
1327
|
_getInitialFocusElement(node) {
|
|
737
1328
|
const {
|
|
738
1329
|
initialFocusId
|
|
@@ -742,7 +1333,7 @@ class modal_backdrop_ModalBackdrop extends external_react_["Component"] {
|
|
|
742
1333
|
return null;
|
|
743
1334
|
}
|
|
744
1335
|
|
|
745
|
-
return
|
|
1336
|
+
return react_dom__WEBPACK_IMPORTED_MODULE_1__["findDOMNode"](node.querySelector(`#${initialFocusId}`));
|
|
746
1337
|
}
|
|
747
1338
|
/**
|
|
748
1339
|
* Returns the first focusable element found inside the Dialog
|
|
@@ -751,7 +1342,7 @@ class modal_backdrop_ModalBackdrop extends external_react_["Component"] {
|
|
|
751
1342
|
|
|
752
1343
|
_getFirstFocusableElement(node) {
|
|
753
1344
|
// get a collection of elements that can be focused
|
|
754
|
-
const focusableElements =
|
|
1345
|
+
const focusableElements = Object(_util_find_focusable_nodes_js__WEBPACK_IMPORTED_MODULE_6__[/* findFocusableNodes */ "a"])(node);
|
|
755
1346
|
|
|
756
1347
|
if (!focusableElements) {
|
|
757
1348
|
return null;
|
|
@@ -768,7 +1359,7 @@ class modal_backdrop_ModalBackdrop extends external_react_["Component"] {
|
|
|
768
1359
|
_getDialogElement(node) {
|
|
769
1360
|
// If no focusable elements are found,
|
|
770
1361
|
// the dialog content element itself will receive focus.
|
|
771
|
-
const dialogElement =
|
|
1362
|
+
const dialogElement = react_dom__WEBPACK_IMPORTED_MODULE_1__["findDOMNode"](node.querySelector('[role="dialog"]')); // add tabIndex to make the Dialog focusable
|
|
772
1363
|
|
|
773
1364
|
dialogElement.tabIndex = -1;
|
|
774
1365
|
return dialogElement;
|
|
@@ -786,17 +1377,18 @@ class modal_backdrop_ModalBackdrop extends external_react_["Component"] {
|
|
|
786
1377
|
testId
|
|
787
1378
|
} = this.props;
|
|
788
1379
|
const backdropProps = {
|
|
789
|
-
[ModalLauncherPortalAttributeName]: true
|
|
1380
|
+
[_util_constants_js__WEBPACK_IMPORTED_MODULE_5__[/* ModalLauncherPortalAttributeName */ "a"]]: true
|
|
790
1381
|
};
|
|
791
|
-
return /*#__PURE__*/
|
|
792
|
-
style:
|
|
793
|
-
|
|
1382
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__["View"], _extends({
|
|
1383
|
+
style: styles.modalPositioner,
|
|
1384
|
+
onMouseDown: this.handleMouseDown,
|
|
1385
|
+
onMouseUp: this.handleMouseUp,
|
|
794
1386
|
testId: testId
|
|
795
1387
|
}, backdropProps), children);
|
|
796
1388
|
}
|
|
797
1389
|
|
|
798
1390
|
}
|
|
799
|
-
const
|
|
1391
|
+
const styles = aphrodite__WEBPACK_IMPORTED_MODULE_2__["StyleSheet"].create({
|
|
800
1392
|
modalPositioner: {
|
|
801
1393
|
position: "fixed",
|
|
802
1394
|
left: 0,
|
|
@@ -814,10 +1406,32 @@ const modal_backdrop_styles = external_aphrodite_["StyleSheet"].create({
|
|
|
814
1406
|
// turns out to be necessary. That sounds hard to do; punting for
|
|
815
1407
|
// now!
|
|
816
1408
|
overflow: "auto",
|
|
817
|
-
background:
|
|
1409
|
+
background: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3___default.a.offBlack64
|
|
818
1410
|
}
|
|
819
1411
|
});
|
|
820
|
-
|
|
1412
|
+
|
|
1413
|
+
/***/ }),
|
|
1414
|
+
/* 20 */
|
|
1415
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1416
|
+
|
|
1417
|
+
"use strict";
|
|
1418
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return findFocusableNodes; });
|
|
1419
|
+
/**
|
|
1420
|
+
* List of elements that can be focused
|
|
1421
|
+
* @see https://www.w3.org/TR/html5/editing.html#can-be-focused
|
|
1422
|
+
*/
|
|
1423
|
+
const FOCUSABLE_ELEMENTS = 'a[href], details, input, textarea, select, button:not([aria-label^="Close"])';
|
|
1424
|
+
function findFocusableNodes(root) {
|
|
1425
|
+
return Array.from(root.querySelectorAll(FOCUSABLE_ELEMENTS));
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
/***/ }),
|
|
1429
|
+
/* 21 */
|
|
1430
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1431
|
+
|
|
1432
|
+
"use strict";
|
|
1433
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
1434
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
821
1435
|
/**
|
|
822
1436
|
* A UI-less component that lets `ModalLauncher` disable page scroll.
|
|
823
1437
|
*
|
|
@@ -839,9 +1453,9 @@ const needsHackyMobileSafariScrollDisabler = (() => {
|
|
|
839
1453
|
return userAgent.indexOf("iPad") > -1 || userAgent.indexOf("iPhone") > -1;
|
|
840
1454
|
})();
|
|
841
1455
|
|
|
842
|
-
class
|
|
1456
|
+
class ScrollDisabler extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
843
1457
|
componentDidMount() {
|
|
844
|
-
if (
|
|
1458
|
+
if (ScrollDisabler.numModalsOpened === 0) {
|
|
845
1459
|
const body = document.body;
|
|
846
1460
|
|
|
847
1461
|
if (!body) {
|
|
@@ -850,14 +1464,14 @@ class scroll_disabler_ScrollDisabler extends external_react_["Component"] {
|
|
|
850
1464
|
// opened.
|
|
851
1465
|
|
|
852
1466
|
|
|
853
|
-
|
|
854
|
-
|
|
1467
|
+
ScrollDisabler.oldOverflow = body.style.overflow;
|
|
1468
|
+
ScrollDisabler.oldScrollY = window.scrollY; // We need to grab all of the original style properties before we
|
|
855
1469
|
// modified any of them.
|
|
856
1470
|
|
|
857
1471
|
if (needsHackyMobileSafariScrollDisabler) {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1472
|
+
ScrollDisabler.oldPosition = body.style.position;
|
|
1473
|
+
ScrollDisabler.oldWidth = body.style.width;
|
|
1474
|
+
ScrollDisabler.oldTop = body.style.top;
|
|
861
1475
|
}
|
|
862
1476
|
|
|
863
1477
|
body.style.overflow = "hidden"; // On mobile Safari, overflow: hidden is not enough, position:
|
|
@@ -867,17 +1481,17 @@ class scroll_disabler_ScrollDisabler extends external_react_["Component"] {
|
|
|
867
1481
|
if (needsHackyMobileSafariScrollDisabler) {
|
|
868
1482
|
body.style.position = "fixed";
|
|
869
1483
|
body.style.width = "100%";
|
|
870
|
-
body.style.top = `${-
|
|
1484
|
+
body.style.top = `${-ScrollDisabler.oldScrollY}px`;
|
|
871
1485
|
}
|
|
872
1486
|
}
|
|
873
1487
|
|
|
874
|
-
|
|
1488
|
+
ScrollDisabler.numModalsOpened++;
|
|
875
1489
|
}
|
|
876
1490
|
|
|
877
1491
|
componentWillUnmount() {
|
|
878
|
-
|
|
1492
|
+
ScrollDisabler.numModalsOpened--;
|
|
879
1493
|
|
|
880
|
-
if (
|
|
1494
|
+
if (ScrollDisabler.numModalsOpened === 0) {
|
|
881
1495
|
const body = document.body;
|
|
882
1496
|
|
|
883
1497
|
if (!body) {
|
|
@@ -885,296 +1499,47 @@ class scroll_disabler_ScrollDisabler extends external_react_["Component"] {
|
|
|
885
1499
|
} // Reset all values on the closing of the final modal.
|
|
886
1500
|
|
|
887
1501
|
|
|
888
|
-
body.style.overflow =
|
|
1502
|
+
body.style.overflow = ScrollDisabler.oldOverflow;
|
|
889
1503
|
|
|
890
1504
|
if (needsHackyMobileSafariScrollDisabler) {
|
|
891
|
-
body.style.position =
|
|
892
|
-
body.style.width =
|
|
893
|
-
body.style.top =
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
if (typeof window !== "undefined" && window.scrollTo) {
|
|
897
|
-
window.scrollTo(0, scroll_disabler_ScrollDisabler.oldScrollY);
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
render() {
|
|
903
|
-
return null;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
scroll_disabler_ScrollDisabler.numModalsOpened = 0;
|
|
909
|
-
/* harmony default export */ var scroll_disabler = (scroll_disabler_ScrollDisabler);
|
|
910
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/components/modal-context.js
|
|
911
|
-
|
|
912
|
-
const defaultContext = {
|
|
913
|
-
closeModal: undefined
|
|
914
|
-
};
|
|
915
|
-
/* harmony default export */ var modal_context = (/*#__PURE__*/external_react_["createContext"](defaultContext));
|
|
916
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/components/modal-launcher.js
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
/**
|
|
926
|
-
* This component enables you to launch a modal, covering the screen.
|
|
927
|
-
*
|
|
928
|
-
* Children have access to `openModal` function via the function-as-children
|
|
929
|
-
* pattern, so one common use case is for this component to wrap a button:
|
|
930
|
-
*
|
|
931
|
-
* ```js
|
|
932
|
-
* <ModalLauncher modal={<TwoColumnModal ... />}>
|
|
933
|
-
* {({openModal}) => <button onClick={openModal}>Learn more</button>}
|
|
934
|
-
* </ModalLauncher>
|
|
935
|
-
* ```
|
|
936
|
-
*
|
|
937
|
-
* The actual modal itself is constructed separately, using a layout component
|
|
938
|
-
* like OnePaneDialog and is provided via
|
|
939
|
-
* the `modal` prop.
|
|
940
|
-
*/
|
|
941
|
-
class modal_launcher_ModalLauncher extends external_react_["Component"] {
|
|
942
|
-
constructor(...args) {
|
|
943
|
-
super(...args);
|
|
944
|
-
this.state = {
|
|
945
|
-
opened: false
|
|
946
|
-
};
|
|
947
|
-
|
|
948
|
-
this._saveLastElementFocused = () => {
|
|
949
|
-
// keep a reference of the element that triggers the modal
|
|
950
|
-
this.lastElementFocusedOutsideModal = document.activeElement;
|
|
951
|
-
};
|
|
952
|
-
|
|
953
|
-
this._openModal = () => {
|
|
954
|
-
this._saveLastElementFocused();
|
|
955
|
-
|
|
956
|
-
this.setState({
|
|
957
|
-
opened: true
|
|
958
|
-
});
|
|
959
|
-
};
|
|
960
|
-
|
|
961
|
-
this.handleCloseModal = () => {
|
|
962
|
-
this.setState({
|
|
963
|
-
opened: false
|
|
964
|
-
}, () => {
|
|
965
|
-
this.props.onClose && this.props.onClose();
|
|
966
|
-
|
|
967
|
-
if (this.lastElementFocusedOutsideModal != null) {
|
|
968
|
-
// return focus to the element that triggered the modal
|
|
969
|
-
this.lastElementFocusedOutsideModal.focus();
|
|
970
|
-
}
|
|
971
|
-
});
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
static getDerivedStateFromProps(props, state) {
|
|
976
|
-
if (typeof props.opened === "boolean" && props.children) {
|
|
977
|
-
// eslint-disable-next-line no-console
|
|
978
|
-
console.warn("'children' and 'opened' can't be used together");
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
if (typeof props.opened === "boolean" && !props.onClose) {
|
|
982
|
-
// eslint-disable-next-line no-console
|
|
983
|
-
console.warn("'onClose' should be used with 'opened'");
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
if (typeof props.opened !== "boolean" && !props.children) {
|
|
987
|
-
// eslint-disable-next-line no-console
|
|
988
|
-
console.warn("either 'children' or 'opened' must be set");
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
return {
|
|
992
|
-
opened: typeof props.opened === "boolean" ? props.opened : state.opened
|
|
993
|
-
};
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
componentDidUpdate(prevProps) {
|
|
997
|
-
// ensures the element is stored only when the modal is opened
|
|
998
|
-
if (!prevProps.opened && this.props.opened) {
|
|
999
|
-
this._saveLastElementFocused();
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
_renderModal() {
|
|
1004
|
-
if (typeof this.props.modal === "function") {
|
|
1005
|
-
return this.props.modal({
|
|
1006
|
-
closeModal: this.handleCloseModal
|
|
1007
|
-
});
|
|
1008
|
-
} else {
|
|
1009
|
-
return this.props.modal;
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
render() {
|
|
1014
|
-
const renderedChildren = this.props.children ? this.props.children({
|
|
1015
|
-
openModal: this._openModal
|
|
1016
|
-
}) : null;
|
|
1017
|
-
const {
|
|
1018
|
-
body
|
|
1019
|
-
} = document;
|
|
1020
|
-
|
|
1021
|
-
if (!body) {
|
|
1022
|
-
return null;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
return (
|
|
1026
|
-
/*#__PURE__*/
|
|
1027
|
-
// This flow check is valid, it's the babel plugin which is broken,
|
|
1028
|
-
// see modal-context.js for details.
|
|
1029
|
-
// $FlowFixMe
|
|
1030
|
-
external_react_["createElement"](modal_context.Provider, {
|
|
1031
|
-
value: {
|
|
1032
|
-
closeModal: this.handleCloseModal
|
|
1033
|
-
}
|
|
1034
|
-
}, renderedChildren, this.state.opened && /*#__PURE__*/external_react_dom_["createPortal"](
|
|
1035
|
-
/*#__PURE__*/
|
|
1036
|
-
|
|
1037
|
-
/* We need the container View that FocusTrap creates to be at the
|
|
1038
|
-
correct z-index so that it'll be above the global nav in webapp. */
|
|
1039
|
-
external_react_["createElement"](focus_trap_FocusTrap, {
|
|
1040
|
-
style: modal_launcher_styles.container
|
|
1041
|
-
}, /*#__PURE__*/external_react_["createElement"](modal_backdrop_ModalBackdrop, {
|
|
1042
|
-
initialFocusId: this.props.initialFocusId,
|
|
1043
|
-
testId: this.props.testId,
|
|
1044
|
-
onCloseModal: this.props.backdropDismissEnabled ? this.handleCloseModal : () => {}
|
|
1045
|
-
}, this._renderModal())), body), this.state.opened && /*#__PURE__*/external_react_["createElement"](modal_launcher_ModalLauncherKeypressListener, {
|
|
1046
|
-
onClose: this.handleCloseModal
|
|
1047
|
-
}), this.state.opened && /*#__PURE__*/external_react_["createElement"](scroll_disabler, null))
|
|
1048
|
-
);
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
}
|
|
1052
|
-
/** A component that, when mounted, calls `onClose` when Escape is pressed. */
|
|
1053
|
-
|
|
1054
|
-
modal_launcher_ModalLauncher.defaultProps = {
|
|
1055
|
-
backdropDismissEnabled: true
|
|
1056
|
-
};
|
|
1057
|
-
|
|
1058
|
-
class modal_launcher_ModalLauncherKeypressListener extends external_react_["Component"] {
|
|
1059
|
-
constructor(...args) {
|
|
1060
|
-
super(...args);
|
|
1061
|
-
|
|
1062
|
-
this._handleKeyup = e => {
|
|
1063
|
-
// We check the key as that's keyboard layout agnostic and also avoids
|
|
1064
|
-
// the minefield of deprecated number type properties like keyCode and
|
|
1065
|
-
// which, with the replacement code, which uses a string instead.
|
|
1066
|
-
if (e.key === "Escape") {
|
|
1067
|
-
// Stop the event going any further.
|
|
1068
|
-
// For cancellation events, like the Escape key, we generally should
|
|
1069
|
-
// air on the side of caution and only allow it to cancel one thing.
|
|
1070
|
-
// So, it's polite for us to stop propagation of the event.
|
|
1071
|
-
// Otherwise, we end up with UX where one Escape key press
|
|
1072
|
-
// unexpectedly cancels multiple things.
|
|
1073
|
-
e.preventDefault();
|
|
1074
|
-
e.stopPropagation();
|
|
1075
|
-
this.props.onClose();
|
|
1505
|
+
body.style.position = ScrollDisabler.oldPosition;
|
|
1506
|
+
body.style.width = ScrollDisabler.oldWidth;
|
|
1507
|
+
body.style.top = ScrollDisabler.oldTop;
|
|
1076
1508
|
}
|
|
1077
|
-
};
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
componentDidMount() {
|
|
1081
|
-
window.addEventListener("keyup", this._handleKeyup);
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
componentWillUnmount() {
|
|
1085
|
-
window.removeEventListener("keyup", this._handleKeyup);
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
render() {
|
|
1089
|
-
return null;
|
|
1090
|
-
}
|
|
1091
|
-
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
const modal_launcher_styles = external_aphrodite_["StyleSheet"].create({
|
|
1095
|
-
container: {
|
|
1096
|
-
// This z-index is copied from the Khan Academy webapp.
|
|
1097
|
-
//
|
|
1098
|
-
// TODO(mdr): Should we keep this in a constants file somewhere? Or
|
|
1099
|
-
// not hardcode it at all, and provide it to Wonder Blocks via
|
|
1100
|
-
// configuration?
|
|
1101
|
-
zIndex: 1080
|
|
1102
|
-
}
|
|
1103
|
-
});
|
|
1104
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/components/modal-content.js
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
1509
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
static isClassOf(instance) {
|
|
1116
|
-
return instance && instance.type && instance.type.__IS_MODAL_CONTENT__;
|
|
1510
|
+
if (typeof window !== "undefined" && window.scrollTo) {
|
|
1511
|
+
window.scrollTo(0, ScrollDisabler.oldScrollY);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1117
1514
|
}
|
|
1118
1515
|
|
|
1119
1516
|
render() {
|
|
1120
|
-
|
|
1121
|
-
scrollOverflow,
|
|
1122
|
-
style,
|
|
1123
|
-
children
|
|
1124
|
-
} = this.props;
|
|
1125
|
-
return /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["MediaLayout"], {
|
|
1126
|
-
styleSheets: modal_content_styleSheets
|
|
1127
|
-
}, ({
|
|
1128
|
-
styles
|
|
1129
|
-
}) => /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
|
|
1130
|
-
style: [styles.wrapper, scrollOverflow && styles.scrollOverflow]
|
|
1131
|
-
}, /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
|
|
1132
|
-
style: [styles.content, style]
|
|
1133
|
-
}, children)));
|
|
1517
|
+
return null;
|
|
1134
1518
|
}
|
|
1135
1519
|
|
|
1136
1520
|
}
|
|
1137
|
-
modal_content_ModalContent.defaultProps = {
|
|
1138
|
-
scrollOverflow: true
|
|
1139
|
-
};
|
|
1140
|
-
modal_content_ModalContent.__IS_MODAL_CONTENT__ = true;
|
|
1141
|
-
const modal_content_styleSheets = {
|
|
1142
|
-
all: external_aphrodite_["StyleSheet"].create({
|
|
1143
|
-
wrapper: {
|
|
1144
|
-
flex: 1,
|
|
1145
|
-
// This helps to ensure that the paddingBottom is preserved when
|
|
1146
|
-
// the contents start to overflow, this goes away on display: flex
|
|
1147
|
-
display: "block"
|
|
1148
|
-
},
|
|
1149
|
-
scrollOverflow: {
|
|
1150
|
-
overflow: "auto"
|
|
1151
|
-
},
|
|
1152
|
-
content: {
|
|
1153
|
-
flex: 1,
|
|
1154
|
-
minHeight: "100%",
|
|
1155
|
-
padding: wonder_blocks_spacing_default.a.xLarge_32,
|
|
1156
|
-
boxSizing: "border-box"
|
|
1157
|
-
}
|
|
1158
|
-
}),
|
|
1159
|
-
small: external_aphrodite_["StyleSheet"].create({
|
|
1160
|
-
content: {
|
|
1161
|
-
padding: `${wonder_blocks_spacing_default.a.xLarge_32}px ${wonder_blocks_spacing_default.a.medium_16}px`
|
|
1162
|
-
}
|
|
1163
|
-
})
|
|
1164
|
-
};
|
|
1165
|
-
// EXTERNAL MODULE: external "@khanacademy/wonder-blocks-icon"
|
|
1166
|
-
var wonder_blocks_icon_ = __webpack_require__(9);
|
|
1167
1521
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
var wonder_blocks_icon_button_default = /*#__PURE__*/__webpack_require__.n(wonder_blocks_icon_button_);
|
|
1522
|
+
ScrollDisabler.numModalsOpened = 0;
|
|
1523
|
+
/* harmony default export */ __webpack_exports__["a"] = (ScrollDisabler);
|
|
1171
1524
|
|
|
1172
|
-
|
|
1525
|
+
/***/ }),
|
|
1526
|
+
/* 22 */
|
|
1527
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1528
|
+
|
|
1529
|
+
"use strict";
|
|
1530
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return CloseButton; });
|
|
1531
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
|
|
1532
|
+
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
|
1533
|
+
/* harmony import */ var _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23);
|
|
1534
|
+
/* harmony import */ var _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1__);
|
|
1535
|
+
/* harmony import */ var _khanacademy_wonder_blocks_icon_button__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(24);
|
|
1536
|
+
/* harmony import */ var _khanacademy_wonder_blocks_icon_button__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_icon_button__WEBPACK_IMPORTED_MODULE_2__);
|
|
1537
|
+
/* harmony import */ var _modal_context_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(12);
|
|
1173
1538
|
|
|
1174
1539
|
|
|
1175
1540
|
|
|
1176
1541
|
|
|
1177
|
-
class
|
|
1542
|
+
class CloseButton extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
1178
1543
|
render() {
|
|
1179
1544
|
const {
|
|
1180
1545
|
light,
|
|
@@ -1182,15 +1547,15 @@ class close_button_CloseButton extends external_react_["Component"] {
|
|
|
1182
1547
|
style,
|
|
1183
1548
|
testId
|
|
1184
1549
|
} = this.props;
|
|
1185
|
-
return /*#__PURE__*/
|
|
1550
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_context_js__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"].Consumer, null, ({
|
|
1186
1551
|
closeModal
|
|
1187
1552
|
}) => {
|
|
1188
1553
|
if (closeModal && onClick) {
|
|
1189
1554
|
throw new Error("You've specified 'onClose' on a modal when using ModalLauncher. Please specify 'onClose' on the ModalLauncher instead");
|
|
1190
1555
|
}
|
|
1191
1556
|
|
|
1192
|
-
return /*#__PURE__*/
|
|
1193
|
-
icon:
|
|
1557
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_icon_button__WEBPACK_IMPORTED_MODULE_2___default.a, {
|
|
1558
|
+
icon: _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1__["icons"].dismiss // TODO(mdr): Translate this string for i18n.
|
|
1194
1559
|
// TODO(kevinb): provide a way to set this label
|
|
1195
1560
|
,
|
|
1196
1561
|
"aria-label": "Close modal",
|
|
@@ -1204,255 +1569,46 @@ class close_button_CloseButton extends external_react_["Component"] {
|
|
|
1204
1569
|
}
|
|
1205
1570
|
|
|
1206
1571
|
}
|
|
1207
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/components/modal-panel.js
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
/**
|
|
1219
|
-
* ModalPanel is the content container.
|
|
1220
|
-
*
|
|
1221
|
-
* **Implementation notes:**
|
|
1222
|
-
*
|
|
1223
|
-
* If you are creating a custom Dialog, make sure to follow these guidelines:
|
|
1224
|
-
* - Make sure to add this component inside the [ModalDialog](/#modaldialog).
|
|
1225
|
-
* - If needed, you can also add a [ModalHeader](/#modalheader) using the
|
|
1226
|
-
* `header` prop. Same goes for [ModalFooter](/#modalfooter).
|
|
1227
|
-
* - If you need to create e2e tests, make sure to pass a `testId` prop. This
|
|
1228
|
-
* will be passed down to this component using a sufix: e.g.
|
|
1229
|
-
* `some-random-id-ModalPanel`. This scope will be propagated to the
|
|
1230
|
-
* CloseButton element as well: e.g. `some-random-id-CloseButton`.
|
|
1231
|
-
*
|
|
1232
|
-
* ```js
|
|
1233
|
-
* <ModalDialog>
|
|
1234
|
-
* <ModalPanel content={"custom content goes here"} />
|
|
1235
|
-
* </ModalDialog>
|
|
1236
|
-
* ```
|
|
1237
|
-
*/
|
|
1238
|
-
class modal_panel_ModalPanel extends external_react_["Component"] {
|
|
1239
|
-
renderMainContent() {
|
|
1240
|
-
const {
|
|
1241
|
-
content,
|
|
1242
|
-
footer,
|
|
1243
|
-
scrollOverflow
|
|
1244
|
-
} = this.props;
|
|
1245
|
-
const mainContent = modal_content_ModalContent.isClassOf(content) ? content : /*#__PURE__*/external_react_["createElement"](modal_content_ModalContent, null, content);
|
|
1246
|
-
|
|
1247
|
-
if (!mainContent) {
|
|
1248
|
-
return mainContent;
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
return /*#__PURE__*/external_react_["cloneElement"](mainContent, {
|
|
1252
|
-
// Pass the scrollOverflow and header in to the main content
|
|
1253
|
-
scrollOverflow,
|
|
1254
|
-
// We override the styling of the main content to help position
|
|
1255
|
-
// it if there is a footer or close button being
|
|
1256
|
-
// shown. We have to do this here as the ModalContent doesn't
|
|
1257
|
-
// know about things being positioned around it.
|
|
1258
|
-
style: [!!footer && modal_panel_styles.hasFooter, mainContent.props.style]
|
|
1259
|
-
});
|
|
1260
|
-
}
|
|
1261
|
-
|
|
1262
|
-
render() {
|
|
1263
|
-
const {
|
|
1264
|
-
closeButtonVisible,
|
|
1265
|
-
footer,
|
|
1266
|
-
header,
|
|
1267
|
-
light,
|
|
1268
|
-
onClose,
|
|
1269
|
-
style,
|
|
1270
|
-
testId
|
|
1271
|
-
} = this.props;
|
|
1272
|
-
const mainContent = this.renderMainContent();
|
|
1273
|
-
return /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
|
|
1274
|
-
style: [modal_panel_styles.wrapper, !light && modal_panel_styles.dark, style],
|
|
1275
|
-
testId: testId && `${testId}-panel`
|
|
1276
|
-
}, closeButtonVisible && /*#__PURE__*/external_react_["createElement"](close_button_CloseButton, {
|
|
1277
|
-
light: !light,
|
|
1278
|
-
onClick: onClose,
|
|
1279
|
-
style: modal_panel_styles.closeButton,
|
|
1280
|
-
testId: testId && `${testId}-close`
|
|
1281
|
-
}), header, mainContent, !footer || modal_footer_ModalFooter.isClassOf(footer) ? footer : /*#__PURE__*/external_react_["createElement"](modal_footer_ModalFooter, null, footer));
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
}
|
|
1285
|
-
modal_panel_ModalPanel.defaultProps = {
|
|
1286
|
-
closeButtonVisible: true,
|
|
1287
|
-
scrollOverflow: true,
|
|
1288
|
-
light: true
|
|
1289
|
-
};
|
|
1290
|
-
const modal_panel_styles = external_aphrodite_["StyleSheet"].create({
|
|
1291
|
-
wrapper: {
|
|
1292
|
-
flex: "1 1 auto",
|
|
1293
|
-
position: "relative",
|
|
1294
|
-
display: "flex",
|
|
1295
|
-
flexDirection: "column",
|
|
1296
|
-
background: "white",
|
|
1297
|
-
boxSizing: "border-box",
|
|
1298
|
-
overflow: "hidden",
|
|
1299
|
-
height: "100%",
|
|
1300
|
-
width: "100%"
|
|
1301
|
-
},
|
|
1302
|
-
closeButton: {
|
|
1303
|
-
position: "absolute",
|
|
1304
|
-
right: wonder_blocks_spacing_default.a.medium_16,
|
|
1305
|
-
top: wonder_blocks_spacing_default.a.medium_16,
|
|
1306
|
-
// This is to allow the button to be tab-ordered before the modal
|
|
1307
|
-
// content but still be above the header and content.
|
|
1308
|
-
zIndex: 1
|
|
1309
|
-
},
|
|
1310
|
-
dark: {
|
|
1311
|
-
background: wonder_blocks_color_default.a.darkBlue,
|
|
1312
|
-
color: wonder_blocks_color_default.a.white
|
|
1313
|
-
},
|
|
1314
|
-
hasFooter: {
|
|
1315
|
-
paddingBottom: wonder_blocks_spacing_default.a.xLarge_32
|
|
1316
|
-
}
|
|
1317
|
-
});
|
|
1318
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/components/one-pane-dialog.js
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
1572
|
|
|
1573
|
+
/***/ }),
|
|
1574
|
+
/* 23 */
|
|
1575
|
+
/***/ (function(module, exports) {
|
|
1324
1576
|
|
|
1577
|
+
module.exports = require("@khanacademy/wonder-blocks-icon");
|
|
1325
1578
|
|
|
1579
|
+
/***/ }),
|
|
1580
|
+
/* 24 */
|
|
1581
|
+
/***/ (function(module, exports) {
|
|
1326
1582
|
|
|
1327
|
-
|
|
1328
|
-
* This is the standard layout for most straightforward modal experiences.
|
|
1329
|
-
*
|
|
1330
|
-
* The ModalHeader is required, but the ModalFooter is optional.
|
|
1331
|
-
* The content of the dialog itself is fully customizable, but the left/right/top/bottom padding is fixed.
|
|
1332
|
-
*/
|
|
1333
|
-
class one_pane_dialog_OnePaneDialog extends external_react_["Component"] {
|
|
1334
|
-
renderHeader(uniqueId) {
|
|
1335
|
-
const {
|
|
1336
|
-
title,
|
|
1337
|
-
breadcrumbs = undefined,
|
|
1338
|
-
subtitle = undefined,
|
|
1339
|
-
testId
|
|
1340
|
-
} = this.props;
|
|
1583
|
+
module.exports = require("@khanacademy/wonder-blocks-icon-button");
|
|
1341
1584
|
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
breadcrumbs: breadcrumbs,
|
|
1346
|
-
titleId: uniqueId,
|
|
1347
|
-
testId: testId && `${testId}-header`
|
|
1348
|
-
});
|
|
1349
|
-
} else if (subtitle) {
|
|
1350
|
-
return /*#__PURE__*/external_react_["createElement"](modal_header_ModalHeader, {
|
|
1351
|
-
title: title,
|
|
1352
|
-
subtitle: subtitle,
|
|
1353
|
-
titleId: uniqueId,
|
|
1354
|
-
testId: testId && `${testId}-header`
|
|
1355
|
-
});
|
|
1356
|
-
} else {
|
|
1357
|
-
return /*#__PURE__*/external_react_["createElement"](modal_header_ModalHeader, {
|
|
1358
|
-
title: title,
|
|
1359
|
-
titleId: uniqueId,
|
|
1360
|
-
testId: testId && `${testId}-header`
|
|
1361
|
-
});
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1585
|
+
/***/ }),
|
|
1586
|
+
/* 25 */
|
|
1587
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
1364
1588
|
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
content,
|
|
1370
|
-
above,
|
|
1371
|
-
below,
|
|
1372
|
-
style,
|
|
1373
|
-
closeButtonVisible,
|
|
1374
|
-
testId,
|
|
1375
|
-
titleId,
|
|
1376
|
-
role
|
|
1377
|
-
} = this.props;
|
|
1378
|
-
return /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["MediaLayout"], {
|
|
1379
|
-
styleSheets: one_pane_dialog_styleSheets
|
|
1380
|
-
}, ({
|
|
1381
|
-
styles
|
|
1382
|
-
}) => /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["IDProvider"], {
|
|
1383
|
-
id: titleId,
|
|
1384
|
-
scope: "modal"
|
|
1385
|
-
}, uniqueId => /*#__PURE__*/external_react_["createElement"](modal_dialog_ModalDialog, {
|
|
1386
|
-
style: [styles.dialog, style],
|
|
1387
|
-
above: above,
|
|
1388
|
-
below: below,
|
|
1389
|
-
testId: testId,
|
|
1390
|
-
"aria-labelledby": uniqueId,
|
|
1391
|
-
role: role
|
|
1392
|
-
}, /*#__PURE__*/external_react_["createElement"](modal_panel_ModalPanel, {
|
|
1393
|
-
onClose: onClose,
|
|
1394
|
-
header: this.renderHeader(uniqueId),
|
|
1395
|
-
content: content,
|
|
1396
|
-
footer: footer,
|
|
1397
|
-
closeButtonVisible: closeButtonVisible,
|
|
1398
|
-
testId: testId
|
|
1399
|
-
}))));
|
|
1400
|
-
}
|
|
1589
|
+
"use strict";
|
|
1590
|
+
__webpack_require__.r(__webpack_exports__);
|
|
1591
|
+
/* harmony import */ var _components_modal_dialog_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9);
|
|
1592
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalDialog", function() { return _components_modal_dialog_js__WEBPACK_IMPORTED_MODULE_0__["a"]; });
|
|
1401
1593
|
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
closeButtonVisible: true
|
|
1405
|
-
};
|
|
1406
|
-
const one_pane_dialog_styleSheets = {
|
|
1407
|
-
small: external_aphrodite_["StyleSheet"].create({
|
|
1408
|
-
dialog: {
|
|
1409
|
-
width: "100%",
|
|
1410
|
-
height: "100%",
|
|
1411
|
-
overflow: "hidden"
|
|
1412
|
-
}
|
|
1413
|
-
}),
|
|
1414
|
-
mdOrLarger: external_aphrodite_["StyleSheet"].create({
|
|
1415
|
-
dialog: {
|
|
1416
|
-
width: "93.75%",
|
|
1417
|
-
maxWidth: 576,
|
|
1418
|
-
height: "81.25%",
|
|
1419
|
-
maxHeight: 624
|
|
1420
|
-
}
|
|
1421
|
-
})
|
|
1422
|
-
};
|
|
1423
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/util/maybe-get-portal-mounted-modal-host-element.js
|
|
1594
|
+
/* harmony import */ var _components_modal_footer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
|
|
1595
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalFooter", function() { return _components_modal_footer_js__WEBPACK_IMPORTED_MODULE_1__["a"]; });
|
|
1424
1596
|
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
* element.
|
|
1428
|
-
* @param {?(Element | Text)} element The element whose ancestors are to be
|
|
1429
|
-
* walked.
|
|
1430
|
-
* @returns {?Element} The nearest parent modal launcher portal.
|
|
1431
|
-
*/
|
|
1597
|
+
/* harmony import */ var _components_modal_header_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
|
|
1598
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalHeader", function() { return _components_modal_header_js__WEBPACK_IMPORTED_MODULE_2__["a"]; });
|
|
1432
1599
|
|
|
1433
|
-
|
|
1434
|
-
|
|
1600
|
+
/* harmony import */ var _components_modal_launcher_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(15);
|
|
1601
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalLauncher", function() { return _components_modal_launcher_js__WEBPACK_IMPORTED_MODULE_3__["a"]; });
|
|
1435
1602
|
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
}
|
|
1603
|
+
/* harmony import */ var _components_modal_panel_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
|
|
1604
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalPanel", function() { return _components_modal_panel_js__WEBPACK_IMPORTED_MODULE_4__["a"]; });
|
|
1439
1605
|
|
|
1440
|
-
|
|
1441
|
-
}
|
|
1442
|
-
/**
|
|
1443
|
-
* From a given element, finds the next modal host that has been mounted in
|
|
1444
|
-
* a modal portal.
|
|
1445
|
-
* @param {?(Element | Text)} element The element whose ancestors are to be
|
|
1446
|
-
* walked.
|
|
1447
|
-
* @returns {?Element} The next portal-mounted modal host element.
|
|
1448
|
-
* TODO(kevinb): look into getting rid of this
|
|
1449
|
-
*/
|
|
1606
|
+
/* harmony import */ var _components_one_pane_dialog_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(16);
|
|
1607
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OnePaneDialog", function() { return _components_one_pane_dialog_js__WEBPACK_IMPORTED_MODULE_5__["a"]; });
|
|
1450
1608
|
|
|
1609
|
+
/* harmony import */ var _util_maybe_get_portal_mounted_modal_host_element_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(17);
|
|
1610
|
+
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "maybeGetPortalMountedModalHostElement", function() { return _util_maybe_get_portal_mounted_modal_host_element_js__WEBPACK_IMPORTED_MODULE_6__["a"]; });
|
|
1451
1611
|
|
|
1452
|
-
function maybeGetPortalMountedModalHostElement(element) {
|
|
1453
|
-
return maybeGetNextAncestorModalLauncherPortal(element);
|
|
1454
|
-
}
|
|
1455
|
-
// CONCATENATED MODULE: ./packages/wonder-blocks-modal/src/index.js
|
|
1456
1612
|
|
|
1457
1613
|
|
|
1458
1614
|
|