Button
Stable Available in release assets
Trigger an immediate native action with theme-driven presentation.
Button primary example
<button class="thin-button" type="submit">
<svg class="thin-icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M20 6 9 17l-5-5" />
</svg>
<span>Save changes</span>
</button>Show code
<button class="thin-button" type="submit">
<svg class="thin-icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M20 6 9 17l-5-5" />
</svg>
<span>Save changes</span>
</button>Variant gallery
Each authored example uses the production assets and includes copyable markup.
Theme-driven variants
Default, secondary, quiet, and danger treatments preserve native button semantics.
<div class="thin-cluster">
<button class="thin-button" type="button">Default</button>
<button class="thin-button" data-variant="secondary" type="button">Secondary</button>
<button class="thin-button" data-variant="quiet" type="button">Quiet</button>
<button class="thin-button" data-variant="danger" type="button">Delete project</button>
</div>Show code
<div class="thin-cluster">
<button class="thin-button" type="button">Default</button>
<button class="thin-button" data-variant="secondary" type="button">Secondary</button>
<button class="thin-button" data-variant="quiet" type="button">Quiet</button>
<button class="thin-button" data-variant="danger" type="button">Delete project</button>
</div>Sizes
Sizes change presentation only; the native control and label remain intact.
<div class="thin-cluster">
<button class="thin-button" data-size="small" type="button">Small</button>
<button class="thin-button" type="button">Default size</button>
<button class="thin-button" data-size="large" type="button">Large</button>
</div>Show code
<div class="thin-cluster">
<button class="thin-button" data-size="small" type="button">Small</button>
<button class="thin-button" type="button">Default size</button>
<button class="thin-button" data-size="large" type="button">Large</button>
</div>Icons and accessible names
Decorative icons are hidden; an icon-only action receives an explicit accessible name.
<div class="thin-cluster">
<button class="thin-button" type="button">
<svg class="thin-icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M20 6 9 17l-5-5" />
</svg>
<span>Save changes</span>
</button>
<button class="thin-button" data-variant="danger" data-icon-only type="button" aria-label="Delete project">
<svg class="thin-icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M3 6h18M8 6V4h8v2m-9 0 1 14h8l1-14M10 11v5m4-5v5" />
</svg>
</button>
</div>Show code
<div class="thin-cluster">
<button class="thin-button" type="button">
<svg class="thin-icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M20 6 9 17l-5-5" />
</svg>
<span>Save changes</span>
</button>
<button class="thin-button" data-variant="danger" data-icon-only type="button" aria-label="Delete project">
<svg class="thin-icon" viewBox="0 0 24 24" aria-hidden="true">
<path d="M3 6h18M8 6V4h8v2m-9 0 1 14h8l1-14M10 11v5m4-5v5" />
</svg>
</button>
</div>Disabled and pending states
Disabled prevents activation. Pending pairs visible status with aria-busy and disabled when repeat submission is unsafe.
<div class="thin-cluster">
<button class="thin-button" type="button" disabled>Unavailable</button>
<button class="thin-button" type="button" aria-busy="true" disabled>
<span>Place order</span>
<span data-pending-label>Placing order…</span>
</button>
</div>Show code
<div class="thin-cluster">
<button class="thin-button" type="button" disabled>Unavailable</button>
<button class="thin-button" type="button" aria-busy="true" disabled>
<span>Place order</span>
<span data-pending-label>Placing order…</span>
</button>
</div>Anatomy
- Native button or link with thin-button class
- Optional decorative Lucide icon
- Visible label
Variants and sizes
- Default — shown above
- Secondary — shown above
- Quiet — shown above
- Danger — shown above
- Small — shown above
- Large — shown above
- Icon-only — shown above
States and difficult content
Rendered fixtures exercise authored content and constrained layouts with the same production assets.
- Default
- Focus-visible
- Disabled
- Pending with aria-busy
- Long and localized labels
- Narrow containers
Structured state fixtures are not published for this item yet.
Interaction and keyboard behavior
Native button activation, form ownership, type, and disabled behavior remain canonical.
Accessibility
Keep a visible label whenever possible. Icon-only buttons require an accessible name. Decorative icons use aria-hidden=true. Set aria-busy=true while an action is pending and disable the button when a repeat activation would be unsafe.
- Contract
NATIVE- Basis
- Native <button> or <a href>; no APG widget
- Evidence
tests/unit/library/core-components-stable.test.ts
API
Add class=thin-button to a native button or a link with href. Set data-variant to secondary, quiet, or danger, and data-size to small or large. Use data-icon-only for icon-only presentation. A button with aria-busy=true shows its direct child marked data-pending-label, when present. Inline Lucide SVGs use the thin-icon class and currentColor.
Behavior tier: native
Hosts
Apply the class to the HTML element that supplies the appropriate landmark or content role.
<button class="thin-button" type="button">…</button><a class="thin-button" href="/…">…</a>
Fallback
Native button behavior remains intact without CSS.
Assets and dependencies
/components.css
Dependencies: None
Source: packages/ui/src/items/button/style.ts
Stability evidence
- Native semantics, icon, pending, disabled, and difficult-content contracts:
test:tests/unit/library/core-components-stable.test.ts - Focused semantic presentation and state tests:
test:tests/unit/library/components.test.ts - Cross-theme, density, narrow-container, and localized review fixture:
review:site/src/pages/quality/index.astro#quality-review
Composition
Derived from the examples and style specs, not authored.
Composes
Used by
- Alert dialog
- Anchored placement
- Authentication flows
- Availability
- Bulk actions
- Calendar
- Carousel
- Cart
- Chat
- Checkout
- Cluster
- Collection
- Combobox and autocomplete
- Command palette
- Command workflows
- Confirm dialog
- Contact
- CRUD edit
- Data table
- Date and time input guidance
- Dialog
- Discounts
- Drawer
- Drag-and-drop file uploader
- Filtered data view
- Form validation
- Hover card
- Icons
- Inline editing
- Input mask
- Interactive charts
- Lightbox
- Logo reel
- Mini-cart drawer
- Multi-step form
- Newsletter
- OTP input
- Poll form
- Product detail
- Product filters
- Product sorting
- Search and results
- Searchable multi-select
- Settings and preferences
- Sheet
- Slide-over
- Switcher
- Thin-Sky theme
- Uploads