@sabrenski/spire-ui-vue

A modern, themeable Vue 3 component library with 57+ components, TypeScript support, and Tailwind CSS v4
42,505
Install
npm install @sabrenski/spire-ui-vue
Latest Version:0.3.39
Vue:3
License:MIT
Last Updated:Jan 7, 2026
Links: npm
Maintainer: sabrenski

Spire UI

A modern, themeable Vue 3 component library with 57+ components, built with TypeScript and Tailwind CSS v4.

Installation

npm install @sabrenski/spire-ui-vue
# or
pnpm add @sabrenski/spire-ui-vue
# or
yarn add @sabrenski/spire-ui-vue

Peer Dependencies

npm install vue@^3.0.0

RichTextEditor Setup (Optional)

If you use the RichTextEditor component, install the Tiptap dependencies:

npm install @tiptap/vue-3 @tiptap/starter-kit @tiptap/pm \
  @tiptap/extension-link @tiptap/extension-image @tiptap/extension-placeholder \
  @tiptap/extension-text-align @tiptap/extension-underline @tiptap/extension-color \
  @tiptap/extension-text-style @tiptap/extension-highlight @tiptap/extension-typography \
  @tiptap/extension-table @tiptap/extension-table-row @tiptap/extension-table-cell \
  @tiptap/extension-table-header @tiptap/extension-task-list @tiptap/extension-task-item \
  @tiptap/extension-character-count @tiptap/extension-bubble-menu @tiptap/extension-font-family

PhoneInput Setup (Optional)

If you use the PhoneInput component with country flags, install:

npm install flag-icons

Quick Start

1. CSS Setup (Required)

Spire UI uses Tailwind CSS v4's @theme directive for theming. Add these imports to your main CSS file:

/* app.css */
@import "@sabrenski/spire-ui-vue/theme.css";
@import "tailwindcss";

/* Required: Tell Tailwind to scan component files for utility classes */
@source "../node_modules/@sabrenski/spire-ui-vue/dist/**/*.js";
  • theme.css - Must be imported before tailwindcss so Tailwind processes the theme tokens
  • @source - Required for Tailwind to discover which utility classes the components use

2. Vue Plugin Setup

// main.ts
import { createApp } from 'vue'
import { SpireUI } from '@sabrenski/spire-ui-vue'
import App from './App.vue'

const app = createApp(App)

// Optional: Configure global defaults
app.use(SpireUI, {
  defaults: {
    form: { variant: 'outline', size: 'md' },
    button: { variant: 'primary', size: 'md' },
  }
})

app.mount('#app')
<script setup lang="ts">
import { Button, Badge, Input, Card } from '@sabrenski/spire-ui-vue'
import type { ButtonProps } from '@sabrenski/spire-ui-vue'
</script>

<template>
  <Card>
    <Input placeholder="Enter your email" />
    <Button variant="primary">Subscribe</Button>
  </Card>
</template>

Global Configuration

Spire UI supports global default configuration for components using the Vue plugin pattern. This allows you to set default prop values across your entire application.

Plugin Setup

import { createApp } from 'vue'
import { SpireUI } from '@sabrenski/spire-ui-vue'
import type { SpireUIOptions } from '@sabrenski/spire-ui-vue'

const app = createApp(App)

