# Sidebar Primitive

Sidebar is a Starwind Runtime primitive in the presence-disclosure-control contract family.
Astro and React share one semantic component API. React coordinates reactive state through controlled and default props plus callbacks. Astro renders initial state and coordinates later changes through DOM events and Runtime methods. Raw HTML uses Runtime attributes, DOM events, and imperative methods.
## Anatomy
### Astro
Use the Astro primitive adapter to render Sidebar anatomy with the Runtime wiring included.
```astro
---
import { Sidebar } from "@starwind-ui/astro/sidebar";
---

<Sidebar.Provider>
  <Sidebar.Sidebar>
    <Sidebar.MenuButton>Dashboard</Sidebar.MenuButton>
  </Sidebar.Sidebar>
  <Sidebar.Trigger>Toggle sidebar</Sidebar.Trigger>
  <Sidebar.Rail />
</Sidebar.Provider>
```

### React
Use the React primitive adapter when Sidebar state participates in React rendering.
```tsx
import { Sidebar } from "@starwind-ui/react/sidebar";

export function Example() {
  return (
    <Sidebar.Provider>
      <Sidebar.Sidebar>
        <Sidebar.MenuButton>Dashboard</Sidebar.MenuButton>
      </Sidebar.Sidebar>
      <Sidebar.Trigger>Toggle sidebar</Sidebar.Trigger>
      <Sidebar.Rail />
    </Sidebar.Provider>
  );
}
```

### HTML
Render the Sidebar data-sw-* contract yourself, then initialize createSidebarController.
```html
<div data-sw-sidebar-provider>
  <div data-sw-sidebar>
    <button data-sw-sidebar-menu-button>Dashboard</button>
  </div>
  <button data-sw-sidebar-trigger type="button">Toggle sidebar</button>
  <button data-sw-sidebar-rail type="button" tabindex="-1"></button>
</div>

<script type="module">
  import { createSidebarController } from "@starwind-ui/runtime/sidebar";

  const root = document.querySelector("[data-sw-sidebar-provider]");
  if (root) {
    createSidebarController(root);
  }
</script>
```

