@carbon/react 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/es/components/ComposedModal/ComposedModal.js +172 -577
  2. package/es/components/ComposedModal/{next/ModalFooter.js → ModalFooter.js} +4 -4
  3. package/es/components/ComposedModal/{next/ModalHeader.js → ModalHeader.js} +2 -2
  4. package/es/components/DataTable/tools/sorting.js +8 -0
  5. package/es/components/Dropdown/Dropdown.js +1 -8
  6. package/es/components/Icon/Icon.Skeleton.js +4 -12
  7. package/es/components/InlineCheckbox/InlineCheckbox.js +0 -1
  8. package/es/components/ModalWrapper/ModalWrapper.js +10 -5
  9. package/es/components/ModalWrapper/index.js +12 -0
  10. package/es/components/NumberInput/NumberInput.js +3 -3
  11. package/es/components/TileGroup/TileGroup.js +1 -1
  12. package/es/index.js +4 -3
  13. package/es/internal/useControllableState.js +1 -1
  14. package/lib/components/ComposedModal/ComposedModal.js +174 -581
  15. package/lib/components/ComposedModal/{next/ModalFooter.js → ModalFooter.js} +4 -4
  16. package/lib/components/ComposedModal/{next/ModalHeader.js → ModalHeader.js} +2 -2
  17. package/lib/components/DataTable/tools/sorting.js +8 -0
  18. package/lib/components/Dropdown/Dropdown.js +1 -8
  19. package/lib/components/Icon/Icon.Skeleton.js +4 -12
  20. package/lib/components/InlineCheckbox/InlineCheckbox.js +0 -1
  21. package/lib/components/ModalWrapper/ModalWrapper.js +10 -5
  22. package/lib/components/ModalWrapper/index.js +16 -0
  23. package/lib/components/NumberInput/NumberInput.js +3 -3
  24. package/lib/components/TileGroup/TileGroup.js +1 -1
  25. package/lib/index.js +29 -28
  26. package/lib/internal/useControllableState.js +1 -1
  27. package/package.json +5 -4
  28. package/es/components/ComposedModal/index.js +0 -19
  29. package/es/components/ComposedModal/next/ComposedModal.js +0 -225
  30. package/lib/components/ComposedModal/index.js +0 -45
  31. package/lib/components/ComposedModal/next/ComposedModal.js +0 -236
