Modern, framework-agnostic UI component library built with the data-attribute state pattern.
Versaur is a universal design system that provides:
- π¨ Framework-agnostic CSS core using CSS Modules
- β‘ Data-attribute state machine pattern for clean component APIs
- π² Tree-shakeable component library
- π Registry-based distribution (shadcn-style code copying)
- βΏ Built-in accessibility features
- π Dark mode support out of the box
versaur/
βββ packages/
β βββ core/ # CSS Modules + Design Tokens (framework-agnostic)
β βββ react/ # React wrapper components
β βββ vue/ # Vue wrapper (planned)
β βββ angular/ # Angular wrapper (planned)
βββ apps/
βββ docs/ # Vite + React documentation site
Instead of complex className concatenation, component states are managed through HTML data attributes:
// Component API (clean props)
<Button variant="primary" size="large" loading />
// Rendered HTML (data attributes)
<button data-variant="primary" data-size="large" data-loading>
// CSS Styling (attribute selectors)
.button[data-variant="primary"] { /* styles */ }
.button[data-loading] { /* loading spinner */ }Benefits:
- Single source of truth for component state
- Easier debugging (inspect HTML attributes)
- Framework-agnostic pattern
- Better CSS specificity control
# Install dependencies
pnpm install
# Build all packages
pnpm run build:packages
# Start development server
pnpm devVisit http://localhost:3000 to see the documentation site.
npm install @versaur/react @versaur/core
# or
pnpm add @versaur/react @versaur/coreimport { Button } from "@versaur/react"
import "@versaur/core/tokens"
import "@versaur/core/button.css" // Import component styles
function App() {
return (
<Button variant="primary" size="large">
Click me
</Button>
)
}Note: You need to import both the design tokens and component-specific CSS for styling to work.
Fetch component source code directly:
curl http://localhost:3000/api/registry?item=buttonCopy the code into your project for full customization.
A versatile button component with multiple variants, sizes, and states.
Variants:
primary- Primary action button (blue)secondary- Secondary action button (gray)danger- Destructive action button (red)
Sizes:
small- 2rem heightmedium- 2.5rem height (default)large- 3rem height
States:
loading- Shows spinner, disables interactiondisabled- Grayed out, non-interactivepressed- Toggle/pressed state
Example:
<Button variant="primary" size="large">
Primary Large
</Button>
<Button variant="danger" loading>
Deleting...
</Button>
<Button disabled>
Disabled
</Button>All visual styling is built on CSS custom properties:
- Primitive scales: blue, gray, red, green (50-900)
- Semantic tokens: primary, secondary, danger
- Automatic dark mode support
- 8px base scale (0.25rem to 4rem)
- Consistent vertical rhythm
- Font families (sans, mono)
- Size scale (xs to 2xl)
- Line heights and weights
- Border radius variants
- Shadow scale
- Focus ring definitions
- Transition timings
# Development
pnpm dev # Start docs dev server
pnpm build # Build everything (packages + docs)
pnpm build:packages # Build only packages
pnpm build:docs # Build only docs
# Production
pnpm start # Start docs production server
# Versioning
pnpm changeset # Create a changeset
pnpm version # Version packages
pnpm release # Build and publish packages
# Cleanup
pnpm clean # Remove all build artifacts-
Create CSS in
packages/core/src/components//* component.module.css */ .component { /* base styles */ } .component[data-variant="primary"] { /* variant */ }
-
Create React wrapper in
packages/react/src/components/import { useDataAttrs } from "../../hooks/use-data-attrs" import { componentStyles } from "@versaur/core" export function Component({ variant, ...props }) { const dataAttrs = useDataAttrs({ variant }) return <div className={componentStyles.component} {...dataAttrs} {...props} /> }
-
Add docs: Create a route at
apps/docs/src/routes/docs/components/<name>.tsx, a doc page atapps/docs/src/previews/pages/<name>-doc-page.tsx, and register it inapps/docs/src/previews/registry.ts
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Modern evergreen browsers
MIT
- Icon component integration
- Input component
- Card layout component
- CLI tool for component copying
- Vue wrapper package
- Angular wrapper package
- Additional color schemes
- Animation system
- Form components (Select, Checkbox, Radio)
- Complex components (Modal, Dropdown, Tabs)
- Layout system (Grid, Stack, Container)
- Component playground with live editing
This is currently a portfolio/demonstration project. Feedback and suggestions are welcome via issues.
Built by [Your Name] as a modern design system demonstration.
Inspired by:
- shadcn/ui (registry distribution model)
- Radix UI (accessibility patterns)
- Tailwind CSS (design token system)