Overview
UI components available as plain CSS classes, React, Astro, Solid, Svelte, and Vue wrappers.
Usage approaches
Plain CSS classes
Every component is usable with any HTML element by applying the right class names. This works in any framework or with no framework at all.
<button class="zui-button zui-button-variant-outline">Click me</button>
React
React wrappers accept typed props instead of class strings. Import from @mrmartineau/zui/react.
import { Button } from '@mrmartineau/zui/react'
<Button variant="outline">Click me</Button>
Astro
Astro wrappers work the same way. Import from @mrmartineau/zui/astro.
---
import { Button } from '@mrmartineau/zui/astro'
---
<Button variant="outline">Click me</Button>
Solid
Solid wrappers use class instead of className. Import from @mrmartineau/zui/solid.
import { Button } from '@mrmartineau/zui/solid'
<Button variant="outline">Click me</Button>
Svelte
Svelte wrappers are Svelte 5 SFCs that use runes and snippets. Import from @mrmartineau/zui/svelte.
<script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button variant="outline">Click me</Button>
Vue
Vue wrappers are SFC components. Import from @mrmartineau/zui/vue.
<template>
<Button variant="outline">Click me</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script>
See Using with React, Using with Astro, Using with Solid, Using with Svelte, and Using with Vue for setup instructions.
CSS layer
Component styles live in the zui.components layer, below zui.utilities. This means utility classes always override component styles when both apply, without needing !important.
@layer zui.base, zui.components, zui.utilities;
CSS custom properties
Every component exposes CSS custom properties (variables) that control its appearance — colours, border radius, padding, shadow, and more. You can override these without touching the source CSS and without ejecting any styles.
Inline overrides
Pass overrides via the style attribute on the component's root element:
<div class="zui-card" style="--zui-card-radius: var(--radius-sm); --zui-card-padding: var(--space-lg);">
…
</div>
CSS overrides
Target the component class in your own stylesheet. Because component styles live in zui.components, any rule outside a @layer already wins — no !important needed:
.zui-card {
--zui-card-radius: var(--radius-sm);
--zui-card-padding: var(--space-lg);
}
To scope an override to a specific context, nest it under a parent selector:
.my-sidebar .zui-button {
--zui-btn-radius: 0;
}
See this live CodePen example showing three cards side by side: one with default styles, one customised via inline style attributes, and one themed via scoped CSS classes. Each component page lists its available custom properties and their defaults.
Components
Accordion
A stacked set of disclosure panels using the native details/summary elements.
Avatar
A circular image with a fallback for when the image fails to load or no source is provided.
Badge
Small status indicators and labels. Supports colour variants and size modifiers.
Button
A flexible button with five variants, three accent colours, five sizes, four shapes, and icon-only mode.
Card
A container for grouping related content, with optional header, body, and footer sections.
Checkbox
Custom-styled checkboxes with list layout.
Collapsible
A single disclosure widget using the native details/summary elements.
Dialog
Modal dialogs built on the native dialog element with a styled backdrop. Requires minimal JavaScript to open.
Flex
A layout component for flexbox-based arrangements. Controls direction, alignment, justification, wrapping, and gap spacing via props.
Input
A styled text input for forms.
Label
Form labels with optional required indicator and description text.
Menu
A strict action menu with managed focus, keyboard navigation, and menu button semantics.
Popover
Floating panels built on the native HTML Popover API and CSS Anchor Positioning. No JavaScript required.
Radio
Custom-styled radio buttons with list layout.
Select
A styled native select dropdown.
Table
A styled table for displaying tabular data.
Tabs
Accessible tabs with horizontal and vertical orientations.
Textarea
A multi-line text input with auto-sizing via field-sizing: content.
Tooltip
Small contextual labels on hover or focus, using the Popover API and CSS Anchor Positioning.