@@ -5,627 +5,222 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { defineProperty as _defineProperty, objectWithoutProperties as _objectWithoutProperties, extends as _extends, inherits as _inherits, createSuper as _createSuper, classCallCheck as _classCallCheck, assertThisInitialized as _assertThisInitialized, createClass as _createClass, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { Component } from 'react';
8
+ import { objectWithoutProperties as _objectWithoutProperties, defineProperty as _defineProperty, extends as _extends, slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
+ import React__default, { useState, useRef, useEffect } from 'react';
10
10
  import PropTypes from 'prop-types';
11
- import Button from '../Button/Button.js';
12
- import ButtonSet from '../ButtonSet/ButtonSet.js';
11
+ import { ModalHeader } from './ModalHeader.js';
12
+ import { ModalFooter } from './ModalFooter.js';
13
13
  import cx from 'classnames';
14
- import { Close } from '@carbon/icons-react';
15
14
  import toggleClass from '../../tools/toggleClass.js';
16
15
  import requiredIfGivenPropIsTruthy from '../../prop-types/requiredIfGivenPropIsTruthy.js';
17
16
  import wrapFocus from '../../internal/wrapFocus.js';
18
- import { PrefixContext, usePrefix } from '../../internal/usePrefix.js';
17
+ import { usePrefix } from '../../internal/usePrefix.js';
19
18
 
20
- var _defineProperty2, _ModalBody$propTypes;
19
+ var _ModalBody$propTypes, _ComposedModal$propTy;
21
20
 
22
- var _excluded = ["aria-labelledby", "aria-label", "className", "containerClassName", "children", "danger", "preventCloseOnClickOutside", "selectorPrimaryFocus", "selectorsFloatingMenus", "size", "forwardedRef"],
23
- _excluded2 = ["className", "labelClassName", "titleClassName", "closeClassName", "closeIconClassName", "label", "title", "children", "iconDescription", "closeModal", "buttonOnClick", "preventCloseOnClickOutside", "forwardedRef"],
24
- _excluded3 = ["className", "children", "hasForm", "hasScrollingContent", "preventCloseOnClickOutside"],
25
- _excluded4 = ["className", "primaryClassName", "secondaryButtons", "secondaryClassName", "secondaryButtonText", "primaryButtonText", "primaryButtonDisabled", "closeModal", "onRequestClose", "onRequestSubmit", "children", "danger", "inputref", "forwardedRef"];
21
+ var _excluded = ["className", "children", "hasForm", "hasScrollingContent"],
22
+ _excluded2 = ["aria-labelledby", "aria-label", "children", "className", "containerClassName", "danger", "onClose", "onKeyDown", "open", "preventCloseOnClickOutside", "selectorPrimaryFocus", "selectorsFloatingMenus", "size"];
23
+ var ModalBody = /*#__PURE__*/React__default.forwardRef(function ModalBody(_ref, ref) {
24
+ var _cx;
26
25
 
27
- var ComposedModal = /*#__PURE__*/function (_Component) {
28
- _inherits(ComposedModal, _Component);
29
-
30
- var _super = _createSuper(ComposedModal);
31
-
32
- function ComposedModal() {
33
- var _this;
34
-
35
- _classCallCheck(this, ComposedModal);
36
-
37
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
38
- args[_key] = arguments[_key];
39
- }
40
-
41
- _this = _super.call.apply(_super, [this].concat(args));
42
-
43
- _defineProperty(_assertThisInitialized(_this), "state", {});
44
-
45
- _defineProperty(_assertThisInitialized(_this), "outerModal", /*#__PURE__*/React__default.createRef());
46
-
47
- _defineProperty(_assertThisInitialized(_this), "innerModal", /*#__PURE__*/React__default.createRef());
48
-
49
- _defineProperty(_assertThisInitialized(_this), "button", /*#__PURE__*/React__default.createRef());
50
-
51
- _defineProperty(_assertThisInitialized(_this), "startSentinel", /*#__PURE__*/React__default.createRef());
52
-
53
- _defineProperty(_assertThisInitialized(_this), "endSentinel", /*#__PURE__*/React__default.createRef());
54
-
55
- _defineProperty(_assertThisInitialized(_this), "handleKeyDown", function (evt) {
56
- // Esc key
57
- if (evt.which === 27) {
58
- _this.closeModal(evt);
59
- }
60
-
61
- _this.props.onKeyDown(evt);
62
- });
63
-
64
- _defineProperty(_assertThisInitialized(_this), "handleClick", function (evt) {
65
- if (!_this.innerModal.current.contains(evt.target) && _this.props.preventCloseOnClickOutside) {
66
- return;
67
- }
68
-
69
- if (_this.innerModal.current && !_this.innerModal.current.contains(evt.target)) {
70
- _this.closeModal(evt);
71
- }
72
- });
73
-
74
- _defineProperty(_assertThisInitialized(_this), "handleBlur", function (_ref) {
75
- var oldActiveNode = _ref.target,
76
- currentActiveNode = _ref.relatedTarget;
77
- var _this$props = _this.props,
78
- open = _this$props.open,
79
- selectorsFloatingMenus = _this$props.selectorsFloatingMenus;
80
-
81
- if (open && currentActiveNode && oldActiveNode) {
82
- var bodyNode = _this.innerModal.current;
83
- var startSentinelNode = _this.startSentinel.current;
84
- var endSentinelNode = _this.endSentinel.current;
85
- wrapFocus({
86
- bodyNode: bodyNode,
87
- startSentinelNode: startSentinelNode,
88
- endSentinelNode: endSentinelNode,
89
- currentActiveNode: currentActiveNode,
90
- oldActiveNode: oldActiveNode,
91
- selectorsFloatingMenus: selectorsFloatingMenus
92
- });
93
- }
94
- });
95
-
96
- _defineProperty(_assertThisInitialized(_this), "focusButton", function (focusContainerElement) {
97
- if (focusContainerElement) {
98
- var primaryFocusElement = focusContainerElement.querySelector(_this.props.selectorPrimaryFocus);
99
-
100
- if (primaryFocusElement) {
101
- primaryFocusElement.focus();
102
- return;
103
- }
104
-
105
- if (_this.button.current) {
106
- _this.button.current.focus();
107
- }
108
- }
109
- });
110
-
111
- _defineProperty(_assertThisInitialized(_this), "handleTransitionEnd", function (evt) {
112
- if (_this.outerModal.current.offsetWidth && _this.outerModal.current.offsetHeight && _this.beingOpen) {
113
- _this.focusButton(evt.currentTarget);
114
-
115
- _this.beingOpen = false;
116
- }
117
- });
118
-
119
- _defineProperty(_assertThisInitialized(_this), "closeModal", function (evt) {
120
- var onClose = _this.props.onClose;
121
-
122
- if (!onClose || onClose(evt) !== false) {
123
- _this.setState({
124
- open: false
125
- });
126
- }
127
- });
128
-
129
- return _this;
130
- }
131
-
132
- _createClass(ComposedModal, [{
133
- key: "componentDidUpdate",
134
- value: function componentDidUpdate(prevProps, prevState) {
135
- if (!prevState.open && this.state.open) {
136
- this.beingOpen = true;
137
- } else if (prevState.open && !this.state.open) {
138
- this.beingOpen = false;
139
- }
140
-
141
- if (prevState.open !== this.state.open) {
142
- toggleClass(document.body, "".concat(this.context, "--body--with-modal-open"), this.state.open);
143
- }
144
- }
145
- }, {
146
- key: "componentWillUnmount",
147
- value: function componentWillUnmount() {
148
- toggleClass(document.body, "".concat(this.context, "--body--with-modal-open"), false);
149
- }
150
- }, {
151
- key: "componentDidMount",
152
- value: function componentDidMount() {
153
- toggleClass(document.body, "".concat(this.context, "--body--with-modal-open"), this.props.open);
154
-
155
- if (!this.props.open) {
156
- return;
157
- }
158
-
159
- if (this.innerModal.current) {
160
- this.focusButton(this.innerModal.current);
161
- }
162
- }
163
- }, {
164
- key: "render",
165
- value: function render() {
166
- var _classNames,
167
- _classNames2,
168
- _this2 = this;
169
-
170
- var open = this.state.open;
171
- var prefix = this.context;
172
-
173
- var _this$props2 = this.props,
174
- ariaLabelledBy = _this$props2['aria-labelledby'],
175
- ariaLabel = _this$props2['aria-label'],
176
- className = _this$props2.className,
177
- containerClassName = _this$props2.containerClassName,
178
- children = _this$props2.children,
179
- danger = _this$props2.danger;
180
- _this$props2.preventCloseOnClickOutside;
181
- _this$props2.selectorPrimaryFocus;
182
- _this$props2.selectorsFloatingMenus;
183
- var size = _this$props2.size,
184
- forwardedRef = _this$props2.forwardedRef,
185
- other = _objectWithoutProperties(_this$props2, _excluded);
186
-
187
- var modalClass = cx((_classNames = {}, _defineProperty(_classNames, "".concat(prefix, "--modal"), true), _defineProperty(_classNames, 'is-visible', open), _defineProperty(_classNames, className, className), _defineProperty(_classNames, "".concat(prefix, "--modal--danger"), danger), _classNames));
188
- var containerClass = cx((_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefix, "--modal-container"), true), _defineProperty(_classNames2, "".concat(prefix, "--modal-container--").concat(size), size), _defineProperty(_classNames2, containerClassName, containerClassName), _classNames2)); // Generate aria-label based on Modal Header label if one is not provided (L253)
189
-
190
- var generatedAriaLabel;
191
- var childrenWithProps = React__default.Children.toArray(children).map(function (child) {
192
- switch (child.type) {
193
- case React__default.createElement(ModalHeader).type:
194
- generatedAriaLabel = child.props.label;
195
- return /*#__PURE__*/React__default.cloneElement(child, {
196
- closeModal: _this2.closeModal
197
- });
198
-
199
- case React__default.createElement(ModalFooter).type:
200
- return /*#__PURE__*/React__default.cloneElement(child, {
201
- closeModal: _this2.closeModal,
202
- inputref: _this2.button
203
- });
204
-
205
- default:
206
- return child;
207
- }
208
- });
209
- return /*#__PURE__*/React__default.createElement("div", _extends({}, other, {
210
- role: "presentation",
211
- ref: function ref(node) {
212
- if (node) {
213
- _this2.outerModal.current = node;
214
-
215
- if (typeof forwardedRef === 'function') {
216
- forwardedRef(node);
217
- } else if (_typeof(forwardedRef) === 'object') {
218
- forwardedRef.current = node;
219
- }
220
- }
221
- },
222
- onBlur: this.handleBlur,
223
- onClick: this.handleClick,
224
- onKeyDown: this.handleKeyDown,
225
- onTransitionEnd: open ? this.handleTransitionEnd : undefined,
226
- className: modalClass,
227
- tabIndex: "-1"
228
- }), /*#__PURE__*/React__default.createElement("span", {
229
- ref: this.startSentinel,
230
- tabIndex: "0",
231
- role: "link",
232
- className: "".concat(prefix, "--visually-hidden")
233
- }, "Focus sentinel"), /*#__PURE__*/React__default.createElement("div", {
234
- ref: this.innerModal,
235
- className: containerClass,
236
- role: "dialog",
237
- "aria-modal": "true",
238
- "aria-label": ariaLabel ? ariaLabel : generatedAriaLabel,
239
- "aria-labelledby": ariaLabelledBy
240
- }, childrenWithProps), /*#__PURE__*/React__default.createElement("span", {
241
- ref: this.endSentinel,
242
- tabIndex: "0",
243
- role: "link",
244
- className: "".concat(prefix, "--visually-hidden")
245
- }, "Focus sentinel"));
246
- }
247
- }], [{
248
- key: "getDerivedStateFromProps",
249
- value: function getDerivedStateFromProps(_ref2, state) {
250
- var open = _ref2.open;
251
- var prevOpen = state.prevOpen;
252
- return prevOpen === open ? null : {
253
- open: open,
254
- prevOpen: open
255
- };
256
- }
257
- }]);
258
-
259
- return ComposedModal;
260
- }(Component);
261
-
262
- _defineProperty(ComposedModal, "contextType", PrefixContext);
263
-
264
- _defineProperty(ComposedModal, "defaultProps", {
265
- onKeyDown: function onKeyDown() {},
266
- selectorPrimaryFocus: '[data-modal-primary-focus]'
267
- });
268
-
269
- _defineProperty(ComposedModal, "propTypes", (_defineProperty2 = {}, _defineProperty(_defineProperty2, 'aria-label', PropTypes.string), _defineProperty(_defineProperty2, 'aria-labelledby', PropTypes.string), _defineProperty(_defineProperty2, "children", PropTypes.node), _defineProperty(_defineProperty2, "className", PropTypes.string), _defineProperty(_defineProperty2, "containerClassName", PropTypes.string), _defineProperty(_defineProperty2, "danger", PropTypes.bool), _defineProperty(_defineProperty2, "onClose", PropTypes.func), _defineProperty(_defineProperty2, "onKeyDown", PropTypes.func), _defineProperty(_defineProperty2, "open", PropTypes.bool), _defineProperty(_defineProperty2, "preventCloseOnClickOutside", PropTypes.bool), _defineProperty(_defineProperty2, "selectorPrimaryFocus", PropTypes.string), _defineProperty(_defineProperty2, "selectorsFloatingMenus", PropTypes.arrayOf(PropTypes.string)), _defineProperty(_defineProperty2, "size", PropTypes.oneOf(['xs', 'sm', 'md', 'lg'])), _defineProperty2));
270
- var ModalHeader = /*#__PURE__*/function (_Component2) {
271
- _inherits(ModalHeader, _Component2);
272
-
273
- var _super2 = _createSuper(ModalHeader);
274
-
275
- function ModalHeader() {
276
- var _this3;
277
-
278
- _classCallCheck(this, ModalHeader);
279
-
280
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
281
- args[_key2] = arguments[_key2];
282
- }
283
-
284
- _this3 = _super2.call.apply(_super2, [this].concat(args));
285
-
286
- _defineProperty(_assertThisInitialized(_this3), "handleCloseButtonClick", function (evt) {
287
- _this3.props.closeModal(evt);
288
-
289
- _this3.props.buttonOnClick();
290
- });
291
-
292
- return _this3;
293
- }
294
-
295
- _createClass(ModalHeader, [{
296
- key: "render",
297
- value: function render() {
298
- var _classNames3, _classNames4, _classNames5, _classNames6, _classNames7;
299
-
300
- var _this$props3 = this.props,
301
- className = _this$props3.className,
302
- labelClassName = _this$props3.labelClassName,
303
- titleClassName = _this$props3.titleClassName,
304
- closeClassName = _this$props3.closeClassName,
305
- closeIconClassName = _this$props3.closeIconClassName,
306
- label = _this$props3.label,
307
- title = _this$props3.title,
308
- children = _this$props3.children,
309
- iconDescription = _this$props3.iconDescription;
310
- _this$props3.closeModal;
311
- _this$props3.buttonOnClick;
312
- _this$props3.preventCloseOnClickOutside;
313
- var forwardedRef = _this$props3.forwardedRef,
314
- other = _objectWithoutProperties(_this$props3, _excluded2);
315
-
316
- var prefix = this.context;
317
- var headerClass = cx((_classNames3 = {}, _defineProperty(_classNames3, "".concat(prefix, "--modal-header"), true), _defineProperty(_classNames3, className, className), _classNames3));
318
- var labelClass = cx((_classNames4 = {}, _defineProperty(_classNames4, "".concat(prefix, "--modal-header__label ").concat(prefix, "--type-delta"), true), _defineProperty(_classNames4, labelClassName, labelClassName), _classNames4));
319
- var titleClass = cx((_classNames5 = {}, _defineProperty(_classNames5, "".concat(prefix, "--modal-header__heading ").concat(prefix, "--type-beta"), true), _defineProperty(_classNames5, titleClassName, titleClassName), _classNames5));
320
- var closeClass = cx((_classNames6 = {}, _defineProperty(_classNames6, "".concat(prefix, "--modal-close"), true), _defineProperty(_classNames6, closeClassName, closeClassName), _classNames6));
321
- var closeIconClass = cx((_classNames7 = {}, _defineProperty(_classNames7, "".concat(prefix, "--modal-close__icon"), true), _defineProperty(_classNames7, closeIconClassName, closeIconClassName), _classNames7));
322
- return /*#__PURE__*/React__default.createElement("div", _extends({
323
- className: headerClass
324
- }, other, {
325
- ref: forwardedRef
326
- }), label && /*#__PURE__*/React__default.createElement("h2", {
327
- className: labelClass
328
- }, label), title && /*#__PURE__*/React__default.createElement("h3", {
329
- className: titleClass
330
- }, title), children, /*#__PURE__*/React__default.createElement("button", {
331
- onClick: this.handleCloseButtonClick,
332
- className: closeClass,
333
- title: iconDescription,
334
- "aria-label": iconDescription,
335
- type: "button"
336
- }, /*#__PURE__*/React__default.createElement(Close, {
337
- size: 20,
338
- className: closeIconClass
339
- })));
340
- }
341
- }]);
342
-
343
- return ModalHeader;
344
- }(Component);
345
-
346
- _defineProperty(ModalHeader, "propTypes", {
347
- /**
348
- * Provide an optional function to be called when the close button is
349
- * clicked
350
- */
351
- buttonOnClick: PropTypes.func,
352
-
353
- /**
354
- * Specify the content to be placed in the ModalHeader
355
- */
356
- children: PropTypes.node,
357
-
358
- /**
359
- * Specify an optional className to be applied to the modal header
360
- */
361
- className: PropTypes.string,
362
-
363
- /**
364
- * Specify an optional className to be applied to the modal close node
365
- */
366
- closeClassName: PropTypes.string,
367
-
368
- /**
369
- * Specify an optional className to be applied to the modal close icon node
370
- */
371
- closeIconClassName: PropTypes.string,
372
-
373
- /**
374
- * Provide an optional function to be called when the modal is closed
375
- */
376
- closeModal: PropTypes.func,
377
-
378
- /**
379
- * Specify a description for the close icon that can be read by screen
380
- * readers
381
- */
382
- iconDescription: PropTypes.string,
383
-
384
- /**
385
- * Specify an optional label to be displayed
386
- */
387
- label: PropTypes.node,
388
-
389
- /**
390
- * Specify an optional className to be applied to the modal header label
391
- */
392
- labelClassName: PropTypes.string,
393
-
394
- /**
395
- * Specify an optional title to be displayed
396
- */
397
- title: PropTypes.node,
398
-
399
- /**
400
- * Specify an optional className to be applied to the modal heading
401
- */
402
- titleClassName: PropTypes.string
403
- });
404
-
405
- _defineProperty(ModalHeader, "contextType", PrefixContext);
406
-
407
- _defineProperty(ModalHeader, "defaultProps", {
408
- iconDescription: 'Close',
409
- buttonOnClick: function buttonOnClick() {}
410
- });
411
-
412
- var ModalBody = /*#__PURE__*/React__default.forwardRef(function ModalBody(props, ref) {
413
- var _classNames8;
414
-
415
- var className = props.className,
416
- children = props.children,
417
- hasForm = props.hasForm,
418
- hasScrollingContent = props.hasScrollingContent;
419
- props.preventCloseOnClickOutside;
420
- var other = _objectWithoutProperties(props, _excluded3);
26
+ var customClassName = _ref.className,
27
+ children = _ref.children,
28
+ hasForm = _ref.hasForm,
29
+ hasScrollingContent = _ref.hasScrollingContent,
30
+ rest = _objectWithoutProperties(_ref, _excluded);
421
31
 
422
32
  var prefix = usePrefix();
423
- var contentClass = cx((_classNames8 = {}, _defineProperty(_classNames8, "".concat(prefix, "--modal-content"), true), _defineProperty(_classNames8, "".concat(prefix, "--modal-content--with-form"), hasForm), _defineProperty(_classNames8, "".concat(prefix, "--modal-scroll-content"), hasScrollingContent), _defineProperty(_classNames8, className, className), _classNames8));
33
+ var contentClass = cx((_cx = {}, _defineProperty(_cx, "".concat(prefix, "--modal-content"), true), _defineProperty(_cx, "".concat(prefix, "--modal-content--with-form"), hasForm), _defineProperty(_cx, "".concat(prefix, "--modal-scroll-content"), hasScrollingContent), _defineProperty(_cx, customClassName, customClassName), _cx));
424
34
  var hasScrollingContentProps = hasScrollingContent ? {
425
35
  tabIndex: 0,
426
36
  role: 'region'
427
37
  } : {};
428
38
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", _extends({
429
39
  className: contentClass
430
- }, hasScrollingContentProps, other, {
40
+ }, hasScrollingContentProps, rest, {
431
41
  ref: ref
432
42
  }), children), hasScrollingContent && /*#__PURE__*/React__default.createElement("div", {
433
43
  className: "".concat(prefix, "--modal-content--overflow-indicator")
434
44
  }));
