Primitives
Accordion
line, card, contained; chevron or plus; icons, descriptions, badges; opens to the content's real height.
line · chevron
At the gate, by scanning the QR on the ticket, or in the app before they leave. Cash goes into the attendant's shift.
card · plus · icons, descriptions, a badge
Each pass bills on the 25th for the next month. A pass unpaid by the 5th stops opening the gate until it is paid.
contained · several open at once
Bikes pay half. Overnight (10 pm – 8 am) is a flat ৳150.
accordion.tsx
"use client";
import { Accordion, AccordionItem, Badge } from "@waveinno/ui";
import { CreditCard, DoorOpen, Wallet } from "lucide-react";
export default function AccordionDemo() {
const faq = [
{ v: "pay", icon: <Wallet />, title: "How do drivers pay?", d: "bKash, Nagad, card or cash", body: "At the gate, by scanning the QR on the ticket, or in the app before they leave. Cash goes into the attendant's shift." },
{ v: "monthly", icon: <CreditCard />, title: "When are monthly passes billed?", d: "On the 25th, due by the 5th", body: "Each pass bills on the 25th for the next month. A pass unpaid by the 5th stops opening the gate until it is paid." },
{ v: "gates", icon: <DoorOpen />, title: "What if a gate goes offline?", d: "Sessions keep recording", body: "The gate controller stores entries and exits and sends them when it is back online. Attendants see a banner until it is." },
];
return (
<div className="grid gap-8 lg:grid-cols-2">
<div className="space-y-2">
<p className="text-[12px] text-muted">line · chevron</p>
<Accordion type="single" collapsible defaultValue="pay">
{faq.map((f) => (
<AccordionItem key={f.v} value={f.v} title={f.title}>
{f.body}
</AccordionItem>
))}
</Accordion>
</div>
<div className="space-y-2">
<p className="text-[12px] text-muted">card · plus · icons, descriptions, a badge</p>
<Accordion type="single" collapsible variant="card" indicator="plus" defaultValue="monthly">
{faq.map((f, i) => (
<AccordionItem key={f.v} value={f.v} title={f.title} description={f.d} icon={f.icon} badge={i === 2 ? <Badge tone="success">New</Badge> : undefined}>
{f.body}
</AccordionItem>
))}
</Accordion>
</div>
<div className="space-y-2 lg:col-span-2">
<p className="text-[12px] text-muted">contained · several open at once</p>
<Accordion type="multiple" variant="contained" defaultValue={["a"]}>
<AccordionItem value="a" title="Rates" description="Cars ৳30 the first hour, ৳20 after">
Bikes pay half. Overnight (10 pm – 8 am) is a flat ৳150.
</AccordionItem>
<AccordionItem value="b" title="Opening hours" description="6 am – midnight">
Monthly pass holders can enter at any hour.
</AccordionItem>
<AccordionItem value="c" title="Staff" description="4 attendants, 1 manager">
Shifts change at 2 pm and 10 pm.
</AccordionItem>
</Accordion>
</div>
</div>
);
}Import#
Everything comes from the package root. The example above uses:
your-component.tsx
import { Accordion, AccordionItem, Badge } from "@waveinno/ui";Props#
Read from the source of this version, so they match the code exactly.
<Accordion>
src/components/ui/accordion.tsx| Prop | Type | Default | Description |
|---|---|---|---|
variant | "line" | "card" | "contained" | "line" | |
indicator | "chevron" | "plus" | "chevron" |
Also takes ComponentPropsWithoutRef<typeof AccordionPrimitive.Root>.
<AccordionItem>
src/components/ui/accordion.tsx| Prop | Type | Default | Description |
|---|---|---|---|
titlerequired | React.ReactNode | — | |
description | React.ReactNode | — | A muted line under the title. |
icon | React.ReactNode | — | |
badge | React.ReactNode | — | Beside the title: a count, "New". |
Also takes Omit<React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>, "title">.
<Badge>
src/components/ui/badge.tsx| Prop | Type | Default | Description |
|---|---|---|---|
dot | boolean | true | |
variant | "soft" | "solid" | "outline" | "dot" | "gradient" | "live" | "soft" |
Also takes HTMLAttributes<HTMLSpanElement> & VariantProps<typeof badgeVariants>.
Install#
If the project does not have the package yet, add it, then follow the setup for Next.js or Vite once.
$ npm install @waveinno/ui