vuetify0

📁 vuetifyjs/0 📅 9 days ago
49
总安装量
16
周安装量
#7983
全站排名
安装命令
npx skills add https://github.com/vuetifyjs/0 --skill vuetify0

Agent 安装分布

opencode 12
codex 11
gemini-cli 9
github-copilot 8
amp 7

Skill 文档

Vuetify0 Skill

@vuetify/v0 — Headless composables and components for Vue 3. Unstyled, logic-focused building blocks for design systems.

For detailed API signatures and usage, see references/REFERENCE.md.

Installation

pnpm install @vuetify/v0

No global plugin is required. Import only what you need:

import { createSelection } from '@vuetify/v0/composables'
import { Tabs } from '@vuetify/v0/components'
import { mergeDeep } from '@vuetify/v0/utilities'
import { IN_BROWSER } from '@vuetify/v0/constants'
import { Vuetify0DateAdapter } from '@vuetify/v0/date'
import type { ID } from '@vuetify/v0/types'

When to Use This Skill

Use v0 whenever you need:

  • Selection state — single, multi, grouped, or stepped selection
  • Headless UI — WAI-ARIA compliant components (tabs, dialogs, checkboxes, radios, popovers)
  • Form validation — async rules, field-level errors, submit handling
  • Shared context — type-safe provide/inject patterns
  • Collection management — registries with lifecycle events
  • Browser utilities — SSR-safe detection, observers, event handling
  • App-wide systems — theming, breakpoints, locale, storage

Vuetify MCP

For structured API access during development, add Vuetify MCP:

claude mcp add --transport http vuetify-mcp https://mcp.vuetifyjs.com/mcp

Available tools: get_vuetify0_skill, get_vuetify0_composable_list, get_vuetify0_composable_guide, get_vuetify0_component_list, get_vuetify0_component_guide

Decision Tree

Before writing custom logic, check if v0 already provides it:

Need Use
Single item selection createSingle
Multi-item selection createSelection or createGroup
Selection with “select all” createGroup (tri-state support)
Step wizard / carousel createStep
Tree / nested items createNested
Form validation createForm
Shared state (provide/inject) createContext or createTrinity
Collection tracking createRegistry
Overflow detection createOverflow
Stacking / z-index layers useStack
Filtering arrays createFilter
Pagination createPagination
Virtual scrolling createVirtual
Undo / redo createTimeline
Notification queue createQueue
Design tokens createTokens
Proxy model (v-model) useProxyModel
Keyboard shortcuts useHotkey
Click outside useClickOutside
Element resizing useResizeObserver
Element visibility useIntersectionObserver
Responsive breakpoints useBreakpoints
Theme switching useTheme
Persistent storage useStorage
SSR check IN_BROWSER
Type guards isString, isNumber, isObject, etc.

Headless Components

All components are unstyled, accessible, and follow WAI-ARIA patterns. They use a compound sub-component pattern:

Tabs

<script lang="ts" setup>
  import { Tabs } from '@vuetify/v0/components'
</script>

<template>
  <Tabs.Root v-model="active">
    <Tabs.List>
      <Tabs.Item value="overview">Overview</Tabs.Item>
      <Tabs.Item value="features">Features</Tabs.Item>
    </Tabs.List>

    <Tabs.Panel value="overview">...</Tabs.Panel>
    <Tabs.Panel value="features">...</Tabs.Panel>
  </Tabs.Root>
</template>

Dialog

<script lang="ts" setup>
  import { Dialog } from '@vuetify/v0/components'
</script>

<template>
  <Dialog.Root v-model="open">
    <Dialog.Activator>Open</Dialog.Activator>
    <Dialog.Content>
      <Dialog.Title>Confirm</Dialog.Title>
      <Dialog.Description>Are you sure?</Dialog.Description>
      <Dialog.Close>Cancel</Dialog.Close>
    </Dialog.Content>
  </Dialog.Root>
</template>

Available Components

