Theme
Bearbeiten
Die Theme-Komponente überschreibt die Standardklassen slot classes und props aller untergeordneten Komponenten, ohne jede einzeln zu modifizieren. Es verwendet den Mechanismus provide/inject von Vue unter der Haube, sodass die Überschreibungen in jeder Tiefe angewendet werden.
app.config.ts.vite.config.ts.Slot-Klassen
Verwenden Sie die ui-prop, um Slot-Klassen von nachgeordneten Komponenten zu überschreiben. Schlüssel sind Komponentennamen (camelCase) und Werte sind ihre Slot-Klassen-Überschreibungen.
<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 Standardeinstellungen: badge{label="4.8+" class="align-text-top"}
Verwenden Sie die props prop, um den Standardwert einer beliebigen prop auf den untergeordneten Komponenten zu überschreiben. Jede Taste wird einem Teil der props dieser Komponente zugeordnet.
<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" />) gewinnen immer über <UTheme :props>. Theme-Standardeinstellungen gelten nur, wenn die Prop nicht explizit übergeben wurde.Examples (Beispiele)
Multiple Komponenten
Verwenden Sie verschiedene Tasten in ui oder props, um mehrere Komponententypen gleichzeitig zu gestalten.
<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>
Verschachtelte Themen
Verschachteln Sie mehrere Theme-Komponenten, um Overrides zu erstellen. Das innerste Theme hat Vorrang, während nicht überschriebene Schlüssel vom äußeren Theme geerbt werden.
<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>
Explicit priority (Priorität)
Das explizite Setzen einer Prop (einschließlich ui) auf eine einzelne Komponente hat immer Vorrang vor der Theme-Komponente.
<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>
Deep Propagation (Tiefenausbreitung)
Die Overrides sind für alle abgeleiteten Komponenten verfügbar, unabhängig davon, wie tief sie verschachtelt sind.
<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 eine benutzerdefinierte Komponente, die eine UButton intern rendert. Die Theme-Overrides gelten weiterhin, da sie sich über den gesamten Komponentenbaum ausbreiten.Form Komponenten
Verwenden Sie die Designkomponente, um ein konsistentes Styling auf eine Gruppe von Formularkomponenten anzuwenden.
<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> und <UAvatarGroup> behalten Vorrang vor <UTheme :props> für size, color und highlight.Prose-Komponenten
Verwenden Sie den Namensraum prose, um Typografiekomponenten zu gestalten. Schlüssel werden unter prose verschachtelt (z. B. 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 (Englisch)
Props (nicht)
| Prop | Default | Type |
|---|---|---|
props | ThemeDefaultsPer-component prop defaults that flow through | |
ui | ThemeUIPer-component slot class overrides (flat shorthand for |
Slots Bearbeiten
| Slot | Type |
|---|---|
default | {} |