Tailwind CSS v4

Every component is headless: no styles ship, and state is exposed as data-* attributes so Tailwind's arbitrary variants style it directly. No plugin, no configuration, no dependency — add the crate, style with the classes you already write.

Style with arbitrary variants

Tailwind v4 supports data-[...] variants out of the box. Every component takes a class prop, added after its built-in leptos-aria-* class on the element it renders. Pass a string, or a closure for classes that change:

use leptos::prelude::*;
use leptos_aria::Accordion;
use leptos_aria::AccordionItem;
use leptos_aria::AccordionPanel;
use leptos_aria::AccordionTrigger;

view! {
	<Accordion>
		<AccordionItem key="one".to_string()>
			<AccordionTrigger class="data-[state=open]:bg-slate-100 font-medium">
				"Section"
			</AccordionTrigger>
			<AccordionPanel class="data-[state=open]:animate-in">
				"Content"
			</AccordionPanel>
		</AccordionItem>
	</Accordion>
}

Or name the variants once

A short @custom-variant block in your CSS turns every state into a one-word variant:

@import "tailwindcss";

@custom-variant open (&:where([data-state="open"], [data-state="checked"], [data-state="on"]));
@custom-variant closed (&:where([data-state="closed"], [data-state="unchecked"], [data-state="off"]));
@custom-variant disabled- (*:disabled, &:where([data-disabled="true"]));
<button class="open:bg-slate-100 closed:bg-white disabled-:opacity-50" />

The attribute contract

AttributeValuesWhere
data-stateopen / closedModal, Popover, Tooltip, AlertDialog, HoverCard, ContextMenu, Accordion item/trigger/panel
data-statechecked / uncheckedSwitch
data-stateon / offToggleGroupItem
data-stateselectedCalendar cells, Tabs, ListBox options
data-stateloaded / fallbackAvatar
data-disabledtrue / falseAccordion item, overlay triggers
data-draggingtrue / falseDropZone
data-is-draggingtrue / falseDraggableItem
data-currenttruePagination page buttons
data-orientationhorizontal / verticalSeparator, Toolbar
data-actioncancel / confirmAlertDialog buttons
data-focusedtrue / falseListBox options (the active option), Tabs (the tab with keyboard focus)
data-expandedtrue / falseComboBox

Alongside the ARIA attributes (aria-expanded, aria-pressed, aria-selected, ...), Tailwind v4's built-in aria-* variants cover the rest: aria-pressed:bg-blue-500 needs no extra code.