435
45
  });
436
46
  ModalBody.propTypes = (_ModalBody$propTypes = {}, _defineProperty(_ModalBody$propTypes, 'aria-label', requiredIfGivenPropIsTruthy('hasScrollingContent', PropTypes.string)), _defineProperty(_ModalBody$propTypes, "children", PropTypes.node), _defineProperty(_ModalBody$propTypes, "className", PropTypes.string), _defineProperty(_ModalBody$propTypes, "hasForm", PropTypes.bool), _defineProperty(_ModalBody$propTypes, "hasScrollingContent", PropTypes.bool), _ModalBody$propTypes);
437
- var ModalFooter = /*#__PURE__*/function (_Component3) {
438
- _inherits(ModalFooter, _Component3);
439
-
440
- var _super3 = _createSuper(ModalFooter);
441
-
442
- function ModalFooter() {
443
- var _this4;
47
+ var ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedModal(_ref2, ref) {
48
+ var _cx2, _cx3;
49
+
50
+ var ariaLabelledBy = _ref2['aria-labelledby'],
51
+ ariaLabel = _ref2['aria-label'],
52
+ children = _ref2.children,
53
+ customClassName = _ref2.className,
54
+ containerClassName = _ref2.containerClassName,
55
+ danger = _ref2.danger,
56
+ onClose = _ref2.onClose,
57
+ onKeyDown = _ref2.onKeyDown,
58
+ open = _ref2.open,
59
+ preventCloseOnClickOutside = _ref2.preventCloseOnClickOutside,
60
+ selectorPrimaryFocus = _ref2.selectorPrimaryFocus,
61
+ selectorsFloatingMenus = _ref2.selectorsFloatingMenus,
62
+ size = _ref2.size,
63
+ rest = _objectWithoutProperties(_ref2, _excluded2);
444
64
 
445
- _classCallCheck(this, ModalFooter);
446
-
447
- for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
448
- args[_key3] = arguments[_key3];
449
- }
65
+ var prefix = usePrefix();
450
66
 
451
- _this4 = _super3.call.apply(_super3, [this].concat(args));
67
+ var _useState = useState(open),
68
+ _useState2 = _slicedToArray(_useState, 2),
69
+ isOpen = _useState2[0],
70
+ setisOpen = _useState2[1];
452
71
 
453
- _defineProperty(_assertThisInitialized(_this4), "handleRequestClose", function (evt) {
454
- _this4.props.closeModal(evt);
72
+ var _useState3 = useState(open),
73
+ _useState4 = _slicedToArray(_useState3, 2),
74
+ prevOpen = _useState4[0],
75
+ setPrevOpen = _useState4[1];
455
76
 
456
- _this4.props.onRequestClose(evt);
457
- });
77
+ var innerModal = useRef();
78
+ var button = useRef();
79
+ var startSentinel = useRef();
80
+ var endSentinel = useRef();
458
81
 
459
- return _this4;
82
+ if (open !== prevOpen) {
83
+ setisOpen(open);
84
+ setPrevOpen(open);
460
85
  }
461
86
 
462
- _createClass(ModalFooter, [{
463
- key: "render",
464
- value: function render() {
465
- var _classNames9,
466
- _this5 = this;
467
-
468
- var _this$props4 = this.props,
469
- className = _this$props4.className,
470
- primaryClassName = _this$props4.primaryClassName,
471
- secondaryButtons = _this$props4.secondaryButtons,
472
- secondaryClassName = _this$props4.secondaryClassName,
473
- secondaryButtonText = _this$props4.secondaryButtonText,
474
- primaryButtonText = _this$props4.primaryButtonText,
475
- primaryButtonDisabled = _this$props4.primaryButtonDisabled;
476
- _this$props4.closeModal;
477
- _this$props4.onRequestClose;
478
- var onRequestSubmit = _this$props4.onRequestSubmit,
479
- children = _this$props4.children,
480
- danger = _this$props4.danger,
481
- inputref = _this$props4.inputref,
482
- forwardedRef = _this$props4.forwardedRef,
483
- other = _objectWithoutProperties(_this$props4, _excluded4);
484
-
485
- var prefix = this.context;
486
- var footerClass = cx((_classNames9 = {}, _defineProperty(_classNames9, "".concat(prefix, "--modal-footer"), true), _defineProperty(_classNames9, className, className), _defineProperty(_classNames9, "".concat(prefix, "--modal-footer--three-button"), Array.isArray(secondaryButtons) && secondaryButtons.length === 2), _classNames9));
487
- var primaryClass = cx(_defineProperty({}, primaryClassName, primaryClassName));
488
- var secondaryClass = cx(_defineProperty({}, secondaryClassName, secondaryClassName));
489
-
490
- var SecondaryButtonSet = function SecondaryButtonSet() {
491
- if (Array.isArray(secondaryButtons) && secondaryButtons.length <= 2) {
492
- return secondaryButtons.map(function (_ref3, i) {
493
- var buttonText = _ref3.buttonText,
494
- onButtonClick = _ref3.onClick;
495
- return /*#__PURE__*/React__default.createElement(Button, {
496
- key: "".concat(buttonText, "-").concat(i),
497
- className: secondaryClass,
498
- kind: "secondary",
499
- onClick: onButtonClick || _this5.handleRequestClose
500
- }, buttonText);
501
- });
502
- }
503
-
504
- if (secondaryButtonText) {
505
- return /*#__PURE__*/React__default.createElement(Button, {
506
- className: secondaryClass,
507
- onClick: _this5.handleRequestClose,
508
- kind: "secondary"
509
- }, secondaryButtonText);
510
- }
511
-
512
- return null;
513
- };
514
-
515
- return /*#__PURE__*/React__default.createElement(ButtonSet, _extends({
516
- className: footerClass
517
- }, other, {
518
- ref: forwardedRef
519
- }), /*#__PURE__*/React__default.createElement(SecondaryButtonSet, null), primaryButtonText && /*#__PURE__*/React__default.createElement(Button, {
520
- onClick: onRequestSubmit,
521
- className: primaryClass,
522
- disabled: primaryButtonDisabled,
523
- kind: danger ? 'danger' : 'primary',
524
- ref: inputref
525
- }, primaryButtonText), children);
87
+ function handleKeyDown(evt) {
88
+ // Esc key
89
+ if (evt.which === 27) {
90
+ closeModal(evt);
526
91
  }
527
- }]);
528
-
529
- return ModalFooter;
530
- }(Component);
531
-
532
- _defineProperty(ModalFooter, "propTypes", {
533
- /**
534
- * Pass in content that will be rendered in the Modal Footer
535
- */
536
- children: PropTypes.node,
537
92
 
538
- /**
539
- * Specify a custom className to be applied to the Modal Footer container
540
- */
541
- className: PropTypes.string,
93
+ onKeyDown(evt);
94
+ }
542
95
 
543
- /**
544
- * Specify an optional function that is called whenever the modal is closed
545
- */
546
- closeModal: PropTypes.func,
96
+ function handleClick(evt) {
97
+ if (!innerModal.current.contains(evt.target) && preventCloseOnClickOutside) {
98
+ return;
99
+ }
547
100
 
548
- /**
549
- * Specify whether the primary button should be replaced with danger button.
550
- * Note that this prop is not applied if you render primary/danger button by yourself
551
- */
552
- danger: PropTypes.bool,
101
+ if (innerModal.current && !innerModal.current.contains(evt.target)) {
102
+ closeModal(evt);
103
+ }
104
+ }
553
105
 
554
- /**
555
- * The `ref` callback for the primary button.
556
- */
557
- inputref: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
558
- current: PropTypes.any
559
- })]),
106
+ function handleBlur(_ref3) {
107
+ var oldActiveNode = _ref3.target,
108
+ currentActiveNode = _ref3.relatedTarget;
109
+
110
+ if (open && currentActiveNode && oldActiveNode) {
111
+ var bodyNode = innerModal.current;
112
+ var startSentinelNode = startSentinel.current;
113
+ var endSentinelNode = endSentinel.current;
114
+ wrapFocus({
115
+ bodyNode: bodyNode,
116
+ startSentinelNode: startSentinelNode,
117
+ endSentinelNode: endSentinelNode,
118
+ currentActiveNode: currentActiveNode,
119
+ oldActiveNode: oldActiveNode,
120
+ selectorsFloatingMenus: selectorsFloatingMenus
121
+ });
122
+ }
123
+ }
560
124
 
