collapsible-react-component
Version:
Collapses and expands content with an animation.
53 lines (50 loc) • 2.54 kB
JavaScript
"use client";
import { jsx } from 'react/jsx-runtime';
import { useRef, useReducer, useCallback } from 'react';
import styles from './Collapsible.module.css.js';
import { revealTypes } from './revealTypes.js';
var transitioningProperty = 'grid-template-rows';
var next = function (callback) { return Promise.resolve().then(callback); };
var Collapsible = function (_a) {
var children = _a.children, open = _a.open, onTransitionEnd = _a.onTransitionEnd, onTransitionStart = _a.onTransitionStart, _b = _a.revealType, revealType = _b === void 0 ? revealTypes[0] : _b, _c = _a.alwaysKeepChildrenMounted, alwaysKeepChildrenMounted = _c === void 0 ? false : _c;
var wrapperRef = useRef(null);
var lastOpenRef = useRef(open);
var stateRef = useRef({ open: open, transitioning: false });
var _d = useReducer(function (counter) {
return counter + 1;
}, 0), forceRender = _d[1];
if (lastOpenRef.current !== open) {
lastOpenRef.current = open;
next(function () {
onTransitionStart === null || onTransitionStart === void 0 ? void 0 : onTransitionStart(open);
});
stateRef.current = { open: open, transitioning: true };
}
var handleTransitionEnd = useCallback(function (event) {
if (event.propertyName === transitioningProperty &&
event.target === wrapperRef.current) {
next(function () {
onTransitionEnd === null || onTransitionEnd === void 0 ? void 0 : onTransitionEnd(open);
});
stateRef.current = { open: open, transitioning: false };
forceRender();
}
}, [open, onTransitionEnd]);
var className = (function () {
var classNames = [
styles.wrapper,
stateRef.current.open ? styles.is_state_open : styles.is_state_closed,
styles["is_revealType_".concat(revealType)],
];
if (stateRef.current.transitioning) {
classNames.push(styles.is_transitioning);
}
return classNames.join(' ');
})();
return (jsx("div", { ref: wrapperRef, className: className, "aria-hidden": !stateRef.current.open, onTransitionEnd: handleTransitionEnd, children: jsx("div", { className: styles.in, children: jsx("div", { className: styles.content, children: (stateRef.current.open ||
stateRef.current.transitioning ||
alwaysKeepChildrenMounted) &&
children }) }) }));
};
export { Collapsible };
//# sourceMappingURL=Collapsible.js.map