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 has CSS custom properties (variables) for its colours, radius, padding, font sizes, shadow, and more. Each component page lists them with their defaults.
Set them on :root to change every instance, on a wrapper to change one part of the page, or in a style attribute to change one element:
:root {
--zui-card-radius: var(--radius-sm);
--zui-card-padding: var(--space-lg);
}
.my-sidebar {
--zui-btn-radius: 0;
}
<div class="zui-card" style="--zui-card-padding: var(--space-lg);">…</div>
See Component custom properties in the theming guide for how variants work, and what to avoid. This live CodePen example shows three cards side by side: one with default styles, one customised via inline style attributes, and one themed via scoped CSS classes.
Components
Accordion
A stacked set of disclosure panels using the native details/summary elements.
App Shell
Application layout primitive — collapsible sidebar, top header, scrollable main content.
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.
Field
Composable form-field primitives for consistent spacing, descriptions, errors, legends and orientation.
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.
Kbd
Keyboard key hints. Render a single key with Kbd, or combine keys into a shortcut with KbdGroup.
Label
Form labels with optional required indicator and description text.
Menu
A strict action menu with managed focus, keyboard navigation, and menu button semantics.
Number Field
A number input with decrease and increase buttons on each side.
Password Input
A password field with a button that shows or hides the password.
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.