@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
Maintainers
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-vuePeer Dependencies
npm install vue@^3.0.0RichTextEditor 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-familyPhoneInput Setup (Optional)
If you use the PhoneInput component with country flags, install:
npm install flag-iconsQuick 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
tailwindcssso 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:
- Prop value - If a prop is explicitly passed to a component, it always takes precedence
- Global default - Value from the plugin configuration
- 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
