Westy Design Systemv0.2.7
OverviewComponentsExamplesStorybook

Foundations

  • Typography
  • Colors
  • Spacing
  • Radius
  • Shadows
  • Icons

Components

  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Data Table
  • Date Picker
  • Dialog
  • Direction
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Menubar
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Questionnaire
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Sonner
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toggle
  • Toggle Group
  • Tooltip

Chat

  • Attachment
  • Bubble
  • Marker
  • Message
  • Message Scroller

Components

Accordion

A vertically stacked set of interactive headings that each reveal a section of content.

Playground

A private shadcn/ui design system: sixty components styled with the Westy tokens and showcased in this Storybook.

—type
—collapsible
—disabled
—dir
Usage
Each AccordionItem pairs an AccordionTrigger with its collapsible AccordionContent. With type="single" only one item stays open at a time; add collapsible so the open item can also be closed again. Items are divided by a bottom border and the caret flips automatically with the open state.

Yes. It adheres to the WAI-ARIA accordion design pattern.

import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@workspace/ui/components/accordion"

<Accordion type="single" collapsible defaultValue="item-1">
  <AccordionItem value="item-1">
    <AccordionTrigger>Is it accessible?</AccordionTrigger>
    <AccordionContent>
      Yes. It adheres to the WAI-ARIA accordion design pattern.
    </AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-2">
    <AccordionTrigger>Is it styled?</AccordionTrigger>
    <AccordionContent>
      Yes. Triggers, carets and content all read from the design tokens.
    </AccordionContent>
  </AccordionItem>
</Accordion>
Multiple open items
type="multiple" lets several items stay expanded at once — the value becomes an array of item values. Multiple accordions are always collapsible, so the collapsible prop does not apply.

CSS variables define every color, radius and font, surfaced to Tailwind as semantic utility classes.

Sixty building blocks composed from Radix primitives and styled with the tokens.

<Accordion type="multiple" defaultValue={["item-1", "item-2"]}>
  <AccordionItem value="item-1">
    <AccordionTrigger>Tokens</AccordionTrigger>
    <AccordionContent>
      CSS variables define every color, radius and font.
    </AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-2">
    <AccordionTrigger>Components</AccordionTrigger>
    <AccordionContent>
      Sixty building blocks composed from Radix primitives.
    </AccordionContent>
  </AccordionItem>
</Accordion>
Disabled item
Set disabled on an AccordionItem to prevent it from being toggled: the trigger dims, ignores pointer events and is skipped by keyboard navigation. Disabling the root Accordion disables every item at once.

This item toggles normally.

<Accordion type="single" collapsible defaultValue="item-1">
  <AccordionItem value="item-1">
    <AccordionTrigger>Available</AccordionTrigger>
    <AccordionContent>This item toggles normally.</AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-2" disabled>
    <AccordionTrigger>Disabled</AccordionTrigger>
    <AccordionContent>This content cannot be reached.</AccordionContent>
  </AccordionItem>
</Accordion>
Outline
The parts are unopinionated about their container, so borders are a styling decision: give each item rounded-md border px-4 and space them with gap-2 on the root for a card-per-item look.

Yes. It adheres to the WAI-ARIA accordion design pattern.

<Accordion type="single" collapsible defaultValue="item-1" className="gap-2">
  <AccordionItem value="item-1" className="rounded-md border px-4">
    <AccordionTrigger>Is it accessible?</AccordionTrigger>
    <AccordionContent>
      Yes. It adheres to the WAI-ARIA accordion design pattern.
    </AccordionContent>
  </AccordionItem>
</Accordion>
In a card
An accordion slots into CardContent for a framed FAQ block — the card supplies the title and outer padding while the item borders keep dividing the questions.
Frequently asked questions
Everything about the Westy design system.

Yes. It adheres to the WAI-ARIA accordion design pattern.

<Card className="w-full max-w-md">
  <CardHeader>
    <CardTitle>Frequently asked questions</CardTitle>
    <CardDescription>
      Everything about the Westy design system.
    </CardDescription>
  </CardHeader>
  <CardContent>
    <Accordion type="single" collapsible defaultValue="item-1">
      <AccordionItem value="item-1">
        <AccordionTrigger>Is it accessible?</AccordionTrigger>
        <AccordionContent>
          Yes. It adheres to the WAI-ARIA accordion design pattern.
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  </CardContent>
</Card>
RTL
Radix reads the dir prop (or a surrounding Direction provider) for its behavior but does not write a DOM attribute, while the styles flip through logical properties (text-start, ms-auto) that follow the HTML dir. Set both: the attribute on a wrapping element and the prop on the root.

نعم، يتبع نمط WAI-ARIA لسهولة الوصول.

<div dir="rtl">
  <Accordion type="single" collapsible defaultValue="item-1" dir="rtl">
    <AccordionItem value="item-1">
      <AccordionTrigger>هل المكوّن متاح للجميع؟</AccordionTrigger>
      <AccordionContent>
        نعم، يتبع نمط WAI-ARIA لسهولة الوصول.
      </AccordionContent>
    </AccordionItem>
  </Accordion>
</div>
Accessibility
Follows the WAI-ARIA accordion pattern: each trigger is a button inside a heading, exposing aria-expanded and aria-controls, and each panel is a labelled region. Enter or Space toggles the focused item, ArrowDown and ArrowUp move focus between triggers, Home and End jump to the first and last, and disabled triggers are skipped.
<div data-slot="accordion">
  <div data-slot="accordion-item" data-state="open">
    <h3 data-orientation="vertical">
      <button aria-expanded="true" aria-controls="radix-:r1:">
        Is it accessible?
      </button>
    </h3>
    <div role="region" id="radix-:r1:" aria-labelledby="radix-:r0:">
      Yes. It adheres to the WAI-ARIA accordion design pattern.
    </div>
  </div>
</div>
API Reference
Every part wraps the matching Radix Accordion primitive and accepts all of its props. The notable ones:
ComponentPropDefault
Accordiontype: "single" | "multiple"required
Accordioncollapsible?: boolean (single only)false
AccordiondefaultValue?: string | string[]—
Accordionvalue?: string | string[], onValueChange?: (value) => void—
Accordiondisabled?: booleanfalse
Accordiondir?: "ltr" | "rtl"inherited
Accordionorientation?: "vertical" | "horizontal""vertical"
AccordionItemvalue: stringrequired
AccordionItemdisabled?: booleanfalse
<Accordion data-slot="accordion" />            // Root — vertical flex column
<AccordionItem data-slot="accordion-item" />   // divider border between items
<AccordionTrigger data-slot="accordion-trigger" />  // <button aria-expanded> in a heading, caret icons
<AccordionContent data-slot="accordion-content" />  // collapsible region, height animation

Tokens used

7 design tokens consumed by the Accordion component.

  • --ring

    Ring

    focus-visible:border-ringfocus-visible:ring-ring/50focus-visible:after:border-ring
  • --muted-foreground

    Muted Foreground

    **:data-[slot=accordion-trigger-icon]:text-muted-foreground
  • --foreground

    Foreground

    [&_a]:hover:text-foreground
  • --border

    Border

    not-last:border-b
  • --radius-md

    Radius 0.8× (8px)

    rounded-md
  • --text-sm

    Text Small (14px)

    text-sm
  • --spacing

    Spacing unit (4px)

    py-4pb-4size-4mb-4