tcmd: Accordion and popover md elements
This commit is contained in:
80
lib/accordion/index.tsx
Normal file
80
lib/accordion/index.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import { FC, PropsWithChildren, ReactNode, useCallback, useState } from "react";
|
||||
|
||||
interface IProps {
|
||||
expandOnHover?: boolean;
|
||||
expanded?: boolean;
|
||||
title?: ReactNode;
|
||||
}
|
||||
|
||||
export const Accordion: FC<PropsWithChildren<IProps>> = (
|
||||
{ children, expandOnHover, expanded, title },
|
||||
) => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
data-expanded={open || expanded}
|
||||
data-expandonhover={expandOnHover}
|
||||
className={(expandOnHover ? "group/hover" : "group/controlled") +
|
||||
" group"}
|
||||
onClick={() => !title && !expandOnHover && setOpen(!open)}
|
||||
>
|
||||
{!!title && (
|
||||
<div
|
||||
className="flex justify-between cursor-pointer"
|
||||
onClick={() => !expandOnHover && setOpen(!open)}
|
||||
>
|
||||
{title}
|
||||
<div
|
||||
className={`
|
||||
group-hover/hover:-rotate-180
|
||||
group-data-[expanded]:-rotate-180
|
||||
transition-transform
|
||||
duration-500
|
||||
grid
|
||||
rounded-full
|
||||
h-min
|
||||
mr-2
|
||||
mt-1
|
||||
scale-y-50
|
||||
`}
|
||||
>
|
||||
<span className="block w-2 h-2 rotate-45 border-r-2 border-b-2 place-self-center">
|
||||
</span>
|
||||
<span className="block w-2 h-2 rotate-45 border-r-2 border-b-2 place-self-center">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const AccordionContent: FC<PropsWithChildren> = ({ children }) => {
|
||||
const [height, setHeight] = useState(0);
|
||||
|
||||
const updateRef = useCallback((node: HTMLDivElement | null) => {
|
||||
if (node) {
|
||||
setHeight(node.clientHeight);
|
||||
} else {
|
||||
setHeight(0);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const Child = () => (
|
||||
<div className="absolute bottom-0 w-full" ref={updateRef}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="relative overflow-hidden">
|
||||
{<Child />}
|
||||
<span
|
||||
style={{ ["--v-height" as never]: height + "px" }}
|
||||
className="w-0 block h-0 group-hover/hover:h-variable group-data-[expanded]/controlled:h-variable transition-all duration-700"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user