app.use(SpireUI, {
  defaults: {
    // Form components: Input, Textarea, Select, NumberInput, Autocomplete
    form: {
      variant: 'filled',  // 'outline' | 'filled' | 'underline'
      size: 'md',         // 'sm' | 'md' | 'lg'
    },
    // Button component
    button: {
      variant: 'primary', // 'primary' | 'secondary' | 'danger' | 'ghost' | 'contrast' | 'outline'
      size: 'md',         // 'sm' | 'md' | 'lg'
      radius: 'md',       // 'none' | 'sm' | 'md' | 'lg' | 'full'
    },
    // Badge component
    badge: {
      variant: 'solid',   // 'solid' | 'flat' | 'outline'
      color: 'default',   // 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'
      size: 'md',         // 'sm' | 'md' | 'lg'
    },
    // Avatar component
    avatar: {
      size: 'md',         // 'xs' | 'sm' | 'md' | 'lg'
      color: 'default',   // 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger'
      radius: 'full',     // 'none' | 'sm' | 'md' | 'lg' | 'full'
    },
    // Alert component
    alert: {
      variant: 'flat',    // 'flat' | 'solid'
      color: 'default',   // 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger'
      radius: 'md',       // 'none' | 'sm' | 'md' | 'lg' | 'full'
    },
    // Spinner component
    spinner: {
      size: 'md',         // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
      variant: 'ring',    // 'ring' | 'dots'
    },
    // Tabs component
    tabs: {
      variant: 'solid',   // 'solid' | 'underline' | 'bordered'
      color: 'default',   // 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger'
      size: 'md',         // 'sm' | 'md' | 'lg'
      radius: 'md',       // 'none' | 'sm' | 'md' | 'lg' | 'full'
    },
    // Progress component
    progress: {
      variant: 'linear',  // 'linear' | 'circular'
      color: 'primary',   // 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger'
      size: 'md',         // 'sm' | 'md' | 'lg'
    },
    // Card component
    card: {
      shadow: 'md',       // 'none' | 'sm' | 'md' | 'lg'
      radius: 'lg',       // 'none' | 'sm' | 'md' | 'lg'
    },
    // Icon component
    icon: {
      size: 'md',         // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'
      stroke: 'regular',  // 'thin' | 'light' | 'regular' | 'medium' | 'bold'
    },
  }
} as SpireUIOptions)

app.mount('#app')

Resolution Order

Props are resolved in the following order:

  1. Prop value - If a prop is explicitly passed to a component, it always takes precedence
  2. Global default - Value from the plugin configuration
  3. Hardcoded fallback - Built-in default value in the component
<!-- Uses global default variant, but overrides size -->
<Input size="lg" />

<!-- Uses both global defaults for variant and size -->
<Input />

<!-- Explicit props always win -->
<Input variant="underline" size="sm" />

Programmatic Configuration

You can also configure defaults programmatically:

import { configureDefaults, getDefaults, resetDefaults } from '@sabrenski/spire-ui-vue'

// Set defaults at runtime
configureDefaults({
  form: { variant: 'filled' },
  button: { variant: 'secondary' }
})

// Get current defaults
const currentDefaults = getDefaults()

// Reset to empty (use component fallbacks)
resetDefaults()

Components

Layout & Structure

  • Card - Container with optional header, body, and footer
  • Divider - Horizontal or vertical separator
  • Group - Flex container for grouping elements
  • Modal - Dialog overlay with customizable placement
  • Popover - Floating content panel
  • Sidebar - Collapsible navigation panel
  • Navbar - Navigation bar with brand, items, and mobile menu

Forms & Inputs

  • Input - Text input with validation states
  • Textarea - Multi-line text input
  • Select - Dropdown selection with search
  • Autocomplete - Input with suggestions
  • Checkbox - Single or group checkboxes
  • Radio - Radio button groups
  • Switch - Toggle switch
  • Slider - Range slider
  • NumberInput - Numeric input with increment/decrement
  • DatePicker - Date selection with calendar
  • TimePicker - Time selection
  • ColorPicker - Color selection with presets
  • FileInput - File upload input
  • OTPInput - One-time password input
  • PhoneInput - International phone input with country codes
  • RichTextEditor - WYSIWYG editor powered by TipTap
  • FormField - Form field wrapper with label and validation

Data Display

  • Table - Data table with sorting and pagination
  • DataList - Key-value list display
  • Badge - Status indicators and labels
  • Avatar - User profile images with fallback
  • AvatarGroup - Stacked avatars
  • Icon - Icon wrapper with size presets
  • IconPicker - Icon selection from 9000+ icons
  • Image - Responsive image with loading states
  • Progress - Progress bar
  • Spinner - Loading indicator
  • User - User info display with avatar
  • Tooltip - Hover tooltips

