UNPKG

@ui5/webcomponents-react

Version:

React Wrapper for UI5 Web Components and additional components

291 lines (275 loc) 8 kB
'use client'; import { createRef, useEffect, useSyncExternalStore, createElement as _createElement } from 'react'; import { createPortal } from 'react-dom'; import { getRandomId } from '../../internal/getRandomId.js'; import { ModalStore } from '../../internal/ModalStore.js'; import { Dialog } from '../../webComponents/Dialog/index.js'; import { Menu } from '../../webComponents/Menu/index.js'; import { Popover } from '../../webComponents/Popover/index.js'; import { ResponsivePopover } from '../../webComponents/ResponsivePopover/index.js'; import { Toast } from '../../webComponents/Toast/index.js'; import { MessageBox } from '../MessageBox/index.js'; /** * @since 2.19.0 */ /** * @since 2.19.0 */ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime"; function autoClose(props) { const openPopovers = ModalStore.getPopoversWithSameOpener(props.opener); openPopovers.forEach(popover => { const popoverRef = popover.ref; if (popoverRef.current) { popoverRef.current.open = false; } }); } /** * @deprecated Passing `container` directly is deprecated. Use the `config` object with `config.container` instead. */ function showDialogFn(props, containerOrConfig) { const isContainer = containerOrConfig instanceof Element || containerOrConfig instanceof DocumentFragment; const id = getRandomId(); const ref = /*#__PURE__*/createRef(); ModalStore.addModal({ Component: Dialog, props: { ...props, open: true, onClose: event => { if (typeof props.onClose === 'function') { props.onClose(event); } ModalStore.removeModal(id); } }, ref, container: isContainer ? containerOrConfig : containerOrConfig?.container, id }); return { ref, close: () => { if (ref.current) { ref.current.open = false; } } }; } /** * @deprecated Passing `container` directly is deprecated. Use the `config` object with `config.container` instead. */ function showPopoverFn(props, containerOrConfig) { const isContainer = containerOrConfig instanceof Element || containerOrConfig instanceof DocumentFragment; const id = getRandomId(); const ref = /*#__PURE__*/createRef(); if (!isContainer && containerOrConfig?.autoClosePopovers) { autoClose(props); } ModalStore.addModal({ Component: Popover, props: { ...props, open: true, onClose: event => { if (typeof props.onClose === 'function') { props.onClose(event); } ModalStore.removeModal(id); } }, ref, container: isContainer ? containerOrConfig : containerOrConfig?.container, id }); return { ref, close: () => { if (ref.current) { ref.current.open = false; } } }; } /** * @deprecated Passing `container` directly is deprecated. Use the `config` object with `config.container` instead. */ function showResponsivePopoverFn(props, containerOrConfig) { const isContainer = containerOrConfig instanceof Element || containerOrConfig instanceof DocumentFragment; const id = getRandomId(); const ref = /*#__PURE__*/createRef(); if (!isContainer && containerOrConfig?.autoClosePopovers) { autoClose(props); } ModalStore.addModal({ Component: ResponsivePopover, props: { ...props, open: true, onClose: event => { if (typeof props.onClose === 'function') { props.onClose(event); } ModalStore.removeModal(id); } }, ref, container: isContainer ? containerOrConfig : containerOrConfig?.container, id }); return { ref, close: () => { if (ref.current) { ref.current.open = false; } } }; } /** * @deprecated Passing `container` directly is deprecated. Use the `config` object with `config.container` instead. */ function showMenuFn(props, containerOrConfig) { const isContainer = containerOrConfig instanceof Element || containerOrConfig instanceof DocumentFragment; const id = getRandomId(); const ref = /*#__PURE__*/createRef(); if (!isContainer && containerOrConfig?.autoClosePopovers) { autoClose(props); } ModalStore.addModal({ Component: Menu, props: { ...props, open: true, onClose: event => { if (typeof props.onClose === 'function') { props.onClose(event); } ModalStore.removeModal(id); } }, ref, container: isContainer ? containerOrConfig : containerOrConfig?.container, id }); return { ref, close: () => { if (ref.current) { ref.current.open = false; } } }; } /** * @deprecated Passing `container` directly is deprecated. Use the `config` object with `config.container` instead. */ function showMessageBoxFn(props, containerOrConfig) { const isContainer = containerOrConfig instanceof Element || containerOrConfig instanceof DocumentFragment; const id = getRandomId(); const ref = /*#__PURE__*/createRef(); ModalStore.addModal({ // @ts-expect-error: props type safety is covered by the `props` property Component: MessageBox, props: { ...props, open: true, onClose: event => { if (typeof props.onClose === 'function') { props.onClose(event); } ModalStore.removeModal(id); } }, ref, container: isContainer ? containerOrConfig : containerOrConfig?.container, id }); return { ref, close: () => { if (ref.current) { ref.current.open = false; } } }; } /** * @deprecated Passing `container` directly is deprecated. Use the `config` object with `config.container` instead. */ function showToastFn(props, containerOrConfig) { const isContainer = containerOrConfig instanceof Element || containerOrConfig instanceof DocumentFragment; const ref = /*#__PURE__*/createRef(); const id = getRandomId(); ModalStore.addModal({ Component: Toast, props: { ...props, open: true, onClose: event => { if (typeof props.onClose === 'function') { props.onClose(event); } ModalStore.removeModal(id); } }, ref, container: isContainer ? containerOrConfig : containerOrConfig?.container, id }); return { ref }; } /** * Utility class for opening modals in an imperative way. * * These static helper methods might be useful for showing e.g. Toasts or MessageBoxes after successful or failed * network calls. * * **In order to use these helpers, please make sure to render the `Modals` component somewhere in your application tree.** * * @since 0.22.2 */ export function Modals() { const modals = useSyncExternalStore(ModalStore.subscribe, ModalStore.getSnapshot, ModalStore.getServerSnapshot); useEffect(() => { return () => { ModalStore.getSnapshot().forEach(modal => { ModalStore.removeModal(modal.id); }); }; }, []); return /*#__PURE__*/_jsx(_Fragment, { children: modals.map(modal => { if (modal?.Component) { if (modal.container) { return /*#__PURE__*/createPortal( /*#__PURE__*/ // @ts-expect-error: ref is supported by all supported modals _createElement(modal.Component, { ...modal.props, ref: modal.ref, key: modal.id, "data-id": modal.id }), modal.container); } // @ts-expect-error: ref is supported by all supported modals return /*#__PURE__*/_createElement(modal.Component, { ...modal.props, ref: modal.ref, key: modal.id, "data-id": modal.id }); } }) }); } Modals.displayName = 'Modals'; Modals.showDialog = showDialogFn; Modals.showPopover = showPopoverFn; Modals.showResponsivePopover = showResponsivePopoverFn; Modals.showMenu = showMenuFn; Modals.showMessageBox = showMessageBoxFn; Modals.showToast = showToastFn;