@intility/bifrost-react
Version:
React library for Intility's design system, Bifrost.
54 lines (53 loc) • 2.1 kB
JavaScript
"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { forwardRef, useRef, useState } from "react";
import classNames from "classnames";
import useAnimationDuration from "../../hooks/useAnimationDuration.js";
import isInert from "../../utils/isInert.js";
import setRef from "../../utils/setRef.js";
/**
* Wrapper for collapsible content with height transition (except for `prefers-reduce-motion` users)
*/ const SlideDown = /*#__PURE__*/ forwardRef(({ open, eager = false, children, className, ...props }, ref)=>{
const animationDuration = useAnimationDuration();
const [previousOpen, setPreviousOpen] = useState(open);
const [isTransitioning, setIsTransitioning] = useState(false);
const wrapperRef = useRef(null);
// when open changes, immediately set isTransitioning to true, if animationDuration is not 0
if (open !== previousOpen) {
if (animationDuration !== 0) {
setIsTransitioning(true);
}
setPreviousOpen(open);
}
// set isTransitioning to false after transition ends
const handleTransitionEnd = (e)=>{
// not ours
if (e.propertyName !== "grid-template-rows" || e.target !== wrapperRef.current) {
return;
}
setIsTransitioning(false);
};
return /*#__PURE__*/ _jsx("div", {
ref: (r)=>{
setRef(ref, r);
setRef(wrapperRef, r);
},
// inert is an attribute to disable interactivity (like clicks and
// focus) and AT (Assistive Technologies, like screen reader).
inert: isInert(!open),
...props,
onTransitionEnd: (e)=>{
props?.onTransitionEnd?.(e);
handleTransitionEnd(e);
},
className: classNames(className, "bf-expand", {
"bf-expand-closed": !open,
"bf-expand-expanded": !isTransitioning && open
}),
children: /*#__PURE__*/ _jsx("div", {
children: (eager || open || isTransitioning) && children
})
});
});
SlideDown.displayName = "SlideDown";
export default SlideDown;