UNPKG

@ui5/webcomponents-react

Version:

React Wrapper for UI5 Web Components and additional components

198 lines (194 loc) 7.05 kB
'use client'; import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js'; import IconMode from '@ui5/webcomponents/dist/types/IconMode.js'; import PopupAccessibleRole from '@ui5/webcomponents/dist/types/PopupAccessibleRole.js'; import TitleLevel from '@ui5/webcomponents/dist/types/TitleLevel.js'; import ValueState from '@ui5/webcomponents-base/dist/types/ValueState.js'; import iconSysHelp from '@ui5/webcomponents-icons/dist/sys-help-2.js'; import { useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base'; import { clsx } from 'clsx'; import { cloneElement, forwardRef, isValidElement, useId } from 'react'; import { MessageBoxAction } from '../../enums/MessageBoxAction.js'; import { MessageBoxType } from '../../enums/MessageBoxType.js'; import { ABORT, CANCEL, CLOSE, CONFIRMATION, DELETE, ERROR, IGNORE, INFORMATION, NO, OK, RETRY, SUCCESS, WARNING, YES } from '../../i18n/i18n-defaults.js'; import { Button, Dialog, Icon, Text, Title } from '../../webComponents/index.js'; import { classNames, styleData } from './MessageBox.module.css.js'; // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const getIcon = (icon, type, classes) => { if (/*#__PURE__*/isValidElement(icon)) return icon; switch (type) { case MessageBoxType.Confirm: return /*#__PURE__*/_jsx(Icon, { name: iconSysHelp, mode: IconMode.Decorative, className: classes.confirmIcon }); default: return null; } }; const convertMessageBoxTypeToState = type => { switch (type) { case MessageBoxType.Information: return ValueState.Information; case MessageBoxType.Success: return ValueState.Positive; case MessageBoxType.Warning: return ValueState.Critical; case MessageBoxType.Error: return ValueState.Negative; default: return ValueState.None; } }; const getActions = (actions, type) => { if (actions && actions.length > 0) { return actions; } if (type === MessageBoxType.Confirm) { return [MessageBoxAction.OK, MessageBoxAction.Cancel]; } if (type === MessageBoxType.Error) { return [MessageBoxAction.Close]; } return [MessageBoxAction.OK]; }; /** * The `MessageBox` component provides easier methods to create a `Dialog`, such as standard alerts, confirmation dialogs, or arbitrary message dialogs. */ const MessageBox = /*#__PURE__*/forwardRef((props, ref) => { const { open, type = MessageBoxType.Confirm, children, className, titleText, icon, actions = [], emphasizedAction = MessageBoxAction.OK, onClose, initialFocus, ...rest } = props; useStylesheet(styleData, MessageBox.displayName); const i18nBundle = useI18nBundle('@ui5/webcomponents-react'); const actionTranslations = { [MessageBoxAction.Abort]: i18nBundle.getText(ABORT), [MessageBoxAction.Cancel]: i18nBundle.getText(CANCEL), [MessageBoxAction.Close]: i18nBundle.getText(CLOSE), [MessageBoxAction.Delete]: i18nBundle.getText(DELETE), [MessageBoxAction.Ignore]: i18nBundle.getText(IGNORE), [MessageBoxAction.No]: i18nBundle.getText(NO), [MessageBoxAction.OK]: i18nBundle.getText(OK), [MessageBoxAction.Retry]: i18nBundle.getText(RETRY), [MessageBoxAction.Yes]: i18nBundle.getText(YES) }; const titleToRender = () => { if (titleText) { return titleText; } switch (type) { case MessageBoxType.Confirm: return i18nBundle.getText(CONFIRMATION); case MessageBoxType.Error: return i18nBundle.getText(ERROR); case MessageBoxType.Information: return i18nBundle.getText(INFORMATION); case MessageBoxType.Success: return i18nBundle.getText(SUCCESS); case MessageBoxType.Warning: return i18nBundle.getText(WARNING); default: return null; } }; const handleDialogClose = e => { if (typeof props.onBeforeClose === 'function') { props.onBeforeClose(e); } if (e.detail.escPressed && typeof onClose === 'function') { onClose(undefined, e.detail.escPressed); } }; const handleOnClose = e => { const { action } = e.currentTarget.dataset; if (typeof onClose === 'function') { onClose(action); } }; const messageBoxId = useId(); const internalActions = getActions(actions, type); const getInitialFocus = () => { const index = internalActions.findIndex(action => action === initialFocus); if (index !== -1 && typeof internalActions[index] === 'string') { return `${messageBoxId}-action-${index}`; } return initialFocus; }; // @ts-expect-error: footer, headerText and onClose are already omitted via prop types const { footer: _0, headerText: _1, onClose: _2, onBeforeClose: _3, ...restWithoutOmitted } = rest; const iconToRender = getIcon(icon, type, classNames); const needsCustomHeader = !props.header && !!iconToRender; return /*#__PURE__*/_jsxs(Dialog, { open: open, ref: ref, className: clsx(classNames.messageBox, className), onBeforeClose: handleDialogClose, accessibleNameRef: needsCustomHeader ? `${messageBoxId}-title ${messageBoxId}-text` : undefined, accessibleRole: PopupAccessibleRole.AlertDialog, ...restWithoutOmitted, headerText: titleToRender(), state: convertMessageBoxTypeToState(type), initialFocus: getInitialFocus(), "data-type": type, children: [needsCustomHeader && /*#__PURE__*/_jsxs("div", { slot: "header", className: classNames.header, children: [iconToRender, iconToRender && /*#__PURE__*/_jsx("span", { className: classNames.spacer }), /*#__PURE__*/_jsx(Title, { id: `${messageBoxId}-title`, level: TitleLevel.H1, children: titleToRender() })] }), /*#__PURE__*/_jsx(Text, { id: `${messageBoxId}-text`, children: children }), /*#__PURE__*/_jsx("div", { slot: "footer", className: classNames.footer, children: internalActions.map((action, index) => { if (typeof action !== 'string' && /*#__PURE__*/isValidElement(action)) { return /*#__PURE__*/cloneElement(action, { onClick: action?.props?.onClick ? e => { action?.props?.onClick(e); handleOnClose(e); } : handleOnClose, 'data-action': action?.props?.['data-action'] ?? `${index}: custom action` }); } if (typeof action === 'string') { return /*#__PURE__*/_jsx(Button, { id: `${messageBoxId}-action-${index}`, design: emphasizedAction === action ? ButtonDesign.Emphasized : ButtonDesign.Transparent, onClick: handleOnClose, "data-action": action, children: actionTranslations[action] ?? action }, `${action}-${index}`); } return null; }) })] }); }); MessageBox.displayName = 'MessageBox'; export { MessageBox };