vlossom

Vlossom UI components for Vue
11,131 3
Install
npm install vlossom
Latest Version:2.2.2
Vue:3
License:MIT
Last Updated:Oct 22, 2026
Links: GitHub  ·  npm
Maintainer: sunio00000

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

  • Vue 3.5+

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

Component Description
vs-container Responsive content container
vs-grid Grid layout system
vs-layout Page layout with header, footer, and content
vs-page Full page wrapper
vs-responsive Responsive breakpoint wrapper
vs-block Block-level section wrapper
vs-header Page header
vs-footer Page footer

Actions

Component Description
vs-button Button control

Form

Component Description
vs-input Text input field
vs-textarea Multi-line text input
vs-date-picker Date and time input
vs-checkbox Checkbox and checkbox set
vs-radio Radio button and radio set
vs-select Dropdown select
vs-switch Toggle switch
vs-toggle Toggle button
vs-file-drop Drag and drop file upload
vs-search-input Search input with suggestions
vs-form Form wrapper with validation
vs-input-wrapper Input label and message wrapper

Display

Component Description
vs-accordion Collapsible content panel
vs-avatar User avatar
vs-bar Horizontal bar
vs-chip Compact label chip
vs-divider Visual divider line
vs-expandable Expandable section
vs-grouped-list Grouped list of items
vs-image Image with fallback
vs-label-value Label-value pair display
vs-skeleton Loading skeleton placeholder
vs-table Data table
vs-text-wrap Text with overflow handling

Feedback

Component Description
vs-loading Loading spinner
vs-message Inline message banner
vs-modal Modal dialog
vs-drawer Slide-in drawer panel
vs-dimmed Dimmed overlay
vs-progress Progress bar
vs-toast Toast notification

Navigation

Component Description
vs-tabs Tab navigation
vs-pagination Page pagination
vs-steps Step indicator
vs-index-view Index-based view switcher

Utility

Component Description
vs-floating Floating positioned element
vs-focus-trap Focus trap for accessibility
vs-inner-scroll Inner scrollable area
vs-render Conditional renderer
vs-visible-render Visibility-based renderer
vs-theme-button Dark/light theme toggle
vs-tooltip Tooltip popup

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

Related Packages

naive-ui

A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript,...

4,431,616 18,588
giime

A Component Library for Vue 3

16,579
next-ui3

A Component Library base on Element Plus for Vue 3

11,049
greeks-live-ui

A Component Library for Vue 3

9,866

Version History

Version Released License
2.2.2 MIT
2.2.1 MIT
2.2.0 MIT
2.1.1 MIT
2.1.0 MIT
Pre-releases (11)
Version Released License
2.0.0-beta.5 MIT
2.0.0-beta.4 MIT
2.0.0-beta.3 MIT
2.0.0-beta.2 MIT
2.0.0-beta.1 MIT