Component Purpose
Atom Polymorphic element — render as any HTML tag
Avatar Image with fallback system
Checkbox Checkbox with tri-state and group support
Dialog Modal with focus trap
ExpansionPanel Accordion (single or multi-expand)
Group Multi-selection container
Pagination Page navigation with First/Last/Next/Prev/Ellipsis
Popover Toggle overlay (CSS anchor positioning)
Radio Radio buttons with roving tabindex
Scrim Overlay backdrop
Selection Generic selection container
Single Single-selection container
Step Stepper / wizard
Tabs Tab navigation with keyboard support

Composables

Selection Patterns

// Single selection (e.g., theme picker, active tab)
const single = createSingle({ mandatory: 'force' })
single.register({ id: 'light', value: 'light' })
single.register({ id: 'dark', value: 'dark' })
single.select('dark')
single.selectedValue // Ref<string | undefined>

// Multi-selection (e.g., tag picker, multi-select list)
const selection = createSelection({ multiple: true })
selection.toggle('a')
selection.isSelected('a') // boolean

// Group with "select all" (e.g., data table checkboxes)
const group = createGroup()
group.selectAll()
group.toggleAll()
group.isMixed // true when partially selected

// Sequential navigation (e.g., stepper, carousel)
const stepper = createStep({ circular: true })
stepper.next()
stepper.prev()
stepper.first()
stepper.last()

Docs: createSingle | createSelection | createGroup | createStep | createNested

Forms

const form = createForm()

form.register({
  id: 'email',
  value: '',
  rules: [
    v => !!v || 'Required',
    v => /.+@.+/.test(v) || 'Invalid email',
    async v => await checkAvailable(v) || 'Email taken'
  ]
})

form.submit() // Validates all fields, returns { valid, errors }

Docs: createForm

Context (Dependency Injection)

// createContext — type-safe provide/inject
const [useTheme, provideTheme] = createContext<ThemeContext>('Theme')

// Provider component
provideTheme({ mode, toggle })

// Consumer component (throws helpful error if not provided)
const { mode, toggle } = useTheme()

// createTrinity — context with built-in defaults
const [useConfig, provideConfig, defaultConfig] = createTrinity<Config>('Config', {
  theme: 'light',
  locale: 'en'
})

Docs: createContext | createTrinity | createPlugin

Data Utilities

// Filtering
const { apply } = createFilter({ keys: ['name', 'email'] })
const filtered = apply(query, users)

// Pagination
const pagination = createPagination({ page: 1, itemsPerPage: 10, length: 100 })
pagination.next()

// Virtual scrolling
const { virtualItems, totalHeight, scrollTo } = createVirtual({
  items: largeList,
  itemHeight: 48
})

// Undo/redo
const timeline = createTimeline({ maxSize: 50 })
timeline.push(state)
timeline.undo()

// Notification queue with auto-dismiss
const notifications = createQueue({ timeout: 5000 })
notifications.push({ message: 'Saved!' })

Docs: createFilter | createPagination | createVirtual | createTimeline | createQueue | createOverflow

Browser & DOM

// SSR-safe environment checks
import { IN_BROWSER, SUPPORTS_TOUCH, SUPPORTS_OBSERVER } from '@vuetify/v0/constants'

// DOM observation (auto-cleanup on unmount)
const { width, height } = useResizeObserver(el)
const { isIntersecting } = useIntersectionObserver(el, { threshold: 0.1 })

// Events
useEventListener(window, 'resize', onResize)
useHotkey('ctrl+k', openSearch)
useClickOutside(menuRef, close)

// Responsive
const { md, lgAndUp } = useBreakpoints()
const { matches } = useMediaQuery('(prefers-color-scheme: dark)')

Docs: useResizeObserver | useIntersectionObserver | useMutationObserver | useEventListener | useHotkey | useClickOutside | useMediaQuery

Plugins (App-Wide Systems)

For features that need app-wide state, use plugins in main.ts:

