@onesy/ui-react
Version:
UI for React
187 lines (186 loc) • 10.3 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const utils_1 = require("@onesy/utils");
const style_react_1 = require("@onesy/style-react");
const __1 = require("..");
const Transitions = (props_) => {
const theme = (0, style_react_1.useOnesyTheme)();
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.onesyTransitions) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]);
const { mode = 'out-in', switch: switch_, id, TransitionProps, children: children__ } = props;
const [init, setInit] = react_1.default.useState(false);
const [status, setStatus] = react_1.default.useState(__1.STATUS.entered);
const [children, setChildren] = react_1.default.useState((0, utils_1.is)('array', children__) ? children__ : [children__]);
const other = Object.assign({ className: true }, TransitionProps);
const [element, setElement] = react_1.default.useState(react_1.default.cloneElement(children__, Object.assign({ in: true }, other)));
const refs = {
element: react_1.default.useRef(undefined),
previousKeyValue: react_1.default.useRef(undefined),
status: react_1.default.useRef(undefined),
id: react_1.default.useRef(undefined),
noTransition: react_1.default.useRef(undefined)
};
refs.element.current = element;
refs.status.current = status;
// No transition controll
// bug solve in nextjs
react_1.default.useEffect(() => {
if (id !== undefined) {
if (id !== refs.id.current) {
refs.noTransition.current = false;
refs.id.current = id;
}
else
refs.noTransition.current = true;
}
}, [id]);
react_1.default.useEffect(() => {
if (id !== undefined)
refs.noTransition.current = id === refs.id.current;
}, [status]);
react_1.default.useEffect(() => {
setInit(true);
}, []);
// Regular
react_1.default.useEffect(() => {
if (!switch_) {
const newChildren = (0, utils_1.is)('array', children__) ? children__ : [children__];
setChildren(items => {
let newItems = (0, utils_1.unique)([...items, ...newChildren], 'key');
newItems = newItems.map(item => {
const prev = items.find(item_ => item_.key === item.key);
const next = newChildren.find(item_ => item_.key === item.key);
const isExiting = !(prev === null || prev === void 0 ? void 0 : prev.props.in);
// New or readded previous add it
if (next && (!prev || isExiting))
return react_1.default.cloneElement(item, Object.assign({ in: true, onExited: onExited(item), enterOnAdd: true }, other));
// No prev in new and it's not already exiting exit it
if (!next && prev && !isExiting)
return react_1.default.cloneElement(item, Object.assign({ in: false }, other));
return item;
});
return newItems;
});
}
}, [children__.length]);
// Switch
react_1.default.useEffect(() => {
refs.previousKeyValue.current = children__.key;
// Abrupted value update
if (refs.noTransition.current) {
setStatus(__1.STATUS.entered);
setElement(children__);
}
else if (refs.status.current !== 'entered') {
setStatus(__1.STATUS.entered);
setElement(react_1.default.cloneElement(children__, Object.assign({ in: true, enterOnAdd: true }, other)));
}
else if (element !== children__ &&
element.key !== children__.key &&
// Lets transition run properly
refs.status.current === 'entered') {
setStatus(__1.STATUS.exit);
}
}, [children__.key]);
const onExited = (element_) => (elementHTML) => {
// Invoke a method
if ((0, utils_1.is)('function', element_.props.onExited))
element_.props.onExited(elementHTML);
// Update
setChildren(items => {
const newItems = [...items];
const index = newItems.findIndex(item => (item === null || item === void 0 ? void 0 : item.key) === (element_ === null || element_ === void 0 ? void 0 : element_.key));
if (index > -1)
newItems.splice(index, 1);
return newItems;
});
};
let children_ = children;
// Init
if (!init && !switch_) {
children_ = children_.map(item => react_1.default.cloneElement(item, Object.assign({ in: true, onExited: onExited(item) }, other)));
}
// Switch
if (switch_) {
children_ = element;
switch (status) {
case __1.STATUS.enter:
if (mode === 'in-out') {
const newElement = react_1.default.cloneElement(refs.previousKeyValue.current !== children__.key ? element : children__, Object.assign({ in: true }, other));
children_ = [
react_1.default.cloneElement(children_, Object.assign({ in: false, onExited: () => {
var _a, _b;
if (refs.status.current === 'entered')
return;
if ((_a = children__.props) === null || _a === void 0 ? void 0 : _a.onExited)
(_b = children__.props) === null || _b === void 0 ? void 0 : _b.onExited();
setStatus(__1.STATUS.entered);
setElement(newElement);
}, exitOnAdd: true, removeOnExited: true }, other)),
newElement
];
}
else if (mode === 'out-in') {
children_ = (react_1.default.cloneElement(children__, Object.assign({ in: true, onEntered: () => {
var _a, _b;
if (refs.status.current === 'entered')
return;
if ((_a = children__.props) === null || _a === void 0 ? void 0 : _a.onEntered)
(_b = children__.props) === null || _b === void 0 ? void 0 : _b.onEntered();
setStatus(__1.STATUS.entered);
setElement(react_1.default.cloneElement(refs.previousKeyValue.current !== children__.key ? element : children__, Object.assign({ in: true }, other)));
}, enterOnAdd: true }, other)));
}
break;
case __1.STATUS.exit:
if (mode === 'in-out') {
children_ = [
element,
react_1.default.cloneElement(children__, Object.assign({ in: true, onEntered: () => {
var _a, _b;
if (refs.status.current === 'entered')
return;
if ((_a = children__.props) === null || _a === void 0 ? void 0 : _a.onEnter)
(_b = children__.props) === null || _b === void 0 ? void 0 : _b.onEnter();
setStatus(__1.STATUS.enter);
}, enterOnAdd: true }, other))
];
}
else if (mode === 'out-in') {
children_ = (react_1.default.cloneElement(children_, Object.assign({ in: false, onExited: () => {
var _a, _b;
if (refs.status.current === 'entered')
return;
if ((_a = children__.props) === null || _a === void 0 ? void 0 : _a.onExited)
(_b = children__.props) === null || _b === void 0 ? void 0 : _b.onExited();
setStatus(__1.STATUS.enter);
}, exitOnAdd: true }, other)));
}
else if (mode === 'in-out-follow') {
if (children__.key === children_.key)
return children_;
children_ = [
react_1.default.cloneElement(children__, Object.assign({ in: true, onEntered: () => {
var _a, _b;
if (refs.status.current === 'entered')
return;
if ((_a = children__.props) === null || _a === void 0 ? void 0 : _a.onEntered)
(_b = children__.props) === null || _b === void 0 ? void 0 : _b.onEntered();
setElement(react_1.default.cloneElement(refs.previousKeyValue.current !== children__.key ? element : children__, Object.assign({ in: true }, other)));
setStatus(__1.STATUS.entered);
}, enterOnAdd: true }, other)),
react_1.default.cloneElement(children_, Object.assign({ in: false, exitOnAdd: true }, other))
];
}
break;
default:
break;
}
}
return children_;
};
Transitions.displayName = 'onesy-Transitions';
exports.default = Transitions;
;