Theme

하위 구성요소의 주제를 지정하는 헤드 없는 구성요소입니다.

Usage

Theme 구성 요소는 각 구성 요소를 개별적으로 수정하지 않고 모든 하위 구성 요소의 기본 **slot 클래스 ** 및 props를 재정의합니다. Vue의 provide/inject 메커니즘을 후드 아래에 사용하므로 재정의는 모든 깊이에서 적용됩니다.

Theme 구성 요소는 HTML 요소를 렌더링하지 않으며 자식에 대한 테마 재정의만 제공합니다.The Theme component does not render any HTML element, it only provides theme overrides to its children.
앱 레벨 테마 구성의 경우 대신 app.config.ts 파일을 사용하는 것이 좋습니다.
앱 레벨 테마 구성의 경우 대신 vite.config.ts 파일을 사용하는 것이 좋습니다.

slot 클래스

ui prop을 사용하여 하위 구성 요소의 슬롯 클래스를 재정의합니다. 키는 구성 요소 이름(camelCase)이고 값은 슬롯 클래스 재정의입니다.

<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 기본값: badge{label="4.8+" class="align-text-top"}

props Prop을 사용하여 하위 구성 요소에 있는 Prop의 기본값을 재정의합니다. 각 키는 해당 구성 요소의 Prop 부분에 매핑됩니다.

<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>
컴포넌트의 명시적 props(예: <UButton color="primary" />)는 항상 <UTheme :props>를 이긴다. topic defaults는 prop이 명시적으로 전달되지 않은 경우에만 적용됩니다.

예

다중 구성 요소

ui 또는 props에서 다른 키를 사용하여 여러 구성요소 유형에 대한 주제를 한 번에 지정합니다.

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

중첩 테마

여러 Theme 구성 요소를 중첩하여 재정의를 작성합니다. 가장 안쪽의 Theme가 우선 순위를 갖고 오버라이드되지 않은 키는 외부 Theme에서 상속됩니다.

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

명시적 우선 순위

개별 컴포넌트에 prop(ui 포함)을 명시적으로 설정하는 것은 항상 Theme 컴포넌트보다 우선합니다.

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

딥 전파

중첩된 깊이에 관계없이 모든 하위 구성요소에서 재지정을 사용할 수 있습니다.

<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는 UButton를 내부적으로 렌더링하는 사용자 정의 구성 요소입니다. 주제 재정의는 전체 구성 요소 트리를 통해 전파되므로 계속 적용됩니다.

Form 구성 요소

Theme 구성 요소를 사용하여 양식 구성 요소 그룹에 일관된 스타일 지정을 적용할 수도 있습니다.

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> 및 <UAvatarGroup>는 size, color 및 highlight에 대해 <UTheme :props>보다 우선 순위를 유지합니다. 검증 오류는 모든 주제 값보다 error 색상을 강제로 적용합니다.

Prose 구성요소

prose 네임스페이스를 사용하여 타이포그래피 구성 요소에 테마를 지정합니다. 키는 prose 아래에 중첩됩니다(예: 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 (### 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).

슬롯

Slot Type
default
{}

변경 로그Name

No recent changes