Theme
Gebruik
De Thema-component overschrijft standaard slot classes en props van alle onderliggende componenten zonder ze afzonderlijk te wijzigen.
Het maakt gebruik van Vue 's provide / inject-mechanisme onder de motorkap, dus de overrides zijn op elke diepte van toepassing.
app.config.ts-bestand te gebruiken.vite.config.ts-bestand te gebruiken.Slot klassen
Gebruik de ui prop om slotklassen van afstammelende componenten te overschrijven. Toetsen zijn componentnamen (camelCase) en waarden zijn hun slotklasse-overschrijvingen.
<template>
<UTheme
:ui="{
button: {
base: 'rounded-full'
}
}"
>
<div class="flex items-center gap-2">
<UButton label="Button" color="neutral" />
<UButton label="Button" color="neutral" variant="outline" />
<UButton label="Button" color="neutral" variant="subtle" />
</div>
</UTheme>
</template>
Prop standaard: badge{label="4.8+" class="align-text-top"}
Gebruik de props-prop om de standaardwaarde van een prop op afstammelingscomponenten te overschrijven. Elke toets wordt toegewezen aan een deel van de rekwisieten van dat onderdeel.
<template>
<UTheme
:props="{
button: { color: 'neutral', variant: 'subtle', size: 'lg' },
tooltip: { delayDuration: 0, arrow: true }
}"
>
<div class="flex items-center gap-2">
<UTooltip text="Inherits delayDuration from theme">
<UButton label="Hover me" />
</UTooltip>
<UButton label="With icon" icon="i-lucide-rocket" />
<UButton label="Square" icon="i-lucide-star" square />
</div>
</UTheme>
</template>
<UButton color="primary" />) winnen altijd <UTheme :props>. Standaardwaarden voor thema 's zijn alleen van toepassing wanneer de prop niet expliciet is doorgegeven.Voorbeelden
Meerdere componenten
Gebruik verschillende toetsen in ui of props om meerdere componenttypen tegelijk te thematiseren.
<template>
<UTheme
:props="{
button: { color: 'neutral', variant: 'outline', size: 'lg' },
input: { size: 'lg' },
select: { size: 'lg' }
}"
:ui="{
button: { base: 'rounded-full' },
input: { base: 'rounded-full' },
select: { base: 'rounded-full' }
}"
>
<div class="flex items-center gap-2">
<UButton label="Button" />
<UInput placeholder="Search..." />
<USelect placeholder="Select" :items="['Item 1', 'Item 2', 'Item 3']" />
</div>
</UTheme>
</template>
Genestelde thema 's
Nest meerdere Thema-componenten om overrides samen te stellen. Het binnenste Thema heeft voorrang, terwijl niet-overschreven toetsen worden overgenomen van het buitenste Thema.
<template>
<UTheme
:ui="{
button: {
base: 'rounded-full'
}
}"
>
<div class="flex flex-col items-start gap-4 border border-muted p-4 rounded-lg">
<div class="flex items-center gap-2">
<UButton label="Outer theme" />
<UButton label="Outer theme" color="neutral" variant="outline" />
</div>
<UTheme
:ui="{
button: {
base: 'font-black uppercase'
}
}"
>
<div class="border border-muted p-4 rounded-lg">
<div class="flex items-center gap-2">
<UButton label="Inner theme" />
<UButton label="Inner theme" color="neutral" variant="outline" />
</div>
</div>
</UTheme>
</div>
</UTheme>
</template>
Expliciete prioriteit
Het expliciet instellen van een prop (inclusief ui) op een individuele component heeft altijd voorrang op de Thema-component.
<template>
<UTheme
:ui="{
button: {
base: 'rounded-full'
}
}"
>
<div class="flex items-center gap-2">
<UButton label="Themed" />
<UButton label="Overridden" :ui="{ base: 'rounded-none' }" />
</div>
</UTheme>
</template>
Diepe voortplanting
De overschrijvingen zijn beschikbaar voor alle afstammelingscomponenten, ongeacht hoe diep ze zijn genest.
<script setup lang="ts">
import MyButton from './MyButton.vue'
</script>
<template>
<UTheme
:ui="{
button: {
base: 'rounded-full'
}
}"
>
<UCard :ui="{ body: 'flex items-center gap-2 sm:flex-row flex-col' }">
<UButton label="Direct child" />
<MyButton />
</UCard>
</UTheme>
</template>
MyButton een aangepast onderdeel dat intern een UButton weergeeft. Het thema overrides is nog steeds van toepassing omdat ze zich door de hele componentboom verspreiden.Form onderdelen
Gebruik de Thema-component om consistente styling toe te passen op een groep formuliercomponenten.
<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent } from '@nuxt/ui'
const schema = z.object({
name: z.string().min(2, 'Too short'),
email: z.email('Invalid email'),
bio: z.string().optional()
})
type Schema = z.output<typeof schema>
const state = reactive<Partial<Schema>>({
name: 'John Doe',
email: 'john@example.com',
bio: undefined
})
const toast = useToast()
async function onSubmit(event: FormSubmitEvent<Schema>) {
toast.add({ title: 'Saved', description: 'Your profile has been updated.', color: 'success' })
console.log(event.data)
}
</script>
<template>
<UTheme
:props="{
input: { size: 'lg' },
textarea: { size: 'lg' }
}"
:ui="{
formField: {
root: 'flex max-sm:flex-col justify-between gap-4',
wrapper: 'w-full sm:max-w-xs'
}
}"
>
<UForm :schema="schema" :state="state" class="space-y-4 w-full" @submit="onSubmit">
<UFormField label="Name" name="name" description="Your public display name.">
<UInput v-model="state.name" />
</UFormField>
<UFormField label="Email" name="email" description="Used for notifications.">
<UInput v-model="state.email" type="email" />
</UFormField>
<UFormField label="Bio" name="bio" description="A short description about yourself.">
<UTextarea v-model="state.bio" placeholder="Tell us about yourself" />
</UFormField>
<div class="flex justify-end">
<UButton type="submit">
Save changes
</UButton>
</div>
</UForm>
</UTheme>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import * as z from 'zod'
import type { FormSubmitEvent } from '@nuxt/ui'
const schema = z.object({
name: z.string().min(2, 'Too short'),
email: z.email('Invalid email'),
bio: z.string().optional()
})
type Schema = z.output<typeof schema>
const state = reactive<Partial<Schema>>({
name: 'John Doe',
email: 'john@example.com',
bio: undefined
})
const toast = useToast()
async function onSubmit(event: FormSubmitEvent<Schema>) {
toast.add({ title: 'Saved', description: 'Your profile has been updated.', color: 'success' })
console.log(event.data)
}
</script>
<template>
<UTheme
:props="{
input: { size: 'lg' },
textarea: { size: 'lg' }
}"
:ui="{
formField: {
root: 'flex max-sm:flex-col justify-between gap-4',
wrapper: 'w-full sm:max-w-xs'
}
}"
>
<UForm :schema="schema" :state="state" class="space-y-4 w-full" @submit="onSubmit">
<UFormField label="Name" name="name" description="Your public display name.">
<UInput v-model="state.name" />
</UFormField>
<UFormField label="Email" name="email" description="Used for notifications.">
<UInput v-model="state.email" type="email" />
</UFormField>
<UFormField label="Bio" name="bio" description="A short description about yourself.">
<UTextarea v-model="state.bio" placeholder="Tell us about yourself" />
</UFormField>
<div class="flex justify-end">
<UButton type="submit">
Save changes
</UButton>
</div>
</UForm>
</UTheme>
</template>
<UFormField>, <UFieldGroup> en <UAvatarGroup> houden voorrang op <UTheme :props> voor size, color en highlight. Validatiefouten dwingen de error-kleur ook boven elke thema-waarde.Prose onderdelen
Gebruik de prose-naamruimte om typografische componenten te thematiseren. Toetsen zijn genest onder prose (bijv. prose.p, prose.code).
Getting started
This is a paragraph with a tighter typographic scale applied through the Theme component.
- First item
- Second item
- Third item
The spacing and font sizes are smaller than the defaults, making it ideal for compact content areas.
<script setup lang="ts">
import { Markdown } from '@comark/vue'
const ui = {
prose: {
p: { base: 'my-2.5 text-sm/6' },
li: { base: 'my-0.5 text-sm/6' },
ul: { base: 'my-2.5' },
ol: { base: 'my-2.5' },
h1: { base: 'text-xl mb-4' },
h2: { base: 'text-lg mt-6 mb-3' },
h3: { base: 'text-base mt-4 mb-2' },
h4: { base: 'text-sm mt-3 mb-1.5' },
code: { base: 'text-xs' },
pre: { root: 'my-2.5', base: 'text-xs/5' },
table: { root: 'my-2.5' },
hr: { base: 'my-5' }
}
}
const value = `## Getting started
This is a paragraph with a **tighter typographic scale** applied through the \`Theme\` component.
- First item
- Second item
- Third item
> The spacing and font sizes are smaller than the defaults, making it ideal for compact content areas.`
</script>
<template>
<UTheme :ui="ui">
<Markdown :value="value" class="*:first:mt-0 *:last:mb-0" />
</UTheme>
</template>
API
Props
| Prop | Default | Type |
|---|---|---|
props | ThemeDefaultsPer-component prop defaults that flow through | |
ui | ThemeUIPer-component slot class overrides (flat shorthand for |
Slots
| Slot | Type |
|---|---|
default | {} |