Theme

GitHub
Een hoofdloze component om kindcomponenten te thematiseren.

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.

De Thema-component geeft geen HTML-element weer, het biedt alleen thema-overschrijvingen aan zijn kinderen.
Voor themaconfiguratie op app-niveau raden we aan in plaats daarvan het app.config.ts-bestand te gebruiken.
Voor themaconfiguratie op app-niveau raden we aan in plaats daarvan het 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>
Expliciete rekwisieten op een component (bijv. <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>
In dit voorbeeld is 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.

Your public display name.

Used for notifications.

A short description about yourself.

<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
ThemeDefaults

Per-component prop defaults that flow through useComponentProps to every descendant. Each key maps to a partial of that component's props.

ui
ThemeUI

Per-component slot class overrides (flat shorthand for :props.<name>.ui).

Slots

Slot Type
default
{}

Wijzigingsgelog

No recent changes