@wordpress/components
Version:
UI components for WordPress.
175 lines (171 loc) • 7.74 kB
JavaScript
;
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