npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sabrenski/spire-ui-vue

v0.3.39

Published

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

Downloads

612

Readme

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