UNPKG

@amaui/ui-react

Version:
235 lines (233 loc) 9.64 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; const _excluded = ["tonal", "color", "version", "open", "openDefault", "position", "direction", "swipe", "swipeTouchAnywhere", "swipeBackgroundFollow", "min", "removeOnExited", "onClose", "TransitionComponentProps", "Component", "className", "children"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import React from 'react'; import { clamp, is } from '@amaui/utils'; import { classNames, style as styleMethod, useAmauiTheme } from '@amaui/style-react'; import ModalElement from '../Modal'; import SlideElement from '../Slide'; import useSwipe from '../useSwipe'; import { staticClassName } from '../utils'; const useStyle = styleMethod(theme => ({ root: { '& .amaui-Modal-surface': { display: 'flex', flexDirection: 'column', margin: '0', maxHeight: 'unset', maxWidth: 'unset', minWidth: 'unset', flex: '1 0 auto', padding: '0' } }, position_fixed: { position: 'fixed' }, position_absolute: { position: 'absolute' }, version_modal_position_fixed: { '& .amaui-Modal-surface': { position: 'fixed' } }, version_modal_position_absolute: { '& .amaui-Modal-surface': { position: 'absolute' } }, version_standard: { '&.amaui-Modal-root': { position: 'unset', inset: 'unset' }, '& .amaui-Modal-surface': { position: 'relative' } }, direction_top: { '& .amaui-Modal-surface': { top: '0', width: '100%', borderRadius: `0 0 ${theme.methods.shape.radius.value(2, 'px')} ${theme.methods.shape.radius.value(2, 'px')}` } }, direction_left: { '& .amaui-Modal-surface': { left: '0', height: '100%', borderRadius: `0 ${theme.methods.shape.radius.value(2, 'px')} ${theme.methods.shape.radius.value(2, 'px')} 0` } }, direction_right: { '& .amaui-Modal-surface': { right: '0', height: '100%', borderRadius: `${theme.methods.shape.radius.value(2, 'px')} 0 0 ${theme.methods.shape.radius.value(2, 'px')}` } }, direction_bottom: { '& .amaui-Modal-surface': { bottom: '0', width: '100%', borderRadius: `${theme.methods.shape.radius.value(2, 'px')} ${theme.methods.shape.radius.value(2, 'px')} 0 0` } } }), { name: 'amaui-NavigationDrawer' }); const NavigationDrawer = /*#__PURE__*/React.forwardRef((props_, ref) => { const theme = useAmauiTheme(); const props = React.useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.amauiNavigationDrawer?.props?.default), props_), [props_]); const Modal = React.useMemo(() => theme?.elements?.Modal || ModalElement, [theme]); const Slide = React.useMemo(() => theme?.elements?.Slide || SlideElement, [theme]); const { tonal = false, color = [undefined, 'modal'].includes(props.version) ? 'themed' : 'default', version = 'modal', open: open_, openDefault, position = 'fixed', direction: direction_ = 'left', swipe = true, swipeTouchAnywhere = true, swipeBackgroundFollow = true, min, removeOnExited, onClose: onClose_, TransitionComponentProps = {}, Component = 'nav', className, children } = props, other = _objectWithoutProperties(props, _excluded); const [entered, setEntered] = React.useState(false); const [open, setOpen] = React.useState(false); const refs = { modal: React.useRef(undefined), background: React.useRef(undefined) }; const { classes } = useStyle(); let direction = direction_; if (theme.direction === 'rtl') { if (direction === 'left') direction = 'right';else if (direction === 'right') direction = 'left'; } let swipeValue; if (swipe) { const swipeOptions = { open, min, direction, touchAnywhere: swipeTouchAnywhere }; swipeValue = useSwipe(refs.modal.current, swipeOptions); } React.useEffect(() => { if (open_ !== open) setOpen(open_); }, [open_]); React.useEffect(() => { if (swipeValue && version === 'modal') { const valueSwipe = swipeValue.value; const valuePercentageSwipe = clamp(swipeValue.valuePercentage, 0, 100); const position_ = swipeValue.position; if (position_ !== undefined) { let value_; if (direction === 'top') value_ = `translateY(${valueSwipe}px)`; if (direction === 'left') value_ = `translateX(${valueSwipe}px)`; if (direction === 'right') value_ = `translateX(${valueSwipe}px)`; if (direction === 'bottom') value_ = `translateY(${valueSwipe}px)`; // Add transitions if (refs.modal.current) { refs.modal.current.style.transition = theme.methods.transitions.make('transform', { duration: 'xs' }); refs.modal.current.style.transform = value_; } if (refs.background.current) { refs.background.current.style.transition = theme.methods.transitions.make('opacity', { duration: 'xs' }); } if (position_ === 'min') { if (refs.background.current) { refs.background.current.style.opacity = '0'; } if (refs.modal.current) setTimeout(() => { onClose(); }, theme.transitions.duration.xs + 14); } if (position_ === 'max') { if (refs.background.current) { refs.background.current.style.opacity = '1'; } } } else { let value_ = ''; if (refs.modal.current) { if (direction === 'top') value_ = `translateY(${valueSwipe}px)`; if (direction === 'left') value_ = `translateX(${valueSwipe}px)`; if (direction === 'right') value_ = `translateX(${valueSwipe}px)`; if (direction === 'bottom') value_ = `translateY(${valueSwipe}px)`; // No transition refs.modal.current.style.transition = 'none'; refs.modal.current.style.transform = value_; } if (swipeBackgroundFollow && refs.background.current) { // No transition refs.background.current.style.transition = 'none'; refs.background.current.style.opacity = `${valuePercentageSwipe / 100}`; } else { // Add transition refs.background.current.style.transition = theme.methods.transitions.make('opacity', { duration: 'xs' }); } } } }, [version, swipeValue?.value, swipeValue?.position]); const onClose = React.useCallback(() => { if (is('function', onClose_)) onClose_(); }, []); if (version === 'standard') { other.portal = other.portal !== undefined ? other.portal : false; other.freezeScroll = other.freezeScroll !== undefined ? other.freezeScroll : false; other.background = other.background !== undefined ? other.background : false; other.focus = other.focus !== undefined ? other.focus : false; other.disableKeyboardClose = other.disableKeyboardClose !== undefined ? other.disableKeyboardClose : true; } TransitionComponentProps.direction = TransitionComponentProps.direction !== undefined ? TransitionComponentProps.direction : direction; TransitionComponentProps.removeOnExited = TransitionComponentProps.removeOnExited !== undefined ? TransitionComponentProps.removeOnExited : min === undefined; if (min !== undefined) { other.freezeScroll = other.freezeScroll !== undefined ? other.freezeScroll : false; other.openDefault = false; TransitionComponentProps.min = TransitionComponentProps.min !== undefined ? TransitionComponentProps.min : min; } return /*#__PURE__*/React.createElement(Modal, _extends({ ref: ref, open: open, mainRef: refs.modal, backgroundRef: refs.background, partialyOpened: min !== undefined, tonal: tonal, color: color, onClose: onClose, TransitionComponentProps: _objectSpread({ onAdded: () => setEntered(true), onEntered: () => setEntered(true), onExited: () => setEntered(false), enterOnAdd: false }, TransitionComponentProps), TransitionComponent: Slide, Component: Component, portal: position === 'fixed', className: classNames([staticClassName('NavigationDrawer', theme) && ['amaui-NavigationDrawer-root'], className, classes.root, classes[`position_${position}`], classes[`direction_${direction}`], classes[`version_${version}`], classes[`version_${version}_position_${position}`]]) }, other), children); }); NavigationDrawer.displayName = 'amaui-NavigationDrawer'; export default NavigationDrawer;