import { createThemePlugin, createBreakpointsPlugin } from '@vuetify/v0'

app.use(
  createThemePlugin({
    themes: {
      light: { colors: { primary: '#3b82f6' } },
      dark: { colors: { primary: '#60a5fa' } },
    }
  })
)
app.use(createBreakpointsPlugin())

// Then in any component:
const { current, toggle } = useTheme()
const { md, lgAndUp } = useBreakpoints()

Available plugins: createThemePlugin, createBreakpointsPlugin, createFeaturesPlugin, createLoggerPlugin, createLocalePlugin, createDatePlugin, createStoragePlugin


Anti-Patterns

Don’t write custom selection logic

// Bad — v0 handles reactivity, mandatory constraints, and events for you
const selected = ref<string[]>([])
function toggle (id: string) {
  const index = selected.value.indexOf(id)
  if (index >= 0) selected.value.splice(index, 1)
  else selected.value.push(id)
}

// Good
const selection = createSelection({ multiple: true })
selection.toggle(id)

Don’t write custom provide/inject

// Bad — no type safety, no error on missing provider
provide('theme', theme)
const theme = inject('theme') // Could be undefined!

// Good — type-safe, throws descriptive error if provider is missing
const [useTheme, provideTheme] = createContext<ThemeContext>('theme')

Don’t write manual SSR checks

// Bad
if (typeof window !== 'undefined')

// Good
import { IN_BROWSER } from '@vuetify/v0/constants'
if (IN_BROWSER)

Composition Hierarchy

Foundation (no dependencies)
├── createContext    → Basic DI
├── createPlugin     → Vue plugin factory
└── createTrinity    → [use, provide, default] pattern

Registry (uses Foundation)
├── createRegistry    → Collection management
├── useProxyRegistry  → External registry proxy
└── useStack          → Layered z-index management

Selection (uses Registry)
├── createSelection   → Multi-select (base)
├── createSingle      → Single-select
├── createGroup       → Multi + tri-state
├── createStep        → Sequential navigation
└── createNested      → Hierarchical

Data (uses Registry)
├── createForm        → Validation
├── createFilter      → Array filtering
├── createPagination  → Page navigation
├── createVirtual     → Virtual scrolling
├── createTokens      → Design tokens
├── createQueue       → FIFO with timeout
└── createTimeline    → Undo/redo

System (standalone)
├── useResizeObserver       → Element dimensions
├── useIntersectionObserver → Visibility detection
├── useMutationObserver     → DOM mutations
├── useEventListener        → Auto-cleanup events
├── useHotkey               → Keyboard shortcuts
├── useClickOutside         → Outside click detection
├── useToggleScope          → Conditional effect scopes
└── createOverflow          → Container overflow detection

Plugins (app-wide, uses createPlugin)
├── useTheme          → Theme switching
├── useBreakpoints    → Responsive detection
├── useLocale         → i18n
├── useDate           → Date utilities
├── useStorage        → localStorage/sessionStorage
├── useFeatures       → Feature flags
├── usePermissions    → Permission management
├── useLogger         → Logging
├── useHydration      → SSR hydration
└── useLazy           → Deferred computation

Transformers
├── toArray           → Normalize to array
└── toReactive        → MaybeRef to reactive

Utility Functions

import { mergeDeep, clamp, range, debounce, useId } from '@vuetify/v0/utilities'

mergeDeep({}, defaults, overrides) // Deep merge (prototype-pollution safe)
clamp(value, 0, 100)              // Clamp to range
range(5)                           // [0, 1, 2, 3, 4]
range(5, 1)                        // [1, 2, 3, 4, 5]

const search = debounce(fn, 300)   // With .clear() and .immediate()
const id = useId()                 // SSR-safe unique ID

Type Guards

import { isString, isNumber, isObject, isArray, isFunction, isBoolean, isNull, isUndefined, isNullOrUndefined, isPrimitive, isSymbol, isNaN } from '@vuetify/v0/utilities'

Resources