@patternfly/react-core
Version:
This library provides a set of common React components for use with the PatternFly reference implementation.
136 lines • 6.48 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Modal = exports.ModalVariant = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const ReactDOM = tslib_1.__importStar(require("react-dom"));
const helpers_1 = require("../../helpers");
const react_styles_1 = require("@patternfly/react-styles");
const backdrop_1 = tslib_1.__importDefault(require("@patternfly/react-styles/css/components/Backdrop/backdrop"));
const ModalContent_1 = require("./ModalContent");
const helpers_2 = require("../../helpers");
var ModalVariant;
(function (ModalVariant) {
ModalVariant["small"] = "small";
ModalVariant["medium"] = "medium";
ModalVariant["large"] = "large";
ModalVariant["default"] = "default";
})(ModalVariant = exports.ModalVariant || (exports.ModalVariant = {}));
class Modal extends React.Component {
constructor(props) {
super(props);
this.boxId = '';
this.labelId = '';
this.descriptorId = '';
this.handleEscKeyClick = (event) => {
const { onEscapePress } = this.props;
if (event.keyCode === helpers_1.KEY_CODES.ESCAPE_KEY && this.props.isOpen) {
onEscapePress ? onEscapePress(event) : this.props.onClose();
}
};
this.getElement = (appendTo) => {
if (typeof appendTo === 'function') {
return appendTo();
}
return appendTo || document.body;
};
this.toggleSiblingsFromScreenReaders = (hide) => {
const { appendTo } = this.props;
const target = this.getElement(appendTo);
const bodyChildren = target.children;
for (const child of Array.from(bodyChildren)) {
if (child !== this.state.container) {
hide ? child.setAttribute('aria-hidden', '' + hide) : child.removeAttribute('aria-hidden');
}
}
};
this.isEmpty = (value) => value === null || value === undefined || value === '';
const boxIdNum = Modal.currentId++;
const labelIdNum = boxIdNum + 1;
const descriptorIdNum = boxIdNum + 2;
this.boxId = props.id || `pf-modal-part-${boxIdNum}`;
this.labelId = `pf-modal-part-${labelIdNum}`;
this.descriptorId = `pf-modal-part-${descriptorIdNum}`;
this.state = {
container: undefined,
ouiaStateId: helpers_2.getDefaultOUIAId(Modal.displayName, props.variant)
};
}
componentDidMount() {
const { appendTo, title, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, hasNoBodyWrapper, header } = this.props;
const target = this.getElement(appendTo);
const container = document.createElement('div');
this.setState({ container });
target.appendChild(container);
target.addEventListener('keydown', this.handleEscKeyClick, false);
if (this.props.isOpen) {
target.classList.add(react_styles_1.css(backdrop_1.default.backdropOpen));
}
else {
target.classList.remove(react_styles_1.css(backdrop_1.default.backdropOpen));
}
if (this.isEmpty(title) && this.isEmpty(ariaLabel) && this.isEmpty(ariaLabelledby)) {
// eslint-disable-next-line no-console
console.error('Modal: Specify at least one of: title, aria-label, aria-labelledby.');
}
if (this.isEmpty(ariaLabel) && this.isEmpty(ariaLabelledby) && (hasNoBodyWrapper || header)) {
// eslint-disable-next-line no-console
console.error('Modal: When using hasNoBodyWrapper or setting a custom header, ensure you assign an accessible name to the the modal container with aria-label or aria-labelledby.');
}
}
componentDidUpdate() {
const { appendTo } = this.props;
const target = this.getElement(appendTo);
if (this.props.isOpen) {
target.classList.add(react_styles_1.css(backdrop_1.default.backdropOpen));
this.toggleSiblingsFromScreenReaders(true);
}
else {
target.classList.remove(react_styles_1.css(backdrop_1.default.backdropOpen));
this.toggleSiblingsFromScreenReaders(false);
}
}
componentWillUnmount() {
const { appendTo } = this.props;
const target = this.getElement(appendTo);
if (this.state.container) {
target.removeChild(this.state.container);
}
target.removeEventListener('keydown', this.handleEscKeyClick, false);
target.classList.remove(react_styles_1.css(backdrop_1.default.backdropOpen));
}
render() {
const _a = this.props, {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
appendTo,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onEscapePress, 'aria-labelledby': ariaLabelledby, 'aria-label': ariaLabel, 'aria-describedby': ariaDescribedby, bodyAriaLabel, bodyAriaRole, title, titleIconVariant, titleLabel, ouiaId, ouiaSafe } = _a, props = tslib_1.__rest(_a, ["appendTo", "onEscapePress", 'aria-labelledby', 'aria-label', 'aria-describedby', "bodyAriaLabel", "bodyAriaRole", "title", "titleIconVariant", "titleLabel", "ouiaId", "ouiaSafe"]);
const { container } = this.state;
if (!helpers_1.canUseDOM || !container) {
return null;
}
return ReactDOM.createPortal(React.createElement(ModalContent_1.ModalContent, Object.assign({}, props, { boxId: this.boxId, labelId: this.labelId, descriptorId: this.descriptorId, title: title, titleIconVariant: titleIconVariant, titleLabel: titleLabel, "aria-label": ariaLabel, "aria-describedby": ariaDescribedby, "aria-labelledby": ariaLabelledby, bodyAriaLabel: bodyAriaLabel, bodyAriaRole: bodyAriaRole, ouiaId: ouiaId !== undefined ? ouiaId : this.state.ouiaStateId, ouiaSafe: ouiaSafe })), container);
}
}
exports.Modal = Modal;
Modal.displayName = 'Modal';
Modal.currentId = 0;
Modal.defaultProps = {
className: '',
isOpen: false,
title: '',
titleIconVariant: null,
titleLabel: '',
'aria-label': '',
showClose: true,
'aria-describedby': '',
'aria-labelledby': '',
id: undefined,
actions: [],
onClose: () => undefined,
variant: 'default',
hasNoBodyWrapper: false,
appendTo: () => document.body,
ouiaSafe: true
};
//# sourceMappingURL=Modal.js.map