UNPKG

@amaui/ui-react

Version:
196 lines (195 loc) 7.83 kB
import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; const _excluded = ["children", "style"], _excluded2 = ["in", "value", "prefix", "run", "append", "add", "enter", "exit", "enterOnAdd", "exitOnAdd", "noAbruption", "removeOnExited", "delay", "duration", "timing_function", "addTransition", "onTransition", "onAppended", "onAdd", "onAdding", "onAdded", "onEnter", "onEntering", "onEntered", "onExit", "onExiting", "onExited", "onRemoved", "expandSize", "orientation", "WrapperProps", "className", "style", "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 { is } from '@amaui/utils'; import { useAmauiTheme } from '@amaui/style-react'; import { Transition } from '..'; const Wrapper = /*#__PURE__*/React.forwardRef((props, ref) => { const { children, style } = props, other = _objectWithoutProperties(props, _excluded); return /*#__PURE__*/React.createElement("div", _extends({ ref: ref }, other, { style: _objectSpread({ width: '100%' }, style) }), props.children); }); const Expand = /*#__PURE__*/React.forwardRef((props_, ref) => { const theme = useAmauiTheme(); const props = React.useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.amauiExpand?.props?.default), props_), [props_]); const { in: inProp, value: valueProvided, prefix, run, append, add, enter, exit, enterOnAdd, exitOnAdd, noAbruption, removeOnExited = true, delay, duration: duration_, timing_function, addTransition, onTransition, onAppended, onAdd, onAdding, onAdded, onEnter, onEntering, onEntered, onExit, onExiting, onExited, onRemoved, expandSize, orientation, WrapperProps, className, style, children } = props, other = _objectWithoutProperties(props, _excluded2); const [value, setValue] = React.useState(valueProvided !== undefined ? valueProvided : null); const [parent, setParent] = React.useState(); const refs = { root: React.useRef(undefined), placeholder: React.useRef(undefined), parent: React.useRef(undefined), element: React.useRef(undefined), value: React.useRef(0) }; refs.value.current = value; refs.parent.current = parent; let prop = 'height'; if (orientation === 'horizontal') prop = 'width'; const isTransition = React.useCallback(item => { const values = ['Transition', 'Fade', 'Grow', 'Slide', 'Zoom']; return values.some(item_ => item?.includes(item_)); }, []); const childrenWithTransition = isTransition(children?.type?.displayName); React.useEffect(() => { const method = () => { setValue(null); setParent(null); }; // on resize // recalculate width, value window.addEventListener('resize', method); return () => { window.removeEventListener('resize', method); }; }, []); const styles = status => { const styles_ = refs.root.current && window.getComputedStyle(refs.root?.current) || {}; const allStyles = { appended: { position: 'fixed', left: '1114%', visibility: 'hidden' }, enter: { transition: 'none', [prop]: 0, overflow: 'hidden' }, entering: { [prop]: `${valueProvided !== undefined ? valueProvided : refs.value.current}px`, overflow: 'hidden' }, entered: { [prop]: 'auto' }, exit: { [prop]: styles_[prop], overflow: 'hidden' }, exiting: { [prop]: expandSize !== undefined ? expandSize : '0', overflow: 'hidden' }, exited: { [prop]: expandSize !== undefined ? expandSize : '0', overflow: 'hidden' } }; return allStyles[status]; }; const duration = function (status) { let property = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'opacity'; const properties = { [prop]: theme.transitions.duration.rg }; return `${(is('simple', duration) ? duration : duration[status]) || properties[property]}ms`; }; const timingFunction = status => (is('simple', timing_function) ? timing_function : timing_function[status]) || theme.transitions.timing_function.standard; const children_ = /*#__PURE__*/React.createElement(Wrapper, WrapperProps, children); return /*#__PURE__*/React.createElement(React.Fragment, null, value === null && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { ref: item => { if (!item) return; if (!parent) setParent(item.parentElement); } }), parent && /*#__PURE__*/React.createElement(Wrapper, _extends({}, WrapperProps, { ref: item => { if (!item) return; if (WrapperProps?.ref) { if (is('function', WrapperProps.ref)) WrapperProps?.ref(item);else WrapperProps.ref.current = item; } if (refs.value.current === null) { setValue(item.getBoundingClientRect()[prop] || 0); } }, style: _objectSpread({ position: 'fixed', left: '1114%', visibility: 'hidden', width: parent.offsetWidth }, WrapperProps?.style) }), /*#__PURE__*/React.cloneElement(children, _objectSpread({}, childrenWithTransition && { in: true })))), value !== null && /*#__PURE__*/React.createElement(Transition, _extends({ removeOnExited: true }, props), (status, ref_) => { // If children update // & value is updated if (['appending', 'appended', 'adding', 'added', 'entering', 'entered'].includes(status)) { const value_ = (refs.root.current?.getBoundingClientRect() || {})[prop]; if (value_ > 0 && value_ !== refs.value.current) setValue(value_); } return /*#__PURE__*/React.cloneElement(children_, _objectSpread(_objectSpread({}, other), {}, { className, ref: item => { refs.root.current = item; if (ref) { if (is('function', ref)) ref(item);else ref.current = item; } if (ref_) { if (is('function', ref_)) ref_(item);else ref_.current = item; } if (children_.ref) { if (is('function', children_.ref)) children_.ref(item);else children_.ref.current = item; } }, style: _objectSpread(_objectSpread(_objectSpread({ position: 'relative', transition: `${prop} ${duration(status, prop)} ${timingFunction(status)} ${addTransition ? `, ${addTransition}` : ''}`, visibility: status === 'exited' && !inProp && expandSize === undefined ? 'hidden' : undefined }, styles(status)), style), children_?.style) })); })); }); Expand.displayName = 'amaui-Expand'; export default Expand;