@khanacademy/wonder-blocks-modal 3.0.7 → 3.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/components/close-button.d.ts +31 -0
- package/dist/components/close-button.js.flow +43 -0
- package/dist/components/focus-trap.d.ts +57 -0
- package/dist/components/focus-trap.js.flow +69 -0
- package/dist/components/modal-backdrop.d.ts +50 -0
- package/dist/components/modal-backdrop.js.flow +63 -0
- package/dist/components/modal-content.d.ts +23 -0
- package/dist/components/modal-content.js.flow +39 -0
- package/dist/components/modal-context.d.ts +6 -0
- package/dist/components/modal-context.js.flow +14 -0
- package/dist/components/modal-dialog.d.ts +60 -0
- package/dist/components/modal-dialog.js.flow +75 -0
- package/dist/components/modal-footer.d.ts +27 -0
- package/dist/components/modal-footer.js.flow +34 -0
- package/dist/components/modal-header.d.ts +93 -0
- package/dist/components/modal-header.js.flow +110 -0
- package/dist/components/modal-launcher.d.ts +17 -0
- package/dist/components/modal-launcher.js.flow +34 -0
- package/dist/components/modal-panel.d.ts +84 -0
- package/dist/components/modal-panel.js.flow +102 -0
- package/dist/components/one-pane-dialog.d.ts +124 -0
- package/dist/components/one-pane-dialog.js.flow +153 -0
- package/dist/components/scroll-disabler.d.ts +24 -0
- package/dist/components/scroll-disabler.js.flow +21 -0
- package/dist/es/index.js +222 -210
- package/dist/index.d.ts +8 -0
- package/dist/index.js +237 -226
- package/dist/index.js.flow +23 -2
- package/dist/util/constants.d.ts +5 -0
- package/dist/util/constants.js.flow +12 -0
- package/dist/util/find-focusable-nodes.d.ts +1 -0
- package/dist/util/find-focusable-nodes.js.flow +10 -0
- package/dist/util/maybe-get-portal-mounted-modal-host-element.d.ts +9 -0
- package/dist/util/maybe-get-portal-mounted-modal-host-element.js.flow +18 -0
- package/dist/util/types.d.ts +12 -0
- package/dist/util/types.js.flow +20 -0
- package/package.json +13 -13
- package/src/components/__tests__/{close-button.test.js → close-button.test.tsx} +0 -1
- package/src/components/__tests__/{focus-trap.test.js → focus-trap.test.tsx} +0 -1
- package/src/components/__tests__/{modal-backdrop.test.js → modal-backdrop.test.tsx} +0 -1
- package/src/components/__tests__/{modal-header.test.js → modal-header.test.tsx} +3 -2
- package/src/components/__tests__/{modal-launcher.test.js → modal-launcher.test.tsx} +11 -15
- package/src/components/__tests__/{modal-panel.test.js → modal-panel.test.tsx} +0 -1
- package/src/components/__tests__/{one-pane-dialog.test.js → one-pane-dialog.test.tsx} +0 -1
- package/src/components/{close-button.js → close-button.tsx} +7 -11
- package/src/components/{focus-trap.js → focus-trap.tsx} +12 -12
- package/src/components/{modal-backdrop.js → modal-backdrop.tsx} +20 -18
- package/src/components/{modal-content.js → modal-content.tsx} +11 -12
- package/src/components/modal-context.ts +13 -0
- package/src/components/{modal-dialog.js → modal-dialog.tsx} +15 -23
- package/src/components/{modal-footer.js → modal-footer.tsx} +5 -6
- package/src/components/{modal-header.js → modal-header.tsx} +20 -26
- package/src/components/{modal-launcher.js → modal-launcher.tsx} +29 -50
- package/src/components/{modal-panel.js → modal-panel.tsx} +27 -28
- package/src/components/{one-pane-dialog.js → one-pane-dialog.tsx} +37 -45
- package/src/components/{scroll-disabler.js → scroll-disabler.ts} +3 -4
- package/src/{index.js → index.ts} +0 -1
- package/src/util/{constants.js → constants.ts} +0 -2
- package/src/util/{find-focusable-nodes.js → find-focusable-nodes.ts} +0 -2
- package/src/util/{maybe-get-portal-mounted-modal-host-element.test.js → maybe-get-portal-mounted-modal-host-element.test.tsx} +4 -5
- package/src/util/{maybe-get-portal-mounted-modal-host-element.js → maybe-get-portal-mounted-modal-host-element.ts} +5 -4
- package/src/util/{types.js → types.ts} +3 -2
- package/tsconfig.json +20 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/src/components/__docs__/modal-dialog.stories.js +0 -308
- package/src/components/__docs__/modal-footer.stories.js +0 -337
- package/src/components/__docs__/modal-header.argtypes.js +0 -76
- package/src/components/__docs__/modal-header.stories.js +0 -294
- package/src/components/__docs__/modal-launcher.argtypes.js +0 -78
- package/src/components/__docs__/modal-launcher.stories.js +0 -513
- package/src/components/__docs__/modal-panel.stories.js +0 -414
- package/src/components/__docs__/one-pane-dialog.argtypes.js +0 -108
- package/src/components/__docs__/one-pane-dialog.stories.js +0 -582
- package/src/components/modal-context.js +0 -14
package/dist/es/index.js
CHANGED
|
@@ -7,12 +7,30 @@ import Color from '@khanacademy/wonder-blocks-color';
|
|
|
7
7
|
import { HeadingMedium, LabelSmall } from '@khanacademy/wonder-blocks-typography';
|
|
8
8
|
import * as ReactDOM from 'react-dom';
|
|
9
9
|
import { withActionScheduler } from '@khanacademy/wonder-blocks-timing';
|
|
10
|
-
import _extends from '@babel/runtime/helpers/extends';
|
|
11
10
|
import { icons } from '@khanacademy/wonder-blocks-icon';
|
|
12
11
|
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
function _setPrototypeOf(o, p) {
|
|
14
|
+
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
|
|
15
|
+
o.__proto__ = p;
|
|
16
|
+
return o;
|
|
17
|
+
};
|
|
18
|
+
return _setPrototypeOf(o, p);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function _inheritsLoose(subClass, superClass) {
|
|
22
|
+
subClass.prototype = Object.create(superClass.prototype);
|
|
23
|
+
subClass.prototype.constructor = subClass;
|
|
24
|
+
_setPrototypeOf(subClass, superClass);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let ModalDialog = function (_React$Component) {
|
|
28
|
+
_inheritsLoose(ModalDialog, _React$Component);
|
|
29
|
+
function ModalDialog() {
|
|
30
|
+
return _React$Component.apply(this, arguments) || this;
|
|
31
|
+
}
|
|
32
|
+
var _proto = ModalDialog.prototype;
|
|
33
|
+
_proto.render = function render() {
|
|
16
34
|
const {
|
|
17
35
|
above,
|
|
18
36
|
below,
|
|
@@ -47,9 +65,9 @@ class ModalDialog extends React.Component {
|
|
|
47
65
|
}, children), above && React.createElement(View, {
|
|
48
66
|
style: styles.above
|
|
49
67
|
}, above))));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
}
|
|
68
|
+
};
|
|
69
|
+
return ModalDialog;
|
|
70
|
+
}(React.Component);
|
|
53
71
|
ModalDialog.defaultProps = {
|
|
54
72
|
role: "dialog"
|
|
55
73
|
};
|
|
@@ -96,21 +114,25 @@ const styleSheets$3 = {
|
|
|
96
114
|
})
|
|
97
115
|
};
|
|
98
116
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
let ModalFooter = function (_React$Component) {
|
|
118
|
+
_inheritsLoose(ModalFooter, _React$Component);
|
|
119
|
+
function ModalFooter() {
|
|
120
|
+
return _React$Component.apply(this, arguments) || this;
|
|
102
121
|
}
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
ModalFooter.isClassOf = function isClassOf(instance) {
|
|
123
|
+
return instance && instance.type && instance.type.__IS_MODAL_FOOTER__;
|
|
124
|
+
};
|
|
125
|
+
var _proto = ModalFooter.prototype;
|
|
126
|
+
_proto.render = function render() {
|
|
105
127
|
const {
|
|
106
128
|
children
|
|
107
129
|
} = this.props;
|
|
108
130
|
return React.createElement(View, {
|
|
109
131
|
style: styles$3.footer
|
|
110
132
|
}, children);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
}
|
|
133
|
+
};
|
|
134
|
+
return ModalFooter;
|
|
135
|
+
}(React.Component);
|
|
114
136
|
ModalFooter.__IS_MODAL_FOOTER__ = true;
|
|
115
137
|
const styles$3 = StyleSheet.create({
|
|
116
138
|
footer: {
|
|
@@ -129,8 +151,13 @@ const styles$3 = StyleSheet.create({
|
|
|
129
151
|
}
|
|
130
152
|
});
|
|
131
153
|
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
let ModalHeader = function (_React$Component) {
|
|
155
|
+
_inheritsLoose(ModalHeader, _React$Component);
|
|
156
|
+
function ModalHeader() {
|
|
157
|
+
return _React$Component.apply(this, arguments) || this;
|
|
158
|
+
}
|
|
159
|
+
var _proto = ModalHeader.prototype;
|
|
160
|
+
_proto.render = function render() {
|
|
134
161
|
const {
|
|
135
162
|
breadcrumbs = undefined,
|
|
136
163
|
light,
|
|
@@ -139,11 +166,9 @@ class ModalHeader extends React.Component {
|
|
|
139
166
|
title,
|
|
140
167
|
titleId
|
|
141
168
|
} = this.props;
|
|
142
|
-
|
|
143
169
|
if (subtitle && breadcrumbs) {
|
|
144
170
|
throw new Error("'subtitle' and 'breadcrumbs' can't be used together");
|
|
145
171
|
}
|
|
146
|
-
|
|
147
172
|
return React.createElement(MediaLayout, {
|
|
148
173
|
styleSheets: styleSheets$2
|
|
149
174
|
}, ({
|
|
@@ -161,9 +186,9 @@ class ModalHeader extends React.Component {
|
|
|
161
186
|
style: light && styles.subtitle,
|
|
162
187
|
testId: testId && `${testId}-subtitle`
|
|
163
188
|
}, subtitle)));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
}
|
|
189
|
+
};
|
|
190
|
+
return ModalHeader;
|
|
191
|
+
}(React.Component);
|
|
167
192
|
ModalHeader.defaultProps = {
|
|
168
193
|
light: true
|
|
169
194
|
};
|
|
@@ -206,52 +231,47 @@ const styleSheets$2 = {
|
|
|
206
231
|
};
|
|
207
232
|
|
|
208
233
|
const FOCUSABLE_ELEMENTS$1 = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
234
|
+
let FocusTrap = function (_React$Component) {
|
|
235
|
+
_inheritsLoose(FocusTrap, _React$Component);
|
|
236
|
+
function FocusTrap(...args) {
|
|
237
|
+
var _this;
|
|
238
|
+
_this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
|
|
239
|
+
_this.modalRoot = void 0;
|
|
240
|
+
_this.getModalRoot = node => {
|
|
214
241
|
if (!node) {
|
|
215
242
|
return;
|
|
216
243
|
}
|
|
217
|
-
|
|
218
244
|
const modalRoot = ReactDOM.findDOMNode(node);
|
|
219
|
-
|
|
220
245
|
if (!modalRoot) {
|
|
221
246
|
throw new Error("Assertion error: modal root should exist after mount");
|
|
222
247
|
}
|
|
223
|
-
|
|
224
|
-
this.modalRoot = modalRoot;
|
|
248
|
+
_this.modalRoot = modalRoot;
|
|
225
249
|
};
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
this.focusElementIn(false);
|
|
250
|
+
_this.handleFocusMoveToLast = () => {
|
|
251
|
+
_this.focusElementIn(false);
|
|
229
252
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
this.focusElementIn(true);
|
|
253
|
+
_this.handleFocusMoveToFirst = () => {
|
|
254
|
+
_this.focusElementIn(true);
|
|
233
255
|
};
|
|
256
|
+
return _this;
|
|
234
257
|
}
|
|
235
|
-
|
|
236
|
-
tryToFocus(node) {
|
|
258
|
+
var _proto = FocusTrap.prototype;
|
|
259
|
+
_proto.tryToFocus = function tryToFocus(node) {
|
|
237
260
|
if (node instanceof HTMLElement) {
|
|
238
261
|
try {
|
|
239
262
|
node.focus();
|
|
240
263
|
} catch (e) {}
|
|
241
|
-
|
|
242
264
|
return document.activeElement === node;
|
|
243
265
|
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
focusElementIn(isLast) {
|
|
266
|
+
};
|
|
267
|
+
_proto.focusElementIn = function focusElementIn(isLast) {
|
|
247
268
|
const modalRootAsHtmlEl = this.modalRoot;
|
|
248
269
|
const focusableNodes = Array.from(modalRootAsHtmlEl.querySelectorAll(FOCUSABLE_ELEMENTS$1));
|
|
249
270
|
const nodeIndex = !isLast ? focusableNodes.length - 1 : 0;
|
|
250
271
|
const focusableNode = focusableNodes[nodeIndex];
|
|
251
272
|
this.tryToFocus(focusableNode);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
render() {
|
|
273
|
+
};
|
|
274
|
+
_proto.render = function render() {
|
|
255
275
|
const {
|
|
256
276
|
style
|
|
257
277
|
} = this.props;
|
|
@@ -273,8 +293,23 @@ class FocusTrap extends React.Component {
|
|
|
273
293
|
position: "fixed"
|
|
274
294
|
}
|
|
275
295
|
}));
|
|
276
|
-
}
|
|
277
|
-
|
|
296
|
+
};
|
|
297
|
+
return FocusTrap;
|
|
298
|
+
}(React.Component);
|
|
299
|
+
|
|
300
|
+
function _extends() {
|
|
301
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
302
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
303
|
+
var source = arguments[i];
|
|
304
|
+
for (var key in source) {
|
|
305
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
306
|
+
target[key] = source[key];
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return target;
|
|
311
|
+
};
|
|
312
|
+
return _extends.apply(this, arguments);
|
|
278
313
|
}
|
|
279
314
|
|
|
280
315
|
const ModalLauncherPortalAttributeName = "data-modal-launcher-portal";
|
|
@@ -284,67 +319,56 @@ function findFocusableNodes(root) {
|
|
|
284
319
|
return Array.from(root.querySelectorAll(FOCUSABLE_ELEMENTS));
|
|
285
320
|
}
|
|
286
321
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
322
|
+
let ModalBackdrop = function (_React$Component) {
|
|
323
|
+
_inheritsLoose(ModalBackdrop, _React$Component);
|
|
324
|
+
function ModalBackdrop(...args) {
|
|
325
|
+
var _this;
|
|
326
|
+
_this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
|
|
327
|
+
_this._mousePressedOutside = false;
|
|
328
|
+
_this.handleMouseDown = e => {
|
|
329
|
+
_this._mousePressedOutside = e.target === e.currentTarget;
|
|
294
330
|
};
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
this.props.onCloseModal();
|
|
331
|
+
_this.handleMouseUp = e => {
|
|
332
|
+
if (e.target === e.currentTarget && _this._mousePressedOutside) {
|
|
333
|
+
_this.props.onCloseModal();
|
|
299
334
|
}
|
|
300
|
-
|
|
301
|
-
this._mousePressedOutside = false;
|
|
335
|
+
_this._mousePressedOutside = false;
|
|
302
336
|
};
|
|
337
|
+
return _this;
|
|
303
338
|
}
|
|
304
|
-
|
|
305
|
-
componentDidMount() {
|
|
339
|
+
var _proto = ModalBackdrop.prototype;
|
|
340
|
+
_proto.componentDidMount = function componentDidMount() {
|
|
306
341
|
const node = ReactDOM.findDOMNode(this);
|
|
307
|
-
|
|
308
342
|
if (!node) {
|
|
309
343
|
return;
|
|
310
344
|
}
|
|
311
|
-
|
|
312
345
|
const firstFocusableElement = this._getInitialFocusElement(node) || this._getFirstFocusableElement(node) || this._getDialogElement(node);
|
|
313
|
-
|
|
314
346
|
setTimeout(() => {
|
|
315
347
|
firstFocusableElement.focus();
|
|
316
348
|
}, 0);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
_getInitialFocusElement(node) {
|
|
349
|
+
};
|
|
350
|
+
_proto._getInitialFocusElement = function _getInitialFocusElement(node) {
|
|
320
351
|
const {
|
|
321
352
|
initialFocusId
|
|
322
353
|
} = this.props;
|
|
323
|
-
|
|
324
354
|
if (!initialFocusId) {
|
|
325
355
|
return null;
|
|
326
356
|
}
|
|
327
|
-
|
|
328
357
|
return ReactDOM.findDOMNode(node.querySelector(`#${initialFocusId}`));
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
_getFirstFocusableElement(node) {
|
|
358
|
+
};
|
|
359
|
+
_proto._getFirstFocusableElement = function _getFirstFocusableElement(node) {
|
|
332
360
|
const focusableElements = findFocusableNodes(node);
|
|
333
|
-
|
|
334
361
|
if (!focusableElements) {
|
|
335
362
|
return null;
|
|
336
363
|
}
|
|
337
|
-
|
|
338
364
|
return focusableElements[0];
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
_getDialogElement(node) {
|
|
365
|
+
};
|
|
366
|
+
_proto._getDialogElement = function _getDialogElement(node) {
|
|
342
367
|
const dialogElement = ReactDOM.findDOMNode(node.querySelector('[role="dialog"]'));
|
|
343
368
|
dialogElement.tabIndex = -1;
|
|
344
369
|
return dialogElement;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
render() {
|
|
370
|
+
};
|
|
371
|
+
_proto.render = function render() {
|
|
348
372
|
const {
|
|
349
373
|
children,
|
|
350
374
|
testId
|
|
@@ -358,9 +382,9 @@ class ModalBackdrop extends React.Component {
|
|
|
358
382
|
onMouseUp: this.handleMouseUp,
|
|
359
383
|
testId: testId
|
|
360
384
|
}, backdropProps), children);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
}
|
|
385
|
+
};
|
|
386
|
+
return ModalBackdrop;
|
|
387
|
+
}(React.Component);
|
|
364
388
|
const styles$2 = StyleSheet.create({
|
|
365
389
|
modalPositioner: {
|
|
366
390
|
position: "fixed",
|
|
@@ -379,71 +403,65 @@ const needsHackyMobileSafariScrollDisabler = (() => {
|
|
|
379
403
|
if (typeof window === "undefined") {
|
|
380
404
|
return false;
|
|
381
405
|
}
|
|
382
|
-
|
|
383
406
|
const userAgent = window.navigator.userAgent;
|
|
384
407
|
return userAgent.indexOf("iPad") > -1 || userAgent.indexOf("iPhone") > -1;
|
|
385
408
|
})();
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
409
|
+
let ScrollDisabler = function (_React$Component) {
|
|
410
|
+
_inheritsLoose(ScrollDisabler, _React$Component);
|
|
411
|
+
function ScrollDisabler() {
|
|
412
|
+
return _React$Component.apply(this, arguments) || this;
|
|
413
|
+
}
|
|
414
|
+
var _proto = ScrollDisabler.prototype;
|
|
415
|
+
_proto.componentDidMount = function componentDidMount() {
|
|
389
416
|
if (ScrollDisabler.numModalsOpened === 0) {
|
|
390
417
|
const body = document.body;
|
|
391
|
-
|
|
392
418
|
if (!body) {
|
|
393
419
|
throw new Error("couldn't find document.body");
|
|
394
420
|
}
|
|
395
|
-
|
|
396
421
|
ScrollDisabler.oldOverflow = body.style.overflow;
|
|
397
422
|
ScrollDisabler.oldScrollY = window.scrollY;
|
|
398
|
-
|
|
399
423
|
if (needsHackyMobileSafariScrollDisabler) {
|
|
400
424
|
ScrollDisabler.oldPosition = body.style.position;
|
|
401
425
|
ScrollDisabler.oldWidth = body.style.width;
|
|
402
426
|
ScrollDisabler.oldTop = body.style.top;
|
|
403
427
|
}
|
|
404
|
-
|
|
405
428
|
body.style.overflow = "hidden";
|
|
406
|
-
|
|
407
429
|
if (needsHackyMobileSafariScrollDisabler) {
|
|
408
430
|
body.style.position = "fixed";
|
|
409
431
|
body.style.width = "100%";
|
|
410
432
|
body.style.top = `${-ScrollDisabler.oldScrollY}px`;
|
|
411
433
|
}
|
|
412
434
|
}
|
|
413
|
-
|
|
414
435
|
ScrollDisabler.numModalsOpened++;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
componentWillUnmount() {
|
|
436
|
+
};
|
|
437
|
+
_proto.componentWillUnmount = function componentWillUnmount() {
|
|
418
438
|
ScrollDisabler.numModalsOpened--;
|
|
419
|
-
|
|
420
439
|
if (ScrollDisabler.numModalsOpened === 0) {
|
|
421
440
|
const body = document.body;
|
|
422
|
-
|
|
423
441
|
if (!body) {
|
|
424
442
|
throw new Error("couldn't find document.body");
|
|
425
443
|
}
|
|
426
|
-
|
|
427
444
|
body.style.overflow = ScrollDisabler.oldOverflow;
|
|
428
|
-
|
|
429
445
|
if (needsHackyMobileSafariScrollDisabler) {
|
|
430
446
|
body.style.position = ScrollDisabler.oldPosition;
|
|
431
447
|
body.style.width = ScrollDisabler.oldWidth;
|
|
432
448
|
body.style.top = ScrollDisabler.oldTop;
|
|
433
449
|
}
|
|
434
|
-
|
|
435
450
|
if (typeof window !== "undefined" && window.scrollTo) {
|
|
436
451
|
window.scrollTo(0, ScrollDisabler.oldScrollY);
|
|
437
452
|
}
|
|
438
453
|
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
render() {
|
|
454
|
+
};
|
|
455
|
+
_proto.render = function render() {
|
|
442
456
|
return null;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
|
|
457
|
+
};
|
|
458
|
+
return ScrollDisabler;
|
|
459
|
+
}(React.Component);
|
|
460
|
+
ScrollDisabler.oldOverflow = void 0;
|
|
461
|
+
ScrollDisabler.oldPosition = void 0;
|
|
462
|
+
ScrollDisabler.oldScrollY = void 0;
|
|
463
|
+
ScrollDisabler.oldWidth = void 0;
|
|
464
|
+
ScrollDisabler.oldTop = void 0;
|
|
447
465
|
ScrollDisabler.numModalsOpened = 0;
|
|
448
466
|
|
|
449
467
|
const defaultContext = {
|
|
@@ -451,35 +469,32 @@ const defaultContext = {
|
|
|
451
469
|
};
|
|
452
470
|
var ModalContext = React.createContext(defaultContext);
|
|
453
471
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
472
|
+
let ModalLauncher = function (_React$Component) {
|
|
473
|
+
_inheritsLoose(ModalLauncher, _React$Component);
|
|
474
|
+
function ModalLauncher(...args) {
|
|
475
|
+
var _this;
|
|
476
|
+
_this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
|
|
477
|
+
_this.lastElementFocusedOutsideModal = void 0;
|
|
478
|
+
_this.state = {
|
|
458
479
|
opened: false
|
|
459
480
|
};
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
this.lastElementFocusedOutsideModal = document.activeElement;
|
|
481
|
+
_this._saveLastElementFocused = () => {
|
|
482
|
+
_this.lastElementFocusedOutsideModal = document.activeElement;
|
|
463
483
|
};
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
this.setState({
|
|
484
|
+
_this._openModal = () => {
|
|
485
|
+
_this._saveLastElementFocused();
|
|
486
|
+
_this.setState({
|
|
469
487
|
opened: true
|
|
470
488
|
});
|
|
471
489
|
};
|
|
472
|
-
|
|
473
|
-
this._returnFocus = () => {
|
|
490
|
+
_this._returnFocus = () => {
|
|
474
491
|
const {
|
|
475
492
|
closedFocusId,
|
|
476
493
|
schedule
|
|
477
|
-
} =
|
|
478
|
-
const lastElement =
|
|
479
|
-
|
|
494
|
+
} = _this.props;
|
|
495
|
+
const lastElement = _this.lastElementFocusedOutsideModal;
|
|
480
496
|
if (closedFocusId) {
|
|
481
497
|
const focusElement = ReactDOM.findDOMNode(document.getElementById(closedFocusId));
|
|
482
|
-
|
|
483
498
|
if (focusElement) {
|
|
484
499
|
schedule.animationFrame(() => {
|
|
485
500
|
focusElement.focus();
|
|
@@ -487,53 +502,46 @@ class ModalLauncher extends React.Component {
|
|
|
487
502
|
return;
|
|
488
503
|
}
|
|
489
504
|
}
|
|
490
|
-
|
|
491
505
|
if (lastElement != null) {
|
|
492
506
|
schedule.animationFrame(() => {
|
|
493
507
|
lastElement.focus();
|
|
494
508
|
});
|
|
495
509
|
}
|
|
496
510
|
};
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
this.setState({
|
|
511
|
+
_this.handleCloseModal = () => {
|
|
512
|
+
_this.setState({
|
|
500
513
|
opened: false
|
|
501
514
|
}, () => {
|
|
502
515
|
const {
|
|
503
516
|
onClose
|
|
504
|
-
} =
|
|
505
|
-
onClose
|
|
506
|
-
|
|
507
|
-
this._returnFocus();
|
|
517
|
+
} = _this.props;
|
|
518
|
+
onClose == null ? void 0 : onClose();
|
|
519
|
+
_this._returnFocus();
|
|
508
520
|
});
|
|
509
521
|
};
|
|
522
|
+
return _this;
|
|
510
523
|
}
|
|
511
|
-
|
|
512
|
-
static getDerivedStateFromProps(props, state) {
|
|
524
|
+
ModalLauncher.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {
|
|
513
525
|
if (typeof props.opened === "boolean" && props.children) {
|
|
514
526
|
console.warn("'children' and 'opened' can't be used together");
|
|
515
527
|
}
|
|
516
|
-
|
|
517
528
|
if (typeof props.opened === "boolean" && !props.onClose) {
|
|
518
529
|
console.warn("'onClose' should be used with 'opened'");
|
|
519
530
|
}
|
|
520
|
-
|
|
521
531
|
if (typeof props.opened !== "boolean" && !props.children) {
|
|
522
532
|
console.warn("either 'children' or 'opened' must be set");
|
|
523
533
|
}
|
|
524
|
-
|
|
525
534
|
return {
|
|
526
535
|
opened: typeof props.opened === "boolean" ? props.opened : state.opened
|
|
527
536
|
};
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
componentDidUpdate(prevProps) {
|
|
537
|
+
};
|
|
538
|
+
var _proto = ModalLauncher.prototype;
|
|
539
|
+
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
|
|
531
540
|
if (!prevProps.opened && this.props.opened) {
|
|
532
541
|
this._saveLastElementFocused();
|
|
533
542
|
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
_renderModal() {
|
|
543
|
+
};
|
|
544
|
+
_proto._renderModal = function _renderModal() {
|
|
537
545
|
if (typeof this.props.modal === "function") {
|
|
538
546
|
return this.props.modal({
|
|
539
547
|
closeModal: this.handleCloseModal
|
|
@@ -541,20 +549,17 @@ class ModalLauncher extends React.Component {
|
|
|
541
549
|
} else {
|
|
542
550
|
return this.props.modal;
|
|
543
551
|
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
render() {
|
|
552
|
+
};
|
|
553
|
+
_proto.render = function render() {
|
|
547
554
|
const renderedChildren = this.props.children ? this.props.children({
|
|
548
555
|
openModal: this._openModal
|
|
549
556
|
}) : null;
|
|
550
557
|
const {
|
|
551
558
|
body
|
|
552
559
|
} = document;
|
|
553
|
-
|
|
554
560
|
if (!body) {
|
|
555
561
|
return null;
|
|
556
562
|
}
|
|
557
|
-
|
|
558
563
|
return React.createElement(ModalContext.Provider, {
|
|
559
564
|
value: {
|
|
560
565
|
closeModal: this.handleCloseModal
|
|
@@ -568,41 +573,38 @@ class ModalLauncher extends React.Component {
|
|
|
568
573
|
}, this._renderModal())), body), this.state.opened && React.createElement(ModalLauncherKeypressListener, {
|
|
569
574
|
onClose: this.handleCloseModal
|
|
570
575
|
}), this.state.opened && React.createElement(ScrollDisabler, null));
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
|
|
576
|
+
};
|
|
577
|
+
return ModalLauncher;
|
|
578
|
+
}(React.Component);
|
|
575
579
|
ModalLauncher.defaultProps = {
|
|
576
580
|
backdropDismissEnabled: true
|
|
577
581
|
};
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
582
|
+
let ModalLauncherKeypressListener = function (_React$Component2) {
|
|
583
|
+
_inheritsLoose(ModalLauncherKeypressListener, _React$Component2);
|
|
584
|
+
function ModalLauncherKeypressListener(...args) {
|
|
585
|
+
var _this2;
|
|
586
|
+
_this2 = _React$Component2.call.apply(_React$Component2, [this].concat(args)) || this;
|
|
587
|
+
_this2._handleKeyup = e => {
|
|
584
588
|
if (e.key === "Escape") {
|
|
585
589
|
e.preventDefault();
|
|
586
590
|
e.stopPropagation();
|
|
587
|
-
|
|
591
|
+
_this2.props.onClose();
|
|
588
592
|
}
|
|
589
593
|
};
|
|
594
|
+
return _this2;
|
|
590
595
|
}
|
|
591
|
-
|
|
592
|
-
componentDidMount() {
|
|
596
|
+
var _proto2 = ModalLauncherKeypressListener.prototype;
|
|
597
|
+
_proto2.componentDidMount = function componentDidMount() {
|
|
593
598
|
window.addEventListener("keyup", this._handleKeyup);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
componentWillUnmount() {
|
|
599
|
+
};
|
|
600
|
+
_proto2.componentWillUnmount = function componentWillUnmount() {
|
|
597
601
|
window.removeEventListener("keyup", this._handleKeyup);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
render() {
|
|
602
|
+
};
|
|
603
|
+
_proto2.render = function render() {
|
|
601
604
|
return null;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
|
|
605
|
+
};
|
|
606
|
+
return ModalLauncherKeypressListener;
|
|
607
|
+
}(React.Component);
|
|
606
608
|
const styles$1 = StyleSheet.create({
|
|
607
609
|
container: {
|
|
608
610
|
zIndex: 1080
|
|
@@ -610,12 +612,16 @@ const styles$1 = StyleSheet.create({
|
|
|
610
612
|
});
|
|
611
613
|
var modalLauncher = withActionScheduler(ModalLauncher);
|
|
612
614
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
615
|
+
let ModalContent = function (_React$Component) {
|
|
616
|
+
_inheritsLoose(ModalContent, _React$Component);
|
|
617
|
+
function ModalContent() {
|
|
618
|
+
return _React$Component.apply(this, arguments) || this;
|
|
616
619
|
}
|
|
617
|
-
|
|
618
|
-
|
|
620
|
+
ModalContent.isClassOf = function isClassOf(instance) {
|
|
621
|
+
return instance && instance.type && instance.type.__IS_MODAL_CONTENT__;
|
|
622
|
+
};
|
|
623
|
+
var _proto = ModalContent.prototype;
|
|
624
|
+
_proto.render = function render() {
|
|
619
625
|
const {
|
|
620
626
|
scrollOverflow,
|
|
621
627
|
style,
|
|
@@ -630,9 +636,9 @@ class ModalContent extends React.Component {
|
|
|
630
636
|
}, React.createElement(View, {
|
|
631
637
|
style: [styles.content, style]
|
|
632
638
|
}, children)));
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
}
|
|
639
|
+
};
|
|
640
|
+
return ModalContent;
|
|
641
|
+
}(React.Component);
|
|
636
642
|
ModalContent.defaultProps = {
|
|
637
643
|
scrollOverflow: true
|
|
638
644
|
};
|
|
@@ -660,8 +666,13 @@ const styleSheets$1 = {
|
|
|
660
666
|
})
|
|
661
667
|
};
|
|
662
668
|
|
|
663
|
-
|
|
664
|
-
|
|
669
|
+
let CloseButton = function (_React$Component) {
|
|
670
|
+
_inheritsLoose(CloseButton, _React$Component);
|
|
671
|
+
function CloseButton() {
|
|
672
|
+
return _React$Component.apply(this, arguments) || this;
|
|
673
|
+
}
|
|
674
|
+
var _proto = CloseButton.prototype;
|
|
675
|
+
_proto.render = function render() {
|
|
665
676
|
const {
|
|
666
677
|
light,
|
|
667
678
|
onClick,
|
|
@@ -674,7 +685,6 @@ class CloseButton extends React.Component {
|
|
|
674
685
|
if (closeModal && onClick) {
|
|
675
686
|
throw new Error("You've specified 'onClose' on a modal when using ModalLauncher. Please specify 'onClose' on the ModalLauncher instead");
|
|
676
687
|
}
|
|
677
|
-
|
|
678
688
|
return React.createElement(IconButton, {
|
|
679
689
|
icon: icons.dismiss,
|
|
680
690
|
"aria-label": "Close modal",
|
|
@@ -685,30 +695,32 @@ class CloseButton extends React.Component {
|
|
|
685
695
|
testId: testId
|
|
686
696
|
});
|
|
687
697
|
});
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
}
|
|
698
|
+
};
|
|
699
|
+
return CloseButton;
|
|
700
|
+
}(React.Component);
|
|
691
701
|
|
|
692
|
-
|
|
693
|
-
|
|
702
|
+
let ModalPanel = function (_React$Component) {
|
|
703
|
+
_inheritsLoose(ModalPanel, _React$Component);
|
|
704
|
+
function ModalPanel() {
|
|
705
|
+
return _React$Component.apply(this, arguments) || this;
|
|
706
|
+
}
|
|
707
|
+
var _proto = ModalPanel.prototype;
|
|
708
|
+
_proto.renderMainContent = function renderMainContent() {
|
|
694
709
|
const {
|
|
695
710
|
content,
|
|
696
711
|
footer,
|
|
697
712
|
scrollOverflow
|
|
698
713
|
} = this.props;
|
|
699
714
|
const mainContent = ModalContent.isClassOf(content) ? content : React.createElement(ModalContent, null, content);
|
|
700
|
-
|
|
701
715
|
if (!mainContent) {
|
|
702
716
|
return mainContent;
|
|
703
717
|
}
|
|
704
|
-
|
|
705
718
|
return React.cloneElement(mainContent, {
|
|
706
719
|
scrollOverflow,
|
|
707
720
|
style: [!!footer && styles.hasFooter, mainContent.props.style]
|
|
708
721
|
});
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
render() {
|
|
722
|
+
};
|
|
723
|
+
_proto.render = function render() {
|
|
712
724
|
const {
|
|
713
725
|
closeButtonVisible,
|
|
714
726
|
footer,
|
|
@@ -728,9 +740,9 @@ class ModalPanel extends React.Component {
|
|
|
728
740
|
style: styles.closeButton,
|
|
729
741
|
testId: testId && `${testId}-close`
|
|
730
742
|
}), header, mainContent, !footer || ModalFooter.isClassOf(footer) ? footer : React.createElement(ModalFooter, null, footer));
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
}
|
|
743
|
+
};
|
|
744
|
+
return ModalPanel;
|
|
745
|
+
}(React.Component);
|
|
734
746
|
ModalPanel.defaultProps = {
|
|
735
747
|
closeButtonVisible: true,
|
|
736
748
|
scrollOverflow: true,
|
|
@@ -763,15 +775,19 @@ const styles = StyleSheet.create({
|
|
|
763
775
|
}
|
|
764
776
|
});
|
|
765
777
|
|
|
766
|
-
|
|
767
|
-
|
|
778
|
+
let OnePaneDialog = function (_React$Component) {
|
|
779
|
+
_inheritsLoose(OnePaneDialog, _React$Component);
|
|
780
|
+
function OnePaneDialog() {
|
|
781
|
+
return _React$Component.apply(this, arguments) || this;
|
|
782
|
+
}
|
|
783
|
+
var _proto = OnePaneDialog.prototype;
|
|
784
|
+
_proto.renderHeader = function renderHeader(uniqueId) {
|
|
768
785
|
const {
|
|
769
786
|
title,
|
|
770
787
|
breadcrumbs = undefined,
|
|
771
788
|
subtitle = undefined,
|
|
772
789
|
testId
|
|
773
790
|
} = this.props;
|
|
774
|
-
|
|
775
791
|
if (breadcrumbs) {
|
|
776
792
|
return React.createElement(ModalHeader, {
|
|
777
793
|
title: title,
|
|
@@ -793,9 +809,8 @@ class OnePaneDialog extends React.Component {
|
|
|
793
809
|
testId: testId && `${testId}-header`
|
|
794
810
|
});
|
|
795
811
|
}
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
render() {
|
|
812
|
+
};
|
|
813
|
+
_proto.render = function render() {
|
|
799
814
|
const {
|
|
800
815
|
onClose,
|
|
801
816
|
footer,
|
|
@@ -832,9 +847,9 @@ class OnePaneDialog extends React.Component {
|
|
|
832
847
|
closeButtonVisible: closeButtonVisible,
|
|
833
848
|
testId: testId
|
|
834
849
|
}))));
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
}
|
|
850
|
+
};
|
|
851
|
+
return OnePaneDialog;
|
|
852
|
+
}(React.Component);
|
|
838
853
|
OnePaneDialog.defaultProps = {
|
|
839
854
|
closeButtonVisible: true
|
|
840
855
|
};
|
|
@@ -858,14 +873,11 @@ const styleSheets = {
|
|
|
858
873
|
|
|
859
874
|
function maybeGetNextAncestorModalLauncherPortal(element) {
|
|
860
875
|
let candidateElement = element && element.parentElement;
|
|
861
|
-
|
|
862
876
|
while (candidateElement && !candidateElement.hasAttribute(ModalLauncherPortalAttributeName)) {
|
|
863
877
|
candidateElement = candidateElement.parentElement;
|
|
864
878
|
}
|
|
865
|
-
|
|
866
879
|
return candidateElement;
|
|
867
880
|
}
|
|
868
|
-
|
|
869
881
|
function maybeGetPortalMountedModalHostElement(element) {
|
|
870
882
|
return maybeGetNextAncestorModalLauncherPortal(element);
|
|
871
883
|
}
|