Installation
One package, one plugin call, and what every option on it does.
Install
pnpm add @vitral/vue
# npm install @vitral/vue
# yarn add @vitral/vueVue 3.5 or newer is the only peer dependency. The other @vitral/* packages come with it.
Register the plugin
import { createApp } from 'vue';
import { Vitral, Prism, ptBR } from '@vitral/vue';
import App from './App.vue';
createApp(App)
.use(Vitral, {
theme: {
preset: Prism, // Prism, Ink, Avalonia, Simple, or your own
colorScheme: 'system', // 'light' | 'dark' | 'system'
storageKey: 'app-scheme' // remember the reader's choice
},
locale: ptBR,
inputVariant: 'outlined', // every field, unless it says otherwise
cssLayer: 'vitral' // wrap component CSS in @layer
})
.mount('#app');There is no stylesheet to import. The plugin injects the theme as CSS variables, and each component injects its own CSS the first time it renders, so a page only carries the components it uses.
Options
| Option | Type | Description |
|---|---|---|
| theme | { preset, colorScheme, storageKey, options } | 'none' | The preset and the scheme. 'none' injects nothing: bring your own variables, or go unstyled. |
| locale | Locale | en and ptBR ship; a locale is a plain object, so a third is a literal. |
| inputVariant | 'outlined' | 'filled' | The default look of every field. Reactive: change it at runtime and the page follows. |
| unstyled | boolean | Drop every built-in class, everywhere. See unstyled mode. |
| pt | GlobalPassThrough | Pass-through for every instance of a component, keyed by name. See pass-through. |
| cssLayer | string | false | Wrap component CSS in @layer, so application CSS wins without !important. |
| zIndex | Partial<ZIndexConfig> | The stacking floors for modals, overlays, menus and tooltips. |
| csp | { nonce?: string } | The nonce put on every injected <style>, for a strict Content-Security-Policy. |
Without import lines
In Nuxt the module does this for you. In a plain Vite application, the same lists are behind @vitral/vue/resolver, for unplugin-vue-components and unplugin-auto-import:
import Components from 'unplugin-vue-components/vite';
import AutoImport from 'unplugin-auto-import/vite';
import { VitralResolver, vitralAutoImports } from '@vitral/vue/resolver';
export default defineConfig({
plugins: [
vue(),
Components({ resolvers: [VitralResolver()] }), // <Button>, v-tooltip
AutoImport({ imports: [vitralAutoImports()] }) // useTheme(), Form
]
});VitralResolver({ prefix: 'Vt' }) answers to <VtButton> instead, and leaves every other name to your own components.
Two components at the root
useToast() and useConfirm() send events, so the components that show them have to be on the page. Put them once, near the root, where they outlive the views that call them.
<script setup lang="ts">
import { Toast, ConfirmDialog } from '@vitral/vue';
</script>
<template>
<RouterView />
<Toast />
<ConfirmDialog />
</template>Without JavaScript
A page that only wants the look can take the compiled theme and the components' CSS as two files.
<link rel="stylesheet" href="/node_modules/@vitral/themes/css/prism.css" />
<link rel="stylesheet" href="/node_modules/@vitral/styles/vitral.css" />Working on Vitral itself
pnpm install
pnpm dev # this site, at http://localhost:5180
pnpm test # vitest + axe
pnpm typecheck
pnpm build