UNPKG

@onesy/ui-react

Version:
324 lines (309 loc) 14.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.STATUS = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _utils = require("@onesy/utils"); var _subscription = _interopRequireDefault(require("@onesy/subscription")); var _styleReact = require("@onesy/style-react"); var _Context = _interopRequireDefault(require("./Context")); var _utils2 = require("../utils"); var _jsxRuntime = require("react/jsx-runtime"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } const STATUS = exports.STATUS = { appended: 'appended', add: 'add', added: 'added', adding: 'adding', enter: 'enter', entering: 'entering', entered: 'entered', exit: 'exit', exiting: 'exiting', exited: 'exited', removed: 'removed' }; const Transition = props_ => { var _theme$ui, _theme$ui2; const theme = (0, _styleReact.useOnesyTheme)(); const props = _objectSpread(_objectSpread(_objectSpread({}, theme === null || theme === void 0 || (_theme$ui = theme.ui) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.elements) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.all) === null || _theme$ui === void 0 || (_theme$ui = _theme$ui.props) === null || _theme$ui === void 0 ? void 0 : _theme$ui.default), theme === null || theme === void 0 || (_theme$ui2 = theme.ui) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.elements) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.onesyTransition) === null || _theme$ui2 === void 0 || (_theme$ui2 = _theme$ui2.props) === null || _theme$ui2 === void 0 ? void 0 : _theme$ui2.default), props_); const { in: inProp_, // @ts-ignore name, prefix, run, append, add: add_, enter: enter_ = true, exit: exit_ = true, enterOnAdd = props.add || props.enter, exitOnAdd, noAbruption, removeOnExited, preEnterAppendTimeout = 14, delay: delay_, duration: duration_, // An all in one method onTransition, onInit, onAppended, onAdd, onAdding, onAdded, onEnter, onEntering, onEntered: onEntered_, onExit, onExiting, onExited, onRemoved, className, children, ref } = props; const [init, setInit] = _react.default.useState(false); const [inProp, setInProp] = _react.default.useState(inProp_); const [status, setStatus] = _react.default.useState(() => { let statusNew = ''; if (inProp) { statusNew = add_ ? STATUS.add : STATUS.entered; if (enterOnAdd) statusNew = STATUS.enter; } else { statusNew = enterOnAdd || removeOnExited ? STATUS.removed : STATUS.exited; if (exitOnAdd) statusNew = STATUS.exit; } if (append) statusNew = 'appended'; return statusNew; }); const subs = _react.default.useRef({ status: new _subscription.default() }); const refs = { root: _react.default.useRef(undefined), status: _react.default.useRef(undefined), inProp: _react.default.useRef(undefined), prefix: _react.default.useRef(undefined) }; refs.status.current = status; refs.inProp.current = inProp; refs.prefix.current = prefix; _react.default.useEffect(() => { let statusNew_0; if (status === 'appended') { if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, 'appended'); if ((0, _utils.is)('function', onAppended)) onAppended(refs.root.current); } if (inProp) { statusNew_0 = add_ ? STATUS.add : STATUS.entered; if (enterOnAdd) statusNew_0 = STATUS.enter; } else { statusNew_0 = enterOnAdd || removeOnExited ? STATUS.removed : STATUS.exited; if (exitOnAdd) statusNew_0 = STATUS.exit; } if ((0, _utils.is)('function', onInit)) onInit(refs.root.current); // Update update(statusNew_0); setInit(true); }, []); _react.default.useEffect(() => { if (init) { var _refs$root$current, _refs$root$current2; let statusNew_1; if (inProp) { if ([STATUS.enter, STATUS.entered].indexOf(status) === -1) statusNew_1 = STATUS.enter; } else { if ([STATUS.exit, STATUS.exited].indexOf(status) === -1) statusNew_1 = STATUS.exit; } // Added const classNameValue = ((_refs$root$current = refs.root.current) === null || _refs$root$current === void 0 || (_refs$root$current = _refs$root$current.className) === null || _refs$root$current === void 0 ? void 0 : _refs$root$current.baseVal) || ((_refs$root$current2 = refs.root.current) === null || _refs$root$current2 === void 0 ? void 0 : _refs$root$current2.className); if (inProp && (!refs.root.current || (classNameValue === null || classNameValue === void 0 ? void 0 : classNameValue.indexOf('removed')) > -1)) { // We add the element and get the ref value // for update below to use it for enter update('appended'); // Prevent update batches setTimeout(() => update(statusNew_1), preEnterAppendTimeout); } else update(statusNew_1); } }, [inProp]); _react.default.useEffect(() => { if (status === STATUS.exited && removeOnExited) { updateStatus('removed'); // Subscriptions subs.current.status.emit('removed'); } }, [status]); _react.default.useEffect(() => { if (!inProp_ && noAbruption && ['enter', 'entering'].indexOf(subs.current.status.value) > -1) { const sub = item => { if (item === 'entered') { setInProp(inProp_); subs.current.status.unsubscribe(sub); } }; subs.current.status.subscribe(sub); } else if (inProp_ && noAbruption && ['exit', 'exiting'].indexOf(subs.current.status.value) > -1) { const sub_0 = item_0 => { if (item_0 === 'exited') { setInProp(inProp_); subs.current.status.unsubscribe(sub_0); } }; subs.current.status.subscribe(sub_0); } else if (!inProp_ && noAbruption && subs.current.status.value === 'entered' || inProp_ && noAbruption && subs.current.status.value === 'exited' || inProp_ !== inProp) setInProp(inProp_); }, [inProp_]); const update = async (status_, pause) => { if (pause !== undefined) await (0, _utils.wait)(pause); refs.status.current = status_; switch (status_) { case 'add': return await add(status_); case 'enter': return await enter(status_); case 'exit': return await exit(status_); case 'exited': return updateStatus(status_); default: return updateStatus(status_); } }; const delay = async status__0 => { let value = delay_; if ((0, _utils.is)('string', value) && theme.transitions.duration[value] !== undefined) value = theme.transitions.duration[value]; if ((0, _utils.is)('object', value)) value = value[status__0] !== undefined ? value[status__0] : value.default; if (!((0, _utils.is)('number', value) && value > 0)) return; await (0, _utils.wait)(value); }; const duration = async status__1 => { let value_0 = duration_; if ((0, _utils.is)('string', value_0) && theme.transitions.duration[value_0] !== undefined) value_0 = theme.transitions.duration[value_0]; if ((0, _utils.is)('object', value_0)) value_0 = value_0[status__1] !== undefined ? value_0[status__1] : value_0.default; if (!(0, _utils.is)('number', value_0)) value_0 = theme.transitions.duration.rg; if (!((0, _utils.is)('number', value_0) && value_0 > 0)) return; await (0, _utils.wait)(value_0); }; const add = async status__2 => { if (!add_ || refs.status.current !== status__2) return; updateStatus('add'); await delay('add'); // Prevent update batches await (0, _utils.wait)(14); updateStatus('adding'); // await duration('add'); if (refs.status.current === status__2) updateStatus('added'); }; const enter = async status__3 => { var _refs$status$current; if (!enter_ || status__3 !== 'appended' && (refs.status.current !== status__3 || !refs.inProp.current)) return; updateStatus('enter'); await delay('enter'); // Prevent update batches await (0, _utils.wait)(14); updateStatus('entering'); await duration('enter'); if (((_refs$status$current = refs.status.current) === null || _refs$status$current === void 0 ? void 0 : _refs$status$current.indexOf('exit')) === -1) updateStatus('entered'); }; const exit = async status__4 => { var _refs$status$current2; if (!exit_ || refs.status.current !== status__4 || refs.inProp.current) return; updateStatus('exit'); await delay('exit'); // Prevent update batches await (0, _utils.wait)(14); updateStatus('exiting'); await duration('exit'); if (((_refs$status$current2 = refs.status.current) === null || _refs$status$current2 === void 0 ? void 0 : _refs$status$current2.indexOf('enter')) === -1) updateStatus('exited'); }; const onEntered = element => { if ((0, _utils.is)('function', onEntered_)) onEntered_(element); if (run && inProp) setInProp(false); }; const updateStatus = status__5 => { setStatus(status__5); // Subscriptions subs.current.status.emit(status__5); switch (status__5) { case 'appended': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onAppended)) onAppended(refs.root.current); break; case 'add': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onAdd)) onAdd(refs.root.current); break; case 'adding': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onAdding)) onAdding(refs.root.current); break; case 'added': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onAdded)) onAdded(refs.root.current); break; case 'enter': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onEnter)) onEnter(refs.root.current); break; case 'entering': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onEntering)) onEntering(refs.root.current); break; case 'entered': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onEntered)) onEntered(refs.root.current); break; case 'exit': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onExit)) onExit(refs.root.current); break; case 'exiting': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onExiting)) onExiting(refs.root.current); break; case 'exited': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onExited)) onExited(refs.root.current); break; case 'removed': if ((0, _utils.is)('function', onTransition)) onTransition(refs.root.current, status__5); if ((0, _utils.is)('function', onRemoved)) onRemoved(refs.root.current); break; default: break; } // Add className if (className && (0, _utils.is)('element', refs.root.current)) { var _ref, _refs$root$current$cl, _refs$root$current$cl2; let className_ = (0, _styleReact.classNames)([(_ref = ((_refs$root$current$cl = refs.root.current.className) === null || _refs$root$current$cl === void 0 ? void 0 : _refs$root$current$cl.baseVal) || refs.root.current.className) === null || _ref === void 0 ? void 0 : _ref.split(' ')]); // Remove all previous classes className_ = className_.replace(new RegExp(`(^| )${refs.prefix.current || ''}(add|enter|exit)(ed|ing)?($| )`, 'g'), ' '); // Add className_ += ` ${refs.prefix.current || ''}${status__5}`; className_ = className_.replace(/ +/g, ' ').trim(); if ((_refs$root$current$cl2 = refs.root.current.className) !== null && _refs$root$current$cl2 !== void 0 && _refs$root$current$cl2.baseVal) refs.root.current.className.baseVal = className_;else refs.root.current.className = className_; } // reflow (0, _utils2.reflow)(refs.root.current); }; if (status === 'removed') return null; const value_ = { status }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Context.default.Provider, { value: value_, children: (0, _utils.is)('function', children) ? children(status, refs.root) : /*#__PURE__*/_react.default.cloneElement(children, { ref: item_1 => { if (ref) { if ((0, _utils.is)('function', ref)) ref(item_1);else ref.current = item_1; } refs.root.current = item_1; } }) }); }; Transition.displayName = 'onesy-Transition'; var _default = exports.default = Transition;