Collapsible
Customizable animated collapsible element using Framer Motion + Radix-UI
Pasithea
Pasithea
import {
Collapsible,
CollapsibleContent,
CollapsibleItem,
CollapsibleTrigger,
} from "@/components/collapsible";
import {
CaretDownIcon,
GithubLogoIcon,
} from "@phosphor-icons/react";
export function CollapsibleDevsDemo() {
const [open, setOpen] = useState(false);
const comments: { name: string; pfp: string; link: string }[] = [
{
name: "Pasithea",
pfp: "https://github.com/Pasithea0.png",
link: "https://github.com/Pasithea0",
},
{
name: "FifthWit",
pfp: "https://github.com/FifthWit.png",
link: "https://github.com/FifthWit",
},
{
name: "shadcn",
pfp: "https://github.com/shadcn.png",
link: "https://github.com/shadcn",
},
];
return (
<div className="flex flex-col h-screen max-h-80">
<Collapsible open={open} onOpenChange={setOpen}>
<div className="flex flex-col items-center w-full">
<CollapsibleTrigger
className="flex flex-row justify-center items-center gap-1 w-fit min-h-12"
asChild
>
<Button variant="ghost">
Cool Developers
<span
aria-hidden
data-open={open}
className="bg-accent p-1 rounded-full aspect-square text-accent-foreground flex data-open:-rotate-180 transition-all"
>
<CaretDownIcon />
</span>
</Button>
</CollapsibleTrigger>
<div className="w-full">
<CollapsibleContent>
{comments.map((c) => (
<CollapsibleItem
key={c.name}
className="flex flex-row gap-2 items-center"
>
<Avatar>
<AvatarImage src={c.pfp} />
<AvatarFallback>{c.name}</AvatarFallback>
</Avatar>
<h2>{c.name}</h2>
<Button variant="ghost" onClick={() => window.open(c.link)}>
<GithubLogoIcon />
</Button>
</CollapsibleItem>
))}
</CollapsibleContent>
</div>
</div>
</Collapsible>
</div>
);
}Installation
npx shadcn@latest add https://raw.githubusercontent.com/FifthWit/ui/refs/heads/main/public/r/collapsible.jsonpnpm dlx shadcn@latest add https://raw.githubusercontent.com/FifthWit/ui/refs/heads/main/public/r/collapsible.jsondeno run -A npm:shadcn@latest add https://raw.githubusercontent.com/FifthWit/ui/refs/heads/main/public/r/collapsible.jsonbunx shadcn@latest add https://raw.githubusercontent.com/FifthWit/ui/refs/heads/main/public/r/collapsible.jsonAnatomy
import {
Collapsible,
CollapsibleContent,
CollapsibleItem,
CollapsibleTrigger,
} from "@/components/collapsible";
export default () => (
<Collapsible>
<CollapsibleTrigger></CollapsibleTrigger>
<CollapsibleContent>
<CollapsibleItem></CollapsibleItem>
</CollapsibleContent>
</Collapsible>
)Examples
Scroll Area
wrapping collapsible in the shadcn ScrollArea
export function CollapsibleNotificiationsDemo() {
const [open, setOpen] = useState(false);
const comments: {
name: string;
pfp: string;
comment: string;
}[] = [
{
name: "Next.js",
pfp: "https://github.com/nextjs.png",
comment: "SSR + DX should be at the cost of using Vercel",
},
{
name: "TypeScript",
pfp: "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/Typescript.svg/1280px-Typescript.svg.png",
comment: "TypeScript > JSDoc",
},
{
name: "React.js",
pfp: "https://github.com/reactjs.png",
comment: "We're a library, not a framework!!!!!!",
},
{
name: "TailwindCSS",
pfp: "https://github.com/tailwindlabs.png",
comment:
"If anyone is a recovering Tailwind addict, there is no hope, keep using it.",
},
{
name: "Radix-UI",
pfp: "https://github.com/radix-ui.png",
comment: "Primitives are the way",
},
{
name: "Fumadocs",
pfp: "https://www.fumadocs.dev/icon.png?icon.f741d7a1.png",
comment: "MDX is life.",
},
];
return (
<div className="flex flex-col bg-card p-4 rounded-lg w-sm aspect-3/4">
<Collapsible open={open} onOpenChange={setOpen}>
<CollapsibleTrigger
className="flex flex-row justify-center items-center gap-1 w-fit min-h-12"
asChild
>
<Button variant="ghost">
ReactCord
<span
aria-hidden
data-open={open}
className="bg-accent p-1 rounded-full aspect-square text-accent-foreground flex data-open:-rotate-180 transition-all"
>
<CaretDownIcon />
</span>
</Button>
</CollapsibleTrigger>
<ScrollArea className="h-100">
<CollapsibleContent>
{comments.map((c) => (
<CollapsibleItem
key={c.name}
className="flex flex-row items-center gap-2"
>
<Avatar>
<AvatarImage src={c.pfp} />
<AvatarFallback>{c.name}</AvatarFallback>
</Avatar>
<div className="w-full flex flex-col">
<p className="text-xs text-muted-foreground">{c.name}</p>
<p className="text-sm">{c.comment}</p>
</div>
</CollapsibleItem>
))}
</CollapsibleContent>
</ScrollArea>
</Collapsible>
</div>
);
}Props
<Collapsible />
Prop
Type
<CollapsibleTrigger />
Prop
Type
<CollapsibleContent />
Prop
Type
<CollapsibleItem />
Prop
Type