> ## Documentation Index
> Fetch the complete documentation index at: https://araf.badr.co.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Collapsible

> A simple show/hide toggle for a section of content — a lightweight alternative to Accordion when only one expandable area is needed.

## Overview

<div style={{padding:"28px 24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",display:"flex",justifyContent:"center"}}>
  <div style={{width:"100%",maxWidth:"360px",fontFamily:"Inter,sans-serif"}}>
    <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"10px",overflow:"hidden"}}>
      <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",cursor:"pointer"}}>
        <div>
          <div style={{fontSize:"14px",fontWeight:500,color:"#101828"}}>@badrinteractive starred 3 repos</div>
        </div>

        <button style={{border:"1px solid #E5E7EB",borderRadius:"6px",padding:"4px 8px",background:"#fff",fontSize:"12px",color:"#344054",cursor:"pointer",display:"flex",alignItems:"center",gap:"4px"}}>
          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <polyline points="6 9 12 15 18 9" />
          </svg>
        </button>
      </div>

      <div style={{borderTop:"1px solid #F2F4F7"}}>
        {["araf-ds/core","araf-ds/docs","araf-ds/tokens"].map(repo => (
                        <div key={repo} style={{display:"flex",alignItems:"center",gap:"8px",padding:"10px 16px",borderBottom:"1px solid #F9FAFB"}}>
                          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#667085" strokeWidth="2"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/></svg>
                          <span style={{fontSize:"13px",color:"#344054"}}>{repo}</span>
                        </div>
                      ))}
      </div>
    </div>
  </div>
</div>

**Collapsible** provides a simple toggle to show or hide a section of content. Unlike `Accordion`, it manages a single open/close state without any grouping logic — ideal for sidebars, filters, and expandable detail panels.

<Note>
  Use **Accordion** when you need multiple collapsible sections with grouped behavior. Use **Collapsible** for a single standalone expand/collapse.
</Note>

***

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @araf-ds/core
  ```

  ```bash yarn theme={null}
  yarn add @araf-ds/core
  ```

  ```bash pnpm theme={null}
  pnpm add @araf-ds/core
  ```
</CodeGroup>

***

## Usage

```tsx theme={null}
import {
  Collapsible,
  CollapsibleTrigger,
  CollapsibleContent,
} from "@araf-ds/core"

export default function Example() {
  const [open, setOpen] = useState(false)

  return (
    <Collapsible open={open} onOpenChange={setOpen}>
      <div className="flex items-center justify-between">
        <h4 className="text-sm font-medium">Starred repositories</h4>
        <CollapsibleTrigger asChild>
          <Button variant="ghost" size="sm">
            <ChevronsUpDown size={14} />
          </Button>
        </CollapsibleTrigger>
      </div>
      <div className="text-sm">@badrinteractive/araf-ds-core</div>
      <CollapsibleContent>
        <div className="text-sm">@badrinteractive/araf-ds-docs</div>
        <div className="text-sm">@badrinteractive/araf-ds-tokens</div>
      </CollapsibleContent>
    </Collapsible>
  )
}
```

***

## Variants

### Basic

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",display:"flex",justifyContent:"center"}}>
  <div style={{width:"100%",maxWidth:"340px",fontFamily:"Inter,sans-serif",display:"flex",flexDirection:"column",gap:"8px"}}>
    <div style={{display:"flex",alignItems:"center",justifyContent:"space-between"}}>
      <span style={{fontSize:"14px",fontWeight:500,color:"#101828"}}>Starred repositories</span>

      <button style={{border:"1px solid #E5E7EB",borderRadius:"6px",padding:"4px 8px",background:"#fff",fontSize:"12px",color:"#344054",cursor:"pointer"}}>
        ⌄ ⌃
      </button>
    </div>

    <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"8px",padding:"10px 12px",fontSize:"13px",color:"#344054"}}>@badrinteractive/araf-ds-core</div>
    <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"8px",padding:"10px 12px",fontSize:"13px",color:"#344054"}}>@badrinteractive/araf-ds-docs</div>
    <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"8px",padding:"10px 12px",fontSize:"13px",color:"#344054"}}>@badrinteractive/araf-ds-tokens</div>
  </div>
</div>

```tsx theme={null}
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="space-y-2">
  <div className="flex items-center justify-between">
    <h4 className="text-sm font-semibold">Starred repositories</h4>
    <CollapsibleTrigger asChild>
      <Button variant="ghost" size="sm">
        <ChevronsUpDownIcon size={14} />
        <span className="sr-only">Toggle</span>
      </Button>
    </CollapsibleTrigger>
  </div>
  <div className="rounded-md border px-4 py-2 text-sm">
    @badrinteractive/araf-ds-core
  </div>
  <CollapsibleContent className="space-y-2">
    <div className="rounded-md border px-4 py-2 text-sm">
      @badrinteractive/araf-ds-docs
    </div>
    <div className="rounded-md border px-4 py-2 text-sm">
      @badrinteractive/araf-ds-tokens
    </div>
  </CollapsibleContent>
