Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 48 additions & 6 deletions apps/docs/src/components/docs/DocsFaq.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,56 @@
<script setup lang="ts">
<script lang="ts">
// Framework
import { ExpansionPanel } from '@vuetify/v0'
import { createFilter, createFilterContext, ExpansionPanel } from '@vuetify/v0'

// Utilities
import { toRef, useSlots } from 'vue'

export const [useFaqFilter, provideFaqFilter] = createFilterContext({
namespace: 'docs:faq',
})
</script>

const props = defineProps<{
<script setup lang="ts">
const { multiple = true } = defineProps<{
multiple?: boolean
}>()

const slots = useSlots()
const filter = createFilter()
provideFaqFilter(filter)

const count = toRef(() => {
const items = slots.default?.() ?? []
return items.filter(v => (v.type as { __name?: string })?.__name === 'DocsFaqItem').length
})

const show = toRef(() => count.value >= 5)

function onInput (e: Event) {
filter.query.value = (e.target as HTMLInputElement).value
}
</script>

<template>
<ExpansionPanel.Group class="flex flex-col gap-3 my-6" :multiple="props.multiple ?? true">
<slot />
</ExpansionPanel.Group>
<div class="my-6">
<div v-if="show" class="relative mb-3">
<AppIcon
class="absolute left-3 top-1/2 -translate-y-1/2 text-on-surface-variant pointer-events-none"
icon="search"
:size="16"
/>

<input
class="w-full pl-9 pr-3 py-2 text-sm bg-surface-tint border border-divider rounded-lg outline-none focus:border-primary transition-colors placeholder:text-on-surface-variant"
placeholder="Search FAQ..."
type="text"
:value="filter.query.value"
@input="onInput"
>
</div>

<ExpansionPanel.Group class="flex flex-col gap-3" :multiple>
<slot />
</ExpansionPanel.Group>
</div>
</template>
14 changes: 12 additions & 2 deletions apps/docs/src/components/docs/DocsFaqItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@
// Framework
import { ExpansionPanel } from '@vuetify/v0'

defineProps<{
// Context
import { useFaqFilter } from './DocsFaq.vue'

// Utilities
import { toRef } from 'vue'

const { question } = defineProps<{
question: string
}>()

const filter = useFaqFilter()
const result = filter.apply(filter.query, () => [question])
const visible = toRef(() => result.items.value.length > 0)
</script>

<template>
<ExpansionPanel.Root>
<ExpansionPanel.Root v-show="visible">
<ExpansionPanel.Activator
v-slot="{ isSelected }"
class="w-full list-item-bordered flex items-center gap-3 text-left"
Expand Down
4 changes: 3 additions & 1 deletion apps/docs/src/components/docs/DocsPaletteBrowse.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { md2 } from '@vuetify/v0/palettes/md2'
import { radix } from '@vuetify/v0/palettes/radix'
import { tailwind } from '@vuetify/v0/palettes/tailwind'
import { vuetify0 } from '@vuetify/v0/palettes/vuetify0'

// Composables
import { useClipboard } from '@/composables/useClipboard'
Expand All @@ -21,6 +22,7 @@
}

const PALETTES: Record<string, PaletteEntry> = {
vuetify0: { label: 'Vuetify0', data: vuetify0 as Record<string, Record<string, string>>, namespace: 'v0' },
tailwind: { label: 'Tailwind', data: tailwind as Record<string, Record<string, string>>, namespace: 'tw' },
md1: { label: 'MD1', data: md1 as Record<string, Record<string, string>>, namespace: 'md1' },
md2: { label: 'MD2', data: md2 as Record<string, Record<string, string>>, namespace: 'md2' },
Expand All @@ -29,7 +31,7 @@
ant: { label: 'Ant Design', data: ant as Record<string, Record<string, string>>, namespace: 'ant' },
}

const selected = shallowRef('tailwind')
const selected = shallowRef('vuetify0')
const clicks = ref(new Map<string, string>())
const { copied, copy } = useClipboard()

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/components/primitives/aspect-ratio.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ inline style and no semantics of its own. Any ARIA attributes belong on the
content inside. Pass `as` to change the element when a different semantic
wrapper is needed (e.g. `as="figure"`).

## Questions
## FAQ

::: faq

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/components/primitives/atom.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ In renderless mode, you're responsible for applying attrs to your custom element
> [!WARNING]
> When using renderless mode, ensure your custom element is accessible. A `<div>` needs explicit `role`, `tabindex`, and keyboard event handlers to match what a native `<button>` provides for free.

## Questions
## FAQ

::: faq
??? When would I use Atom directly vs just using a v0 component?
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/components/primitives/portal.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Portal is transparent — it adds no DOM elements, ARIA attributes, or keyboard
> [!TIP]
> When teleporting interactive content (modals, menus, notifications), ensure it has proper ARIA roles, keyboard handling, and focus management. Portal handles *where* content renders, not *how* it behaves.

## Questions
## FAQ

::: faq
??? When should I use Portal vs native Teleport?
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/components/primitives/presence.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Presence is transparent — it adds no DOM elements, ARIA attributes, or keyboar
> [!TIP]
> Ensure animated content respects `prefers-reduced-motion`. Presence doesn't enforce motion preferences — your CSS should handle `@media (prefers-reduced-motion: reduce)`.

## Questions
## FAQ

::: faq
??? Why not use Vue's Transition component?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ flowchart LR
> [!TIP] Deep vs shallow
> Pass `{ deep: true }` for `reactive()`, or omit for `shallowReactive()` (default). Shallow is more performant when ticket internals don't need tracking.

## Frequently Asked Questions
## FAQ

::: faq
??? Why does the registry need `events: true`?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ A design system with four token categories — color palettes, semantic aliases,

:::

## Frequently Asked Questions
## FAQ

::: faq
??? What's the difference between `depth: Infinity` and `flat: true`?
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/composables/system/use-presence.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Toggle content with a CSS-driven enter/exit animation. `isMounted` drives `v-if`

:::

## Questions
## FAQ

::: faq
??? How does usePresence relate to useLazy?
Expand Down
1 change: 1 addition & 0 deletions apps/docs/src/pages/guide/features/palettes.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ v0 ships pre-built color data from popular design systems and generator adapters

| Import | Source | Hues | Shades |
| - | - | - | - |
| `@vuetify/v0/palettes/vuetify0` | Vuetify0 brand | 11 | 50-950 |
| `@vuetify/v0/palettes/md1` | Material Design 1 | 16 | 50-900, A100-A700 |
| `@vuetify/v0/palettes/md2` | Material Design 2 | 19 | 50-900, A100-A700 |
| `@vuetify/v0/palettes/material` | Material Design 3 | 6 groups | tones 0-100 |
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/guide/fundamentals/composables.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ ticket?.value // MyItem

> [!ASKAI] Which composables should I use for a data table with filtering and pagination?

## Frequently Asked Questions
## FAQ

::: faq
??? Should I always use context injection or can I call factories directly?
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/guide/fundamentals/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ wizard.last() // Jump to end

> [!ASKAI] How do I handle scoped contexts for nested components without prop drilling?

## Frequently Asked Questions
## FAQ

::: faq
??? Why use createContext instead of Vue's provide/inject directly?
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/pages/guide/fundamentals/reactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ See [Benchmarks](/guide/fundamentals/benchmarks) for detailed measurements and m

> [!ASKAI] Should I use useProxyRegistry or events for a list of 500 items that updates every few seconds?

## Frequently Asked Questions
## FAQ

::: faq
??? Why doesn't v0 just make everything reactive like Vue?
Expand Down
5 changes: 5 additions & 0 deletions packages/0/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"./palettes/md2": "./dist/palettes/md2/index.mjs",
"./palettes/radix": "./dist/palettes/radix/index.mjs",
"./palettes/tailwind": "./dist/palettes/tailwind/index.mjs",
"./palettes/vuetify0": "./dist/palettes/vuetify0/index.mjs",
"./permissions": "./dist/permissions/index.mjs",
"./permissions/adapters": "./dist/permissions/adapters/index.mjs",
"./permissions/adapters/v0": "./dist/permissions/adapters/v0/index.mjs",
Expand Down Expand Up @@ -268,6 +269,10 @@
"development": "./src/palettes/tailwind/index.ts",
"default": "./dist/palettes/tailwind/index.mjs"
},
"./palettes/vuetify0": {
"development": "./src/palettes/vuetify0/index.ts",
"default": "./dist/palettes/vuetify0/index.mjs"
},
"./permissions": {
"development": "./src/permissions/index.ts",
"default": "./dist/permissions/index.mjs"
Expand Down
148 changes: 148 additions & 0 deletions packages/0/src/palettes/vuetify0/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Types
import type { TokenCollection } from '#v0/composables/createTokens'

export const vuetify0: TokenCollection = {
violet: {
50: '#f5f3ff',
100: '#ede9fe',
200: '#ddd6fe',
300: '#c4b5fd',
400: '#a78bfa',
500: '#7c5cf6',
600: '#6d28d9',
700: '#5b21b6',
800: '#4c1d95',
900: '#3b1f7a',
950: '#2e1065',
},
indigo: {
50: '#eef2ff',
100: '#e0e7ff',
200: '#c7d2fe',
300: '#a5b4fc',
400: '#818cf8',
500: '#6366f1',
600: '#4f46e5',
700: '#4338ca',
800: '#3730a3',
900: '#312e81',
950: '#1e1b4b',
},
purple: {
50: '#faf5ff',
100: '#f3e8ff',
200: '#e9d5ff',
300: '#d8b4fe',
400: '#c084fc',
500: '#a855f7',
600: '#9333ea',
700: '#7e22ce',
800: '#6b21a8',
900: '#581c87',
950: '#3b0764',
},
slate: {
50: '#f8fafc',
100: '#f1f5f9',
200: '#e2e8f0',
300: '#cbd5e1',
400: '#94a3b8',
500: '#64748b',
600: '#475569',
700: '#334155',
800: '#1e293b',
900: '#0f172a',
950: '#020617',
},
neutral: {
50: '#fafafa',
100: '#f5f5f5',
200: '#e8e8e8',
300: '#d4d4d4',
400: '#a3a3a3',
500: '#737373',
600: '#525252',
700: '#404040',
800: '#262626',
900: '#1a1a1a',
950: '#121212',
},
red: {
50: '#fef2f2',
100: '#fee2e2',
200: '#fecaca',
300: '#fca5a5',
400: '#f87171',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c',
800: '#991b1b',
900: '#7f1d1d',
950: '#450a0a',
},
green: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d',
950: '#052e16',
},
amber: {
50: '#fffbeb',
100: '#fef3c7',
200: '#fde68a',
300: '#fcd34d',
400: '#fbbf24',
500: '#f59e0b',
600: '#d97706',
700: '#b45309',
800: '#92400e',
900: '#78350f',
950: '#451a03',
},
orange: {
50: '#fff7ed',
100: '#ffedd5',
200: '#fed7aa',
300: '#fdba74',
400: '#fb923c',
500: '#f97316',
600: '#ea580c',
700: '#c2410c',
800: '#9a3412',
900: '#7c2d12',
950: '#431407',
},
sky: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e',
950: '#082f49',
},
blue: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#1867c0',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
950: '#172554',
},
}
Loading