UNPKG

wix-style-react

Version:
135 lines 7.76 kB
import React, { useEffect } from 'react'; import { generateDataAttr } from '../utils/generateDataAttr'; import PropTypes from 'prop-types'; import throttle from 'lodash/throttle'; import Header from './HeaderLayout'; import Footer from './FooterLayout'; import { st, classes } from './MessageBoxFunctionalLayout.st.css'; import { dataHooks } from './constants'; import { WixStyleReactContext } from '../WixStyleReactProvider/context'; /** MessageBoxFunctionalLayout */ const MessageBoxFunctionalLayout = ({ theme = 'blue', buttonsHeight = 'small', disableCancel = false, disableConfirmation = false, noBodyPadding = false, fullscreen = false, withEmptyState = false, dataHook, title, onCancel, onOk, onClose, confirmText, confirmPrefixIcon, confirmSuffixIcon, cancelText, cancelPrefixIcon, cancelSuffixIcon, hideFooter, footerBottomChildren, closeButton, width, margin, sideActions, withFooterAction, noPadding, image, maxHeight, children, }) => { const [state, setState] = React.useState({ hasScroll: false, scrolledToBottom: false, }); const ref = React.useRef(null); const handleMessageBoxScroll = throttle(() => { const scrolledToBottom = ref.current.scrollTop + ref.current.clientHeight === ref.current.scrollHeight; if (scrolledToBottom !== state.scrolledToBottom) { setState({ scrolledToBottom }); } }, 16); useEffect(() => { if (ref && ref.current.scrollHeight > ref.current.clientHeight) { ref.current.addEventListener('scroll', handleMessageBoxScroll); setState({ hasScroll: true }); } return () => { handleMessageBoxScroll.cancel(); // TODO: fix ESLint error // eslint-disable-next-line react-hooks/exhaustive-deps ref.current.removeEventListener('scroll', handleMessageBoxScroll); }; // TODO: fix ESLint error // eslint-disable-next-line react-hooks/exhaustive-deps }, [ref]); const Content = ({ newColorsBranding }) => { const { hasScroll, scrolledToBottom } = state; const ContentLayout = () => (React.createElement("div", { ref: ref, "data-hook": dataHooks.content, className: st(classes.content, { scrollable: typeof maxHeight !== 'undefined', noPadding: noBodyPadding, newColorsBranding, fullscreenBody: fullscreen, noFooter: hideFooter, footerBorder: hasScroll && !scrolledToBottom, withEmptyState, }), style: { maxHeight } }, children)); if (image && !withEmptyState && !newColorsBranding) { return (React.createElement("div", { className: classes.contentWithImage }, React.createElement("div", { className: st(classes.image, { withFooterAction, noPadding, }) }, image), React.createElement(ContentLayout, null))); } return React.createElement(ContentLayout, null); }; return (React.createElement(WixStyleReactContext.Consumer, null, ({ newColorsBranding }) => (React.createElement("div", { "data-hook": dataHook, className: st(classes.root, { fullscreen, newColorsBranding: newColorsBranding && !image, hasImage: newColorsBranding && !!image, }), style: { width, margin }, ...generateDataAttr({ noBodyPadding, theme }, [ 'noBodyPadding', 'theme', ]) }, React.createElement("div", { className: st(classes.topAreaContainer, { newColorsBranding }) }, newColorsBranding && image ? (React.createElement("div", { className: classes.imageContainer }, image)) : null, React.createElement("div", { className: st(classes.contentAreaContainer, { newColorsBranding, }) }, React.createElement(Header, { title: title, onCancel: onClose ? onClose : onCancel, theme: !newColorsBranding ? theme : 'newColorsBranding', closeButton: closeButton, size: newColorsBranding ? 'large' : 'medium', newColorsBranding: newColorsBranding }), React.createElement(Content, { newColorsBranding: newColorsBranding }))), !hideFooter ? (React.createElement(Footer, { newColorsBranding: newColorsBranding, bottomChildren: footerBottomChildren, enableCancel: !disableCancel, enableOk: !disableConfirmation, buttonsHeight: buttonsHeight, confirmText: confirmText, confirmPrefixIcon: confirmPrefixIcon, confirmSuffixIcon: confirmSuffixIcon, cancelText: cancelText, cancelPrefixIcon: cancelPrefixIcon, cancelSuffixIcon: cancelSuffixIcon, onCancel: onCancel, onOk: onOk, theme: theme, sideActions: sideActions })) : null)))); }; MessageBoxFunctionalLayout.displayName = 'MessageBoxFunctionalLayout'; MessageBoxFunctionalLayout.propTypes = { /** applied as data-hook HTML attribute that can be used to create driver in testing */ dataHook: PropTypes.string, /** Hides the footer that contains the action buttons */ hideFooter: PropTypes.bool, /** Defines the main action button text */ confirmText: PropTypes.node, /** Add a prefix icon for the main action button */ confirmPrefixIcon: PropTypes.element, /** Add a suffix icon for the main action button */ confirmSuffixIcon: PropTypes.element, /** Defines the secondary action button text */ cancelText: PropTypes.node, /** Add a prefix icon for the secondary action button */ cancelPrefixIcon: PropTypes.element, /** Add a suffix icon for the secondary action button */ cancelSuffixIcon: PropTypes.element, /** modal theme color */ theme: PropTypes.oneOf(['red', 'blue', 'purple']), /** Called when the main action (confirm) is clicked */ onOk: PropTypes.func, /** Called when the secondary action (cancel) is clicked */ onCancel: PropTypes.func, /** Called when the close button is clicked */ onClose: PropTypes.func, /** Specify exact width */ width: PropTypes.string, /** Specify exact margin. Use to fine tune position inside other elements. * When used inside `<Modal>`, beware that `<Modal>` is a flex container, therefore specific flex item CSS rules apply for this margin. */ margin: PropTypes.string, /** Defines the modals's header title */ title: PropTypes.node, /** The content to be displayed. can be text or some node */ children: PropTypes.any, /** Max height. When supplied - will allow internal scroll to the component */ maxHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** Defines the buttons size */ buttonsHeight: PropTypes.oneOf(['tiny', 'small', 'medium', 'large']), /** Show/hide the close button */ closeButton: PropTypes.bool, /** Defines the secondary action button */ disableCancel: PropTypes.bool, /** Defines the main action button */ disableConfirmation: PropTypes.bool, /** Removes the content padding. Used in custom modal that defines it's own padding*/ noBodyPadding: PropTypes.bool, /** A render slot to display a foot note */ footerBottomChildren: PropTypes.node, /** Stretches the component to a full screen mode (with some padding) */ fullscreen: PropTypes.bool, /** Changes the internal padding to be used with `<EmptyState/>` component */ withEmptyState: PropTypes.bool, /** Used to display some side component in the footer, for example `<Checkbox/>` */ sideActions: PropTypes.node, /** Used to display an illustration on the left side */ image: PropTypes.node, }; export default MessageBoxFunctionalLayout; //# sourceMappingURL=MessageBoxFunctionalLayout.js.map