@vuecs/form-controls

A package containing form controls.
8,048 4
Install
npm install @vuecs/form-controls
Latest Version:2.5.0
Vue:3
Last Updated:Oct 16, 2026
Links: GitHub  ·  npm
Maintainer: tada5hi

vuecs

vuecs

The Vue 3 theming framework.
Components, themes, design tokens, dark mode, runtime palettes & locale —
all reskinnable through a single app.use() call.

CI npm version Known Vulnerabilities Conventional Commits License

Documentation · Getting Started · Components · Example Apps


Why vuecs?

Most component libraries lock you into one design system. vuecs inverts that: components ship undesigned — structure, behavior, and accessibility, with no design opinion baked in — and themes supply the design. A layered resolution engine wires the two together at runtime.

app.use(vuecs, { themes: [tailwind()] });   // an entire app, Tailwind-skinned
app.use(vuecs, { themes: [bootstrap()] });  // same app, now Bootstrap — no component changes

That inversion serves two audiences:

  • App teams get one component set whose look comes entirely from the installed theme — the Bootstrap theme supplies real .btn / .card classes, the Tailwind theme supplies utilities — so the components blend into an existing app without visual seams, and switching design systems later is a config swap, not a rewrite.
  • Component-library authors get a theming contract: build your own components on the same machinery, ship them with your default styling, and your consumers restyle them — together with vuecs and every other library on the contract — through one theme config. You stop dictating a CSS framework to everyone who installs your package.

The value proposition is layered, and every layer is independently consumable:

  1. 🎛️ Theming machinery (@vuecs/core) — useComponentTheme / useComponentDefaults composables, <VCConfigProvider>, defineTheme() for composing themes on top of existing ones, a structured variant system (variant × color × size × compoundVariants), and typed, augmentable registries (ThemeElements, ComponentDefaults, Config).
  2. 🧱 A full baseline of theme-aware components — buttons, forms, tables, lists, overlays, navigation, pagination, skeletons and more, built on that machinery with Reka UI primitives handling the accessibility heavy lifting.
  3. 🔌 An opt-in path for third-party libraries to publish components on the same machinery — so one app.use(vuecs, { ... }) call reskins everything: vuecs primitives and every library that builds on them.

Plus the runtime extras most design systems make you assemble yourself:

  • 🌗 Dark mode — token-driven .dark flips via useColorMode() (light / dark / system), SSR-safe in Nuxt.
  • 🎨 Runtime palette switching — useColorPalette().set({ primary: 'emerald' }) re-tints every component and native Bootstrap/Bulma widgets, live, with no rebuild.
  • 🌍 Locale plumbing — browser-detected, cookie/storage-persisted locale source that bridges into every locale-aware component and composes with vue-i18n / any i18n library.
  • 🧩 Design tokens (@vuecs/design) — OKLCH color scales, radius + motion primitives, consumable with Tailwind, Bootstrap, Bulma, or no framework at all.

Getting Started

npm install @vuecs/core @vuecs/button @vuecs/theme-tailwind @vuecs/design @vuecs/icon @vuecs/icons-lucide
import { createApp } from 'vue';
import vuecs, { extend } from '@vuecs/core';
import button from '@vuecs/button';
import tailwind from '@vuecs/theme-tailwind';
import lucide from '@vuecs/icons-lucide';

const app = createApp(App);

app.use(vuecs, {
    themes: [tailwind()],     // CSS class strings for every component
    icons:  [lucide()],       // Iconify names for every semantic icon slot
    overrides: {
        elements: {
            button: { classes: { root: extend('shadow-lg') } },  // merge on top of the theme
        },
    },
});
app.use(button);
<VCButton color="primary" variant="solid" icon-left="lucide:plus" :loading="busy">
    Create
</VCButton>

Follow the full walkthrough at vuecs.dev/getting-started.

How theming works

Every component resolves its CSS classes through four layers, then applies structured variants on top:

┌─────────────────────────────────────────────┐
│ 4. instance prop      :theme-class          │  per-component override
│ 3. overrides          app.use(vuecs, {...}) │  app-wide override
│ 2. themes             tailwind(), custom()  │  merged in array order
│ 1. component defaults vc-* structural       │  always preserved
└─────────────────────────────────────────────┘
            ↓ then variants resolve
   :theme-variant="{ color: 'error', size: 'sm' }"

Higher layers replace by default; wrap a value in extend() to merge instead. Themes are pure data — functions returning { elements, classesMergeFn? } — so they compose, stack, and ship from third-party packages. defineTheme({ extends: tailwindTheme(), elements: { ... } }) lets you publish a self-contained brand theme that inherits a shipped one.

→ Deep dive: Theme system · Variants · Composing themes · Build a themable component

Runtime superpowers

import { useColorMode, useColorPalette } from '@vuecs/design';

const { mode, resolved, toggle } = useColorMode();        // 'light' | 'dark' | 'system', persisted
const { set } = useColorPalette();                        // re-tint the whole app at runtime
set({ primary: 'emerald', info: 'cyan' });                // no rebuild, persists across reloads
import { useLocaleManager } from '@vuecs/locale';

