Glassmorphism Vue 3 component library for modern gaming UIs
🎮 Live Demo • Installation • Components
A beautiful, theme-switchable Vue 3 component library featuring glassmorphism effects, animated gradient backgrounds, and a gaming-focused design aesthetic. Try all 5 themes (Dark, White, Blue, Matrix, Neumorphism) in the live demo!
- 🎨 5 Built-in Themes: Dark (default), White, Blue, Matrix, Neumorphism
- 💎 True Glassmorphism: Animated gradient mesh backgrounds with backdrop blur
- ⚡ Vue 3 + Vite: Fast, modern, tree-shakeable
- 🎮 Gaming Aesthetic: MMORPG-inspired design with angular borders and bold typography
- 📦 Zero Dependencies: Only requires Vue 3 as peer dependency
- 🎯 TypeScript Ready: Full JSDoc annotations
- 🌐 SSR Compatible: Works with Nuxt and other SSR frameworks
- ♿ Accessible: WCAG 2.1 AA compliant with proper ARIA labels
npm install @aresrpg/ui// main.js
import { createApp } from 'vue'
import AresRPGUI from '@aresrpg/ui'
import '@aresrpg/ui/style.css'
import App from './App.vue'
const app = createApp(App)
app.use(AresRPGUI)
app.mount('#app')Now all components are available with Ares prefix:
<template>
<AresButton variant="gradient">Click me</AresButton>
<AresCard title="Hello World" />
</template><script setup>
import { Button, Card, ThemeSwitcher } from '@aresrpg/ui'
import '@aresrpg/ui/style.css'
</script>
<template>
<div>
<ThemeSwitcher />
<Button variant="gradient">Click me</Button>
<Card title="Hello World" />
</div>
</template>- dark (default): Gold/Orange accents, MMORPG gaming aesthetic
- white: Clean professional look with Blue/Purple accents
- blue: Ocean/Cyberpunk theme with Cyan accents
- matrix: Terminal/Hacker theme with Green accents
- neumorphism: Soft shadows and depth, minimalist design
<script setup>
import { ThemeSwitcher } from '@aresrpg/ui'
</script>
<template>
<ThemeSwitcher />
</template><script setup>
import { useTheme } from '@aresrpg/ui'
const { currentTheme, setTheme, toggleTheme, themes } = useTheme()
// Set specific theme
setTheme('matrix')
// Toggle through themes
toggleTheme()
// Get current theme
console.log(currentTheme.value) // 'matrix'
// Get all available themes
console.log(themes) // ['dark', 'white', 'blue', 'matrix', 'neumorphism']
</script>Glassmorphism button with multiple variants, sizes, and states.
<script setup>
import { Button } from '@aresrpg/ui'
</script>
<template>
<!-- Variants -->
<Button variant="primary">Primary</Button>
<Button variant="gradient">Gradient</Button>
<Button variant="success">Success</Button>
<Button variant="error">Error</Button>
<Button variant="outline">Outline</Button>
<!-- Sizes -->
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<!-- States -->
<Button :disabled="true">Disabled</Button>
<Button :loading="true">Loading</Button>
</template>Props:
variant: 'primary' | 'gradient' | 'success' | 'error' | 'outline' (default: 'primary')size: 'sm' | 'md' | 'lg' (default: 'md')disabled: boolean (default: false)loading: boolean (default: false)
Events:
@click: Emitted when button is clicked
Glassmorphism card with header, icon, and footer slots.
<script setup>
import { Card, Button } from '@aresrpg/ui'
</script>
<template>
<Card
title="Card Title"
description="Card description"
icon="bx bx-star"
:hoverable="true"
>
<p>Card content goes here</p>
<template #footer>
<Button size="sm">Learn More</Button>
</template>
</Card>
</template>Props:
title: string - Card titledescription: string - Card descriptionicon: string - Icon class (e.g., 'bx bx-star')hoverable: boolean (default: true) - Enable hover effect
Slots:
default: Card contenticon: Custom icon contenttitle: Custom title contentdescription: Custom description contentheader: Full custom headerfooter: Footer content
Glassmorphism text input with validation states and icon support.
<script setup>
import { ref } from 'vue'
import { Input } from '@aresrpg/ui'
const username = ref('')
const email = ref('')
</script>
<template>
<!-- Basic input -->
<Input
v-model="username"
type="text"
label="Username"
placeholder="Enter username..."
/>
<!-- With validation states -->
<Input
v-model="email"
type="email"
label="Email"
:error="true"
error-message="Invalid email format"
prefix-icon="bx bx-envelope"
/>
<!-- Success state -->
<Input
v-model="username"
label="Username"
:success="true"
success-message="Username available"
/>
<!-- With helper text -->
<Input
label="Password"
type="password"
helper-text="Must be at least 8 characters"
suffix-icon="bx bx-lock"
/>
</template>Props:
modelValue: string | number - v-model bindingtype: 'text' | 'email' | 'password' | 'number' (default: 'text')label: string - Input labelplaceholder: string - Placeholder textdisabled: boolean (default: false)error: boolean (default: false) - Show error stateerrorMessage: string - Error message textsuccess: boolean (default: false) - Show success statesuccessMessage: string - Success message texthelperText: string - Helper text below inputprefixIcon: string - Icon class for prefix iconsuffixIcon: string - Icon class for suffix icon
Events:
@update:modelValue: Emitted when input value changes@focus: Emitted when input gains focus@blur: Emitted when input loses focus
Glassmorphism modal with backdrop blur and multiple size variants.
<script setup>
import { ref } from 'vue'
import { Modal, Button } from '@aresrpg/ui'
const showModal = ref(false)
</script>
<template>
<Button @click="showModal = true">Open Modal</Button>
<Modal
v-model="showModal"
title="Modal Title"
size="md"
:closable="true"
:close-on-overlay="true"
>
<p>Modal content goes here</p>
<template #footer>
<Button @click="showModal = false">Cancel</Button>
<Button variant="gradient" @click="showModal = false">Confirm</Button>
</template>
</Modal>
</template>Props:
modelValue: boolean (required) - v-model binding for visibilitytitle: string - Modal titlesize: 'sm' | 'md' | 'lg' | 'xl' | 'full' (default: 'md') - Modal sizeclosable: boolean (default: true) - Show close buttoncloseOnOverlay: boolean (default: true) - Close when clicking overlay
Events:
@update:modelValue: Emitted when modal visibility changes@close: Emitted when modal is closed
Slots:
default: Modal contentheader: Custom header contentfooter: Footer content
Status badge with color variants.
<script setup>
import { Badge } from '@aresrpg/ui'
</script>
<template>
<Badge variant="primary">Primary</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="error">Error</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="info">Info</Badge>
</template>Props:
variant: 'primary' | 'success' | 'error' | 'warning' | 'info' (default: 'primary')
Alert messages with icon and dismissible variants.
<script setup>
import { ref } from 'vue'
import { Alert } from '@aresrpg/ui'
const showAlert = ref(true)
</script>
<template>
<Alert
v-model="showAlert"
variant="success"
title="Success!"
message="Your changes have been saved successfully."
:dismissible="true"
/>
<Alert
variant="error"
title="Error"
message="Something went wrong. Please try again."
/>
<Alert
variant="warning"
title="Warning"
message="This action cannot be undone."
/>
<Alert
variant="info"
title="Info"
message="You have 3 new messages."
/>
</template>Props:
modelValue: boolean - v-model for visibility (optional)variant: 'success' | 'error' | 'warning' | 'info' (default: 'info')title: string - Alert titlemessage: string - Alert messagedismissible: boolean (default: true) - Show dismiss button
Toggle switch component with label support.
<script setup>
import { ref } from 'vue'
import { Toggle } from '@aresrpg/ui'
const enabled = ref(false)
const darkMode = ref(true)
</script>
<template>
<!-- Basic toggle -->
<Toggle v-model="enabled" />
<!-- With label -->
<Toggle v-model="darkMode" label="Dark mode" />
<!-- Disabled -->
<Toggle v-model="enabled" label="Auto-save" :disabled="true" />
</template>Props:
modelValue: boolean - v-model bindinglabel: string - Toggle labeldisabled: boolean (default: false)
Events:
@update:modelValue: Emitted when toggle state changes
Tab navigation component with icon and badge support.
<script setup>
import { ref } from 'vue'
import { Tabs, Button } from '@aresrpg/ui'
const activeTab = ref(0)
const tabs = [
{ label: 'Tab 1', icon: 'bx bx-home', badge: '3' },
{ label: 'Tab 2', icon: 'bx bx-user' },
{ label: 'Tab 3', icon: 'bx bx-cog' }
]
</script>
<template>
<Tabs v-model="activeTab" :tabs="tabs">
<template #tab-0>
<h4>Tab 1 Content</h4>
<p>Content for the first tab</p>
<Button>Action Button</Button>
</template>
<template #tab-1>
<p>Content for tab 2</p>
</template>
<template #tab-2>
<p>Content for tab 3</p>
</template>
</Tabs>
</template>Props:
modelValue: number - v-model for active tab indextabs: Array<{ label: string, icon?: string, badge?: string }> - Tab configuration
Events:
@update:modelValue: Emitted when active tab changes
Hover tooltips with customizable positioning.
<script setup>
import { Tooltip, Button } from '@aresrpg/ui'
</script>
<template>
<Tooltip content="Tooltip text" position="top">
<Button>Top</Button>
</Tooltip>
<Tooltip content="Tooltip text" position="bottom">
<Button>Bottom</Button>
</Tooltip>
<Tooltip content="Tooltip text" position="left">
<Button>Left</Button>
</Tooltip>
<Tooltip content="Tooltip text" position="right">
<Button>Right</Button>
</Tooltip>
</template>Props:
content: string - Tooltip contentposition: 'top' | 'bottom' | 'left' | 'right' (default: 'top')
User avatar with size variants and status indicators.
<script setup>
import { Avatar } from '@aresrpg/ui'
</script>
<template>
<!-- Sizes -->
<Avatar size="sm" src="avatar.jpg" alt="User" />
<Avatar size="md" src="avatar.jpg" alt="User" />
<Avatar size="lg" src="avatar.jpg" alt="User" />
<Avatar size="xl" src="avatar.jpg" alt="User" />
<!-- With icons (when no src) -->
<Avatar icon="bx bx-user" />
<!-- With status indicators -->
<Avatar src="avatar.jpg" status="online" />
<Avatar src="avatar.jpg" status="away" />
<Avatar src="avatar.jpg" status="busy" />
</template>Props:
src: string - Avatar image URLalt: string - Alt text for imagesize: 'sm' | 'md' | 'lg' | 'xl' (default: 'md')icon: string - Icon class (when no src provided)status: 'online' | 'away' | 'busy' - Status indicator
Dropdown menu with icons and animations.
<script setup>
import { ref } from 'vue'
import { Dropdown } from '@aresrpg/ui'
const selected = ref(null)
const options = [
{ value: 'option1', label: 'Option 1', icon: 'bx bx-home' },
{ value: 'option2', label: 'Option 2', icon: 'bx bx-user' },
{ value: 'option3', label: 'Option 3', icon: 'bx bx-cog' },
{ value: 'option4', label: 'Option 4', icon: 'bx bx-bell' }
]
</script>
<template>
<Dropdown
v-model="selected"
:options="options"
placeholder="Select an option..."
/>
</template>Props:
modelValue: any - v-model binding for selected valueoptions: Array<{ value: any, label: string, icon?: string }> - Dropdown optionsplaceholder: string - Placeholder text
Events:
@update:modelValue: Emitted when selection changes
Responsive navigation bar with glassmorphism.
<script setup>
import { Navbar } from '@aresrpg/ui'
const navItems = [
{ label: 'Overview', icon: 'bx bx-home', href: '#' },
{ label: 'Components', icon: 'bx bx-grid', href: '#' },
{ label: 'Docs', icon: 'bx bx-book', href: '#' }
]
</script>
<template>
<Navbar brand="Dashboard" :items="navItems">
<template #actions>
<Button size="sm" variant="gradient">New</Button>
<Button size="sm" variant="outline" aria-label="Notifications">
<i class="bx bx-bell"></i>
</Button>
</template>
</Navbar>
</template>Props:
brand: string - Brand name or logo textitems: Array<{ label: string, icon?: string, href: string }> - Navigation items
Slots:
brand: Custom brand contentactions: Action buttons in navbar
Collapsible sidebar navigation with glassmorphism.
<script setup>
import { ref } from 'vue'
import { Sidebar } from '@aresrpg/ui'
const collapsed = ref(false)
const menuItems = [
{ label: 'Dashboard', icon: 'bx bx-home', badge: null },
{ label: 'Components', icon: 'bx bx-grid', badge: '14' },
{ label: 'Themes', icon: 'bx bx-palette', badge: '5' },
{ label: 'Documentation', icon: 'bx bx-book' },
{ label: 'Settings', icon: 'bx bx-cog' }
]
</script>
<template>
<Sidebar
v-model:collapsed="collapsed"
brand="AresRPG UI"
:items="menuItems"
>
<template #footer>
<div class="version">v0.1.0</div>
<Button variant="outline" size="sm">
<i class="bx bx-log-out"></i>
Logout
</Button>
</template>
</Sidebar>
</template>Props:
collapsed: boolean - v-model for collapsed statebrand: string - Brand nameitems: Array<{ label: string, icon: string, badge?: string }> - Menu items
Slots:
brand: Custom brand contentfooter: Footer content
Skeleton loader component for loading states.
<script setup>
import { Skeleton } from '@aresrpg/ui'
</script>
<template>
<!-- Text skeleton -->
<Skeleton variant="text" width="200px" />
<!-- Circle skeleton (for avatars) -->
<Skeleton variant="circle" width="40px" height="40px" />
<!-- Rectangle skeleton -->
<Skeleton variant="rectangle" width="100%" height="100px" />
<!-- Card skeleton -->
<Skeleton variant="card" width="300px" height="200px" />
<!-- Disable animation -->
<Skeleton variant="text" :animated="false" />
</template>Props:
variant: 'text' | 'circle' | 'rectangle' | 'card' (default: 'text')width: string | number - Width in px or % (default: '100%')height: string | number - Height in px or % (default: auto based on variant)animated: boolean (default: true) - Enable shimmer animation
Empty state component for no-data scenarios.
<script setup>
import { EmptyState, Button } from '@aresrpg/ui'
</script>
<template>
<!-- Basic empty state -->
<EmptyState
icon="bx bx-inbox"
title="No data"
message="There is nothing to display here."
/>
<!-- With custom action -->
<EmptyState
icon="bx bx-search"
title="No results found"
message="Try adjusting your search or filter criteria."
>
<template #action>
<Button variant="gradient">Clear Filters</Button>
</template>
</EmptyState>
<!-- Custom content with slots -->
<EmptyState>
<template #title>
<h3>Custom Title</h3>
</template>
<template #message>
<p>Custom message content</p>
</template>
<template #action>
<Button>Take Action</Button>
</template>
</EmptyState>
</template>Props:
icon: string (default: 'bx bx-inbox') - Icon classtitle: string (default: 'No data') - Title textmessage: string (default: 'There is nothing to display here.') - Message text
Slots:
title: Custom title contentmessage: Custom message contentaction: Action button or custom content
Composable for theme management.
const {
currentTheme, // Ref<string> - Current active theme
themes, // string[] - All available themes
setTheme, // (theme: string) => void - Set theme
getTheme, // () => string - Get current theme
toggleTheme, // () => void - Toggle to next theme
initTheme // () => void - Initialize theme from localStorage
} = useTheme()All themes use CSS variables that you can override:
[data-theme="dark"] {
--color-accent-primary: #your-color;
--glass-bg: rgba(30, 30, 30, 0.25);
/* ... other variables */
}Add a new theme by defining CSS variables:
[data-theme="custom"] {
--color-bg-primary: #your-bg;
--color-text-primary: #your-text;
--color-accent-primary: #your-accent;
--gradient-primary: linear-gradient(135deg, #start, #end);
/* ... define all required variables */
}Then add your theme to the themes array in useTheme().
# Install dependencies
npm install
# Start dev server with demo app
npm run dev
# Build library
npm run build
# Preview demo
npm run preview- Chrome/Edge (latest)
- Firefox (latest)
- Safari 15.4+ (backdrop-filter support)
MIT © AresRPG
Contributions are welcome! Feel free to open issues or submit pull requests.