561
- /**
562
- * Specify an optional function for when the modal is requesting to be
563
- * closed
564
- */
565
- onRequestClose: PropTypes.func,
125
+ function closeModal(evt) {
126
+ if (!onClose || onClose(evt) !== false) {
127
+ setisOpen(false);
128
+ }
129
+ }
566
130
 
567
- /**
568
- * Specify an optional function for when the modal is requesting to be
569
- * submitted
570
- */
571
- onRequestSubmit: PropTypes.func,
131
+ var modalClass = cx((_cx2 = {}, _defineProperty(_cx2, "".concat(prefix, "--modal"), true), _defineProperty(_cx2, 'is-visible', isOpen), _defineProperty(_cx2, customClassName, customClassName), _defineProperty(_cx2, "".concat(prefix, "--modal--danger"), danger), _cx2));
132
+ var containerClass = cx((_cx3 = {}, _defineProperty(_cx3, "".concat(prefix, "--modal-container"), true), _defineProperty(_cx3, "".concat(prefix, "--modal-container--").concat(size), size), _defineProperty(_cx3, containerClassName, containerClassName), _cx3)); // Generate aria-label based on Modal Header label if one is not provided (L253)
572
133
 
573
- /**
574
- * Specify whether the primary button should be disabled
575
- */
576
- primaryButtonDisabled: PropTypes.bool,
134
+ var generatedAriaLabel;
135
+ var childrenWithProps = React__default.Children.toArray(children).map(function (child) {
136
+ switch (child.type) {
137
+ case React__default.createElement(ModalHeader).type:
138
+ generatedAriaLabel = child.props.label;
139
+ return /*#__PURE__*/React__default.cloneElement(child, {
140
+ closeModal: closeModal
141
+ });
577
142
 
578
- /**
579
- * Specify the text for the primary button
580
- */
581
- primaryButtonText: PropTypes.string,
143
+ case React__default.createElement(ModalFooter).type:
144
+ return /*#__PURE__*/React__default.cloneElement(child, {
145
+ closeModal: closeModal,
146
+ inputref: button
147
+ });
582
148
 
583
- /**
584
- * Specify a custom className to be applied to the primary button
585
- */
586
- primaryClassName: PropTypes.string,
149
+ default:
150
+ return child;
151
+ }
152
+ });
153
+ useEffect(function () {
154
+ if (prevOpen !== isOpen) {
155
+ toggleClass(document.body, "".concat(prefix, "--body--with-modal-open"), isOpen);
156
+ }
157
+ });
158
+ useEffect(function () {
159
+ return function () {
160
+ return toggleClass(document.body, "".concat(prefix, "--body--with-modal-open"), false);
161
+ };
162
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
163
+
164
+ useEffect(function () {
165
+ toggleClass(document.body, "".concat(prefix, "--body--with-modal-open"), open);
166
+ }, [open, prefix]);
167
+ useEffect(function () {
168
+ var focusButton = function focusButton(focusContainerElement) {
169
+ if (focusContainerElement) {
170
+ var primaryFocusElement = focusContainerElement.querySelector(selectorPrimaryFocus);
587
171
 
588
- /**
589
- * Specify the text for the secondary button
590
- */
591
- secondaryButtonText: PropTypes.string,
172
+ if (primaryFocusElement) {
173
+ primaryFocusElement.focus();
174
+ return;
175
+ }
592
176
 
593
- /**
594
- * Specify an array of config objects for secondary buttons
595
- * (`Array<{
596
- * buttonText: string,
597
- * onClick: function,
598
- * }>`).
599
- */
600
- secondaryButtons: function secondaryButtons(props, propName, componentName) {
601
- if (props.secondaryButtons) {
602
- if (!Array.isArray(props.secondaryButtons) || props.secondaryButtons.length !== 2) {
603
- return new Error("".concat(propName, " needs to be an array of two button config objects"));
177
+ if (button.current) {
178
+ button.current.focus();
179
+ }
604
180
  }
181
+ };
605
182
 
606
- var shape = {
607
- buttonText: PropTypes.node,
608
- onClick: PropTypes.func
609
- };
610
- props[propName].forEach(function (secondaryButton) {
611
- PropTypes.checkPropTypes(shape, secondaryButton, propName, componentName);
612
- });
183
+ if (!open) {
184
+ return;
613
185
  }
614
186
 
615
- return null;
616
- },
617
-
618
- /**
619
- * Specify a custom className to be applied to the secondary button
620
- */
621
- secondaryClassName: PropTypes.string
622
- });
623
-
624
- _defineProperty(ModalFooter, "defaultProps", {
625
- onRequestClose: function onRequestClose() {},
626
- onRequestSubmit: function onRequestSubmit() {}
187
+ if (innerModal.current) {
188
+ focusButton(innerModal.current);
189
+ }
190
+ }, [open, selectorPrimaryFocus]);
191
+ return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, {
192
+ role: "presentation",
193
+ ref: ref,
194
+ "aria-hidden": !open,
195
+ onBlur: handleBlur,
196
+ onClick: handleClick,
197
+ onKeyDown: handleKeyDown,
198
+ className: modalClass,
199
+ tabIndex: "-1"
200
+ }), /*#__PURE__*/React__default.createElement("div", {
201
+ className: containerClass,
202
+ role: "dialog",
203
+ "aria-modal": "true",
204
+ "aria-label": ariaLabel ? ariaLabel : generatedAriaLabel,
205
+ "aria-labelledby": ariaLabelledBy
206
+ }, /*#__PURE__*/React__default.createElement("button", {
207
+ type: "button",
208
+ ref: startSentinel,
209
+ className: "".concat(prefix, "--visually-hidden")
210
+ }, "Focus sentinel"), /*#__PURE__*/React__default.createElement("div", {
211
+ ref: innerModal,
212
+ className: "".concat(prefix, "--modal-container-body")
213
+ }, childrenWithProps), /*#__PURE__*/React__default.createElement("button", {
214
+ type: "button",
215
+ ref: endSentinel,
216
+ className: "".concat(prefix, "--visually-hidden")
217
+ }, "Focus sentinel")));
627
218
  });
