@gechiui/components
Version:
UI components for GeChiUI.
136 lines (124 loc) • 4.09 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { createElement } from "@gechiui/element";
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* GeChiUI dependencies
*/
import { createPortal, useEffect, useRef } from '@gechiui/element';
import { useInstanceId, useFocusReturn, useFocusOnMount, __experimentalUseFocusOutside as useFocusOutside, useConstrainedTabbing, useMergeRefs } from '@gechiui/compose';
import deprecated from '@gechiui/deprecated';
import { ESCAPE } from '@gechiui/keycodes';
import { __ } from '@gechiui/i18n';
import { closeSmall } from '@gechiui/icons';
/**
* Internal dependencies
*/
import * as ariaHelper from './aria-helper';
import Button from '../button';
import StyleProvider from '../style-provider'; // Used to count the number of open modals.
let openModalCount = 0;
export default function Modal(_ref) {
let {
bodyOpenClassName = 'modal-open',
role = 'dialog',
title = null,
focusOnMount = true,
shouldCloseOnEsc = true,
shouldCloseOnClickOutside = true,
isDismissable,
// Deprecated
isDismissible = isDismissable || true,
/* accessibility */
aria = {
labelledby: null,
describedby: null
},
onRequestClose,
icon,
closeButtonLabel,
children,
style,
overlayClassName,
className,
contentLabel,
onKeyDown,
isFullScreen = false
} = _ref;
const ref = useRef();
const instanceId = useInstanceId(Modal);
const headingId = title ? `components-modal-header-${instanceId}` : aria.labelledby;
const focusOnMountRef = useFocusOnMount(focusOnMount);
const constrainedTabbingRef = useConstrainedTabbing();
const focusReturnRef = useFocusReturn();
const focusOutsideProps = useFocusOutside(onRequestClose);
useEffect(() => {
openModalCount++;
if (openModalCount === 1) {
ariaHelper.hideApp(ref.current);
document.body.classList.add(bodyOpenClassName);
}
return () => {
openModalCount--;
if (openModalCount === 0) {
document.body.classList.remove(bodyOpenClassName);
ariaHelper.showApp();
}
};
}, []);
if (isDismissable) {
deprecated('isDismissable prop of the Modal component', {
since: '5.4',
alternative: 'isDismissible prop (renamed) of the Modal component'
});
}
function handleEscapeKeyDown(event) {
if (shouldCloseOnEsc && event.keyCode === ESCAPE && !event.defaultPrevented) {
event.preventDefault();
if (onRequestClose) {
onRequestClose(event);
}
}
}
return createPortal( // eslint-disable-next-line jsx-a11y/no-static-element-interactions
createElement("div", {
ref: ref,
className: classnames('components-modal__screen-overlay', overlayClassName),
onKeyDown: handleEscapeKeyDown
}, createElement(StyleProvider, {
document: document
}, createElement("div", _extends({
className: classnames('components-modal__frame', className, {
'is-full-screen': isFullScreen
}),
style: style,
ref: useMergeRefs([constrainedTabbingRef, focusReturnRef, focusOnMountRef]),
role: role,
"aria-label": contentLabel,
"aria-labelledby": contentLabel ? null : headingId,
"aria-describedby": aria.describedby,
tabIndex: "-1"
}, shouldCloseOnClickOutside ? focusOutsideProps : {}, {
onKeyDown: onKeyDown
}), createElement("div", {
className: 'components-modal__content',
role: "document"
}, createElement("div", {
className: "components-modal__header"
}, createElement("div", {
className: "components-modal__header-heading-container"
}, icon && createElement("span", {
className: "components-modal__icon-container",
"aria-hidden": true
}, icon), title && createElement("h1", {
id: headingId,
className: "components-modal__header-heading"
}, title)), isDismissible && createElement(Button, {
onClick: onRequestClose,
icon: closeSmall,
label: closeButtonLabel || __('关闭对话框')
})), children)))), document.body);
}
//# sourceMappingURL=index.js.map