# @vuetify/v0 - Complete Documentation > Headless Vue 3 UI primitives and composables for building modern applications and design systems. --- # Contributing URL: https://0.vuetifyjs.com/introduction/contributing # Contributing Thank you for your interest in contributing to Vuetify0! This guide will help you get started. ## Getting Started Before contributing, please: 1. Read the [Getting Started](/introduction/getting-started) guide to understand the project 2. Review existing [issues](https://github.com/vuetifyjs/0/issues) 3. Join our [Discord community](https://community.vuetifyjs.com) for questions ## Reporting Issues ### Bug Reports When reporting bugs, please include: - A clear, descriptive title - Steps to reproduce the issue - Expected vs actual behavior - Browser and OS information - A minimal reproduction (preferably a link to a repo or CodeSandbox) ### Feature Requests For new features: - Check if it's already been requested in [issues](https://github.com/vuetifyjs/0/issues) - Explain the use case and why it would benefit others - Consider if it fits the headless/composable philosophy of Vuetify0 ## Local Development ### Prerequisites - Node.js 20.19+ or 22+ - pnpm 10.6+ - Git ### Setup ```bash # Clone the repository git clone https://github.com/vuetifyjs/0.git cd 0 # Install dependencies pnpm install # Start the playground pnpm dev # Start the docs site pnpm dev:docs ``` ### Project Structure ```text ├── packages/ │ └── 0/ # @vuetify/v0 - main package │ ├── src/ │ │ ├── components/ # Vue components │ │ ├── composables/ # Composable functions │ │ ├── utilities/ # Helper functions │ │ └── types/ # TypeScript types ├── apps/ │ ├── docs/ # Documentation site │ └── storybook/ # Storybook stories └── playground/ # Development playground ``` ### Useful Commands ```bash # Development pnpm dev # Start playground pnpm dev:docs # Start docs site # Testing pnpm test # Run tests in watch mode pnpm test:run # Run tests once # Type checking pnpm typecheck # Check all packages # Linting pnpm lint # Lint codebase pnpm lint:fix # Auto-fix lint issues # Building pnpm build # Build packages ``` ## Pull Requests ### Before Submitting 1. Create a new branch from `master` 2. Make your changes 3. Run `pnpm lint:fix` to fix formatting 4. Run `pnpm typecheck` to check types 5. Run `pnpm test:run` to verify tests pass 6. Write tests for new functionality ### PR Guidelines - Keep PRs focused - one feature or fix per PR - Write a clear title and description - Reference any related issues - Be responsive to feedback ### Branch Naming Use descriptive branch names: - `fix/issue-description` - Bug fixes - `feat/feature-name` - New features - `docs/what-changed` - Documentation updates - `refactor/what-changed` - Code refactoring ## Commit Messages Follow the [Conventional Commits](https://www.conventionalcommits.org/) format: ```text type(scope): subject ``` ### Types - `feat` - New feature - `fix` - Bug fix - `docs` - Documentation changes - `refactor` - Code refactoring - `test` - Adding or updating tests - `chore` - Maintenance tasks ### Examples ```bash feat(useSelection): add toggle method fix(ExpansionPanel): correct aria-expanded state docs(getting-started): update installation instructions refactor(useRegistry): simplify reindex logic test(useForm): add validation edge cases ``` ### Guidelines - Use imperative mood ("add" not "added") - Keep the subject under 60 characters - Don't end with a period - Reference issues when applicable: `fix(useForm): validation error (#123)` ## Code Style ### General - Use TypeScript for all new code - Follow existing patterns in the codebase - Prefer `function` declarations over `const` arrow functions - Use single-word variable names when clear - Add JSDoc comments for public APIs ### Composables - Place in `packages/0/src/composables/` - Each composable in its own directory with `index.ts` - Include `@module` JSDoc block at the top - Colocate tests as `index.test.ts` - Export both standalone and context-creation functions ### Components - Follow the compound component pattern (Root/Item) - Extend `AtomProps` for polymorphic components - Use `useProxyModel` for v-model binding - Include proper ARIA attributes ## Testing - Write tests for new composables and components - Focus on behavior, not implementation details - Test edge cases and error conditions - Use `describe` blocks to organize related tests ```ts describe('useSelection', () => { it('should select an item', () => { // ... }) it('should respect mandatory option', () => { // ... }) }) ``` ## Questions? - [Discord](https://community.vuetifyjs.com) - Real-time chat and questions - [GitHub Issues](https://github.com/vuetifyjs/0/issues) - Bug reports and feature requests Thank you for contributing! --- # Frequently Asked URL: https://0.vuetifyjs.com/introduction/frequently-asked # Frequently Asked Common questions and answers about Vuetify0. Have a question that isn't answered here? Join our [Discord community](https://community.vuetifyjs.com) or open an [issue on GitHub](https://github.com/vuetifyjs/0/issues). --- # Getting Started URL: https://0.vuetifyjs.com/introduction/getting-started # Get started with Vuetify0 Vuetify0 provides headless UI primitives and composables for Vue 3. Components are unstyled and logic-focused, giving you complete control over styling while handling accessibility, keyboard navigation, and state management. ## Installation Install `@vuetify/v0` with your preferred package manager: ::: code-group ```bash pnpm pnpm add @vuetify/v0 ``` ```bash npm npm install @vuetify/v0 ``` ```bash yarn yarn add @vuetify/v0 ``` ```bash bun bun add @vuetify/v0 ``` ::: ## Requirements - Vue 3.3.0 or higher - Node 22+ ## Quick Start Import and use components directly - no plugin installation required: ```vue QuickStart.vue playground ``` Components are completely unstyled. Add your own classes using Tailwind, UnoCSS, or plain CSS. ## Styling v0 is style-agnostic. Choose your preferred CSS framework and map theme colors to v0's CSS variables. ### UnoCSS [UnoCSS](https://unocss.dev) is our recommended choice for its speed and flexibility. #### 1. Install ::: code-group ```bash pnpm pnpm add -D unocss @unocss/preset-wind ``` ```bash npm npm install -D unocss @unocss/preset-wind ``` ```bash yarn yarn add -D unocss @unocss/preset-wind ``` ```bash bun bun add -D unocss @unocss/preset-wind ``` ::: #### 2. Configure ```ts uno.config.ts import { defineConfig, presetWind } from 'unocss' export default defineConfig({ presets: [presetWind()], theme: { colors: { primary: 'var(--v0-primary)', surface: 'var(--v0-surface)', 'on-primary': 'var(--v0-on-primary)', 'on-surface': 'var(--v0-on-surface)', }, }, }) ``` #### 3. Add Vite Plugin ```ts vite.config.ts import UnoCSS from 'unocss/vite' export default defineConfig({ plugins: [ vue(), UnoCSS(), ], }) ``` #### 4. Import Styles ```ts main.ts import 'virtual:uno.css' ``` Now use utility classes in your components: ```vue ``` ### Tailwind CSS v4 [Tailwind v4](https://tailwindcss.com) uses CSS-first configuration with native cascade layers. #### 1. Install ::: code-group ```bash pnpm pnpm add -D tailwindcss @tailwindcss/vite ``` ```bash npm npm install -D tailwindcss @tailwindcss/vite ``` ```bash yarn yarn add -D tailwindcss @tailwindcss/vite ``` ```bash bun bun add -D tailwindcss @tailwindcss/vite ``` ::: #### 2. Add Vite Plugin ```ts vite.config.ts import tailwindcss from '@tailwindcss/vite' export default defineConfig({ plugins: [ vue(), tailwindcss(), ], }) ``` #### 3. Create Stylesheet ```css src/styles/main.css @import "tailwindcss"; @theme { --color-primary: var(--v0-primary); --color-surface: var(--v0-surface); --color-on-primary: var(--v0-on-primary); --color-on-surface: var(--v0-on-surface); } ``` #### 4. Import Styles ```ts main.ts import './styles/main.css' ``` Now use utility classes in your components: ```vue ``` ### CSS Modules Vue's built-in [CSS Modules](https://vuejs.org/api/sfc-css-features#css-modules) require zero configuration. ```vue Button.vue ``` Type-safe access via `useCssModule()`: ```vue ``` > [!TIP] > For dark mode, custom themes, and design tokens, see the [Theming Guide](/guide/theming). ## Nuxt 3 v0 works with Nuxt 3 via a standard plugin. ### 1. Create Plugin ```ts plugins/v0.ts import { createHydrationPlugin, createThemePlugin } from '@vuetify/v0' export default defineNuxtPlugin((nuxtApp) => { nuxtApp.vueApp.use(createHydrationPlugin()) nuxtApp.vueApp.use( createThemePlugin({ default: 'light', themes: { light: { dark: false, colors: { primary: '#3b82f6', surface: '#ffffff', 'on-primary': '#ffffff', 'on-surface': '#212121', }, }, dark: { dark: true, colors: { primary: '#60a5fa', surface: '#1e1e1e', 'on-primary': '#1a1a1a', 'on-surface': '#e0e0e0', }, }, }, }), ) }) ``` ### 2. Configure Nuxt ```ts nuxt.config.ts export default defineNuxtConfig({ build: { transpile: ['@vuetify/v0'], }, }) ``` > [!TIP] > For auto-imports, SSR hydration, and theme persistence, see the [Nuxt Guide](/guide/nuxt). ## Exposed Exports The following export paths exist for the Vuetify0 framework: | Name | Description | | ---- | ----------- | | `@vuetify/v0` | Main entry point exposing all components, composables, and utilities. | | `@vuetify/v0/components` | Components only. | | `@vuetify/v0/composables` | Composables only. | | `@vuetify/v0/utilities` | Utilities only. | | `@vuetify/v0/constants` | Constants only (not included in main entry). | ```ts // Everything import { ExpansionPanel, useSelection } from '@vuetify/v0' // Components only import { ExpansionPanel, Single, Group } from '@vuetify/v0/components' // Composables only import { useSelection, useTheme, useForm } from '@vuetify/v0/composables' // Utilities only import { isObject, isString } from '@vuetify/v0/utilities' // Constants only import { IN_BROWSER } from '@vuetify/v0/constants' ``` ## Next Steps - [Explore Components](/components/) See all available components - [Browse Composables](/composables/) Dive into the composables API --- # guide URL: https://0.vuetifyjs.com/guide # Guide Learn v0's patterns and build headless UI systems. Start with [Getting Started](/introduction/getting-started) if you haven't installed v0 yet. ## Prerequisites Before diving into the guides, ensure you're familiar with: - **Required**: Vue 3 basics (ref, computed, provide/inject) - **Helpful**: Composables pattern, TypeScript generics ## What's Different About v0 | Traditional Component Libraries | v0 Approach | | - | - | | Pre-styled, override with CSS | Zero styles - you own all styling | | Props configure behavior | Composables expose reactive state | | Component = black box | Component = transparent composition | | Fight the framework | Build with the framework | **The v0 Mental Model:** - Components are **delivery mechanisms**, not behavior containers - Logic lives in **composables** you can use independently - **Trinity pattern**: `[use, provide, context]` - predictable, debuggable - **Registry/Context pattern**: Parent-child coordination without prop drilling ## Learning Paths ### Track A: Core Concepts For understanding the system architecture. | Guide | What You'll Learn | | - | - | | [Structure](/guide/structure) | Package organization, imports, file conventions | | [Core](/guide/core) | Trinity, Context, Registry patterns | | [Components](/guide/components) | Component categories, Atom primitive, slot props | | [Plugins](/guide/plugins) | Using and creating Vue plugins | ### Track B: Features & Polish For building production UIs. | Guide | What You'll Learn | | - | - | | [Theming](/guide/theming) | CSS variables, design tokens, dark mode | | [Accessibility](/guide/accessibility) | ARIA patterns, keyboard nav, testing | | [Utilities](/guide/utilities) | Helper functions, type guards | > [!TIP] > New to v0? Start with Track A. Already building? Jump to Track B as needed. > [!SUGGESTION] How do I migrate an existing styled component library to use v0's headless approach? ## Quick Reference | Pattern | Use Case | Guide | | - | - | - | | `createContext` | Share state across component tree | [Core](/guide/core) | | `useSelection` | Multi-select, toggles, radio groups | [Composables](/composables/selection/use-selection) | | `useRegistry` | Dynamic child registration | [Core](/guide/core) | | `Atom` component | Polymorphic base element | [Components](/guide/components) | | `useTheme` | Theme switching, CSS variables | [Theming](/guide/theming) | --- # Accessibility URL: https://0.vuetifyjs.com/guide/accessibility # Accessibility v0 provides ARIA attributes out-of-the-box through the `attrs` pattern. You provide styling and visual feedback. ## The `attrs` Pattern Every v0 component exposes an `attrs` object containing all accessibility attributes. Spread it onto your elements: ```vue playground ``` ### What's Included in `attrs` | Component | ARIA Attributes Provided | | - | - | | Selection.Item | `aria-selected`, `aria-disabled`, `data-selected`, `data-disabled` | | Group.Item | `role="checkbox"`, `aria-checked`, `aria-disabled`, `data-selected`, `data-disabled`, `data-mixed` | | ExpansionPanel.Activator | `id`, `role`, `tabindex`, `aria-expanded`, `aria-controls`, `aria-disabled` | | Pagination.Root | `aria-label`, `role="navigation"` (when not using `