219
+ ComposedModal.propTypes = (_ComposedModal$propTy = {}, _defineProperty(_ComposedModal$propTy, 'aria-label', PropTypes.string), _defineProperty(_ComposedModal$propTy, 'aria-labelledby', PropTypes.string), _defineProperty(_ComposedModal$propTy, "children", PropTypes.node), _defineProperty(_ComposedModal$propTy, "className", PropTypes.string), _defineProperty(_ComposedModal$propTy, "containerClassName", PropTypes.string), _defineProperty(_ComposedModal$propTy, "danger", PropTypes.bool), _defineProperty(_ComposedModal$propTy, "onClose", PropTypes.func), _defineProperty(_ComposedModal$propTy, "onKeyDown", PropTypes.func), _defineProperty(_ComposedModal$propTy, "open", PropTypes.bool), _defineProperty(_ComposedModal$propTy, "preventCloseOnClickOutside", PropTypes.bool), _defineProperty(_ComposedModal$propTy, "selectorPrimaryFocus", PropTypes.string), _defineProperty(_ComposedModal$propTy, "selectorsFloatingMenus", PropTypes.arrayOf(PropTypes.string)), _defineProperty(_ComposedModal$propTy, "size", PropTypes.oneOf(['xs', 'sm', 'md', 'lg'])), _ComposedModal$propTy);
220
+ ComposedModal.defaultProps = {
221
+ onKeyDown: function onKeyDown() {},
222
+ selectorPrimaryFocus: '[data-modal-primary-focus]'
223
+ };
224
+ var ComposedModal$1 = ComposedModal;
628
225
 
629
- _defineProperty(ModalFooter, "contextType", PrefixContext);
630
-
631
- export { ModalBody, ModalFooter, ModalHeader, ComposedModal as default };
226
+ export { ModalBody, ComposedModal$1 as default };