Cnippet

Collapsible

Component 10

About

A minimal show/hide primitive built on Base UI's Collapsible. A trigger toggles a height-animated panel — perfect for read-more text, FAQ rows, nested groups and expandable log output. Controlled or uncontrolled via open / defaultOpen, with data-panel-open styling hooks. Ships Collapsible, CollapsibleTrigger and CollapsiblePanel (also exported as CollapsibleContent).

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Collapsible to your project and fits it to your theme.

Code

How Collapsible is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import { ChevronDownIcon } from "lucide-react";
import {
  Collapsible,
  CollapsiblePanel,
  CollapsibleTrigger,
} from "@/components/ui/cnippet-collapsible";

type StepStatus = "success" | "failed" | "running" | "pending";

const statusBadge: Record<StepStatus, string> = {
  failed: "border-transparent bg-destructive/15 text-destructive",
  pending: "border text-muted-foreground",
  running: "border-transparent bg-blue-500/15 text-blue-600 dark:text-blue-400",
  success:
    "border-transparent bg-emerald-500/15 text-emerald-600 dark:text-emerald-400",
};

const steps: {
  id: string;
  name: string;
  status: StepStatus;
  duration: string;
  log: string[];
}[] = [
  {
    duration: "3s",
    id: "install",
    log: [
      "$ bun install",
      "bun install v1.1.0",
      "Resolving dependencies...",
      "✓ 412 packages installed [3.14s]",
    ],
    name: "Install dependencies",
    status: "success",
  },
  {
    duration: "12s",
    id: "typecheck",
    log: [
      "$ tsc --noEmit",
      "src/components/Button.tsx(14,7): error TS2322",
      "  Type 'string' is not assignable to type 'number'.",
      "Found 1 error.",
    ],
    name: "Type check",
    status: "failed",
  },
  {
    duration: "—",
    id: "build",
    log: [],
    name: "Build",
    status: "pending",
  },
];

export default function CollapsiblePipeline() {
  return (
    <div className="w-full max-w-md space-y-2">
      {steps.map((step) => (
        <div
          className="overflow-hidden rounded-xl border bg-card text-card-foreground shadow-sm"
          key={step.id}
        >
          <Collapsible disabled={step.status === "pending"}>
            <CollapsibleTrigger className="w-full">
              <div className="px-4 py-3">
                <div className="flex items-center justify-between gap-3">
                  <div className="flex items-center gap-2.5">
                    <span
                      className={`inline-flex items-center rounded-md px-2 py-0.5 font-medium text-xs ${statusBadge[step.status]}`}
                    >
                      {step.status}
                    </span>
                    <span className="font-medium text-sm">{step.name}</span>
                  </div>
                  <div className="flex items-center gap-2 text-muted-foreground">
                    <span className="text-xs">{step.duration}</span>
                    {step.status !== "pending" && (
                      <ChevronDownIcon className="size-3.5 in-data-panel-open:rotate-180 transition-transform duration-200" />
                    )}
                  </div>
                </div>
              </div>
            </CollapsibleTrigger>

            {step.log.length > 0 && (
              <CollapsiblePanel>
                <div className="border-t bg-muted/40 px-4 py-3">
                  <pre className="space-y-0.5 overflow-x-auto text-xs leading-relaxed">
                    {step.log.map((line) => (
                      <div
                        className={
                          line.startsWith("$")
                            ? "font-semibold text-foreground"
                            : line.includes("error") || line.includes("Error")
                              ? "text-destructive"
                              : "text-muted-foreground"
                        }
                        key={line}
                      >
                        {line}
                      </div>
                    ))}
                  </pre>
                </div>
              </CollapsiblePanel>
            )}
          </Collapsible>
        </div>
      ))}
    </div>
  );
}

Dependencies

More by Cnippet

View all
  • Team

    Team

    1.3K
  • Davincho Hero-1

    Davincho Hero-1

    683
  • Aero Hero-3

    Aero Hero-3

    558
  • Features

    Features

    510
  • Random Letter Swap Navigation

    Random Letter Swap Navigation

    487
  • Services with Animated Hover Modal

    Services with Animated Hover Modal

    465
  • Blogs

    Blogs

    396
  • Aero Hero-1

    Aero Hero-1

    356