Features
- Various Color Schemes — Easily style any component with a single prop
- Layered Style Sets — Global, named, or per-instance style overrides via CSS variables
- Overlay System — Modal, Toast, Alert, Confirm, Prompt as plugins with full app context inheritance
- Declarative Responsive — Breakpoint objects instead of media queries
- Async Validation — Sync and async rules with built-in defaults per component
- Dark / Light Theme — One-line global toggle, auto-persisted
Requirements
Installation
npm install vlossom
# or
pnpm add vlossom
# or
yarn add vlossom
[!TIP]
Vlossom supports per-component tree shaking.
See VLOSSOM_USAGE_GUIDE.md.
Setup
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import { createVlossom, VlossomComponents } from 'vlossom';
import 'vlossom/styles';
const app = createApp(App);
app.use(
createVlossom({
components: VlossomComponents,
}),
);
app.mount('#app');
Usage
<template>
<vs-button primary>Hello Vlossom</vs-button>
</template>
<script setup lang="ts">
// Components are globally registered via createVlossom — no import needed
</script>
Deep into
Basic Components
Mix buttons, inputs, and modals with reactive bindings, props, and slots:
<template>
<vs-button primary>Click me</vs-button>
<vs-input v-model="name" label="Name" color-scheme="blue" />
<vs-modal v-model="isOpen">
<template #header>Title</template>
Modal content here
</vs-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const name = ref('');
const isOpen = ref(false);
</script>
Declarative Responsive Layout
Use breakpoint objects instead of media queries — no CSS required:
<template>
<vs-grid column-gap="16px" row-gap="16px">
<vs-responsive
v-for="item in items"
:key="item.id"
:grid="{ xs: 12, sm: 6, md: 4, lg: 3, xl: 2 }"
>
<div>{{ item.name }}</div>
</vs-responsive>
</vs-grid>
</template>
Form Validation (Sync & Async)
Pass sync and async rules in the same array — Vlossom handles both seamlessly:
<template>
<vs-input v-model="email" label="Email" :rules="[required, uniqueEmail]" :max="50" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const email = ref('');
const required = (v: string) => (v ? '' : 'Email is required');
const uniqueEmail = async (v: string) => {
const res = await fetch(`/api/check-email?email=${v}`);
const { exists } = await res.json();
return exists ? 'Already in use' : '';
};
</script>
Overlay Plugins (Toast · Alert · Confirm · Prompt · Modal)
Call overlays from any composable — no template wiring needed:
<script setup lang="ts">
import { useVlossom } from 'vlossom';
import EditForm from './EditForm.vue';
const $vs = useVlossom();
function notify() {
$vs.toast.success('Saved successfully');
}
async function alertSaved() {
await $vs.alert.open('Saved successfully');
}
async function remove() {
const ok = await $vs.confirm.open('Delete this item?', {
okText: 'Delete',
cancelText: 'Cancel',
colorScheme: 'red',
});
if (ok) {
$vs.toast.info('Item deleted');
}
}
async function askReason() {
const reason = await $vs.prompt.open('Why are you deleting this item?', {
input: { placeholder: 'Reason' },
okText: 'Submit',
cancelText: 'Skip',
});
if (reason) {
$vs.toast.info(`Reason: ${reason}`);
}
}
function openEditor() {
$vs.modal.open(EditForm, {
size: 'md',
callbacks: {
onSave: (data: unknown) => {
$vs.toast.success('Updated');
$vs.modal.close();
},
},
});
}
</script>
Components
Layout
Actions
| Component |
Description |
| vs-button |
Button control |
Form
Display
Feedback
Navigation
Utility
Vlossom Options
Configure the app-wide theme, radius, and named style sets in createVlossom, then adjust individual components with props when needed:
app.use(
createVlossom({
components: VlossomComponents,
theme: 'dark',
radiusRatio: 0.5,
styleSet: {
brand: {
VsButton: {
backgroundColor: '#1a1a1a',
fontColor: '#fff',
},
},
},
}),
);
theme sets the initial global theme. Use <vs-theme-button /> to toggle it at runtime.
radiusRatio controls the global border radius ratio from 0 to 1.
styleSet defines reusable named style overrides for components.
messages overrides the built-in texts Vlossom renders. See Messages.
color-scheme applies a built-in color to a component instance.
- Available colors:
red · orange · brown · amber · yellow · lime · green · emerald · teal · cyan · sky · blue · indigo · violet · purple · fuchsia · pink · rose · gray · none
Messages
Every text Vlossom renders on its own — validation messages, empty states, overlay button labels, aria labels — comes
from a single message table. Override any subset in createVlossom to localize or reword them:
app.use(
createVlossom({
components: VlossomComponents,
messages: {
VS_VALIDATION_REQUIRED: '필수 항목입니다',
VS_VALIDATION_MAX_LENGTH: ({ value }) => `최대 ${value}자까지 입력할 수 있어요`,
VS_TABLE_NO_DATA: '내역이 없어요',
},
}),
);
Line Tiers
Borders and dividers are drawn with two line variables, so lines carry a visual hierarchy instead of all reading at the
same weight. Each color scheme and theme defines both.
| Variable |
Used for |
--vs-cs-border |
Default. Everything at rest: borders, dividers and form controls. |
--vs-cs-border-strong |
Lines that need to be noticed: focus, hover, active, and separators that delimit a region. |
Both tiers come straight from the palette, and the resting tier is always exactly one palette step weaker than the
strong one, in every scheme and theme:
.my-scope {
--vs-cs-border: #c8c8c8;
--vs-cs-border-strong: #a3a3a3;
}
Links
License
MIT