Navigation

  • Tabs - Tab navigation
  • Breadcrumbs - Breadcrumb navigation
  • Pagination - Page navigation
  • Link - Styled anchor links

Feedback

  • Alert - Alert messages with variants
  • Toast - Toast notifications
  • EmptyState - Empty state placeholder
  • Error - Error display

Typography

  • Heading - Semantic headings (h1-h6)
  • Text - Text with size and color variants
  • Label - Form labels
  • Hint - Helper text

Charts

  • LineChart - Line/area charts
  • BarChart - Bar charts
  • PieChart - Pie/donut charts
  • Sparkline - Compact inline charts
  • StatsCard - Metric display with trend

Advanced

  • Accordion - Collapsible content panels
  • Calendar - Full calendar view
  • Carousel - Responsive carousel/slider
  • EventsCalendar - Events calendar with day/week/month views
  • Dropdown - Dropdown menu with items and sections
  • Rating - Star rating input
  • Timer - Countdown/stopwatch timer
  • Tree - Hierarchical tree view

Composables

import { useToast, useDarkMode, useTheme, useRovingFocus, useVirtualScroll, useComponentDefault } from '@sabrenski/spire-ui-vue'
  • useToast - Toast notification management
  • useDarkMode - Dark mode management with system preference detection
  • useTheme - Color scheme theme management
  • useRovingFocus - Keyboard navigation for lists
  • useVirtualScroll - Virtualized scrolling for large lists
  • useAnchor - CSS anchor positioning
  • useTrigger - Trigger/popover positioning
  • useScrollDirection - Scroll direction detection
  • useChart - Chart utilities
  • useComponentDefault - Resolve component defaults from global config

useDarkMode

Manage dark mode with system preference detection and localStorage persistence.

<script setup>
import { useDarkMode } from '@sabrenski/spire-ui-vue'

const { isDark, toggle, set, clearPreference } = useDarkMode()
</script>

<template>
  <button @click="toggle">
    {{ isDark ? 'Light Mode' : 'Dark Mode' }}
  </button>
</template>
Option Type Default Description
storageKey string 'spire-dark-mode' localStorage key for persistence
initialValue boolean System preference Initial dark mode state
selector string 'html' Element to apply dark class
darkClass string 'dark' CSS class for dark mode
listenToSystemChanges boolean true React to system preference changes
Return Type Description
isDark Ref<boolean> Reactive dark mode state
toggle () => void Toggle dark mode on/off
set (value: boolean) => void Set dark mode explicitly
clearPreference () => void Clear stored preference and follow system

useTheme

Manage color scheme themes with localStorage persistence.

<script setup>
import { useTheme } from '@sabrenski/spire-ui-vue'

const { schemes, currentScheme, setScheme } = useTheme()
</script>

<template>
  <select v-model="currentScheme">
    <option v-for="scheme in schemes" :key="scheme" :value="scheme">
      {{ scheme }}
    </option>
  </select>
</template>
Option Type Default Description
storageKey string 'spire-theme-scheme' localStorage key for persistence
initialScheme ThemeScheme 'default' Initial color scheme
selector string 'html' Element to apply theme class
customSchemes string[] [] Additional custom schemes
Return Type Description
schemes ComputedRef<ThemeScheme[]> All available scheme names
currentScheme Ref<ThemeScheme> Current active scheme
setScheme (scheme: ThemeScheme) => void Set the color scheme
clearPreference () => void Clear stored preference and reset to default

Available schemes: 'default', 'ocean', 'forest', 'sunset', 'rose', 'midnight'

Component Examples

Button

<Button variant="primary" size="md" :loading="isLoading">
  Submit
</Button>
Prop Type Default Description
variant 'primary' | 'secondary' | 'danger' | 'ghost' | 'contrast' | 'outline' 'primary' Visual style
size 'sm' | 'md' | 'lg' 'md' Button size
disabled boolean false Disable interactions
loading boolean false Show loading spinner
iconOnly boolean false Icon-only mode
type 'button' | 'submit' | 'reset' 'button' HTML button type

