UNPKG

@wordpress/components

Version:
175 lines (171 loc) 7.74 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.ConfirmDialog = void 0; var _i18n = require("@wordpress/i18n"); var _element = require("@wordpress/element"); var _modal = _interopRequireDefault(require("../modal")); var _context = require("../context"); var _flex = require("../flex"); var _button = _interopRequireDefault(require("../button")); var _text = require("../text"); var _vStack = require("../v-stack"); var styles = _interopRequireWildcard(require("./styles")); var _useCx = require("../utils/hooks/use-cx"); var _jsxRuntime = require("react/jsx-runtime"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /** * WordPress dependencies */ /** * Internal dependencies */ const UnconnectedConfirmDialog = (props, forwardedRef) => { const { isOpen: isOpenProp, onConfirm, onCancel, children, confirmButtonText, cancelButtonText, ...otherProps } = (0, _context.useContextSystem)(props, 'ConfirmDialog'); const cx = (0, _useCx.useCx)(); const wrapperClassName = cx(styles.wrapper); const cancelButtonRef = (0, _element.useRef)(); const confirmButtonRef = (0, _element.useRef)(); const [isOpen, setIsOpen] = (0, _element.useState)(); const [shouldSelfClose, setShouldSelfClose] = (0, _element.useState)(); (0, _element.useEffect)(() => { // We only allow the dialog to close itself if `isOpenProp` is *not* set. // If `isOpenProp` is set, then it (probably) means it's controlled by a // parent component. In that case, `shouldSelfClose` might do more harm than // good, so we disable it. const isIsOpenSet = typeof isOpenProp !== 'undefined'; setIsOpen(isIsOpenSet ? isOpenProp : true); setShouldSelfClose(!isIsOpenSet); }, [isOpenProp]); const handleEvent = (0, _element.useCallback)(callback => event => { callback?.(event); if (shouldSelfClose) { setIsOpen(false); } }, [shouldSelfClose, setIsOpen]); const handleEnter = (0, _element.useCallback)(event => { // Avoid triggering the 'confirm' action when a button is focused, // as this can cause a double submission. const isConfirmOrCancelButton = event.target === cancelButtonRef.current || event.target === confirmButtonRef.current; if (!isConfirmOrCancelButton && event.key === 'Enter') { handleEvent(onConfirm)(event); } }, [handleEvent, onConfirm]); const cancelLabel = cancelButtonText !== null && cancelButtonText !== void 0 ? cancelButtonText : (0, _i18n.__)('Cancel'); const confirmLabel = confirmButtonText !== null && confirmButtonText !== void 0 ? confirmButtonText : (0, _i18n.__)('OK'); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, { children: isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_modal.default, { onRequestClose: handleEvent(onCancel), onKeyDown: handleEnter, closeButtonLabel: cancelLabel, isDismissible: true, ref: forwardedRef, overlayClassName: wrapperClassName, __experimentalHideHeader: true, ...otherProps, children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_vStack.VStack, { spacing: 8, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_text.Text, { children: children }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_flex.Flex, { direction: "row", justify: "flex-end", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_button.default, { __next40pxDefaultSize: true, ref: cancelButtonRef, variant: "tertiary", onClick: handleEvent(onCancel), children: cancelLabel }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.default, { __next40pxDefaultSize: true, ref: confirmButtonRef, variant: "primary", onClick: handleEvent(onConfirm), children: confirmLabel })] })] }) }) }); }; /** * `ConfirmDialog` is built of top of [`Modal`](/packages/components/src/modal/README.md) * and displays a confirmation dialog, with _confirm_ and _cancel_ buttons. * The dialog is confirmed by clicking the _confirm_ button or by pressing the `Enter` key. * It is cancelled (closed) by clicking the _cancel_ button, by pressing the `ESC` key, or by * clicking outside the dialog focus (i.e, the overlay). * * `ConfirmDialog` has two main implicit modes: controlled and uncontrolled. * * UnControlled: * * Allows the component to be used standalone, just by declaring it as part of another React's component render method: * - It will be automatically open (displayed) upon mounting; * - It will be automatically closed when clicking the _cancel_ button, by pressing the `ESC` key, or by clicking outside the dialog focus (i.e, the overlay); * - `onCancel` is not mandatory but can be passed. Even if passed, the dialog will still be able to close itself. * * Activating this mode is as simple as omitting the `isOpen` prop. The only mandatory prop, in this case, is the `onConfirm` callback. The message is passed as the `children`. You can pass any JSX you'd like, which allows to further format the message or include sub-component if you'd like: * * ```jsx * import { __experimentalConfirmDialog as ConfirmDialog } from '@wordpress/components'; * * function Example() { * return ( * <ConfirmDialog onConfirm={ () => console.debug( ' Confirmed! ' ) }> * Are you sure? <strong>This action cannot be undone!</strong> * </ConfirmDialog> * ); * } * ``` * * * Controlled mode: * Let the parent component control when the dialog is open/closed. It's activated when a * boolean value is passed to `isOpen`: * - It will not be automatically closed. You need to let it know when to open/close by updating the value of the `isOpen` prop; * - Both `onConfirm` and the `onCancel` callbacks are mandatory props in this mode; * - You'll want to update the state that controls `isOpen` by updating it from the `onCancel` and `onConfirm` callbacks. * *```jsx * import { __experimentalConfirmDialog as ConfirmDialog } from '@wordpress/components'; * import { useState } from '@wordpress/element'; * * function Example() { * const [ isOpen, setIsOpen ] = useState( true ); * * const handleConfirm = () => { * console.debug( 'Confirmed!' ); * setIsOpen( false ); * }; * * const handleCancel = () => { * console.debug( 'Cancelled!' ); * setIsOpen( false ); * }; * * return ( * <ConfirmDialog * isOpen={ isOpen } * onConfirm={ handleConfirm } * onCancel={ handleCancel } * > * Are you sure? <strong>This action cannot be undone!</strong> * </ConfirmDialog> * ); * } * ``` */ const ConfirmDialog = exports.ConfirmDialog = (0, _context.contextConnect)(UnconnectedConfirmDialog, 'ConfirmDialog'); var _default = exports.default = ConfirmDialog; //# sourceMappingURL=component.js.map