A modern Vue 3 UI component library with Tailwind CSS, featuring semantic color tokens that adapt to your project's design system.
Chalkos (χαλκός) — Greek for copper/brass
- Vue 3 Composition API with full TypeScript support
- Tailwind CSS with semantic color tokens
- Dark/Light mode via
.darkclass on<html> - Customizable via CSS variables
- Accessible with proper ARIA attributes, keyboard navigation, and
prefers-reduced-motionsupport - Tree-shakeable - import only what you need
- Secure - Rich text editors include DOMPurify for XSS protection
- 60+ Components including navigation, layout, forms, and advanced interactive components
npm install chalkos-ui// main.ts
import 'chalkos-ui/styles'If you want to use Chalkos UI's semantic color classes in your own components, extend your Tailwind config:
// tailwind.config.js
export default {
content: [
// ... your content paths
'./node_modules/chalkos-ui/dist/**/*.js',
],
darkMode: 'class',
theme: {
extend: {
colors: {
accent: {
DEFAULT: 'var(--cu-accent)',
hover: 'var(--cu-accent-hover)',
muted: 'var(--cu-accent-muted)',
foreground: 'var(--cu-accent-foreground)',
},
// ... add other semantic colors as needed
},
},
},
}Override the CSS variables to match your brand:
:root {
/* Your brand colors */
--cu-accent: #3b82f6;
--cu-accent-hover: #2563eb;
--cu-accent-muted: rgba(59, 130, 246, 0.1);
--cu-accent-foreground: #ffffff;
}
.dark {
--cu-accent: #60a5fa;
--cu-accent-hover: #93c5fd;
}<script setup lang="ts">
import { ref } from 'vue'
import {
CuButton,
CuInput,
CuSearchableSelect,
CuMultiSelect,
useToast
} from 'chalkos-ui'
import type { SelectOption } from 'chalkos-ui'
const toast = useToast()
const name = ref('')
const country = ref('')
const skills = ref<string[]>([])
const countries: SelectOption[] = [
{ value: 'us', label: 'United States', code: 'US' },
{ value: 'gb', label: 'United Kingdom', code: 'GB' },
]
const skillOptions: SelectOption[] = [
{ value: 'vue', label: 'Vue.js', code: 'VUE' },
{ value: 'react', label: 'React', code: 'RE' },
]
const handleSubmit = () => {
toast.success('Form submitted!')
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<CuInput v-model="name" placeholder="Your name" />
<CuSearchableSelect
v-model="country"
:options="countries"
placeholder="Select country"
/>
<CuMultiSelect
v-model="skills"
:options="skillOptions"
placeholder="Select skills"
/>
<CuButton type="submit">Submit</CuButton>
</form>
</template>- CuButton - Buttons with variants (primary, secondary, outline, ghost, danger)
- CuInput - Text input with prefix/suffix support
- CuSelect - Native select wrapper
- CuSearchableSelect - Single-select dropdown with search
- CuMultiSelect - Multi-select dropdown with tags
- CuCheckbox - Styled checkbox with indeterminate state
- CuSwitch - Toggle switch
- CuRadio - Styled radio button
- CuDateInput - Date input with keyboard entry, auto-formatting, and calendar picker
- CuTimeInput - Time input with 12h/24h format, auto-formatting, and time picker
- CuDateTimeInput - Combined date and time input
- CuDateRangePicker - Date range selection with dual calendars
- CuNumberInput - Numeric input with increment/decrement controls
- CuSlider - Range slider input
- CuTextarea - Multi-line text input with auto-resize and character count
- CuHtmlInput - Rich text WYSIWYG editor with formatting toolbar (XSS-safe via DOMPurify)
- CuMarkdownInput - Markdown editor with live preview and view modes (XSS-safe via DOMPurify)
- CuAlert - Alert cards (success, warning, danger, info)
- CuBadge - Status badges with optional dot indicator
- CuToastContainer + useToast - Toast notification system
- CuNavbar - Horizontal top navigation bar with dropdown submenus and mobile support
- CuSidebar - Vertical sidebar navigation with collapsible sections and tooltips
- CuMegaMenu - Mega menu navigation with multi-column dropdown panels
- CuNavDropdown - Navigation mega-menu dropdown
- CuPagination - Pagination controls
- CuBreadcrumb - Breadcrumb navigation
- CuTabs - Tab navigation
- CuCard - Content card container
- CuModal - Dialog/confirmation modal
- CuDrawer - Slide-out panel
- CuAccordion - Collapsible content sections
- CuPopover - Floating content panel
- CuTooltip - Contextual hover tooltips
- CuGrid - Responsive CSS grid layout with gap and alignment controls
- CuStack - Flexbox stack layout (horizontal/vertical) with spacing
- CuDivider - Visual separator with optional label and orientation
- CuScrollArea - Custom scrollable container with styled scrollbars
- CuSplitPane - Resizable split panel layout (horizontal/vertical)
- CuTable - Data table with sorting and selection
- CuAvatar - User avatar with fallback
- CuProgress - Progress bar
- CuTimeline - Vertical timeline
- CuStepper - Step progress indicator
- CuEmptyState - Empty state placeholder
- CuSkeleton - Loading skeleton
- CuCommandPalette - Keyboard-driven command palette (⌘K) with search and actions
- CuCombobox - Autocomplete input with keyboard navigation and custom rendering
- CuDropdownMenu - Context menu with nested submenus and keyboard support
- CuThemeToggle - Dark/light mode switch
- CuSpinner - Loading spinner
- CuTagInput - Tag/chip input
- CuFileUpload - File upload with drag-and-drop
- CuColorPicker - Color selection
- CuRating - Star rating input
- CuTransition - Animation wrapper with 12 presets (fade, slide, scale, blur, etc.)
- useClickOutside - Detect clicks outside an element
- useToast - Programmatic toast notifications
CuHtmlInput and CuMarkdownInput include built-in XSS protection via DOMPurify. Sanitization is enabled by default.
<template>
<!-- Sanitization enabled by default -->
<CuHtmlInput v-model="content" />
<!-- Explicitly disable sanitization (only for trusted content) -->
<CuHtmlInput v-model="trustedContent" :sanitize="false" />
<!-- Custom sanitization config -->
<CuHtmlInput v-model="content" :sanitize-config="customConfig" />
</template>
<script setup lang="ts">
import type { Config } from 'dompurify'
// Custom config to allow only specific tags
const customConfig: Config = {
ALLOWED_TAGS: ['p', 'b', 'i', 'a'],
ALLOWED_ATTR: ['href', 'target'],
}
</script>| Prop | Type | Default | Description |
|---|---|---|---|
sanitize |
boolean |
true |
Enable/disable HTML sanitization |
sanitizeConfig |
DOMPurify.Config |
See below | Custom DOMPurify configuration |
The default sanitization config allows common formatting tags:
- Text:
p,br,hr,strong,b,em,i,u,s,del,strike - Headings:
h1,h2,h3,h4,h5,h6 - Lists:
ul,ol,li - Blocks:
blockquote,pre,code - Media:
a,img - Structure:
div,span
href, src, alt, title, target, rel, class, style
All components use CSS variables for theming. Override these in your CSS:
:root {
/* Accent (primary) color */
--cu-accent: #b55724;
--cu-accent-hover: #c96830;
--cu-accent-muted: rgba(181, 87, 36, 0.1);
--cu-accent-foreground: #000000;
/* Surface colors */
--cu-surface: #ffffff;
--cu-surface-secondary: #f9fafb;
--cu-surface-elevated: #ffffff;
/* Border colors */
--cu-border: #e5e7eb;
--cu-border-muted: #f3f4f6;
/* Text colors */
--cu-foreground: #111827;
--cu-foreground-secondary: #6b7280;
--cu-foreground-muted: #9ca3af;
/* Status colors */
--cu-success: #10b981;
--cu-warning: #f59e0b;
--cu-danger: #ef4444;
--cu-info: #3b82f6;
/* Typography */
--cu-font-sans: system-ui, sans-serif;
--cu-font-mono: ui-monospace, monospace;
/* Border radius */
--cu-radius: 0.5rem;
--cu-radius-sm: 0.375rem;
--cu-radius-lg: 0.75rem;
}
/* Dark mode overrides */
.dark {
--cu-accent: #d4915c;
--cu-surface: #0f0f0f;
--cu-foreground: #f5f5f5;
/* ... */
}Chalkos UI detects dark mode via the .dark class on the <html> element. Use CuThemeToggle or implement your own toggle:
// Toggle dark mode
document.documentElement.classList.toggle('dark')# Install dependencies
npm install
# Start Storybook (with dark/light mode toggle)
npm run storybook
# Run tests (326 tests across 51 files)
npm test
# Build library
npm run build
# Build Storybook static site
npm run build-storybook- Storybook 10 - Component documentation with dark/light mode support
- Vitest - Unit and component testing with browser mode
- Playwright - Browser testing integration
- TypeScript - Full type safety
Storybook is automatically deployed to GitHub Pages on every push to main or master. To enable this:
- Go to your repository Settings → Pages
- Under Build and deployment, set Source to GitHub Actions
- Push to
mainormasterto trigger deployment
You can also manually trigger a deployment from the Actions tab using "Run workflow".
Chalkos UI is built with accessibility in mind:
- ARIA attributes - Proper roles, labels, and states
- Keyboard navigation - Full keyboard support for all interactive components
- Focus management - Visible focus indicators and logical focus order
- Reduced motion - Respects
prefers-reduced-motionmedia query
/* Animations automatically reduce when user prefers reduced motion */
@media (prefers-reduced-motion: reduce) {
/* CuTransition and other animations adapt automatically */
}The CuTransition component provides 12 animation presets:
<template>
<CuTransition name="fade">
<div v-if="show">Fading content</div>
</CuTransition>
<CuTransition name="slide-up" duration="slow">
<div v-if="show">Sliding content</div>
</CuTransition>
</template>Available presets: fade, slide-up, slide-down, slide-left, slide-right, scale, scale-up, scale-down, blur, blur-scale, expand, collapse
Duration options: fast (150ms), normal (200ms), slow (300ms)
GPL-3.0