### Vue
Use the Vue 3.5 beta adapter to render Sidebar anatomy.
```vue
<script setup lang="ts">
import Sidebar from "@starwind-ui/vue/sidebar";
</script>

<template>
  <Sidebar.Provider>
    <Sidebar.Sidebar>
      <Sidebar.MenuButton>Dashboard</Sidebar.MenuButton>
    </Sidebar.Sidebar>
    <Sidebar.Trigger>Toggle sidebar</Sidebar.Trigger>
    <Sidebar.Rail />
  </Sidebar.Provider>
</template>
```
## API Reference
### Provider
Provides shared Sidebar state to nested parts.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-sidebar-provider` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| open | `boolean` | - | control | Controls whether Sidebar is open. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for state changes.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:sidebar-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:sidebar-change, and call setOpen for later updates. |
| defaultOpen | `boolean` | true | control | Sets whether Sidebar starts open. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for state changes.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:sidebar-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:sidebar-change, and call setOpen for later updates. |
| mobileOpen | `boolean` | - | control | Controls the mobile open state for Sidebar. | **React:** Use mobileOpen for controlled state and defaultMobileOpen for default state, and onMobileOpenChange for state changes.<br>**Astro:** Use mobileOpen or defaultMobileOpen for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates.<br>**Runtime / HTML:** Use data-default-mobile-open for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates. |
| defaultMobileOpen | `boolean` | false | control | Controls the default mobile open state for Sidebar. | **React:** Use mobileOpen for controlled state and defaultMobileOpen for default state, and onMobileOpenChange for state changes.<br>**Astro:** Use mobileOpen or defaultMobileOpen for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates.<br>**Runtime / HTML:** Use data-default-mobile-open for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates. |
| keyboardShortcut | `string` | "b" | option | Configures the keyboard shortcut option for the Provider part. | - |
| mobileQuery | `string` | "(max-width: 767.98px)" | option | Configures the mobile query option for the Provider part. | - |
| persistOpen | `boolean` | false | option | Configures the persist open option for the Provider part. | - |
| persistenceKey | `string` | "starwind-sidebar-open" | option | Configures the persistence key option for the Provider part. | - |
| persistenceStorage | `SidebarPersistenceStorage` | "localStorage" | option | Configures the persistence storage option for the Provider part. | - |
| persistenceMaxAge | `number` | 604800 | option | Configures the persistence max age option for the Provider part. | - |
| onOpenChange | `(open: boolean, details: SidebarOpenChangeDetails) => void` | - | callback | Runs when Sidebar opens or closes. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for state changes.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:sidebar-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:sidebar-change, and call setOpen for later updates. |
| onMobileOpenChange | `(open: boolean, details: SidebarMobileOpenChangeDetails) => void` | - | callback | Runs when on mobile open change changes for Sidebar. | **React:** Use mobileOpen for controlled state and defaultMobileOpen for default state, and onMobileOpenChange for state changes.<br>**Astro:** Use mobileOpen or defaultMobileOpen for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates.<br>**Runtime / HTML:** Use data-default-mobile-open for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates. |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-sidebar-provider` | runtime | - | Marks the Provider part so Starwind Runtime can find it. |
| `data-default-open` | prop | - | Reflects the default open prop on the Provider part. |
| `data-default-mobile-open` | prop | - | Reflects the default mobile open prop on the Provider part. |
| `data-state` | state | - | Reflects the current state on the Provider part. |
| `data-mobile-open` | state | - | Reflects the mobile open state on the Provider part. |
| `data-keyboard-shortcut` | prop | - | Reflects the keyboard shortcut prop on the Provider part. |
| `data-mobile-query` | prop | - | Reflects the mobile query prop on the Provider part. |
| `data-persist-open` | prop | - | Reflects the persist open prop on the Provider part. |
| `data-persistence-key` | prop | - | Reflects the persistence key prop on the Provider part. |
| `data-persistence-storage` | prop | - | Reflects the persistence storage prop on the Provider part. |
| `data-persistence-max-age` | prop | - | Reflects the persistence max age prop on the Provider part. |
#### State
| State | Value Type | Controlled Prop | Default Prop | Initial Attribute | Runtime Getter | Runtime Setter | Description | State Control Support |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| open | `boolean` | open | defaultOpen | `data-default-open` | `getOpen` | `setOpen` | Tracks whether Sidebar is open. | **React:** Use open for controlled state and defaultOpen for default state, and onOpenChange for state changes.<br>**Astro:** Use open or defaultOpen for initial state, listen for starwind:sidebar-change, and call setOpen for later updates.<br>**Runtime / HTML:** Use data-default-open for initial state, listen for starwind:sidebar-change, and call setOpen for later updates. |
| mobileOpen | `boolean` | mobileOpen | defaultMobileOpen | `data-default-mobile-open` | `getMobileOpen` | `setMobileOpen` | Tracks whether the mobile Sidebar panel is open. | **React:** Use mobileOpen for controlled state and defaultMobileOpen for default state, and onMobileOpenChange for state changes.<br>**Astro:** Use mobileOpen or defaultMobileOpen for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates.<br>**Runtime / HTML:** Use data-default-mobile-open for initial state, listen for starwind:sidebar-mobile-change, and call setMobileOpen for later updates. |
#### Events
| Event | Callback | DOM Event | Value | Details | Timing | Cancelable | Description | Cancellation Sequence |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| openChange | onOpenChange | starwind:sidebar-change | open: `boolean` | SidebarOpenChangeDetails | - | - | Fires when Sidebar opens or closes. | - |
| mobileOpenChange | onMobileOpenChange | starwind:sidebar-mobile-change | open: `boolean` | SidebarMobileOpenChangeDetails | - | - | Fires when the mobile panel opens or closes for Sidebar. | - |
#### Runtime Setters
| Method | Target | Options | Suppresses Emit | Description |
| --- | --- | --- | --- | --- |
| `setOpen` | state: open | emit: false | Yes | Opens or closes Sidebar from Runtime code. |
| `setMobileOpen` | state: mobileOpen | emit: false | Yes | Opens or closes the mobile Sidebar panel from Runtime code. |
#### Refs
| Part | Public |
| --- | --- |
| provider | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-sidebar-provider`, `data-default-open`, `data-default-mobile-open`, `data-state`, `data-mobile-open`, `data-keyboard-shortcut`, `data-mobile-query`, `data-persist-open`, `data-persistence-key`, `data-persistence-storage`, `data-persistence-max-age` | The provider needs initial desktop/mobile state, shortcut, media query, and opt-in persistence markers before hydration. |

### Sidebar
The visible sidebar panel for Sidebar.
| Fact | Value |
| --- | --- |
| Default element | `div` |
| Discovery hook | `data-sw-sidebar` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| side | `"left" \| "right"` | "left" | attribute | Sets the preferred side for Sidebar content. | - |
| variant | `"sidebar" \| "floating" \| "inset"` | "sidebar" | attribute | Selects the visual variant for the Sidebar part. | - |
| collapsible | `"offcanvas" \| "icon"` | "offcanvas" | attribute | Allows all Sidebar items to be collapsed. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-sidebar` | runtime | - | Marks the Sidebar part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Sidebar part. |
| `data-collapsible` | state | - | Reflects the collapsible state on the Sidebar part. |
| `data-collapsible-mode` | prop | - | Reflects the collapsible mode prop on the Sidebar part. |
| `data-variant` | prop | - | Reflects the variant prop on the Sidebar part. |
| `data-side` | prop | - | Reflects the side prop on the Sidebar part. |
#### Refs
| Part | Public |
| --- | --- |
| sidebar | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-sidebar`, `data-state`, `data-collapsible`, `data-collapsible-mode`, `data-variant`, `data-side` | The desktop sidebar uses initial state, collapsible mode, variant, and side attributes for layout before hydration. |

### Trigger
The control that opens, closes, or targets the Sidebar content.
| Fact | Value |
| --- | --- |
| Default element | `button` |
| Discovery hook | `data-sw-sidebar-trigger` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| asChild | `boolean` | false | rendering | Merges behavior onto your child element instead of rendering the default Trigger element. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-sidebar-trigger` | runtime | - | Marks the Trigger part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Trigger part. |
#### Refs
| Part | Public |
| --- | --- |
| trigger | Yes |
#### asChild
| Part | Merged Props |
| --- | --- |
| trigger | aria, className, data, ref |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-sidebar-trigger`, `type`, `aria-expanded`, `data-state` | Triggers need button semantics, expanded state, and discovery before listeners attach. |

### Rail
A compact control for resizing or toggling Sidebar.
| Fact | Value |
| --- | --- |
| Default element | `button` |
| Discovery hook | `data-sw-sidebar-rail` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-sidebar-rail` | runtime | - | Marks the Rail part so Starwind Runtime can find it. |
| `data-state` | state | - | Reflects the current state on the Rail part. |
#### Refs
| Part | Public |
| --- | --- |
| rail | Yes |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-sidebar-rail`, `type`, `aria-expanded`, `data-state`, `tabindex` | The resize rail acts as an unfocusable toggle target with stable expanded state before hydration. |

### Menu Button
A menu-style button rendered inside Sidebar.
| Fact | Value |
| --- | --- |
| Default element | `button` |
| Discovery hook | `data-sw-sidebar-menu-button` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| asChild | `boolean` | false | rendering | Merges behavior onto your child element instead of rendering the default Menu Button element. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-sidebar-menu-button` | runtime | - | Marks the Menu Button part so Starwind Runtime can find it. |
| `data-sidebar-state` | state | - | Reflects the sidebar state on the Menu Button part. |
#### Refs
| Part | Public |
| --- | --- |
| menuButton | Yes |
#### asChild
| Part | Merged Props |
| --- | --- |
| menuButton | aria, className, data, events, ref |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-sidebar-menu-button`, `data-sidebar-state` | Menu buttons receive the current sidebar state for icon-mode tooltip styling. |
## Runtime API
| Fact | Value |
| --- | --- |
| Factory | [`createSidebarController`](/docs/runtime/#create-sidebar-controller) |
| Import | `@starwind-ui/runtime/sidebar` |
| Root part | provider |
| Option props | defaultMobileOpen, defaultOpen, keyboardShortcut, mobileOpen, mobileQuery, onMobileOpenChange, onOpenChange, open, persistOpen, persistenceKey, persistenceMaxAge, persistenceStorage |
| Option lifecycles | defaultMobileOpen: constructor-only, defaultOpen: constructor-only, keyboardShortcut: constructor-only, mobileOpen: setter-backed, mobileQuery: constructor-only, onMobileOpenChange: constructor-only, onOpenChange: constructor-only, open: setter-backed, persistOpen: constructor-only, persistenceKey: constructor-only, persistenceMaxAge: constructor-only, persistenceStorage: constructor-only |
## Related Styled Components
| Component | Relationship |
| --- | --- |
| [Sidebar](/docs/components/sidebar/) | Direct Primitive |
## Exports
| Group | Import | Exports |
| --- | --- | --- |
| Runtime | `@starwind-ui/runtime/sidebar` | `createSidebarController` |
| Astro Primitive | `@starwind-ui/astro/sidebar` | `Sidebar`, `SidebarProvider`, `SidebarSidebar`, `SidebarTrigger`, `SidebarRail`, `SidebarMenuButton` |
| React Primitive | `@starwind-ui/react/sidebar` | `Sidebar`, `SidebarProvider`, `SidebarSidebar`, `SidebarTrigger`, `SidebarRail`, `SidebarMenuButton` |
## Canonical Names
| Kind | Name |
| --- | --- |
| namespace | `Sidebar` |
| runtime-factory | `createSidebarController` |
| part | `Sidebar.Provider` |
| part | `Sidebar.Sidebar` |
| part | `Sidebar.Trigger` |
| part | `Sidebar.Rail` |
| part | `Sidebar.MenuButton` |
## Changelog
### v1.0.0
- Promoted this Primitive's vendoring version to the stable 1.0.0 baseline. Its existing API and Runtime behavior carry forward from the previous release.
### v0.1.1
- Marked generated React Primitive files as client modules so vendored installs preserve client boundaries in React server frameworks.
### v0.1.0
- Introduced provider-owned expanded, collapsed, and mobile state with coordinated controls and panels.