</Collapsible>
```

### Filter Panel

A common pattern for sidebar filter sections.

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",display:"flex",justifyContent:"center"}}>
  <div style={{width:"100%",maxWidth:"220px",fontFamily:"Inter,sans-serif"}}>
    <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"8px"}}>
      <span style={{fontSize:"13px",fontWeight:600,color:"#344054"}}>Status</span>

      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#71717A" strokeWidth="2" style={{cursor:"pointer"}}>
        <polyline points="18 15 12 9 6 15" />
      </svg>
    </div>

    {["Active","Pending","Archived","Deleted"].map(s => (
            <div key={s} style={{display:"flex",alignItems:"center",gap:"8px",padding:"4px 0",cursor:"pointer"}}>
              <div style={{width:"14px",height:"14px",borderRadius:"3px",border:s==="Active"?"none":"1px solid #D0D5DD",background:s==="Active"?"#0479CE":"transparent",display:"flex",alignItems:"center",justifyContent:"center"}}>
                {s==="Active" && <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3"><polyline points="20 6 9 17 4 12"/></svg>}
              </div>
              <span style={{fontSize:"13px",color:"#344054"}}>{s}</span>
            </div>
          ))}
  </div>
</div>

```tsx theme={null}
<Collapsible defaultOpen>
  <CollapsibleTrigger className="flex w-full items-center justify-between py-2">
    <span className="text-sm font-semibold">Status</span>
    <ChevronUpIcon size={14} />
  </CollapsibleTrigger>
  <CollapsibleContent className="space-y-1">
    {statuses.map(status => (
      <label key={status} className="flex items-center gap-2 cursor-pointer">
        <Checkbox />
        <span className="text-sm">{status}</span>
      </label>
    ))}
  </CollapsibleContent>
</Collapsible>
```

***

## API Reference

### Collapsible

<ParamField path="open" type="boolean">
  Controlled open state.
</ParamField>

<ParamField path="onOpenChange" type="(open: boolean) => void">
  Callback fired when open state changes.
</ParamField>

<ParamField path="defaultOpen" type="boolean" default="false">
  Uncontrolled default open state.
</ParamField>

<ParamField path="disabled" type="boolean" default="false">
  Prevents the collapsible from being opened or closed.
</ParamField>

### CollapsibleTrigger

<ParamField path="asChild" type="boolean" default="false">
  Render as a child element (e.g. a Button) instead of a default `<button>`.
</ParamField>

### CollapsibleContent

Animates open and close with a CSS height transition. No additional props required.

***

## Accessibility

* `CollapsibleTrigger` renders as `<button>` with `aria-expanded="true|false"`
* `CollapsibleContent` has `aria-hidden="true"` when closed
* The trigger and content are linked via `aria-controls` and `id`
* Keyboard: Space/Enter on the trigger toggles open state

***

## Do's & Don'ts

<CardGroup cols={2}>
  <Card title="Do" icon="check" iconType="solid" color="#16A34A">
    * Use `defaultOpen` for sections that should start expanded
    * Always show some content outside the collapsible as a summary
    * Use `asChild` to make any element the trigger (a heading, row, etc.)
    * Use Collapsible for single sections; Accordion for multiple grouped sections
  </Card>

  <Card title="Don't" icon="xmark" iconType="solid" color="#DC2626">
    * Don't hide critical information inside a collapsed section by default
    * Don't use Collapsible when only one section should be open at a time — use Accordion with `type="single"`
    * Don't nest Collapsibles more than 2 levels deep
    * Don't forget a visible toggle indicator (chevron icon) for discoverability
  </Card>
</CardGroup>