Badge

<Badge content="New" color="primary" />

<Badge content="3" color="danger" placement="top-right">
  <Button>Notifications</Button>
</Badge>
Prop Type Default Description
content string | number - Badge content
variant 'solid' | 'flat' | 'outline' 'solid' Visual style
color 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' 'default' Color
size 'sm' | 'md' | 'lg' 'md' Size
dot boolean false Show as dot

Icon

<script setup>
import { Icon } from '@sabrenski/spire-ui-vue'
</script>

<template>
  <Icon name="home-01" size="md" />
</template>
Prop Type Default Description
name string required Icon name from Hugeicons
size 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' 'md' Size (12-40px)
stroke 'thin' | 'light' | 'regular' | 'medium' | 'bold' 'regular' Stroke width

See Icon System Guide for advanced configuration including custom adapters and icon registries.

Toast

<script setup>
import { useToast, ToastContainer } from '@sabrenski/spire-ui-vue'

const toast = useToast()

function showToast() {
  toast.success('Operation completed!')
}
</script>

<template>
  <Button @click="showToast">Show Toast</Button>
  <ToastContainer />
</template>

Theming

CSS Imports

Spire UI provides two CSS exports:

Import Purpose
@sabrenski/spire-ui-vue/theme.css Raw @theme tokens for Tailwind v4 to process
@sabrenski/spire-ui-vue/style.css Pre-built component styles (optional)

For Tailwind v4 projects:

/* app.css */
@import "@sabrenski/spire-ui-vue/theme.css";
@import "tailwindcss";

/* Required: Scan component files for utility classes */
@source "../node_modules/@sabrenski/spire-ui-vue/dist/**/*.js";

You can also import individual theme files:

@import "@sabrenski/spire-ui-vue/theme/base.css";      /* Color palette */
@import "@sabrenski/spire-ui-vue/theme/semantic.css";  /* Semantic tokens + dark mode */
@import "@sabrenski/spire-ui-vue/theme/components.css"; /* Component-specific tokens */

Dark Mode

Add the dark class to <html> or any parent element:

<html class="dark">

Theme Variants

  • Light (default)
  • Dark (class="dark")
  • Ocean (class="ocean")
  • Forest (class="forest")
  • Sunset (class="sunset")
  • Rose (class="rose")
  • Midnight (class="midnight")

Customizing Colors

Override the base color variables to customize the entire palette:

:root {
  --color-primary-base: oklch(55% 0.2 250);  /* Blue primary */
  --color-danger-base: oklch(55% 0.22 27);
}

Or override individual semantic tokens:

:root {
  --color-primary: oklch(0.6 0.2 250);
  --color-primary-hover: oklch(0.55 0.2 250);
}

TypeScript

Full TypeScript support with exported types:

import type {
  ButtonProps,
  BadgeProps,
  AlertProps,
  CardProps,
  ModalProps,
  ToastOptions,
  SpinnerProps,
  TooltipProps,
  // Global configuration types
  SpireUIOptions,
  SpireUIDefaults,
} from '@sabrenski/spire-ui-vue'

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

MIT

Related Packages

@itguy614/clean-ui

A clean, dark-mode-ready Vue 3 component library — 100+ token-driven, themeable,...

2,243 0
@jeesson/vibe-ui

Vibe UI — a Vue 3 component library for vibe coders: 50+ components, dark/light...

567 0
@cocoar/vue-ui

Cocoar Design System — a touch-first Vue 3 component library with 30+ accessible...

17,724 0
@hina-ui/vue

The design system behind Hikarinagi: Vue 3 components built on Tailwind CSS v4.

4,608 10
brutx-ui-vue

A Neo-Brutalism styled Vue 3 UI component library

10,283 4

Version History

Version Released Vue License
0.3.39 ^3.0.0 MIT
0.3.38 ^3.0.0 MIT
0.3.37 ^3.0.0 MIT
0.3.36 ^3.0.0 MIT
0.3.35 ^3.0.0 MIT