const { set, reset, resolved } = useLocaleManager();
set('de-DE');   // apply a backend-saved preference
reset();        // back to 'auto' → browser language

In Nuxt, all three (color mode, palette, locale) ship as SSR-safe, cookie-backed plugins via @vuecs/nuxt — rendered into the head before first paint, so there's no flash of the wrong theme.

Packages

Foundation

Package Version Description
@vuecs/core npm Theme resolution engine, variants, behavioral defaults, cross-cutting config, headless composables, VCPrimitive
@vuecs/design npm CSS design tokens (OKLCH), dark mode, motion primitives, runtime palette engine
@vuecs/icon npm <VCIcon> — Iconify-backed icon component
@vuecs/locale npm Browser-language-aware, resettable locale source

Components

Package Version Description
@vuecs/button npm Button with variant × color × size axes, loading state, icon slots
@vuecs/elements npm Atomic elements — Badge, Tag, Avatar, Separator, plus the Card / Alert / Collapse compounds
@vuecs/forms npm Complete form-input family on Reka primitives — input, select, slider, pin, tags, …
@vuecs/table npm Compound table — columns/data driver, multi-sort, selection, expandable rows
@vuecs/list npm Compound list with defineList() state factory and ARIA-listbox selection
@vuecs/overlays npm Modal, Popover, HoverCard, Tooltip, DropdownMenu, ContextMenu, Toast
@vuecs/navigation npm Multi-level navigation with reactive registry, plus <VCStepper>
@vuecs/pagination npm Offset/limit pagination on Reka's Pagination primitives
@vuecs/placeholder npm Skeleton loading primitives — wave/glow shimmer, reduced-motion aware
@vuecs/countdown npm Countdown timer with typed scoped slot
@vuecs/gravatar npm Gravatar avatar with fallback support
@vuecs/link npm Router-aware anchor — NuxtLink / RouterLink / <a> auto-detection
@vuecs/timeago npm Relative-time display, locale-aware, auto-updating

Themes

Package Version Description
@vuecs/theme-tailwind npm Tailwind v4 utility classes + twMerge-backed extend() + palette runtime
@vuecs/theme-bootstrap npm Bootstrap 5 classes + --bs-* ↔ --vc-color-* design-token bridge
@vuecs/theme-bulma npm Bulma 1.0+ classes + --bulma-* bridge + palette renderer

Icon presets

Package Version Description
@vuecs/icons-lucide npm Lucide icon names for every semantic icon slot
@vuecs/icons-font-awesome npm Font Awesome 6 Solid icon names

Integrations

Package Version Description
@vuecs/nuxt npm Theme-agnostic Nuxt module — SSR-safe color mode, palette & locale, auto-imports

Pick your stack

vuecs doesn't assume Tailwind. Each shipping theme pairs with the CSS stack you already use:

/* Tailwind app */
@import "tailwindcss";
@import "@vuecs/design";
@import "@vuecs/theme-tailwind";

/* Bootstrap app — no Tailwind anywhere */
@import "bootstrap/dist/css/bootstrap.css";
@import "@vuecs/design/standalone";
@import "@vuecs/theme-bootstrap";

/* Bulma app — no Tailwind anywhere */
@import "bulma/css/bulma.css";
@import "@vuecs/design/standalone";
@import "@vuecs/theme-bulma";

The Bootstrap and Bulma themes additionally bridge their framework's native CSS variables (--bs-*, --bulma-*) onto vuecs design tokens — so runtime palette switching re-tints native Bootstrap/Bulma widgets too, not just vuecs components.

Example apps

Four runnable apps under examples/, all mounting the same demo views from a shared catalog — living proof that one codebase reskins across ecosystems:

App Stack
examples/nuxt Nuxt 4 + Tailwind theme — SSR color mode, palette & locale
examples/tailwind Vite + Vue 3 + Tailwind theme
examples/bootstrap Vite + Vue 3 + Bootstrap 5
examples/bulma Vite + Vue 3 + Bulma 1.0+

A Playwright visual-regression matrix (3 themes × every demo route) guards against unintended drift.

Contributing

npm ci             # install
npm run build      # build all packages (Nx, cached)
npm run test       # run tests
npm run lint       # ESLint — must pass with zero errors

Commits follow Conventional Commits; releases are fully automated via release-please.

License

Made with 💚

Published under Apache 2.0 License.

Related Packages

@vuecs/forms

Form controls (inputs, checkbox, switch, select, textarea, range slider) on Reka...

7,577 4
@vue-layout/hyperscript

A package containing hyperscript components for usage in render functions.

1,245 4
simput

Provide a simple way to write input simulation files.

6,004 20

Version History

Version Released Vue License
2.5.0 ^3.x
2.4.3 ^3.x
2.4.2 ^3.x
2.4.1 ^3.x
2.4.0 ^3.x