UNPKG

@amaui/ui-react

Version:
348 lines (347 loc) 15.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.STATUS = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = __importDefault(require("react")); const utils_1 = require("@amaui/utils"); const subscription_1 = __importDefault(require("@amaui/subscription")); const style_react_1 = require("@amaui/style-react"); const Context_1 = __importDefault(require("./Context")); const utils_2 = require("../utils"); 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_) => { const theme = (0, style_react_1.useAmauiTheme)(); const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.amauiTransition) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]); const { in: inProp_, 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_1.default.useState(false); const [inProp, setInProp] = react_1.default.useState(inProp_); const [status, setStatus] = react_1.default.useState(() => { let statusNew = ''; if (inProp) { statusNew = add_ ? exports.STATUS.add : exports.STATUS.entered; if (enterOnAdd) statusNew = exports.STATUS.enter; } else { statusNew = (enterOnAdd || removeOnExited) ? exports.STATUS.removed : exports.STATUS.exited; if (exitOnAdd) statusNew = exports.STATUS.exit; } if (append) statusNew = 'appended'; return statusNew; }); const subs = react_1.default.useRef({ status: new subscription_1.default() }); const refs = { root: react_1.default.useRef(undefined), status: react_1.default.useRef(undefined), inProp: react_1.default.useRef(undefined), prefix: react_1.default.useRef(undefined) }; refs.status.current = status; refs.inProp.current = inProp; refs.prefix.current = prefix; react_1.default.useEffect(() => { let statusNew; if (status === 'appended') { if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, 'appended'); if ((0, utils_1.is)('function', onAppended)) onAppended(refs.root.current); } if (inProp) { statusNew = add_ ? exports.STATUS.add : exports.STATUS.entered; if (enterOnAdd) statusNew = exports.STATUS.enter; } else { statusNew = (enterOnAdd || removeOnExited) ? exports.STATUS.removed : exports.STATUS.exited; if (exitOnAdd) statusNew = exports.STATUS.exit; } if ((0, utils_1.is)('function', onInit)) onInit(refs.root.current); // Update update(statusNew); setInit(true); }, []); react_1.default.useEffect(() => { var _a, _b, _c; if (init) { let statusNew; if (inProp) { if ([exports.STATUS.enter, exports.STATUS.entered].indexOf(status) === -1) statusNew = exports.STATUS.enter; } else { if ([exports.STATUS.exit, exports.STATUS.exited].indexOf(status) === -1) statusNew = exports.STATUS.exit; } // Added const classNameValue = ((_b = (_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.className) === null || _b === void 0 ? void 0 : _b.baseVal) || ((_c = refs.root.current) === null || _c === void 0 ? void 0 : _c.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), preEnterAppendTimeout); } else update(statusNew); } }, [inProp]); react_1.default.useEffect(() => { if (status === exports.STATUS.exited && removeOnExited) { updateStatus('removed'); // Subscriptions subs.current.status.emit('removed'); } }, [status]); react_1.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 = (item) => { if (item === 'exited') { setInProp(inProp_); subs.current.status.unsubscribe(sub); } }; subs.current.status.subscribe(sub); } 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_1.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 = react_1.default.useCallback(async (status_) => { let value = delay_; if ((0, utils_1.is)('string', value) && theme.transitions.duration[value] !== undefined) value = theme.transitions.duration[value]; if ((0, utils_1.is)('object', value)) value = value[status_] !== undefined ? value[status_] : value.default; if (!((0, utils_1.is)('number', value) && value > 0)) return; await (0, utils_1.wait)(value); }, [delay_, theme]); const duration = react_1.default.useCallback(async (status_) => { let value = duration_; if ((0, utils_1.is)('string', value) && theme.transitions.duration[value] !== undefined) value = theme.transitions.duration[value]; if ((0, utils_1.is)('object', value)) value = value[status_] !== undefined ? value[status_] : value.default; if (!(0, utils_1.is)('number', value)) value = theme.transitions.duration.rg; if (!((0, utils_1.is)('number', value) && value > 0)) return; await (0, utils_1.wait)(value); }, [duration_, theme]); const add = async (status_) => { if (!add_ || (refs.status.current !== status_)) return; updateStatus('add'); // Reflow (0, utils_2.reflow)(refs.root.current); await delay('add'); // Prevent update batches await (0, utils_1.wait)(14); updateStatus('adding'); // await duration('add'); if (refs.status.current === status_) updateStatus('added'); }; const enter = async (status_) => { var _a; if (!enter_ || (status_ !== 'appended' && (refs.status.current !== status_ || !refs.inProp.current))) return; updateStatus('enter'); // Reflow (0, utils_2.reflow)(refs.root.current); await delay('enter'); // Prevent update batches await (0, utils_1.wait)(14); updateStatus('entering'); await duration('enter'); if (((_a = refs.status.current) === null || _a === void 0 ? void 0 : _a.indexOf('exit')) === -1) updateStatus('entered'); }; const exit = async (status_) => { var _a; if (!exit_ || (refs.status.current !== status_ || refs.inProp.current)) return; updateStatus('exit'); // Reflow (0, utils_2.reflow)(refs.root.current); await delay('exit'); // Prevent update batches await (0, utils_1.wait)(14); updateStatus('exiting'); await duration('exit'); if (((_a = refs.status.current) === null || _a === void 0 ? void 0 : _a.indexOf('enter')) === -1) updateStatus('exited'); }; const onEntered = (element) => { if ((0, utils_1.is)('function', onEntered_)) onEntered_(element); if (run && inProp) setInProp(false); }; const updateStatus = (status_) => { var _a, _b, _c; setStatus(status_); // Subscriptions subs.current.status.emit(status_); switch (status_) { case 'appended': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onAppended)) onAppended(refs.root.current); break; case 'add': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onAdd)) onAdd(refs.root.current); break; case 'adding': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onAdding)) onAdding(refs.root.current); break; case 'added': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onAdded)) onAdded(refs.root.current); break; case 'enter': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onEnter)) onEnter(refs.root.current); break; case 'entering': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onEntering)) onEntering(refs.root.current); break; case 'entered': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onEntered)) onEntered(refs.root.current); break; case 'exit': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onExit)) onExit(refs.root.current); break; case 'exiting': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onExiting)) onExiting(refs.root.current); break; case 'exited': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onExited)) onExited(refs.root.current); break; case 'removed': if ((0, utils_1.is)('function', onTransition)) onTransition(refs.root.current, status_); if ((0, utils_1.is)('function', onRemoved)) onRemoved(refs.root.current); break; default: break; } // Add className if (className && (0, utils_1.is)('element', refs.root.current)) { let className_ = (0, style_react_1.classNames)([(_b = (((_a = refs.root.current.className) === null || _a === void 0 ? void 0 : _a.baseVal) || refs.root.current.className)) === null || _b === void 0 ? void 0 : _b.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_}`; className_ = className_.replace(/ +/g, ' ').trim(); if ((_c = refs.root.current.className) === null || _c === void 0 ? void 0 : _c.baseVal) refs.root.current.className.baseVal = className_; else refs.root.current.className = className_; } }; if (status === 'removed') return null; const value_ = { status }; return ((0, jsx_runtime_1.jsx)(Context_1.default.Provider, Object.assign({ value: value_ }, { children: (0, utils_1.is)('function', children) ? children(status, refs.root) : react_1.default.cloneElement(children, { ref: (item) => { if (ref) { if ((0, utils_1.is)('function', ref)) ref(item); else ref.current = item; } refs.root.current = item; } }) }))); }; Transition.displayName = 'amaui-Transition'; exports.default = Transition;