@khanacademy/wonder-blocks-modal 3.0.2 → 3.0.3

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/dist/index.js DELETED
@@ -1,3013 +0,0 @@
1
- module.exports =
2
- /******/ (function(modules) { // webpackBootstrap
3
- /******/ // The module cache
4
- /******/ var installedModules = {};
5
- /******/
6
- /******/ // The require function
7
- /******/ function __webpack_require__(moduleId) {
8
- /******/
9
- /******/ // Check if module is in cache
10
- /******/ if(installedModules[moduleId]) {
11
- /******/ return installedModules[moduleId].exports;
12
- /******/ }
13
- /******/ // Create a new module (and put it into the cache)
14
- /******/ var module = installedModules[moduleId] = {
15
- /******/ i: moduleId,
16
- /******/ l: false,
17
- /******/ exports: {}
18
- /******/ };
19
- /******/
20
- /******/ // Execute the module function
21
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22
- /******/
23
- /******/ // Flag the module as loaded
24
- /******/ module.l = true;
25
- /******/
26
- /******/ // Return the exports of the module
27
- /******/ return module.exports;
28
- /******/ }
29
- /******/
30
- /******/
31
- /******/ // expose the modules object (__webpack_modules__)
32
- /******/ __webpack_require__.m = modules;
33
- /******/
34
- /******/ // expose the module cache
35
- /******/ __webpack_require__.c = installedModules;
36
- /******/
37
- /******/ // define getter function for harmony exports
38
- /******/ __webpack_require__.d = function(exports, name, getter) {
39
- /******/ if(!__webpack_require__.o(exports, name)) {
40
- /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41
- /******/ }
42
- /******/ };
43
- /******/
44
- /******/ // define __esModule on exports
45
- /******/ __webpack_require__.r = function(exports) {
46
- /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47
- /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48
- /******/ }
49
- /******/ Object.defineProperty(exports, '__esModule', { value: true });
50
- /******/ };
51
- /******/
52
- /******/ // create a fake namespace object
53
- /******/ // mode & 1: value is a module id, require it
54
- /******/ // mode & 2: merge all properties of value into the ns
55
- /******/ // mode & 4: return value when already ns object
56
- /******/ // mode & 8|1: behave like require
57
- /******/ __webpack_require__.t = function(value, mode) {
58
- /******/ if(mode & 1) value = __webpack_require__(value);
59
- /******/ if(mode & 8) return value;
60
- /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61
- /******/ var ns = Object.create(null);
62
- /******/ __webpack_require__.r(ns);
63
- /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64
- /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65
- /******/ return ns;
66
- /******/ };
67
- /******/
68
- /******/ // getDefaultExport function for compatibility with non-harmony modules
69
- /******/ __webpack_require__.n = function(module) {
70
- /******/ var getter = module && module.__esModule ?
71
- /******/ function getDefault() { return module['default']; } :
72
- /******/ function getModuleExports() { return module; };
73
- /******/ __webpack_require__.d(getter, 'a', getter);
74
- /******/ return getter;
75
- /******/ };
76
- /******/
77
- /******/ // Object.prototype.hasOwnProperty.call
78
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79
- /******/
80
- /******/ // __webpack_public_path__
81
- /******/ __webpack_require__.p = "";
82
- /******/
83
- /******/
84
- /******/ // Load entry module and return exports
85
- /******/ return __webpack_require__(__webpack_require__.s = 27);
86
- /******/ })
87
- /************************************************************************/
88
- /******/ ([
89
- /* 0 */
90
- /***/ (function(module, exports) {
91
-
92
- module.exports = require("react");
93
-
94
- /***/ }),
95
- /* 1 */
96
- /***/ (function(module, exports) {
97
-
98
- module.exports = require("@khanacademy/wonder-blocks-spacing");
99
-
100
- /***/ }),
101
- /* 2 */
102
- /***/ (function(module, exports) {
103
-
104
- module.exports = require("@khanacademy/wonder-blocks-core");
105
-
106
- /***/ }),
107
- /* 3 */
108
- /***/ (function(module, exports) {
109
-
110
- module.exports = require("aphrodite");
111
-
112
- /***/ }),
113
- /* 4 */
114
- /***/ (function(module, exports) {
115
-
116
- module.exports = require("@khanacademy/wonder-blocks-color");
117
-
118
- /***/ }),
119
- /* 5 */
120
- /***/ (function(module, exports) {
121
-
122
- module.exports = require("@khanacademy/wonder-blocks-layout");
123
-
124
- /***/ }),
125
- /* 6 */
126
- /***/ (function(module, exports) {
127
-
128
- module.exports = require("react-dom");
129
-
130
- /***/ }),
131
- /* 7 */
132
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
133
-
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__);
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
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;
211
-
212
- if (subtitle && breadcrumbs) {
213
- throw new Error("'subtitle' and 'breadcrumbs' can't be used together");
214
- }
215
-
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
- };
277
-
278
- /***/ }),
279
- /* 8 */
280
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
281
-
282
- "use strict";
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
-
296
-
297
-
298
-
299
-
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
- * **Usage**
310
- *
311
- * ```js
312
- * <ModalFooter>
313
- * <Button onClick={() => {}}>Submit</Button>
314
- * </ModalFooter>
315
- * ```
316
- */
317
- class ModalFooter extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
318
- static isClassOf(instance) {
319
- return instance && instance.type && instance.type.__IS_MODAL_FOOTER__;
320
- }
321
-
322
- render() {
323
- const {
324
- children
325
- } = this.props;
326
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
327
- style: styles.footer
328
- }, children);
329
- }
330
-
331
- }
332
- ModalFooter.__IS_MODAL_FOOTER__ = true;
333
- const styles = aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
334
- footer: {
335
- flex: "0 0 auto",
336
- boxSizing: "border-box",
337
- minHeight: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xxxLarge_64,
338
- paddingLeft: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
339
- paddingRight: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
340
- paddingTop: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xSmall_8,
341
- paddingBottom: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xSmall_8,
342
- display: "flex",
343
- flexDirection: "row",
344
- alignItems: "center",
345
- justifyContent: "flex-end",
346
- boxShadow: `0px -1px 0px ${_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.offBlack16}`
347
- }
348
- });
349
-
350
- /***/ }),
351
- /* 9 */
352
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
353
-
354
- "use strict";
355
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalDialog; });
356
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
357
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
358
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
359
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
360
- /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
361
- /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__);
362
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
363
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
364
- /* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1);
365
- /* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__);
366
-
367
-
368
-
369
-
370
-
371
-
372
- /**
373
- * `ModalDialog` is a component that contains these elements:
374
- * - The visual dialog element itself (`<div role="dialog"/>`)
375
- * - The custom contents below and/or above the Dialog itself (e.g. decorative graphics).
376
- *
377
- * **Accessibility notes:**
378
- * - By default (e.g. using `OnePaneDialog`), `aria-labelledby` is populated automatically using the dialog title `id`.
379
- * - If there is a custom Dialog implementation (e.g. `TwoPaneDialog`), the dialog element doesn’t have to have
380
- * the `aria-labelledby` attribute however this is recommended. It should match the `id` of the dialog title.
381
- */
382
- class ModalDialog extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
383
- render() {
384
- const {
385
- above,
386
- below,
387
- role,
388
- style,
389
- children,
390
- testId,
391
-
392
- /* eslint-disable react/prop-types */
393
- // the react/prop-types plugin does not like these
394
- "aria-labelledby": ariaLabelledBy,
395
- "aria-describedby": ariaDescribedBy
396
- /* eslint-enable react/prop-types */
397
-
398
- } = this.props;
399
- const contextValue = {
400
- ssrSize: "large",
401
- mediaSpec: _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MEDIA_MODAL_SPEC"]
402
- };
403
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MediaLayoutContext"].Provider, {
404
- value: contextValue
405
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MediaLayout"], {
406
- styleSheets: styleSheets
407
- }, ({
408
- styles
409
- }) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
410
- style: [styles.wrapper, style]
411
- }, below && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
412
- style: styles.below
413
- }, below), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
414
- role: role,
415
- "aria-modal": "true",
416
- "aria-labelledby": ariaLabelledBy,
417
- "aria-describedby": ariaDescribedBy,
418
- style: styles.dialog,
419
- testId: testId
420
- }, children), above && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
421
- style: styles.above
422
- }, above))));
423
- }
424
-
425
- }
426
- ModalDialog.defaultProps = {
427
- role: "dialog"
428
- };
429
- const styleSheets = {
430
- all: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
431
- wrapper: {
432
- display: "flex",
433
- flexDirection: "row",
434
- alignItems: "stretch",
435
- width: "100%",
436
- height: "100%",
437
- position: "relative"
438
- },
439
-
440
- /**
441
- * Ensures the dialog container uses the container size
442
- */
443
- dialog: {
444
- width: "100%",
445
- height: "100%",
446
- borderRadius: 4,
447
- overflow: "hidden"
448
- },
449
- above: {
450
- pointerEvents: "none",
451
- position: "absolute",
452
- top: 0,
453
- left: 0,
454
- bottom: 0,
455
- right: 0,
456
- zIndex: 1
457
- },
458
- below: {
459
- pointerEvents: "none",
460
- position: "absolute",
461
- top: 0,
462
- left: 0,
463
- bottom: 0,
464
- right: 0,
465
- zIndex: -1
466
- }
467
- }),
468
- small: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
469
- wrapper: {
470
- padding: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
471
- flexDirection: "column"
472
- }
473
- })
474
- };
475
-
476
- /***/ }),
477
- /* 10 */
478
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
479
-
480
- "use strict";
481
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalPanel; });
482
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
483
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
484
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
485
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
486
- /* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
487
- /* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2__);
488
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
489
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
490
- /* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1);
491
- /* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__);
492
- /* harmony import */ var _modal_content_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(14);
493
- /* harmony import */ var _modal_header_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7);
494
- /* harmony import */ var _modal_footer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(8);
495
- /* harmony import */ var _close_button_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(24);
496
-
497
-
498
-
499
-
500
-
501
-
502
-
503
-
504
-
505
-
506
- /**
507
- * ModalPanel is the content container.
508
- *
509
- * **Implementation notes:**
510
- *
511
- * If you are creating a custom Dialog, make sure to follow these guidelines:
512
- * - Make sure to add this component inside the [ModalDialog](/#modaldialog).
513
- * - If needed, you can also add a [ModalHeader](/#modalheader) using the
514
- * `header` prop. Same goes for [ModalFooter](/#modalfooter).
515
- * - If you need to create e2e tests, make sure to pass a `testId` prop. This
516
- * will be passed down to this component using a sufix: e.g.
517
- * `some-random-id-ModalPanel`. This scope will be propagated to the
518
- * CloseButton element as well: e.g. `some-random-id-CloseButton`.
519
- *
520
- * ```js
521
- * <ModalDialog>
522
- * <ModalPanel content={"custom content goes here"} />
523
- * </ModalDialog>
524
- * ```
525
- */
526
- class ModalPanel extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
527
- renderMainContent() {
528
- const {
529
- content,
530
- footer,
531
- scrollOverflow
532
- } = this.props;
533
- 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);
534
-
535
- if (!mainContent) {
536
- return mainContent;
537
- }
538
-
539
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["cloneElement"](mainContent, {
540
- // Pass the scrollOverflow and header in to the main content
541
- scrollOverflow,
542
- // We override the styling of the main content to help position
543
- // it if there is a footer or close button being
544
- // shown. We have to do this here as the ModalContent doesn't
545
- // know about things being positioned around it.
546
- style: [!!footer && styles.hasFooter, mainContent.props.style]
547
- });
548
- }
549
-
550
- render() {
551
- const {
552
- closeButtonVisible,
553
- footer,
554
- header,
555
- light,
556
- onClose,
557
- style,
558
- testId
559
- } = this.props;
560
- const mainContent = this.renderMainContent();
561
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["View"], {
562
- style: [styles.wrapper, !light && styles.dark, style],
563
- testId: testId && `${testId}-panel`
564
- }, closeButtonVisible && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_close_button_js__WEBPACK_IMPORTED_MODULE_8__[/* default */ "a"], {
565
- light: !light,
566
- onClick: onClose,
567
- style: styles.closeButton,
568
- testId: testId && `${testId}-close`
569
- }), 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));
570
- }
571
-
572
- }
573
- ModalPanel.defaultProps = {
574
- closeButtonVisible: true,
575
- scrollOverflow: true,
576
- light: true
577
- };
578
- const styles = aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
579
- wrapper: {
580
- flex: "1 1 auto",
581
- position: "relative",
582
- display: "flex",
583
- flexDirection: "column",
584
- background: "white",
585
- boxSizing: "border-box",
586
- overflow: "hidden",
587
- height: "100%",
588
- width: "100%"
589
- },
590
- closeButton: {
591
- position: "absolute",
592
- right: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
593
- top: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.medium_16,
594
- // This is to allow the button to be tab-ordered before the modal
595
- // content but still be above the header and content.
596
- zIndex: 1
597
- },
598
- dark: {
599
- background: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.darkBlue,
600
- color: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_2___default.a.white
601
- },
602
- hasFooter: {
603
- paddingBottom: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xLarge_32
604
- }
605
- });
606
-
607
- /***/ }),
608
- /* 11 */
609
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
610
-
611
- "use strict";
612
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalLauncherPortalAttributeName; });
613
- /**
614
- * The attribute used to identify a modal launcher portal.
615
- */
616
- const ModalLauncherPortalAttributeName = "data-modal-launcher-portal";
617
-
618
-
619
- /***/ }),
620
- /* 12 */
621
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
622
-
623
- "use strict";
624
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
625
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
626
-
627
- const defaultContext = {
628
- closeModal: undefined
629
- };
630
- /* harmony default export */ __webpack_exports__["a"] = (/*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createContext"](defaultContext));
631
-
632
- /***/ }),
633
- /* 13 */
634
- /***/ (function(module, exports) {
635
-
636
- module.exports = require("@khanacademy/wonder-blocks-typography");
637
-
638
- /***/ }),
639
- /* 14 */
640
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
641
-
642
- "use strict";
643
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalContent; });
644
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
645
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
646
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
647
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
648
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
649
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__);
650
- /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
651
- /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3__);
652
- /* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1);
653
- /* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4__);
654
-
655
-
656
-
657
-
658
-
659
-
660
- /**
661
- * The Modal content included after the header
662
- */
663
- class ModalContent extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
664
- static isClassOf(instance) {
665
- return instance && instance.type && instance.type.__IS_MODAL_CONTENT__;
666
- }
667
-
668
- render() {
669
- const {
670
- scrollOverflow,
671
- style,
672
- children
673
- } = this.props;
674
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_3__["MediaLayout"], {
675
- styleSheets: styleSheets
676
- }, ({
677
- styles
678
- }) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__["View"], {
679
- style: [styles.wrapper, scrollOverflow && styles.scrollOverflow]
680
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__["View"], {
681
- style: [styles.content, style]
682
- }, children)));
683
- }
684
-
685
- }
686
- ModalContent.defaultProps = {
687
- scrollOverflow: true
688
- };
689
- ModalContent.__IS_MODAL_CONTENT__ = true;
690
- const styleSheets = {
691
- all: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
692
- wrapper: {
693
- flex: 1,
694
- // This helps to ensure that the paddingBottom is preserved when
695
- // the contents start to overflow, this goes away on display: flex
696
- display: "block"
697
- },
698
- scrollOverflow: {
699
- overflow: "auto"
700
- },
701
- content: {
702
- flex: 1,
703
- minHeight: "100%",
704
- padding: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_4___default.a.xLarge_32,
705
- boxSizing: "border-box"
706
- }
707
- }),
708
- small: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
709
- content: {
710
- 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`
711
- }
712
- })
713
- };
714
-
715
- /***/ }),
716
- /* 15 */
717
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
718
-
719
- "use strict";
720
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
721
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
722
- /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
723
- /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
724
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
725
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_2__);
726
- /* harmony import */ var _khanacademy_wonder_blocks_timing__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(18);
727
- /* harmony import */ var _khanacademy_wonder_blocks_timing__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_timing__WEBPACK_IMPORTED_MODULE_3__);
728
- /* harmony import */ var _focus_trap_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(19);
729
- /* harmony import */ var _modal_backdrop_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20);
730
- /* harmony import */ var _scroll_disabler_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(23);
731
- /* harmony import */ var _modal_context_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(12);
732
-
733
-
734
-
735
-
736
-
737
-
738
-
739
-
740
-
741
- /**
742
- * This component enables you to launch a modal, covering the screen.
743
- *
744
- * Children have access to `openModal` function via the function-as-children
745
- * pattern, so one common use case is for this component to wrap a button:
746
- *
747
- * ```js
748
- * <ModalLauncher modal={<TwoColumnModal ... />}>
749
- * {({openModal}) => <button onClick={openModal}>Learn more</button>}
750
- * </ModalLauncher>
751
- * ```
752
- *
753
- * The actual modal itself is constructed separately, using a layout component
754
- * like OnePaneDialog and is provided via
755
- * the `modal` prop.
756
- */
757
- class ModalLauncher extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
758
- constructor(...args) {
759
- super(...args);
760
- this.state = {
761
- opened: false
762
- };
763
-
764
- this._saveLastElementFocused = () => {
765
- // keep a reference of the element that triggers the modal
766
- this.lastElementFocusedOutsideModal = document.activeElement;
767
- };
768
-
769
- this._openModal = () => {
770
- this._saveLastElementFocused();
771
-
772
- this.setState({
773
- opened: true
774
- });
775
- };
776
-
777
- this._returnFocus = () => {
778
- const {
779
- closedFocusId,
780
- schedule
781
- } = this.props;
782
- const lastElement = this.lastElementFocusedOutsideModal; // Focus on the specified element after closing the modal.
783
-
784
- if (closedFocusId) {
785
- const focusElement = react_dom__WEBPACK_IMPORTED_MODULE_1__["findDOMNode"](document.getElementById(closedFocusId));
786
-
787
- if (focusElement) {
788
- // Wait for the modal to leave the DOM before trying
789
- // to focus on the specified element.
790
- schedule.animationFrame(() => {
791
- focusElement.focus();
792
- });
793
- return;
794
- }
795
- }
796
-
797
- if (lastElement != null) {
798
- // Wait for the modal to leave the DOM before trying to
799
- // return focus to the element that triggered the modal.
800
- schedule.animationFrame(() => {
801
- lastElement.focus();
802
- });
803
- }
804
- };
805
-
806
- this.handleCloseModal = () => {
807
- this.setState({
808
- opened: false
809
- }, () => {
810
- const {
811
- onClose
812
- } = this.props;
813
- onClose && onClose();
814
-
815
- this._returnFocus();
816
- });
817
- };
818
- }
819
-
820
- static getDerivedStateFromProps(props, state) {
821
- if (typeof props.opened === "boolean" && props.children) {
822
- // eslint-disable-next-line no-console
823
- console.warn("'children' and 'opened' can't be used together");
824
- }
825
-
826
- if (typeof props.opened === "boolean" && !props.onClose) {
827
- // eslint-disable-next-line no-console
828
- console.warn("'onClose' should be used with 'opened'");
829
- }
830
-
831
- if (typeof props.opened !== "boolean" && !props.children) {
832
- // eslint-disable-next-line no-console
833
- console.warn("either 'children' or 'opened' must be set");
834
- }
835
-
836
- return {
837
- opened: typeof props.opened === "boolean" ? props.opened : state.opened
838
- };
839
- }
840
-
841
- componentDidUpdate(prevProps) {
842
- // ensures the element is stored only when the modal is opened
843
- if (!prevProps.opened && this.props.opened) {
844
- this._saveLastElementFocused();
845
- }
846
- }
847
-
848
- _renderModal() {
849
- if (typeof this.props.modal === "function") {
850
- return this.props.modal({
851
- closeModal: this.handleCloseModal
852
- });
853
- } else {
854
- return this.props.modal;
855
- }
856
- }
857
-
858
- render() {
859
- const renderedChildren = this.props.children ? this.props.children({
860
- openModal: this._openModal
861
- }) : null;
862
- const {
863
- body
864
- } = document;
865
-
866
- if (!body) {
867
- return null;
868
- }
869
-
870
- return (
871
- /*#__PURE__*/
872
- // This flow check is valid, it's the babel plugin which is broken,
873
- // see modal-context.js for details.
874
- // $FlowFixMe
875
- react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_context_js__WEBPACK_IMPORTED_MODULE_7__[/* default */ "a"].Provider, {
876
- value: {
877
- closeModal: this.handleCloseModal
878
- }
879
- }, renderedChildren, this.state.opened && /*#__PURE__*/react_dom__WEBPACK_IMPORTED_MODULE_1__["createPortal"](
880
- /*#__PURE__*/
881
-
882
- /* We need the container View that FocusTrap creates to be at the
883
- correct z-index so that it'll be above the global nav in webapp. */
884
- react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_focus_trap_js__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"], {
885
- style: styles.container
886
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_backdrop_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"], {
887
- initialFocusId: this.props.initialFocusId,
888
- testId: this.props.testId,
889
- onCloseModal: this.props.backdropDismissEnabled ? this.handleCloseModal : () => {}
890
- }, this._renderModal())), body), this.state.opened && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](ModalLauncherKeypressListener, {
891
- onClose: this.handleCloseModal
892
- }), this.state.opened && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_scroll_disabler_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"], null))
893
- );
894
- }
895
-
896
- }
897
- /** A component that, when mounted, calls `onClose` when Escape is pressed. */
898
-
899
-
900
- ModalLauncher.defaultProps = {
901
- backdropDismissEnabled: true
902
- };
903
-
904
- class ModalLauncherKeypressListener extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
905
- constructor(...args) {
906
- super(...args);
907
-
908
- this._handleKeyup = e => {
909
- // We check the key as that's keyboard layout agnostic and also avoids
910
- // the minefield of deprecated number type properties like keyCode and
911
- // which, with the replacement code, which uses a string instead.
912
- if (e.key === "Escape") {
913
- // Stop the event going any further.
914
- // For cancellation events, like the Escape key, we generally should
915
- // air on the side of caution and only allow it to cancel one thing.
916
- // So, it's polite for us to stop propagation of the event.
917
- // Otherwise, we end up with UX where one Escape key press
918
- // unexpectedly cancels multiple things.
919
- e.preventDefault();
920
- e.stopPropagation();
921
- this.props.onClose();
922
- }
923
- };
924
- }
925
-
926
- componentDidMount() {
927
- window.addEventListener("keyup", this._handleKeyup);
928
- }
929
-
930
- componentWillUnmount() {
931
- window.removeEventListener("keyup", this._handleKeyup);
932
- }
933
-
934
- render() {
935
- return null;
936
- }
937
-
938
- }
939
-
940
- const styles = aphrodite__WEBPACK_IMPORTED_MODULE_2__["StyleSheet"].create({
941
- container: {
942
- // This z-index is copied from the Khan Academy webapp.
943
- //
944
- // TODO(mdr): Should we keep this in a constants file somewhere? Or
945
- // not hardcode it at all, and provide it to Wonder Blocks via
946
- // configuration?
947
- zIndex: 1080
948
- }
949
- });
950
- /* harmony default export */ __webpack_exports__["a"] = (Object(_khanacademy_wonder_blocks_timing__WEBPACK_IMPORTED_MODULE_3__["withActionScheduler"])(ModalLauncher));
951
-
952
- /***/ }),
953
- /* 16 */
954
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
955
-
956
- "use strict";
957
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return OnePaneDialog; });
958
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
959
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
960
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
961
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_1__);
962
- /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
963
- /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__);
964
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2);
965
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__);
966
- /* harmony import */ var _modal_dialog_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9);
967
- /* harmony import */ var _modal_panel_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(10);
968
- /* harmony import */ var _modal_header_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7);
969
-
970
-
971
-
972
-
973
-
974
-
975
-
976
-
977
- /**
978
- * This is the standard layout for most straightforward modal experiences.
979
- *
980
- * The ModalHeader is required, but the ModalFooter is optional.
981
- * The content of the dialog itself is fully customizable, but the
982
- * left/right/top/bottom padding is fixed.
983
- *
984
- * ### Usage
985
- *
986
- * ```jsx
987
- * import {OnePaneDialog} from "@khanacademy/wonder-blocks-modal";
988
- * import {Body} from "@khanacademy/wonder-blocks-typography";
989
- *
990
- * <OnePaneDialog
991
- * title="Some title"
992
- * content={
993
- * <Body>
994
- * {`Lorem ipsum dolor sit amet, consectetur adipiscing
995
- * elit, sed do eiusmod tempor incididunt ut labore et
996
- * dolore magna aliqua. Ut enim ad minim veniam,
997
- * quis nostrud exercitation ullamco laboris nisi ut
998
- * aliquip ex ea commodo consequat. Duis aute irure
999
- * dolor in reprehenderit in voluptate velit esse
1000
- * cillum dolore eu fugiat nulla pariatur. Excepteur
1001
- * sint occaecat cupidatat non proident, sunt in culpa
1002
- * qui officia deserunt mollit anim id est.`}
1003
- * </Body>
1004
- * }
1005
- * />
1006
- * ```
1007
- */
1008
- class OnePaneDialog extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1009
- renderHeader(uniqueId) {
1010
- const {
1011
- title,
1012
- breadcrumbs = undefined,
1013
- subtitle = undefined,
1014
- testId
1015
- } = this.props;
1016
-
1017
- if (breadcrumbs) {
1018
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_header_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"], {
1019
- title: title,
1020
- breadcrumbs: breadcrumbs,
1021
- titleId: uniqueId,
1022
- testId: testId && `${testId}-header`
1023
- });
1024
- } else if (subtitle) {
1025
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_header_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"], {
1026
- title: title,
1027
- subtitle: subtitle,
1028
- titleId: uniqueId,
1029
- testId: testId && `${testId}-header`
1030
- });
1031
- } else {
1032
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_header_js__WEBPACK_IMPORTED_MODULE_6__[/* default */ "a"], {
1033
- title: title,
1034
- titleId: uniqueId,
1035
- testId: testId && `${testId}-header`
1036
- });
1037
- }
1038
- }
1039
-
1040
- render() {
1041
- const {
1042
- onClose,
1043
- footer,
1044
- content,
1045
- above,
1046
- below,
1047
- style,
1048
- closeButtonVisible,
1049
- testId,
1050
- titleId,
1051
- role,
1052
- "aria-describedby": ariaDescribedBy
1053
- } = this.props;
1054
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["MediaLayout"], {
1055
- styleSheets: styleSheets
1056
- }, ({
1057
- styles
1058
- }) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_3__["IDProvider"], {
1059
- id: titleId,
1060
- scope: "modal"
1061
- }, uniqueId => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_dialog_js__WEBPACK_IMPORTED_MODULE_4__[/* default */ "a"], {
1062
- style: [styles.dialog, style],
1063
- above: above,
1064
- below: below,
1065
- testId: testId,
1066
- "aria-labelledby": uniqueId,
1067
- "aria-describedby": ariaDescribedBy,
1068
- role: role
1069
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_panel_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"], {
1070
- onClose: onClose,
1071
- header: this.renderHeader(uniqueId),
1072
- content: content,
1073
- footer: footer,
1074
- closeButtonVisible: closeButtonVisible,
1075
- testId: testId
1076
- }))));
1077
- }
1078
-
1079
- }
1080
- OnePaneDialog.defaultProps = {
1081
- closeButtonVisible: true
1082
- };
1083
- const styleSheets = {
1084
- small: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
1085
- dialog: {
1086
- width: "100%",
1087
- height: "100%",
1088
- overflow: "hidden"
1089
- }
1090
- }),
1091
- mdOrLarger: aphrodite__WEBPACK_IMPORTED_MODULE_1__["StyleSheet"].create({
1092
- dialog: {
1093
- width: "93.75%",
1094
- maxWidth: 576,
1095
- height: "81.25%",
1096
- maxHeight: 624
1097
- }
1098
- })
1099
- };
1100
-
1101
- /***/ }),
1102
- /* 17 */
1103
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
1104
-
1105
- "use strict";
1106
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return maybeGetPortalMountedModalHostElement; });
1107
- /* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
1108
-
1109
- /**
1110
- * From a given element, finds its next ancestor that is a modal launcher portal
1111
- * element.
1112
- * @param {?(Element | Text)} element The element whose ancestors are to be
1113
- * walked.
1114
- * @returns {?Element} The nearest parent modal launcher portal.
1115
- */
1116
-
1117
- function maybeGetNextAncestorModalLauncherPortal(element) {
1118
- let candidateElement = element && element.parentElement;
1119
-
1120
- while (candidateElement && !candidateElement.hasAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_0__[/* ModalLauncherPortalAttributeName */ "a"])) {
1121
- candidateElement = candidateElement.parentElement;
1122
- }
1123
-
1124
- return candidateElement;
1125
- }
1126
- /**
1127
- * From a given element, finds the next modal host that has been mounted in
1128
- * a modal portal.
1129
- * @param {?(Element | Text)} element The element whose ancestors are to be
1130
- * walked.
1131
- * @returns {?Element} The next portal-mounted modal host element.
1132
- * TODO(kevinb): look into getting rid of this
1133
- */
1134
-
1135
-
1136
- function maybeGetPortalMountedModalHostElement(element) {
1137
- return maybeGetNextAncestorModalLauncherPortal(element);
1138
- }
1139
-
1140
- /***/ }),
1141
- /* 18 */
1142
- /***/ (function(module, exports, __webpack_require__) {
1143
-
1144
- module.exports =
1145
- /******/
1146
- function (modules) {
1147
- // webpackBootstrap
1148
-
1149
- /******/
1150
- // The module cache
1151
-
1152
- /******/
1153
- var installedModules = {};
1154
- /******/
1155
-
1156
- /******/
1157
- // The require function
1158
-
1159
- /******/
1160
-
1161
- function __webpack_require__(moduleId) {
1162
- /******/
1163
-
1164
- /******/
1165
- // Check if module is in cache
1166
-
1167
- /******/
1168
- if (installedModules[moduleId]) {
1169
- /******/
1170
- return installedModules[moduleId].exports;
1171
- /******/
1172
- }
1173
- /******/
1174
- // Create a new module (and put it into the cache)
1175
-
1176
- /******/
1177
-
1178
-
1179
- var module = installedModules[moduleId] = {
1180
- /******/
1181
- i: moduleId,
1182
-
1183
- /******/
1184
- l: false,
1185
-
1186
- /******/
1187
- exports: {}
1188
- /******/
1189
-
1190
- };
1191
- /******/
1192
-
1193
- /******/
1194
- // Execute the module function
1195
-
1196
- /******/
1197
-
1198
- modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
1199
- /******/
1200
-
1201
- /******/
1202
- // Flag the module as loaded
1203
-
1204
- /******/
1205
-
1206
- module.l = true;
1207
- /******/
1208
-
1209
- /******/
1210
- // Return the exports of the module
1211
-
1212
- /******/
1213
-
1214
- return module.exports;
1215
- /******/
1216
- }
1217
- /******/
1218
-
1219
- /******/
1220
-
1221
- /******/
1222
- // expose the modules object (__webpack_modules__)
1223
-
1224
- /******/
1225
-
1226
-
1227
- __webpack_require__.m = modules;
1228
- /******/
1229
-
1230
- /******/
1231
- // expose the module cache
1232
-
1233
- /******/
1234
-
1235
- __webpack_require__.c = installedModules;
1236
- /******/
1237
-
1238
- /******/
1239
- // define getter function for harmony exports
1240
-
1241
- /******/
1242
-
1243
- __webpack_require__.d = function (exports, name, getter) {
1244
- /******/
1245
- if (!__webpack_require__.o(exports, name)) {
1246
- /******/
1247
- Object.defineProperty(exports, name, {
1248
- enumerable: true,
1249
- get: getter
1250
- });
1251
- /******/
1252
- }
1253
- /******/
1254
-
1255
- };
1256
- /******/
1257
-
1258
- /******/
1259
- // define __esModule on exports
1260
-
1261
- /******/
1262
-
1263
-
1264
- __webpack_require__.r = function (exports) {
1265
- /******/
1266
- if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
1267
- /******/
1268
- Object.defineProperty(exports, Symbol.toStringTag, {
1269
- value: 'Module'
1270
- });
1271
- /******/
1272
- }
1273
- /******/
1274
-
1275
-
1276
- Object.defineProperty(exports, '__esModule', {
1277
- value: true
1278
- });
1279
- /******/
1280
- };
1281
- /******/
1282
-
1283
- /******/
1284
- // create a fake namespace object
1285
-
1286
- /******/
1287
- // mode & 1: value is a module id, require it
1288
-
1289
- /******/
1290
- // mode & 2: merge all properties of value into the ns
1291
-
1292
- /******/
1293
- // mode & 4: return value when already ns object
1294
-
1295
- /******/
1296
- // mode & 8|1: behave like require
1297
-
1298
- /******/
1299
-
1300
-
1301
- __webpack_require__.t = function (value, mode) {
1302
- /******/
1303
- if (mode & 1) value = __webpack_require__(value);
1304
- /******/
1305
-
1306
- if (mode & 8) return value;
1307
- /******/
1308
-
1309
- if (mode & 4 && typeof value === 'object' && value && value.__esModule) return value;
1310
- /******/
1311
-
1312
- var ns = Object.create(null);
1313
- /******/
1314
-
1315
- __webpack_require__.r(ns);
1316
- /******/
1317
-
1318
-
1319
- Object.defineProperty(ns, 'default', {
1320
- enumerable: true,
1321
- value: value
1322
- });
1323
- /******/
1324
-
1325
- if (mode & 2 && typeof value != 'string') for (var key in value) __webpack_require__.d(ns, key, function (key) {
1326
- return value[key];
1327
- }.bind(null, key));
1328
- /******/
1329
-
1330
- return ns;
1331
- /******/
1332
- };
1333
- /******/
1334
-
1335
- /******/
1336
- // getDefaultExport function for compatibility with non-harmony modules
1337
-
1338
- /******/
1339
-
1340
-
1341
- __webpack_require__.n = function (module) {
1342
- /******/
1343
- var getter = module && module.__esModule ?
1344
- /******/
1345
- function getDefault() {
1346
- return module['default'];
1347
- } :
1348
- /******/
1349
- function getModuleExports() {
1350
- return module;
1351
- };
1352
- /******/
1353
-
1354
- __webpack_require__.d(getter, 'a', getter);
1355
- /******/
1356
-
1357
-
1358
- return getter;
1359
- /******/
1360
- };
1361
- /******/
1362
-
1363
- /******/
1364
- // Object.prototype.hasOwnProperty.call
1365
-
1366
- /******/
1367
-
1368
-
1369
- __webpack_require__.o = function (object, property) {
1370
- return Object.prototype.hasOwnProperty.call(object, property);
1371
- };
1372
- /******/
1373
-
1374
- /******/
1375
- // __webpack_public_path__
1376
-
1377
- /******/
1378
-
1379
-
1380
- __webpack_require__.p = "";
1381
- /******/
1382
-
1383
- /******/
1384
-
1385
- /******/
1386
- // Load entry module and return exports
1387
-
1388
- /******/
1389
-
1390
- return __webpack_require__(__webpack_require__.s = 14);
1391
- /******/
1392
- }
1393
- /************************************************************************/
1394
-
1395
- /******/
1396
- ([
1397
- /* 0 */
1398
-
1399
- /***/
1400
- function (module, __webpack_exports__, __webpack_require__) {
1401
- "use strict";
1402
- /* harmony export (binding) */
1403
-
1404
- __webpack_require__.d(__webpack_exports__, "b", function () {
1405
- return SchedulePolicy;
1406
- });
1407
- /* harmony export (binding) */
1408
-
1409
-
1410
- __webpack_require__.d(__webpack_exports__, "a", function () {
1411
- return ClearPolicy;
1412
- });
1413
-
1414
- const SchedulePolicy = {
1415
- Immediately: "schedule-immediately",
1416
- OnDemand: "schedule-on-demand"
1417
- };
1418
- const ClearPolicy = {
1419
- Resolve: "resolve-on-clear",
1420
- Cancel: "cancel-on-clear"
1421
- };
1422
- /***/
1423
- },
1424
- /* 1 */
1425
-
1426
- /***/
1427
- function (module, exports) {
1428
- module.exports = __webpack_require__(0);
1429
- /***/
1430
- },
1431
- /* 2 */
1432
-
1433
- /***/
1434
- function (module, __webpack_exports__, __webpack_require__) {
1435
- "use strict";
1436
- /* harmony export (binding) */
1437
-
1438
- __webpack_require__.d(__webpack_exports__, "a", function () {
1439
- return useUpdatingRef;
1440
- });
1441
- /* harmony import */
1442
-
1443
-
1444
- var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
1445
- /* harmony import */
1446
-
1447
-
1448
- var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1449
- /**
1450
- * Returns a ref whose .current value is updated whenever
1451
- * the `value` passed to this hook changes.
1452
- *
1453
- * this is great for values that you want to reference from
1454
- * within a useCallback or useEffect event listener, without
1455
- * re-triggering the effect when the value changes
1456
- *
1457
- * @returns {{current: T}}
1458
- */
1459
-
1460
-
1461
- const useUpdatingRef = value => {
1462
- const ref = Object(react__WEBPACK_IMPORTED_MODULE_0__["useRef"])(value);
1463
- Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
1464
- ref.current = value;
1465
- }, [value]);
1466
- return ref;
1467
- };
1468
- /***/
1469
-
1470
- },
1471
- /* 3 */
1472
-
1473
- /***/
1474
- function (module, __webpack_exports__, __webpack_require__) {
1475
- "use strict";
1476
- /* harmony export (binding) */
1477
-
1478
- __webpack_require__.d(__webpack_exports__, "a", function () {
1479
- return useInterval;
1480
- });
1481
- /* harmony import */
1482
-
1483
-
1484
- var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
1485
- /* harmony import */
1486
-
1487
-
1488
- var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1489
- /* harmony import */
1490
-
1491
-
1492
- var _internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
1493
- /**
1494
- * A simple hook for using `setInterval`.
1495
- *
1496
- * @param action called every `intervalMs` when `active` is true
1497
- * @param intervalMs the duration between calls to `action`
1498
- * @param active whether or not the interval is active
1499
- */
1500
-
1501
-
1502
- function useInterval(action, intervalMs, active) {
1503
- // We using a ref instead of a callback for `action` to avoid resetting
1504
- // the interval whenever the `action` changes.
1505
- const actionRef = Object(_internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_1__[
1506
- /* useUpdatingRef */
1507
- "a"])(action);
1508
- Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
1509
- if (active) {
1510
- const intervalId = setInterval(() => {
1511
- actionRef.current();
1512
- }, intervalMs);
1513
- return () => {
1514
- clearInterval(intervalId);
1515
- };
1516
- } // actionRef isn't actually required, but react-hooks/exhaustive-deps
1517
- // doesn't recognize it as a ref and thus complains if it isn't in the
1518
- // deps list. It isn't a big deal though since the value ofactionRef
1519
- // never changes (only its contents do).
1520
-
1521
- }, [intervalMs, active, actionRef]);
1522
- }
1523
- /***/
1524
-
1525
- },
1526
- /* 4 */
1527
-
1528
- /***/
1529
- function (module, __webpack_exports__, __webpack_require__) {
1530
- "use strict";
1531
- /* harmony export (binding) */
1532
-
1533
- __webpack_require__.d(__webpack_exports__, "a", function () {
1534
- return useTimeout;
1535
- });
1536
- /* harmony import */
1537
-
1538
-
1539
- var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
1540
- /* harmony import */
1541
-
1542
-
1543
- var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1544
- /* harmony import */
1545
-
1546
-
1547
- var _internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
1548
- /**
1549
- * A simple hook for using `setTimeout`.
1550
- *
1551
- * @param action called after `timeoutMs` when `active` is true
1552
- * @param timeoutMs the duration after which `action` is called
1553
- * @param active whether or not the interval is active
1554
- */
1555
-
1556
-
1557
- function useTimeout(action, timeoutMs, active) {
1558
- // We using a ref instead of a callback for `action` to avoid resetting
1559
- // the interval whenever the `action` changes.
1560
- const actionRef = Object(_internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_1__[
1561
- /* useUpdatingRef */
1562
- "a"])(action);
1563
- Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
1564
- if (active) {
1565
- const timeoutId = setTimeout(() => {
1566
- actionRef.current();
1567
- }, timeoutMs);
1568
- return () => {
1569
- clearTimeout(timeoutId);
1570
- };
1571
- } // actionRef isn't actually required, but react-hooks/exhaustive-deps
1572
- // doesn't recognize it as a ref and thus complains if it isn't in the
1573
- // deps list. It isn't a big deal though since the value ofactionRef
1574
- // never changes (only its contents do).
1575
-
1576
- }, [timeoutMs, active, actionRef]);
1577
- }
1578
- /***/
1579
-
1580
- },
1581
- /* 5 */
1582
-
1583
- /***/
1584
- function (module, __webpack_exports__, __webpack_require__) {
1585
- "use strict";
1586
- /* harmony export (binding) */
1587
-
1588
- __webpack_require__.d(__webpack_exports__, "a", function () {
1589
- return withActionScheduler;
1590
- });
1591
- /* harmony import */
1592
-
1593
-
1594
- var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8);
1595
- /* harmony import */
1596
-
1597
-
1598
- var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);
1599
- /* harmony import */
1600
-
1601
-
1602
- var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1);
1603
- /* harmony import */
1604
-
1605
-
1606
- var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
1607
- /* harmony import */
1608
-
1609
-
1610
- var _action_scheduler_provider_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9);
1611
- /**
1612
- * A higher order component that attaches the given component to an
1613
- * `IScheduleActions` instance. Any actions scheduled will automatically be
1614
- * cleared on unmount.
1615
- *
1616
- * @template TOwnProps The own props of the component being rendered, without
1617
- * the additional action scheduler prop. To attach the additional prop to
1618
- * these props use the `WithActionScheduler` type.
1619
- */
1620
-
1621
-
1622
- function withActionScheduler(WrappedComponent) {
1623
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["forwardRef"]((props, ref) => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_action_scheduler_provider_js__WEBPACK_IMPORTED_MODULE_2__[
1624
- /* default */
1625
- "a"], null, schedule => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["createElement"](WrappedComponent, _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default()({}, props, {
1626
- ref: ref,
1627
- schedule: schedule
1628
- }))));
1629
- }
1630
- /***/
1631
-
1632
- },
1633
- /* 6 */
1634
-
1635
- /***/
1636
- function (module, __webpack_exports__, __webpack_require__) {
1637
- "use strict";
1638
- /* harmony export (binding) */
1639
-
1640
- __webpack_require__.d(__webpack_exports__, "a", function () {
1641
- return useScheduledInterval;
1642
- });
1643
- /* harmony import */
1644
-
1645
-
1646
- var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
1647
- /* harmony import */
1648
-
1649
-
1650
- var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1651
- /* harmony import */
1652
-
1653
-
1654
- var _util_policies_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
1655
- /* harmony import */
1656
-
1657
-
1658
- var _internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
1659
- /* harmony import */
1660
-
1661
-
1662
- var _use_interval_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3);
1663
-
1664
- function useScheduledInterval(action, intervalMs, options) {
1665
- var _options$schedulePoli;
1666
-
1667
- if (typeof action !== "function") {
1668
- throw new Error("Action must be a function");
1669
- }
1670
-
1671
- if (intervalMs < 1) {
1672
- throw new Error("Interval period must be >= 1");
1673
- }
1674
-
1675
- const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1676
- /* SchedulePolicy */
1677
- "b"].Immediately;
1678
- const [isSet, setIsSet] = Object(react__WEBPACK_IMPORTED_MODULE_0__["useState"])(schedulePolicy === _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1679
- /* SchedulePolicy */
1680
- "b"].Immediately);
1681
- const set = Object(react__WEBPACK_IMPORTED_MODULE_0__["useCallback"])(() => setIsSet(true), []);
1682
- const actionRef = Object(_internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_2__[
1683
- /* useUpdatingRef */
1684
- "a"])(action);
1685
- const clear = Object(react__WEBPACK_IMPORTED_MODULE_0__["useCallback"])(policy => {
1686
- var _policy;
1687
-
1688
- policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
1689
-
1690
- if (isSet && policy === _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1691
- /* ClearPolicy */
1692
- "a"].Resolve) {
1693
- actionRef.current();
1694
- }
1695
-
1696
- setIsSet(false);
1697
- }, // react-hooks/exhaustive-deps doesn't require refs to be
1698
- // listed in the deps array. Unfortunately, in this situation
1699
- // it doesn't recognized actionRef as a ref.
1700
- [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
1701
- const runOnUnmountRef = Object(_internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_2__[
1702
- /* useUpdatingRef */
1703
- "a"])(isSet && (options == null ? void 0 : options.clearPolicy) === _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1704
- /* ClearPolicy */
1705
- "a"].Resolve);
1706
- Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
1707
- return () => {
1708
- // This code will only run with the component using this
1709
- // hook is unmounted.
1710
- // eslint-disable-next-line react-hooks/exhaustive-deps
1711
- if (runOnUnmountRef.current) {
1712
- // eslint-disable-next-line react-hooks/exhaustive-deps
1713
- actionRef.current();
1714
- }
1715
- }; // This eslint rule doesn't realize actionRef and runOnUnmountRef
1716
- // a both refs and thus do not have to be listed as deps.
1717
- // eslint-disable-next-line react-hooks/exhaustive-deps
1718
- }, []);
1719
- Object(_use_interval_js__WEBPACK_IMPORTED_MODULE_3__[
1720
- /* useInterval */
1721
- "a"])(action, intervalMs, isSet);
1722
- return {
1723
- isSet,
1724
- set,
1725
- clear
1726
- };
1727
- }
1728
- /***/
1729
-
1730
- },
1731
- /* 7 */
1732
-
1733
- /***/
1734
- function (module, __webpack_exports__, __webpack_require__) {
1735
- "use strict";
1736
- /* harmony export (binding) */
1737
-
1738
- __webpack_require__.d(__webpack_exports__, "a", function () {
1739
- return useScheduledTimeout;
1740
- });
1741
- /* harmony import */
1742
-
1743
-
1744
- var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
1745
- /* harmony import */
1746
-
1747
-
1748
- var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1749
- /* harmony import */
1750
-
1751
-
1752
- var _util_policies_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
1753
- /* harmony import */
1754
-
1755
-
1756
- var _internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
1757
- /* harmony import */
1758
-
1759
-
1760
- var _use_timeout_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
1761
-
1762
- function useScheduledTimeout(action, timeoutMs, options) {
1763
- var _options$schedulePoli;
1764
-
1765
- if (typeof action !== "function") {
1766
- throw new Error("Action must be a function");
1767
- }
1768
-
1769
- if (timeoutMs < 0) {
1770
- throw new Error("Timeout period must be >= 0");
1771
- }
1772
-
1773
- const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1774
- /* SchedulePolicy */
1775
- "b"].Immediately;
1776
- const [isSet, setIsSet] = Object(react__WEBPACK_IMPORTED_MODULE_0__["useState"])(schedulePolicy === _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1777
- /* SchedulePolicy */
1778
- "b"].Immediately);
1779
- const set = Object(react__WEBPACK_IMPORTED_MODULE_0__["useCallback"])(() => setIsSet(true), []); // This wrapper isn't present in useScheduledInterval because we
1780
- // don't need to update `isSet` in that situations.
1781
-
1782
- const wrappedAction = Object(react__WEBPACK_IMPORTED_MODULE_0__["useCallback"])(() => {
1783
- setIsSet(false);
1784
- action();
1785
- }, [action]);
1786
- const actionRef = Object(_internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_2__[
1787
- /* useUpdatingRef */
1788
- "a"])(wrappedAction);
1789
- const clear = Object(react__WEBPACK_IMPORTED_MODULE_0__["useCallback"])(policy => {
1790
- var _policy;
1791
-
1792
- policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
1793
-
1794
- if (isSet && policy === _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1795
- /* ClearPolicy */
1796
- "a"].Resolve) {
1797
- actionRef.current();
1798
- }
1799
-
1800
- setIsSet(false);
1801
- }, // react-hooks/exhaustive-deps doesn't require refs to be
1802
- // listed in the deps array. Unfortunately, in this situation
1803
- // it doesn't recognized actionRef as a ref.
1804
- [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
1805
- const runOnUnmountRef = Object(_internal_use_updating_ref_js__WEBPACK_IMPORTED_MODULE_2__[
1806
- /* useUpdatingRef */
1807
- "a"])(isSet && (options == null ? void 0 : options.clearPolicy) === _util_policies_js__WEBPACK_IMPORTED_MODULE_1__[
1808
- /* ClearPolicy */
1809
- "a"].Resolve);
1810
- Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
1811
- return () => {
1812
- // This code will only run with the component using this
1813
- // hook is unmounted.
1814
- // eslint-disable-next-line react-hooks/exhaustive-deps
1815
- if (runOnUnmountRef.current) {
1816
- // eslint-disable-next-line react-hooks/exhaustive-deps
1817
- actionRef.current();
1818
- }
1819
- }; // This eslint rule doesn't realize actionRef and runOnUnmountRef
1820
- // a both refs and thus do not have to be listed as deps.
1821
- // eslint-disable-next-line react-hooks/exhaustive-deps
1822
- }, []);
1823
- Object(_use_timeout_js__WEBPACK_IMPORTED_MODULE_3__[
1824
- /* useTimeout */
1825
- "a"])(wrappedAction, timeoutMs, isSet);
1826
- return {
1827
- isSet,
1828
- set,
1829
- clear
1830
- };
1831
- }
1832
- /***/
1833
-
1834
- },
1835
- /* 8 */
1836
-
1837
- /***/
1838
- function (module, exports) {
1839
- function _extends() {
1840
- module.exports = _extends = Object.assign ? Object.assign.bind() : function (target) {
1841
- for (var i = 1; i < arguments.length; i++) {
1842
- var source = arguments[i];
1843
-
1844
- for (var key in source) {
1845
- if (Object.prototype.hasOwnProperty.call(source, key)) {
1846
- target[key] = source[key];
1847
- }
1848
- }
1849
- }
1850
-
1851
- return target;
1852
- }, module.exports.__esModule = true, module.exports["default"] = module.exports;
1853
- return _extends.apply(this, arguments);
1854
- }
1855
-
1856
- module.exports = _extends, module.exports.__esModule = true, module.exports["default"] = module.exports;
1857
- /***/
1858
- },
1859
- /* 9 */
1860
-
1861
- /***/
1862
- function (module, __webpack_exports__, __webpack_require__) {
1863
- "use strict";
1864
- /* harmony export (binding) */
1865
-
1866
- __webpack_require__.d(__webpack_exports__, "a", function () {
1867
- return ActionSchedulerProvider;
1868
- });
1869
- /* harmony import */
1870
-
1871
-
1872
- var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
1873
- /* harmony import */
1874
-
1875
-
1876
- var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1877
- /* harmony import */
1878
-
1879
-
1880
- var _util_action_scheduler_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
1881
- /**
1882
- * A provider component that passes our action scheduling API to its children
1883
- * and ensures that all scheduled actions are cleared on unmount.
1884
- *
1885
- * ```jsx
1886
- * <ActionSchedulerProvider>
1887
- * {schedule => this.renderThingThatNeedsTimers(schedule)}
1888
- * </ActionSchedulerProvider>
1889
- * ```
1890
- */
1891
-
1892
-
1893
- class ActionSchedulerProvider extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1894
- constructor(...args) {
1895
- super(...args);
1896
- this._actionScheduler = new _util_action_scheduler_js__WEBPACK_IMPORTED_MODULE_1__[
1897
- /* default */
1898
- "a"]();
1899
- }
1900
-
1901
- componentWillUnmount() {
1902
- this._actionScheduler.disable();
1903
- }
1904
-
1905
- render() {
1906
- const {
1907
- children
1908
- } = this.props;
1909
- return children(this._actionScheduler);
1910
- }
1911
-
1912
- }
1913
- /***/
1914
-
1915
- },
1916
- /* 10 */
1917
-
1918
- /***/
1919
- function (module, __webpack_exports__, __webpack_require__) {
1920
- "use strict";
1921
- /* harmony export (binding) */
1922
-
1923
- __webpack_require__.d(__webpack_exports__, "a", function () {
1924
- return ActionScheduler;
1925
- });
1926
- /* harmony import */
1927
-
1928
-
1929
- var _timeout_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
1930
- /* harmony import */
1931
-
1932
-
1933
- var _interval_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12);
1934
- /* harmony import */
1935
-
1936
-
1937
- var _animation_frame_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13);
1938
- /**
1939
- * Implements the `IScheduleActions` API to provide timeout, interval, and
1940
- * animation frame support. This is not intended for direct use, but instead
1941
- * is to be used solely by the `ActionSchedulerProvider` to provide an
1942
- * `IScheduleActions` instance.
1943
- */
1944
-
1945
-
1946
- class ActionScheduler {
1947
- constructor() {
1948
- this._disabled = false;
1949
- this._registeredActions = [];
1950
- }
1951
-
1952
- timeout(action, period, options) {
1953
- if (this._disabled) {
1954
- return ActionScheduler.NoopAction;
1955
- }
1956
-
1957
- const timeout = new _timeout_js__WEBPACK_IMPORTED_MODULE_0__[
1958
- /* default */
1959
- "a"](action, period, options == null ? void 0 : options.schedulePolicy);
1960
-
1961
- this._registeredActions.push(() => timeout.clear(options == null ? void 0 : options.clearPolicy));
1962
-
1963
- return timeout;
1964
- }
1965
-
1966
- interval(action, period, options) {
1967
- if (this._disabled) {
1968
- return ActionScheduler.NoopAction;
1969
- }
1970
-
1971
- const interval = new _interval_js__WEBPACK_IMPORTED_MODULE_1__[
1972
- /* default */
1973
- "a"](action, period, options == null ? void 0 : options.schedulePolicy);
1974
-
1975
- this._registeredActions.push(() => interval.clear(options == null ? void 0 : options.clearPolicy));
1976
-
1977
- return interval;
1978
- }
1979
-
1980
- animationFrame(action, options) {
1981
- if (this._disabled) {
1982
- return ActionScheduler.NoopAction;
1983
- }
1984
-
1985
- const animationFrame = new _animation_frame_js__WEBPACK_IMPORTED_MODULE_2__[
1986
- /* default */
1987
- "a"](action, options == null ? void 0 : options.schedulePolicy);
1988
-
1989
- this._registeredActions.push(() => animationFrame.clear(options == null ? void 0 : options.clearPolicy));
1990
-
1991
- return animationFrame;
1992
- }
1993
-
1994
- clearAll() {
1995
- const registered = [].concat(this._registeredActions);
1996
- this._registeredActions = [];
1997
- registered.forEach(clearFn => clearFn());
1998
- }
1999
- /**
2000
- * Prevents this scheduler from creating any additional actions.
2001
- * This also clears any pending actions.
2002
- */
2003
-
2004
-
2005
- disable() {
2006
- this._disabled = true;
2007
- this.clearAll();
2008
- }
2009
-
2010
- }
2011
-
2012
- ActionScheduler.NoopAction = {
2013
- set: () => {},
2014
-
2015
- get isSet() {
2016
- return false;
2017
- },
2018
-
2019
- clear: () => {}
2020
- };
2021
- /***/
2022
- },
2023
- /* 11 */
2024
-
2025
- /***/
2026
- function (module, __webpack_exports__, __webpack_require__) {
2027
- "use strict";
2028
- /* harmony export (binding) */
2029
-
2030
- __webpack_require__.d(__webpack_exports__, "a", function () {
2031
- return Timeout;
2032
- });
2033
- /* harmony import */
2034
-
2035
-
2036
- var _policies_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
2037
- /**
2038
- * Encapsulates everything associated with calling setTimeout/clearTimeout, and
2039
- * managing the lifecycle of that timer, including the ability to resolve or
2040
- * cancel a pending timeout action.
2041
- *
2042
- * @export
2043
- * @class Timeout
2044
- * @implements {ITimeout}
2045
- */
2046
-
2047
-
2048
- class Timeout {
2049
- /**
2050
- * Creates a timeout that will invoke the given action after
2051
- * the given period. The timeout does not start until set is called.
2052
- *
2053
- * @param {() => mixed} action The action to be invoked when the timeout
2054
- * period has passed.
2055
- * @param {number} timeoutMs The timeout period.
2056
- * @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
2057
- * the timer is set immediately on instantiation; otherwise, `set` must be
2058
- * called to set the timeout.
2059
- * Defaults to `SchedulePolicy.Immediately`.
2060
- * @memberof Timeout
2061
- */
2062
- constructor(action, timeoutMs, schedulePolicy = _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2063
- /* SchedulePolicy */
2064
- "b"].Immediately) {
2065
- if (typeof action !== "function") {
2066
- throw new Error("Action must be a function");
2067
- }
2068
-
2069
- if (timeoutMs < 0) {
2070
- throw new Error("Timeout period must be >= 0");
2071
- }
2072
-
2073
- this._action = action;
2074
- this._timeoutMs = timeoutMs;
2075
-
2076
- if (schedulePolicy === _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2077
- /* SchedulePolicy */
2078
- "b"].Immediately) {
2079
- this.set();
2080
- }
2081
- }
2082
- /**
2083
- * Determine if the timeout is set or not.
2084
- *
2085
- * @returns {boolean} true if the timeout is set (aka pending), otherwise
2086
- * false.
2087
- * @memberof Timeout
2088
- */
2089
-
2090
-
2091
- get isSet() {
2092
- return this._timeoutId != null;
2093
- }
2094
- /**
2095
- * Set the timeout.
2096
- *
2097
- * If the timeout is pending, this cancels that pending timeout and
2098
- * sets the timeout afresh. If the timeout is not pending, this
2099
- * sets a new timeout.
2100
- *
2101
- * @memberof Timeout
2102
- */
2103
-
2104
-
2105
- set() {
2106
- if (this.isSet) {
2107
- this.clear(_policies_js__WEBPACK_IMPORTED_MODULE_0__[
2108
- /* ClearPolicy */
2109
- "a"].Cancel);
2110
- }
2111
-
2112
- this._timeoutId = setTimeout(() => this.clear(_policies_js__WEBPACK_IMPORTED_MODULE_0__[
2113
- /* ClearPolicy */
2114
- "a"].Resolve), this._timeoutMs);
2115
- }
2116
- /**
2117
- * Clear the set timeout.
2118
- *
2119
- * If the timeout is pending, this cancels that pending timeout without
2120
- * invoking the action. If no timeout is pending, this does nothing.
2121
- *
2122
- * @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
2123
- * was set when called, the request action is invoked after cancelling
2124
- * the request; otherwise, the pending action is cancelled.
2125
- * Defaults to `ClearPolicy.Cancel`.
2126
- *
2127
- * @returns {void}
2128
- * @memberof Timeout
2129
- */
2130
-
2131
-
2132
- clear(policy = _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2133
- /* ClearPolicy */
2134
- "a"].Cancel) {
2135
- const timeoutId = this._timeoutId;
2136
- this._timeoutId = null;
2137
-
2138
- if (timeoutId == null) {
2139
- return;
2140
- }
2141
-
2142
- clearTimeout(timeoutId);
2143
-
2144
- if (policy === _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2145
- /* ClearPolicy */
2146
- "a"].Resolve) {
2147
- this._action();
2148
- }
2149
- }
2150
-
2151
- }
2152
- /***/
2153
-
2154
- },
2155
- /* 12 */
2156
-
2157
- /***/
2158
- function (module, __webpack_exports__, __webpack_require__) {
2159
- "use strict";
2160
- /* harmony export (binding) */
2161
-
2162
- __webpack_require__.d(__webpack_exports__, "a", function () {
2163
- return Interval;
2164
- });
2165
- /* harmony import */
2166
-
2167
-
2168
- var _policies_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
2169
- /**
2170
- * Encapsulates everything associated with calling setInterval/clearInterval,
2171
- * and managing the lifecycle of that interval. This includes the ability to
2172
- * cancel the interval, and knowing if the interval is active.
2173
- *
2174
- * @export
2175
- * @class Interval
2176
- * @implements {IInterval}
2177
- */
2178
-
2179
-
2180
- class Interval {
2181
- /**
2182
- * Creates an interval that will invoke the given action after
2183
- * the given period. The interval does not start until set is called.
2184
- *
2185
- * @param {() => mixed} action The action to be invoked each time the
2186
- * interval period has passed.
2187
- * @param {number} intervalMs The interval period.
2188
- * @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
2189
- * the interval is set immediately on instantiation; otherwise, `set` must be
2190
- * called to set the interval.
2191
- * Defaults to `SchedulePolicy.Immediately`.
2192
- * @memberof Interval
2193
- */
2194
- constructor(action, intervalMs, schedulePolicy = _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2195
- /* SchedulePolicy */
2196
- "b"].Immediately) {
2197
- if (typeof action !== "function") {
2198
- throw new Error("Action must be a function");
2199
- }
2200
-
2201
- if (intervalMs < 1) {
2202
- throw new Error("Interval period must be >= 1");
2203
- }
2204
-
2205
- this._action = action;
2206
- this._intervalMs = intervalMs;
2207
-
2208
- if (schedulePolicy === _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2209
- /* SchedulePolicy */
2210
- "b"].Immediately) {
2211
- this.set();
2212
- }
2213
- }
2214
- /**
2215
- * Determine if the interval is active or not.
2216
- *
2217
- * @returns {boolean} true if the interval is active, otherwise false.
2218
- * @memberof Interval
2219
- */
2220
-
2221
-
2222
- get isSet() {
2223
- return this._intervalId != null;
2224
- }
2225
- /**
2226
- * Activate the interval.
2227
- *
2228
- * If the interval is active, this cancels that interval and starts the
2229
- * interval afresh. If the interval is not active, this starts it.
2230
- *
2231
- * @memberof Interval
2232
- */
2233
-
2234
-
2235
- set() {
2236
- if (this.isSet) {
2237
- this.clear(_policies_js__WEBPACK_IMPORTED_MODULE_0__[
2238
- /* ClearPolicy */
2239
- "a"].Cancel);
2240
- }
2241
-
2242
- this._intervalId = setInterval(() => this._action(), this._intervalMs);
2243
- }
2244
- /**
2245
- * Clear the active interval.
2246
- *
2247
- * If the interval is active, this cancels that interval. If no interval is
2248
- * pending, this does nothing.
2249
- *
2250
- * @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
2251
- * was set when called, the request action is invoked after cancelling
2252
- * the request; otherwise, the pending action is cancelled.
2253
- * Defaults to `ClearPolicy.Cancel`.
2254
- *
2255
- * @returns {void}
2256
- * @memberof Interval
2257
- */
2258
-
2259
-
2260
- clear(policy = _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2261
- /* ClearPolicy */
2262
- "a"].Cancel) {
2263
- const intervalId = this._intervalId;
2264
- this._intervalId = null;
2265
-
2266
- if (intervalId == null) {
2267
- return;
2268
- }
2269
-
2270
- clearInterval(intervalId);
2271
-
2272
- if (policy === _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2273
- /* ClearPolicy */
2274
- "a"].Resolve) {
2275
- this._action();
2276
- }
2277
- }
2278
-
2279
- }
2280
- /***/
2281
-
2282
- },
2283
- /* 13 */
2284
-
2285
- /***/
2286
- function (module, __webpack_exports__, __webpack_require__) {
2287
- "use strict";
2288
- /* harmony export (binding) */
2289
-
2290
- __webpack_require__.d(__webpack_exports__, "a", function () {
2291
- return AnimationFrame;
2292
- });
2293
- /* harmony import */
2294
-
2295
-
2296
- var _policies_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
2297
- /**
2298
- * Encapsulates everything associated with calling requestAnimationFrame/
2299
- * cancelAnimationFrame, and managing the lifecycle of that request, including
2300
- * the ability to resolve or cancel a pending request action.
2301
- *
2302
- * @export
2303
- * @class AnimationFrame
2304
- * @implements {IAnimationFrame}
2305
- */
2306
-
2307
-
2308
- class AnimationFrame {
2309
- /**
2310
- * Creates an animation frame request that will invoke the given action.
2311
- * The request is not made until set is called.
2312
- *
2313
- * @param {DOMHighResTimeStamp => mixed} action The action to be invoked.
2314
- * @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
2315
- * the interval is set immediately on instantiation; otherwise, `set` must be
2316
- * called to set the interval.
2317
- * Defaults to `SchedulePolicy.Immediately`.
2318
- * @memberof AnimationFrame
2319
- */
2320
- constructor(action, schedulePolicy = _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2321
- /* SchedulePolicy */
2322
- "b"].Immediately) {
2323
- if (typeof action !== "function") {
2324
- throw new Error("Action must be a function");
2325
- }
2326
-
2327
- this._action = action;
2328
-
2329
- if (schedulePolicy === _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2330
- /* SchedulePolicy */
2331
- "b"].Immediately) {
2332
- this.set();
2333
- }
2334
- }
2335
- /**
2336
- * Determine if the request is pending or not.
2337
- *
2338
- * @returns {boolean} true if the request is pending, otherwise
2339
- * false.
2340
- * @memberof AnimationFrame
2341
- */
2342
-
2343
-
2344
- get isSet() {
2345
- return this._animationFrameId != null;
2346
- }
2347
- /**
2348
- * Make the animation frame request.
2349
- *
2350
- * If the request is pending, this cancels that pending request and
2351
- * makes the request afresh. If the request is not pending, this
2352
- * makes a new request.
2353
- *
2354
- * @memberof AnimationFrame
2355
- */
2356
-
2357
-
2358
- set() {
2359
- if (this.isSet) {
2360
- this.clear(_policies_js__WEBPACK_IMPORTED_MODULE_0__[
2361
- /* ClearPolicy */
2362
- "a"].Cancel);
2363
- }
2364
-
2365
- this._animationFrameId = requestAnimationFrame(time => this.clear(_policies_js__WEBPACK_IMPORTED_MODULE_0__[
2366
- /* ClearPolicy */
2367
- "a"].Resolve, time));
2368
- }
2369
- /**
2370
- * Clear the pending request.
2371
- *
2372
- * If the request is pending, this cancels that pending request without
2373
- * invoking the action. If no request is pending, this does nothing.
2374
- *
2375
- * @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
2376
- * was set when called, the request action is invoked after cancelling
2377
- * the request; otherwise, the pending action is cancelled.
2378
- * Defaults to `ClearPolicy.Cancel`.
2379
- * @param {DOMHighResTimeStamp} [time] Timestamp to pass to the action when
2380
- * ClearPolicy.Resolve is specified. Ignored when ClearPolicy.Cancel is
2381
- * specified.
2382
- *
2383
- * @returns {void}
2384
- * @memberof AnimationFrame
2385
- */
2386
-
2387
-
2388
- clear(policy = _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2389
- /* ClearPolicy */
2390
- "a"].Cancel, time) {
2391
- const animationFrameId = this._animationFrameId;
2392
- this._animationFrameId = null;
2393
-
2394
- if (animationFrameId == null) {
2395
- return;
2396
- }
2397
-
2398
- cancelAnimationFrame(animationFrameId);
2399
-
2400
- if (policy === _policies_js__WEBPACK_IMPORTED_MODULE_0__[
2401
- /* ClearPolicy */
2402
- "a"].Resolve) {
2403
- this._action(time || performance.now());
2404
- }
2405
- }
2406
-
2407
- }
2408
- /***/
2409
-
2410
- },
2411
- /* 14 */
2412
-
2413
- /***/
2414
- function (module, __webpack_exports__, __webpack_require__) {
2415
- "use strict";
2416
-
2417
- __webpack_require__.r(__webpack_exports__);
2418
- /* harmony import */
2419
-
2420
-
2421
- var _util_policies_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
2422
- /* harmony reexport (safe) */
2423
-
2424
-
2425
- __webpack_require__.d(__webpack_exports__, "SchedulePolicy", function () {
2426
- return _util_policies_js__WEBPACK_IMPORTED_MODULE_0__["b"];
2427
- });
2428
- /* harmony reexport (safe) */
2429
-
2430
-
2431
- __webpack_require__.d(__webpack_exports__, "ClearPolicy", function () {
2432
- return _util_policies_js__WEBPACK_IMPORTED_MODULE_0__["a"];
2433
- });
2434
- /* harmony import */
2435
-
2436
-
2437
- var _components_with_action_scheduler_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
2438
- /* harmony reexport (safe) */
2439
-
2440
-
2441
- __webpack_require__.d(__webpack_exports__, "withActionScheduler", function () {
2442
- return _components_with_action_scheduler_js__WEBPACK_IMPORTED_MODULE_1__["a"];
2443
- });
2444
- /* harmony import */
2445
-
2446
-
2447
- var _hooks_use_interval_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3);
2448
- /* harmony reexport (safe) */
2449
-
2450
-
2451
- __webpack_require__.d(__webpack_exports__, "useInterval", function () {
2452
- return _hooks_use_interval_js__WEBPACK_IMPORTED_MODULE_2__["a"];
2453
- });
2454
- /* harmony import */
2455
-
2456
-
2457
- var _hooks_use_timeout_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
2458
- /* harmony reexport (safe) */
2459
-
2460
-
2461
- __webpack_require__.d(__webpack_exports__, "useTimeout", function () {
2462
- return _hooks_use_timeout_js__WEBPACK_IMPORTED_MODULE_3__["a"];
2463
- });
2464
- /* harmony import */
2465
-
2466
-
2467
- var _hooks_use_scheduled_interval_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6);
2468
- /* harmony reexport (safe) */
2469
-
2470
-
2471
- __webpack_require__.d(__webpack_exports__, "useScheduledInterval", function () {
2472
- return _hooks_use_scheduled_interval_js__WEBPACK_IMPORTED_MODULE_4__["a"];
2473
- });
2474
- /* harmony import */
2475
-
2476
-
2477
- var _hooks_use_scheduled_timeout_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7);
2478
- /* harmony reexport (safe) */
2479
-
2480
-
2481
- __webpack_require__.d(__webpack_exports__, "useScheduledTimeout", function () {
2482
- return _hooks_use_scheduled_timeout_js__WEBPACK_IMPORTED_MODULE_5__["a"];
2483
- });
2484
- /***/
2485
-
2486
- }
2487
- /******/
2488
- ]);
2489
-
2490
- /***/ }),
2491
- /* 19 */
2492
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
2493
-
2494
- "use strict";
2495
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return FocusTrap; });
2496
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
2497
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
2498
- /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
2499
- /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);
2500
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
2501
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__);
2502
-
2503
-
2504
-
2505
-
2506
- /**
2507
- * List of elements that can be focused
2508
- * @see https://www.w3.org/TR/html5/editing.html#can-be-focused
2509
- */
2510
- const FOCUSABLE_ELEMENTS = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
2511
- /**
2512
- * This component ensures that focus stays within itself. If the user uses Tab
2513
- * at the end of the modal, or Shift-Tab at the start of the modal, then this
2514
- * component wraps focus to the start/end respectively.
2515
- *
2516
- * We use this in `ModalBackdrop` to ensure that focus stays within the launched
2517
- * modal.
2518
- *
2519
- * Adapted from the WAI-ARIA dialog behavior example.
2520
- * https://www.w3.org/TR/2017/NOTE-wai-aria-practices-1.1-20171214/examples/dialog-modal/dialog.html
2521
- *
2522
- * NOTE(mdr): This component frequently references the "modal" and the "modal
2523
- * root", to aid readability in this package. But this component isn't
2524
- * actually coupled to the modal, and these could be renamed "children"
2525
- * instead if we were to generalize!
2526
- */
2527
-
2528
- class FocusTrap extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
2529
- constructor(...args) {
2530
- super(...args);
2531
-
2532
- this.getModalRoot = node => {
2533
- if (!node) {
2534
- // The component is being umounted
2535
- return;
2536
- }
2537
-
2538
- const modalRoot = react_dom__WEBPACK_IMPORTED_MODULE_1__["findDOMNode"](node);
2539
-
2540
- if (!modalRoot) {
2541
- throw new Error("Assertion error: modal root should exist after mount");
2542
- }
2543
-
2544
- this.modalRoot = modalRoot;
2545
- };
2546
-
2547
- this.handleFocusMoveToLast = () => {
2548
- this.focusElementIn(false);
2549
- };
2550
-
2551
- this.handleFocusMoveToFirst = () => {
2552
- this.focusElementIn(true);
2553
- };
2554
- }
2555
-
2556
- /**
2557
- * Try to focus the given node. Return true if successful.
2558
- */
2559
- tryToFocus(node) {
2560
- if (node instanceof HTMLElement) {
2561
- try {
2562
- node.focus();
2563
- } catch (e) {// ignore error
2564
- }
2565
-
2566
- return document.activeElement === node;
2567
- }
2568
- }
2569
- /**
2570
- * Focus the next available focusable element within the modal root.
2571
- *
2572
- * @param {boolean} isLast Used to determine the next available item. true =
2573
- * First element within the modal, false = Last element within the modal.
2574
- */
2575
-
2576
-
2577
- focusElementIn(isLast) {
2578
- const modalRootAsHtmlEl = this.modalRoot; // Get the list of available focusable elements within the modal.
2579
-
2580
- const focusableNodes = Array.from(modalRootAsHtmlEl.querySelectorAll(FOCUSABLE_ELEMENTS));
2581
- const nodeIndex = !isLast ? focusableNodes.length - 1 : 0;
2582
- const focusableNode = focusableNodes[nodeIndex];
2583
- this.tryToFocus(focusableNode);
2584
- }
2585
- /**
2586
- * Triggered when the focus is set to the first sentinel. This way, the
2587
- * focus will be redirected to the last element inside the modal dialog.
2588
- */
2589
-
2590
-
2591
- render() {
2592
- const {
2593
- style
2594
- } = this.props;
2595
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](react__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("div", {
2596
- tabIndex: "0",
2597
- className: "modal-focus-trap-first",
2598
- onFocus: this.handleFocusMoveToLast,
2599
- style: {
2600
- position: "fixed"
2601
- }
2602
- }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__["View"], {
2603
- style: style,
2604
- ref: this.getModalRoot
2605
- }, this.props.children), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("div", {
2606
- tabIndex: "0",
2607
- className: "modal-focus-trap-last",
2608
- onFocus: this.handleFocusMoveToFirst,
2609
- style: {
2610
- position: "fixed"
2611
- }
2612
- }));
2613
- }
2614
-
2615
- }
2616
-
2617
- /***/ }),
2618
- /* 20 */
2619
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
2620
-
2621
- "use strict";
2622
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ModalBackdrop; });
2623
- /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21);
2624
- /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);
2625
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
2626
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
2627
- /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
2628
- /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_2__);
2629
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3);
2630
- /* harmony import */ var aphrodite__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(aphrodite__WEBPACK_IMPORTED_MODULE_3__);
2631
- /* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4);
2632
- /* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4__);
2633
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2);
2634
- /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_5__);
2635
- /* harmony import */ var _util_constants_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(11);
2636
- /* harmony import */ var _util_find_focusable_nodes_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(22);
2637
-
2638
-
2639
-
2640
-
2641
-
2642
-
2643
-
2644
-
2645
-
2646
- /**
2647
- * A private component used by ModalLauncher. This is the fixed-position
2648
- * container element that gets mounted outside the DOM. It overlays the modal
2649
- * content (provided as `children`) over the content, with a gray backdrop
2650
- * behind it.
2651
- *
2652
- * This component is also responsible for cloning the provided modal `children`,
2653
- * and adding an `onClose` prop that will call `onCloseModal`. If an
2654
- * `onClose` prop is already provided, the two are merged.
2655
- */
2656
- class ModalBackdrop extends react__WEBPACK_IMPORTED_MODULE_1__["Component"] {
2657
- constructor(...args) {
2658
- super(...args);
2659
- this._mousePressedOutside = false;
2660
-
2661
- this.handleMouseDown = e => {
2662
- // Confirm that it is the backdrop that is being clicked, not the child
2663
- this._mousePressedOutside = e.target === e.currentTarget;
2664
- };
2665
-
2666
- this.handleMouseUp = e => {
2667
- // Confirm that it is the backdrop that is being clicked, not the child
2668
- // and that the mouse was pressed in the backdrop first.
2669
- if (e.target === e.currentTarget && this._mousePressedOutside) {
2670
- this.props.onCloseModal();
2671
- }
2672
-
2673
- this._mousePressedOutside = false;
2674
- };
2675
- }
2676
-
2677
- componentDidMount() {
2678
- const node = react_dom__WEBPACK_IMPORTED_MODULE_2__["findDOMNode"](this);
2679
-
2680
- if (!node) {
2681
- return;
2682
- }
2683
-
2684
- const firstFocusableElement = // 1. try to get element specified by the user
2685
- this._getInitialFocusElement(node) || // 2. get first occurence from list of focusable elements
2686
- this._getFirstFocusableElement(node) || // 3. get the dialog itself
2687
- this._getDialogElement(node); // wait for styles to applied
2688
-
2689
-
2690
- setTimeout(() => {
2691
- firstFocusableElement.focus();
2692
- }, 0);
2693
- }
2694
-
2695
- /**
2696
- * Returns an element specified by the user
2697
- */
2698
- _getInitialFocusElement(node) {
2699
- const {
2700
- initialFocusId
2701
- } = this.props;
2702
-
2703
- if (!initialFocusId) {
2704
- return null;
2705
- }
2706
-
2707
- return react_dom__WEBPACK_IMPORTED_MODULE_2__["findDOMNode"](node.querySelector(`#${initialFocusId}`));
2708
- }
2709
- /**
2710
- * Returns the first focusable element found inside the Dialog
2711
- */
2712
-
2713
-
2714
- _getFirstFocusableElement(node) {
2715
- // get a collection of elements that can be focused
2716
- const focusableElements = Object(_util_find_focusable_nodes_js__WEBPACK_IMPORTED_MODULE_7__[/* findFocusableNodes */ "a"])(node);
2717
-
2718
- if (!focusableElements) {
2719
- return null;
2720
- } // if found, return the first focusable element
2721
-
2722
-
2723
- return focusableElements[0];
2724
- }
2725
- /**
2726
- * Returns the dialog element
2727
- */
2728
-
2729
-
2730
- _getDialogElement(node) {
2731
- // If no focusable elements are found,
2732
- // the dialog content element itself will receive focus.
2733
- const dialogElement = react_dom__WEBPACK_IMPORTED_MODULE_2__["findDOMNode"](node.querySelector('[role="dialog"]')); // add tabIndex to make the Dialog focusable
2734
-
2735
- dialogElement.tabIndex = -1;
2736
- return dialogElement;
2737
- }
2738
- /**
2739
- * When the user clicks on the gray backdrop area (i.e., the click came
2740
- * _directly_ from the positioner, not bubbled up from its children), close
2741
- * the modal.
2742
- */
2743
-
2744
-
2745
- render() {
2746
- const {
2747
- children,
2748
- testId
2749
- } = this.props;
2750
- const backdropProps = {
2751
- [_util_constants_js__WEBPACK_IMPORTED_MODULE_6__[/* ModalLauncherPortalAttributeName */ "a"]]: true
2752
- };
2753
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_5__["View"], _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default()({
2754
- style: styles.modalPositioner,
2755
- onMouseDown: this.handleMouseDown,
2756
- onMouseUp: this.handleMouseUp,
2757
- testId: testId
2758
- }, backdropProps), children);
2759
- }
2760
-
2761
- }
2762
- const styles = aphrodite__WEBPACK_IMPORTED_MODULE_3__["StyleSheet"].create({
2763
- modalPositioner: {
2764
- position: "fixed",
2765
- left: 0,
2766
- top: 0,
2767
- width: "100%",
2768
- height: "100%",
2769
- alignItems: "center",
2770
- justifyContent: "center",
2771
- // If the modal ends up being too big for the viewport (e.g., the min
2772
- // height is triggered), add another scrollbar specifically for
2773
- // scrolling modal content.
2774
- //
2775
- // TODO(mdr): The specified behavior is that the modal should scroll
2776
- // with the rest of the page, rather than separately, if overflow
2777
- // turns out to be necessary. That sounds hard to do; punting for
2778
- // now!
2779
- overflow: "auto",
2780
- background: _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_4___default.a.offBlack64
2781
- }
2782
- });
2783
-
2784
- /***/ }),
2785
- /* 21 */
2786
- /***/ (function(module, exports) {
2787
-
2788
- function _extends() {
2789
- module.exports = _extends = Object.assign ? Object.assign.bind() : function (target) {
2790
- for (var i = 1; i < arguments.length; i++) {
2791
- var source = arguments[i];
2792
- for (var key in source) {
2793
- if (Object.prototype.hasOwnProperty.call(source, key)) {
2794
- target[key] = source[key];
2795
- }
2796
- }
2797
- }
2798
- return target;
2799
- }, module.exports.__esModule = true, module.exports["default"] = module.exports;
2800
- return _extends.apply(this, arguments);
2801
- }
2802
- module.exports = _extends, module.exports.__esModule = true, module.exports["default"] = module.exports;
2803
-
2804
- /***/ }),
2805
- /* 22 */
2806
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
2807
-
2808
- "use strict";
2809
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return findFocusableNodes; });
2810
- /**
2811
- * List of elements that can be focused
2812
- * @see https://www.w3.org/TR/html5/editing.html#can-be-focused
2813
- */
2814
- const FOCUSABLE_ELEMENTS = 'a[href], details, input, textarea, select, button:not([aria-label^="Close"])';
2815
- function findFocusableNodes(root) {
2816
- return Array.from(root.querySelectorAll(FOCUSABLE_ELEMENTS));
2817
- }
2818
-
2819
- /***/ }),
2820
- /* 23 */
2821
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
2822
-
2823
- "use strict";
2824
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
2825
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
2826
- /**
2827
- * A UI-less component that lets `ModalLauncher` disable page scroll.
2828
- *
2829
- * The positioning of the modal requires some global page state changed
2830
- * unfortunately, and this handles that in an encapsulated way.
2831
- *
2832
- * NOTE(mdr): This component was copied from webapp. Be wary of sync issues. It
2833
- * also doesn't have unit tests, and we haven't added any, since it's a
2834
- * relatively stable component that has now been stress-tested lots in prod.
2835
- */
2836
-
2837
-
2838
- const needsHackyMobileSafariScrollDisabler = (() => {
2839
- if (typeof window === "undefined") {
2840
- return false;
2841
- }
2842
-
2843
- const userAgent = window.navigator.userAgent;
2844
- return userAgent.indexOf("iPad") > -1 || userAgent.indexOf("iPhone") > -1;
2845
- })();
2846
-
2847
- class ScrollDisabler extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
2848
- componentDidMount() {
2849
- if (ScrollDisabler.numModalsOpened === 0) {
2850
- const body = document.body;
2851
-
2852
- if (!body) {
2853
- throw new Error("couldn't find document.body");
2854
- } // Prevent scrolling of the background, the first time a modal is
2855
- // opened.
2856
-
2857
-
2858
- ScrollDisabler.oldOverflow = body.style.overflow;
2859
- ScrollDisabler.oldScrollY = window.scrollY; // We need to grab all of the original style properties before we
2860
- // modified any of them.
2861
-
2862
- if (needsHackyMobileSafariScrollDisabler) {
2863
- ScrollDisabler.oldPosition = body.style.position;
2864
- ScrollDisabler.oldWidth = body.style.width;
2865
- ScrollDisabler.oldTop = body.style.top;
2866
- }
2867
-
2868
- body.style.overflow = "hidden"; // On mobile Safari, overflow: hidden is not enough, position:
2869
- // fixed is also required. Setting style.top = -scollTop maintains
2870
- // the scroll position (without which we'd scroll to the top).
2871
-
2872
- if (needsHackyMobileSafariScrollDisabler) {
2873
- body.style.position = "fixed";
2874
- body.style.width = "100%";
2875
- body.style.top = `${-ScrollDisabler.oldScrollY}px`;
2876
- }
2877
- }
2878
-
2879
- ScrollDisabler.numModalsOpened++;
2880
- }
2881
-
2882
- componentWillUnmount() {
2883
- ScrollDisabler.numModalsOpened--;
2884
-
2885
- if (ScrollDisabler.numModalsOpened === 0) {
2886
- const body = document.body;
2887
-
2888
- if (!body) {
2889
- throw new Error("couldn't find document.body");
2890
- } // Reset all values on the closing of the final modal.
2891
-
2892
-
2893
- body.style.overflow = ScrollDisabler.oldOverflow;
2894
-
2895
- if (needsHackyMobileSafariScrollDisabler) {
2896
- body.style.position = ScrollDisabler.oldPosition;
2897
- body.style.width = ScrollDisabler.oldWidth;
2898
- body.style.top = ScrollDisabler.oldTop;
2899
- }
2900
-
2901
- if (typeof window !== "undefined" && window.scrollTo) {
2902
- window.scrollTo(0, ScrollDisabler.oldScrollY);
2903
- }
2904
- }
2905
- }
2906
-
2907
- render() {
2908
- return null;
2909
- }
2910
-
2911
- }
2912
-
2913
- ScrollDisabler.numModalsOpened = 0;
2914
- /* harmony default export */ __webpack_exports__["a"] = (ScrollDisabler);
2915
-
2916
- /***/ }),
2917
- /* 24 */
2918
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
2919
-
2920
- "use strict";
2921
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return CloseButton; });
2922
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
2923
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
2924
- /* harmony import */ var _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25);
2925
- /* harmony import */ var _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1__);
2926
- /* harmony import */ var _khanacademy_wonder_blocks_icon_button__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(26);
2927
- /* 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__);
2928
- /* harmony import */ var _modal_context_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(12);
2929
-
2930
-
2931
-
2932
-
2933
- class CloseButton extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
2934
- render() {
2935
- const {
2936
- light,
2937
- onClick,
2938
- style,
2939
- testId
2940
- } = this.props;
2941
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_modal_context_js__WEBPACK_IMPORTED_MODULE_3__[/* default */ "a"].Consumer, null, ({
2942
- closeModal
2943
- }) => {
2944
- if (closeModal && onClick) {
2945
- throw new Error("You've specified 'onClose' on a modal when using ModalLauncher. Please specify 'onClose' on the ModalLauncher instead");
2946
- }
2947
-
2948
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_icon_button__WEBPACK_IMPORTED_MODULE_2___default.a, {
2949
- icon: _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_1__["icons"].dismiss // TODO(mdr): Translate this string for i18n.
2950
- // TODO(kevinb): provide a way to set this label
2951
- ,
2952
- "aria-label": "Close modal",
2953
- onClick: onClick || closeModal,
2954
- kind: light ? "primary" : "tertiary",
2955
- light: light,
2956
- style: style,
2957
- testId: testId
2958
- });
2959
- });
2960
- }
2961
-
2962
- }
2963
-
2964
- /***/ }),
2965
- /* 25 */
2966
- /***/ (function(module, exports) {
2967
-
2968
- module.exports = require("@khanacademy/wonder-blocks-icon");
2969
-
2970
- /***/ }),
2971
- /* 26 */
2972
- /***/ (function(module, exports) {
2973
-
2974
- module.exports = require("@khanacademy/wonder-blocks-icon-button");
2975
-
2976
- /***/ }),
2977
- /* 27 */
2978
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
2979
-
2980
- "use strict";
2981
- __webpack_require__.r(__webpack_exports__);
2982
- /* harmony import */ var _components_modal_dialog_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9);
2983
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalDialog", function() { return _components_modal_dialog_js__WEBPACK_IMPORTED_MODULE_0__["a"]; });
2984
-
2985
- /* harmony import */ var _components_modal_footer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
2986
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalFooter", function() { return _components_modal_footer_js__WEBPACK_IMPORTED_MODULE_1__["a"]; });
2987
-
2988
- /* harmony import */ var _components_modal_header_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
2989
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalHeader", function() { return _components_modal_header_js__WEBPACK_IMPORTED_MODULE_2__["a"]; });
2990
-
2991
- /* harmony import */ var _components_modal_launcher_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(15);
2992
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalLauncher", function() { return _components_modal_launcher_js__WEBPACK_IMPORTED_MODULE_3__["a"]; });
2993
-
2994
- /* harmony import */ var _components_modal_panel_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
2995
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModalPanel", function() { return _components_modal_panel_js__WEBPACK_IMPORTED_MODULE_4__["a"]; });
2996
-
2997
- /* harmony import */ var _components_one_pane_dialog_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(16);
2998
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OnePaneDialog", function() { return _components_one_pane_dialog_js__WEBPACK_IMPORTED_MODULE_5__["a"]; });
2999
-
3000
- /* harmony import */ var _util_maybe_get_portal_mounted_modal_host_element_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(17);
3001
- /* 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"]; });
3002
-
3003
-
3004
-
3005
-
3006
-
3007
-
3008
-
3009
-
3010
-
3011
-
3012
- /***/ })
3013
- /******/ ]);