- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Banner
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Command
- Collapsible
- Combobox
- Context Menu
- Data Table
- Date Picker
- Dialog
- Dropdown Menu
- Editor
- Input
- Input Group
- Label
- Loading Spinner
- Native Select
- Popover
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Steps
- Switch
- Tabs
- Textarea
- Tooltip
Data attributes
Style any part of a component from your own CSS.
Every component marks its parts with
data-slot, and every component that has state reports it with
data-state.
Both use the same names as ShadCn, so a stylesheet written for ShadCn works here.
This means you can restyle a component without publishing it and without touching Alpine.
Slots
data-slot names a part. A component with one element has one slot. A component built from several elements names
each one:
<div data-slot="card"> <div data-slot="card-header"> <h3 data-slot="card-title">Billing</h3> <p data-slot="card-description">Your plan renews monthly.</p> </div> <div data-slot="card-content">...</div> <div data-slot="card-footer">...</div></div>
<div data-slot="card"> <div data-slot="card-header"> <h3 data-slot="card-title">Billing</h3> <p data-slot="card-description">Your plan renews monthly.</p> </div> <div data-slot="card-content">...</div> <div data-slot="card-footer">...</div></div>
Target a part from your CSS:
[data-slot="card-title"] { letter-spacing: -0.02em;}
[data-slot="card-title"] { letter-spacing: -0.02em;}
Or from a Tailwind class on a parent:
<april:card class="[&_[data-slot=card-title]]:text-primary">...</april:card>
<april:card class="[&_[data-slot=card-title]]:text-primary">...</april:card>
When a component wraps another one, the outer name wins.
sidebar-input renders an input with
data-slot="sidebar-input", not
data-slot="input".
State
data-state says what the component is doing. The value depends on the component:
<!-- Anything that opens -->data-state="open" | data-state="closed"<!-- Switch --><p>data-state="checked" | data-state="unchecked"</p><!-- Tabs --><p>data-state="active" | data-state="inactive"</p><!-- Sidebar --><p>data-state="expanded" | data-state="collapsed"
<!-- Anything that opens -->data-state="open" | data-state="closed"<!-- Switch --><p>data-state="checked" | data-state="unchecked"</p><!-- Tabs --><p>data-state="active" | data-state="inactive"</p><!-- Sidebar --><p>data-state="expanded" | data-state="collapsed"
A disabled control also gets
data-disabled.
The starting state is in the HTML the server sends, so the page looks right before Alpine boots. Alpine keeps the attribute current after that.
Using it
[data-slot="dialog-content"][data-state="open"] { animation: fade-in 150ms ease-out;}
[data-slot="dialog-content"][data-state="open"] { animation: fade-in 150ms ease-out;}
Tailwind can do the same with the
data- variant:
<april:switch class="data-[state=checked]:ring-2" />
<april:switch class="data-[state=checked]:ring-2" />
Which components report state
| Component | Attribute | Values |
|---|---|---|
| accordion-item | data-state |
open, closed |
| alert | data-state |
open, closed |
| banner | data-state |
open, closed |
| date-picker | data-state |
open, closed |
| dialog | data-state |
open, closed |
| dropdown-menu | data-state |
open, closed |
| dropdown-menu-sub | data-state |
open, closed |
| popover | data-state |
open, closed |
| select | data-state,
data-disabled |
open, closed |
| sheet | data-state |
open, closed |
| sidebar | data-state,
data-side,
data-variant,
data-collapsible |
expanded, collapsed |
| switch | data-state,
data-disabled |
checked, unchecked |
| tabs-trigger | data-state |
active, inactive |
| tabs-content | data-state |
active, inactive |
| tooltip | data-state |
open, closed |
Animation classes such as
animate-in and
slide-in-from-right are not part of Tailwind. If you want them, install
tw-animate-css. Without it those classes produce no CSS. The
components animate with Alpine transitions either way.