🌐 Nodejs.cn

将标签、控件和帮助文本组合起来,以构建可访问的表单字段和分组输入。

Payment Method

All transactions are secure and encrypted

Enter your 16-digit card number

Billing Address

The billing address associated with your payment method

<script setup lang="ts">
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldLegend,
  FieldSeparator,
  FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
</script>

<template>
  <div class="w-full max-w-md">
    <form>
      <FieldGroup>
        <FieldSet>
          <FieldLegend>Payment Method</FieldLegend>
          <FieldDescription>
            All transactions are secure and encrypted
          </FieldDescription>
          <FieldGroup>
            <Field>
              <FieldLabel for="checkout-7j9-card-name-43j">
                Name on Card
              </FieldLabel>
              <Input
                id="checkout-7j9-card-name-43j"
                placeholder="Evil Rabbit"
                required
              />
            </Field>
            <Field>
              <FieldLabel for="checkout-7j9-card-number-uw1">
                Card Number
              </FieldLabel>
              <Input
                id="checkout-7j9-card-number-uw1"
                placeholder="1234 5678 9012 3456"
                required
              />
              <FieldDescription>
                Enter your 16-digit card number
              </FieldDescription>
            </Field>
            <div class="grid grid-cols-3 gap-4">
              <Field>
                <FieldLabel for="checkout-exp-month-ts6">
                  Month
                </FieldLabel>
                <Select default-value="">
                  <SelectTrigger id="checkout-exp-month-ts6">
                    <SelectValue placeholder="MM" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="01">
                      01
                    </SelectItem>
                    <SelectItem value="02">
                      02
                    </SelectItem>
                    <SelectItem value="03">
                      03
                    </SelectItem>
                    <SelectItem value="04">
                      04
                    </SelectItem>
                    <SelectItem value="05">
                      05
                    </SelectItem>
                    <SelectItem value="06">
                      06
                    </SelectItem>
                    <SelectItem value="07">
                      07
                    </SelectItem>
                    <SelectItem value="08">
                      08
                    </SelectItem>
                    <SelectItem value="09">
                      09
                    </SelectItem>
                    <SelectItem value="10">
                      10
                    </SelectItem>
                    <SelectItem value="11">
                      11
                    </SelectItem>
                    <SelectItem value="12">
                      12
                    </SelectItem>
                  </SelectContent>
                </Select>
              </Field>
              <Field>
                <FieldLabel for="checkout-7j9-exp-year-f59">
                  Year
                </FieldLabel>
                <Select default-value="">
                  <SelectTrigger id="checkout-7j9-exp-year-f59">
                    <SelectValue placeholder="YYYY" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="2024">
                      2024
                    </SelectItem>
                    <SelectItem value="2025">
                      2025
                    </SelectItem>
                    <SelectItem value="2026">
                      2026
                    </SelectItem>
                    <SelectItem value="2027">
                      2027
                    </SelectItem>
                    <SelectItem value="2028">
                      2028
                    </SelectItem>
                    <SelectItem value="2029">
                      2029
                    </SelectItem>
                  </SelectContent>
                </Select>
              </Field>
              <Field>
                <FieldLabel for="checkout-7j9-cvv">
                  CVV
                </FieldLabel>
                <Input id="checkout-7j9-cvv" placeholder="123" required />
              </Field>
            </div>
          </FieldGroup>
        </FieldSet>
        <FieldSeparator />
        <FieldSet>
          <FieldLegend>Billing Address</FieldLegend>
          <FieldDescription>
            The billing address associated with your payment method
          </FieldDescription>
          <FieldGroup>
            <Field orientation="horizontal">
              <Checkbox
                id="checkout-7j9-same-as-shipping-wgm"
                :default-value="true"
              />
              <FieldLabel
                for="checkout-7j9-same-as-shipping-wgm"
                class="font-normal"
              >
                Same as shipping address
              </FieldLabel>
            </Field>
          </FieldGroup>
        </FieldSet>
        <FieldSet>
          <FieldGroup>
            <Field>
              <FieldLabel for="checkout-7j9-optional-comments">
                Comments
              </FieldLabel>
              <Textarea
                id="checkout-7j9-optional-comments"
                placeholder="Add any additional comments"
                class="resize-none"
              />
            </Field>
          </FieldGroup>
        </FieldSet>
        <Field orientation="horizontal">
          <Button type="submit">
            Submit
          </Button>
          <Button variant="outline" type="button">
            Cancel
          </Button>
        </Field>
      </FieldGroup>
    </form>
  </div>
</template>

安装

🌐 Installation

pnpm dlx shadcn-vue@latest add field

用法

🌐 Usage

<script setup lang="ts">
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldError,
  FieldGroup,
  FieldLabel,
  FieldLegend,
  FieldSeparator,
  FieldSet,
  FieldTitle,
} from '@/components/ui/field'
</script>

<template>
  <FieldSet>
    <FieldLegend>Profile</FieldLegend>
    <FieldDescription>This appears on invoices and emails.</FieldDescription>
    <FieldGroup>
      <Field>
        <FieldLabel for="name">
          Full name
        </FieldLabel>
        <Input id="name" autocomplete="off" placeholder="Evil Rabbit" />
        <FieldDescription>This appears on invoices and emails.</FieldDescription>
      </Field>
      <Field>
        <FieldLabel for="username">
          Username
        </FieldLabel>
        <Input id="username" autocomplete="off" aria-invalid />
        <FieldError>Choose another username.</FieldError>
      </Field>
      <Field orientation="horizontal">
        <Switch id="newsletter" />
        <FieldLabel for="newsletter">
          Subscribe to the newsletter
        </FieldLabel>
      </Field>
    </FieldGroup>
  </FieldSet>
</template>

剖析

🌐 Anatomy

Field 系列旨在用于创建可访问的表单。一个典型的字段结构如下:

🌐 The Field family is designed for composing accessible forms. A typical field is structured as follows:

<template>
  <Field>
    <FieldLabel for="input-id">
      Label
    </FieldLabel>
    <!-- Input, Select, Switch, etc. -->
    <FieldDescription>Optional helper text.</FieldDescription>
    <FieldError>Validation message.</FieldError>
  </Field>
</template>
  • Field 是单个字段的核心封装器。
  • FieldContent 是一个弹性列,用于组合标签和描述。如果没有描述,则不是必需的。
  • FieldGroup 封装相关字段,并使用 FieldSetFieldLegend 进行语义分组。

示例

🌐 Examples

输入

🌐 Input

Choose a unique username for your account.

Must be at least 8 characters long.

<script setup lang="ts">
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
</script>

<template>
  <div class="w-full max-w-md">
    <FieldSet>
      <FieldGroup>
        <Field>
          <FieldLabel for="username">
            Username
          </FieldLabel>
          <Input id="username" type="text" placeholder="Max Leiter" />
          <FieldDescription>
            Choose a unique username for your account.
          </FieldDescription>
        </Field>
        <Field>
          <FieldLabel for="password">
            Password
          </FieldLabel>
          <FieldDescription>
            Must be at least 8 characters long.
          </FieldDescription>
          <Input id="password" type="password" placeholder="********" />
        </Field>
      </FieldGroup>
    </FieldSet>
  </div>
</template>

文本区域

🌐 Textarea

Share your thoughts about our service.

<script setup lang="ts">
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldSet,
} from '@/components/ui/field'
import { Textarea } from '@/components/ui/textarea'
</script>

<template>
  <div class="w-full max-w-md">
    <FieldSet>
      <FieldGroup>
        <Field>
          <FieldLabel for="feedback">
            Feedback
          </FieldLabel>
          <Textarea
            id="feedback"
            placeholder="Your feedback helps us improve..."
            :rows="4"
          />
          <FieldDescription>
            Share your thoughts about our service.
          </FieldDescription>
        </Field>
      </FieldGroup>
    </FieldSet>
  </div>
</template>

选择

🌐 Select

Select your department or area of work.

<script setup lang="ts">
import {
  Field,
  FieldDescription,
  FieldLabel,
} from '@/components/ui/field'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
</script>

<template>
  <div class="w-full max-w-md">
    <Field>
      <FieldLabel>Department</FieldLabel>
      <Select>
        <SelectTrigger>
          <SelectValue placeholder="Choose department" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="engineering">
            Engineering
          </SelectItem>
          <SelectItem value="design">
            Design
          </SelectItem>
          <SelectItem value="marketing">
            Marketing
          </SelectItem>
          <SelectItem value="sales">
            Sales
          </SelectItem>
          <SelectItem value="support">
            Customer Support
          </SelectItem>
          <SelectItem value="hr">
            Human Resources
          </SelectItem>
          <SelectItem value="finance">
            Finance
          </SelectItem>
          <SelectItem value="operations">
            Operations
          </SelectItem>
        </SelectContent>
      </Select>
      <FieldDescription>
        Select your department or area of work.
      </FieldDescription>
    </Field>
  </div>
</template>

滑块

🌐 Slider

Price Range

Set your budget range ($ 200 - 800).

<script setup lang="ts">
import { ref } from 'vue'
import {
  Field,
  FieldDescription,
  FieldTitle,
} from '@/components/ui/field'
import { Slider } from '@/components/ui/slider'

const value = ref([200, 800])
</script>

<template>
  <div class="w-full max-w-md">
    <Field>
      <FieldTitle>Price Range</FieldTitle>
      <FieldDescription>
        Set your budget range ($
        <span class="font-medium tabular-nums">{{ value[0] }}</span> -
        <span class="font-medium tabular-nums">{{ value[1] }}</span>).
      </FieldDescription>
      <Slider
        v-model="value"
        :max="1000"
        :min="0"
        :step="10"
        class="mt-2 w-full"
        aria-label="Price Range"
      />
    </Field>
  </div>
</template>

字段集

🌐 Fieldset

Address Information

We need your address to deliver your order.

<script setup lang="ts">
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldLegend,
  FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
</script>

<template>
  <div class="w-full max-w-md space-y-6">
    <FieldSet>
      <FieldLegend>Address Information</FieldLegend>
      <FieldDescription>
        We need your address to deliver your order.
      </FieldDescription>
      <FieldGroup>
        <Field>
          <FieldLabel for="street">
            Street Address
          </FieldLabel>
          <Input id="street" type="text" placeholder="123 Main St" />
        </Field>
        <div class="grid grid-cols-2 gap-4">
          <Field>
            <FieldLabel for="city">
              City
            </FieldLabel>
            <Input id="city" type="text" placeholder="New York" />
          </Field>
          <Field>
            <FieldLabel for="zip">
              Postal Code
            </FieldLabel>
            <Input id="zip" type="text" placeholder="90502" />
          </Field>
        </div>
      </FieldGroup>
    </FieldSet>
  </div>
</template>

复选框

🌐 Checkbox

Show these items on the desktop

Select the items you want to show on the desktop.

Your Desktop & Documents folders are being synced with iCloud Drive. You can access them from other devices.

<script setup lang="ts">
import { Checkbox } from '@/components/ui/checkbox'
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldLegend,
  FieldSeparator,
  FieldSet,
} from '@/components/ui/field'
</script>

<template>
  <div class="w-full max-w-md">
    <FieldGroup>
      <FieldSet>
        <FieldLegend variant="label">
          Show these items on the desktop
        </FieldLegend>
        <FieldDescription>
          Select the items you want to show on the desktop.
        </FieldDescription>
        <FieldGroup class="gap-3">
          <Field orientation="horizontal">
            <Checkbox id="finder-pref-9k2-hard-disks-ljj" />
            <FieldLabel
              for="finder-pref-9k2-hard-disks-ljj"
              class="font-normal"
              :default-value="true"
            >
              Hard disks
            </FieldLabel>
          </Field>
          <Field orientation="horizontal">
            <Checkbox id="finder-pref-9k2-external-disks-1yg" />
            <FieldLabel
              for="finder-pref-9k2-external-disks-1yg"
              class="font-normal"
            >
              External disks
            </FieldLabel>
          </Field>
          <Field orientation="horizontal">
            <Checkbox id="finder-pref-9k2-cds-dvds-fzt" />
            <FieldLabel
              for="finder-pref-9k2-cds-dvds-fzt"
              class="font-normal"
            >
              CDs, DVDs, and iPods
            </FieldLabel>
          </Field>
          <Field orientation="horizontal">
            <Checkbox id="finder-pref-9k2-connected-servers-6l2" />
            <FieldLabel
              for="finder-pref-9k2-connected-servers-6l2"
              class="font-normal"
            >
              Connected servers
            </FieldLabel>
          </Field>
        </FieldGroup>
      </FieldSet>
      <FieldSeparator />
      <Field orientation="horizontal">
        <Checkbox id="finder-pref-9k2-sync-folders-nep" :default-value="true" />
        <FieldContent>
          <FieldLabel for="finder-pref-9k2-sync-folders-nep">
            Sync Desktop & Documents folders
          </FieldLabel>
          <FieldDescription>
            Your Desktop & Documents folders are being synced with iCloud
            Drive. You can access them from other devices.
          </FieldDescription>
        </FieldContent>
      </Field>
    </FieldGroup>
  </div>
</template>

单选框

🌐 Radio

Yearly and lifetime plans offer significant savings.

<script setup lang="ts">
import {
  Field,
  FieldDescription,
  FieldLabel,
  FieldSet,
} from '@/components/ui/field'
import {
  RadioGroup,
  RadioGroupItem,
} from '@/components/ui/radio-group'
</script>

<template>
  <div class="w-full max-w-md">
    <FieldSet>
      <FieldLabel>Subscription Plan</FieldLabel>
      <FieldDescription>
        Yearly and lifetime plans offer significant savings.
      </FieldDescription>
      <RadioGroup defaultvalue="monthly">
        <Field orientation="horizontal">
          <RadioGroupItem id="plan-monthly" value="monthly" />
          <FieldLabel for="plan-monthly" class="font-normal">
            Monthly ($9.99/month)
          </FieldLabel>
        </Field>
        <Field orientation="horizontal">
          <RadioGroupItem id="plan-yearly" value="yearly" />
          <FieldLabel for="plan-yearly" class="font-normal">
            Yearly ($99.99/year)
          </FieldLabel>
        </Field>
        <Field orientation="horizontal">
          <RadioGroupItem id="plan-lifetime" value="lifetime" />
          <FieldLabel for="plan-lifetime" class="font-normal">
            Lifetime ($299.99)
          </FieldLabel>
        </Field>
      </RadioGroup>
    </FieldSet>
  </div>
</template>

切换

🌐 Switch

Enable multi-factor authentication. If you do not have a two-factor device, you can use a one-time code sent to your email.

<script setup lang="ts">
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldLabel,
} from '@/components/ui/field'
import { Switch } from '@/components/ui/switch'
</script>

<template>
  <div class="w-full max-w-md">
    <Field orientation="horizontal">
      <FieldContent>
        <FieldLabel for="2fa">
          Multi-factor authentication
        </FieldLabel>
        <FieldDescription>
          Enable multi-factor authentication. If you do not have a two-factor
          device, you can use a one-time code sent to your email.
        </FieldDescription>
      </FieldContent>
      <Switch id="2fa" />
    </Field>
  </div>
</template>

选择卡

🌐 Choice Card

Field 组件封装在 FieldLabel 内以创建可选择的字段组。这适用于 RadioItemCheckboxSwitch 组件。

🌐 Wrap Field components inside FieldLabel to create selectable field groups. This works with RadioItem, Checkbox and Switch components.

Select the compute environment for your cluster.

<script setup lang="ts">
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldSet,
  FieldTitle,
} from '@/components/ui/field'
import {
  RadioGroup,
  RadioGroupItem,
} from '@/components/ui/radio-group'
</script>

<template>
  <div class="w-full max-w-md">
    <FieldGroup>
      <FieldSet>
        <FieldLabel for="compute-environment-p8w">
          Compute Environment
        </FieldLabel>
        <FieldDescription>
          Select the compute environment for your cluster.
        </FieldDescription>
        <RadioGroup default-value="kubernetes">
          <FieldLabel for="kubernetes-r2h">
            <Field orientation="horizontal">
              <FieldContent>
                <FieldTitle>Kubernetes</FieldTitle>
                <FieldDescription>
                  Run GPU workloads on a K8s configured cluster.
                </FieldDescription>
              </FieldContent>
              <RadioGroupItem id="kubernetes-r2h" value="kubernetes" />
            </Field>
          </FieldLabel>
          <FieldLabel for="vm-z4k">
            <Field orientation="horizontal">
              <FieldContent>
                <FieldTitle>Virtual Machine</FieldTitle>
                <FieldDescription>
                  Access a VM configured cluster to run GPU workloads.
                </FieldDescription>
              </FieldContent>
              <RadioGroupItem id="vm-z4k" value="vm" />
            </Field>
          </FieldLabel>
        </RadioGroup>
      </FieldSet>
    </FieldGroup>
  </div>
</template>

字段组

🌐 Field Group

Field 组件与 FieldGroup 堆叠。添加 FieldSeparator 来分隔它们。

🌐 Stack Field components with FieldGroup. Add FieldSeparator to divide them.

Get notified when ChatGPT responds to requests that take time, like research or image generation.

Get notified when tasks you've created have updates. Manage tasks

<script setup lang="ts">
import { Checkbox } from '@/components/ui/checkbox'
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldSeparator,
  FieldSet,
} from '@/components/ui/field'
</script>

<template>
  <div class="w-full max-w-md">
    <FieldGroup>
      <FieldSet>
        <FieldLabel>Responses</FieldLabel>
        <FieldDescription>
          Get notified when ChatGPT responds to requests that take time, like
          research or image generation.
        </FieldDescription>
        <FieldGroup data-slot="checkbox-group">
          <Field orientation="horizontal">
            <Checkbox id="push" :default-value="true" disabled />
            <FieldLabel for="push" class="font-normal">
              Push notifications
            </FieldLabel>
          </Field>
        </FieldGroup>
      </FieldSet>
      <FieldSeparator />
      <FieldSet>
        <FieldLabel>Tasks</FieldLabel>
        <FieldDescription>
          Get notified when tasks you've created have updates.
          <a href="#">Manage tasks</a>
        </FieldDescription>
        <FieldGroup data-slot="checkbox-group">
          <Field orientation="horizontal">
            <Checkbox id="push-tasks" />
            <FieldLabel for="push-tasks" class="font-normal">
              Push notifications
            </FieldLabel>
          </Field>
          <Field orientation="horizontal">
            <Checkbox id="email-tasks" />
            <FieldLabel for="email-tasks" class="font-normal">
              Email notifications
            </FieldLabel>
          </Field>
        </FieldGroup>
      </FieldSet>
    </FieldGroup>
  </div>
</template>

响应式布局

🌐 Responsive Layout

如果你使用的是 tailwindcss v3,你需要安装 @tailwindcss/container-queries

🌐 If you are in tailwindcss v3 you need to install @tailwindcss/container-queries

  • 垂直字段: 默认方向将标签、控件和辅助文本垂直堆叠——非常适合移动优先布局。
  • 水平字段:Field 上设置 orientation="horizontal" 以使标签和控件并排对齐。与 FieldContent 配合使用以保持描述对齐。
  • 响应字段: 在容器感知的父元素内部设置 orientation="responsive" 以实现自动列布局。在 FieldGroup 上应用 @container/field-group 类以在特定断点切换方向。
Profile

Fill in your profile information.

Provide your full name for identification

You can write your message here. Keep it short, preferably under 100 characters.

<script setup lang="ts">
import { Button } from '@/components/ui/button'
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldLegend,
  FieldSeparator,
  FieldSet,
} from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
</script>

<template>
  <div class="w-full max-w-4xl">
    <form>
      <FieldSet>
        <FieldLegend>Profile</FieldLegend>
        <FieldDescription>Fill in your profile information.</FieldDescription>
        <FieldSeparator />
        <FieldGroup>
          <Field orientation="responsive">
            <FieldContent>
              <FieldLabel for="name">
                Name
              </FieldLabel>
              <FieldDescription>
                Provide your full name for identification
              </FieldDescription>
            </FieldContent>
            <Input id="name" placeholder="Evil Rabbit" required />
          </Field>
          <FieldSeparator />
          <Field orientation="responsive">
            <FieldContent>
              <FieldLabel for="lastName">
                Message
              </FieldLabel>
              <FieldDescription>
                You can write your message here. Keep it short, preferably
                under 100 characters.
              </FieldDescription>
            </FieldContent>
            <Textarea
              id="message"
              placeholder="Hello, world!"
              required
              class="min-h-[100px] resize-none sm:min-w-[300px]"
            />
          </Field>
          <FieldSeparator />
          <Field orientation="responsive">
            <Button type="submit">
              Submit
            </Button>
            <Button type="button" variant="outline">
              Cancel
            </Button>
          </Field>
        </FieldGroup>
      </FieldSet>
    </form>
  </div>
</template>

验证与错误

🌐 Validation and Errors

  • data-invalid 添加到 Field 以将整个块切换到错误状态。
  • 在输入本身上添加 aria-invalid 以辅助辅助技术。
  • 在控件后立即渲染 FieldError 或放在 FieldContent 内,以保持错误信息与字段对齐。
<template>
  <Field data-invalid>
    <FieldLabel for="email">
      Email
    </FieldLabel>
    <Input id="email" type="email" aria-invalid />
    <FieldError>Enter a valid email address.</FieldError>
  </Field>
</template>

可访问性

🌐 Accessibility

  • FieldSetFieldLegend 让相关控件保持分组,以便键盘和辅助技术用户使用。
  • Field 输出 role="group",因此嵌套控件在组合时继承 FieldLabelFieldLegend 的标签。
  • 谨慎使用 FieldSeparator,以确保屏幕阅读器能遇到清晰的章节边界。

API参考

🌐 API Reference

FieldSet

用于渲染带有间距预设的语义 fieldset 的容器。

🌐 Container that renders a semantic fieldset with spacing presets.

属性类型默认值
classstring
<template>
  <FieldSet>
    <FieldLegend>Delivery</FieldLegend>
    <FieldGroup>
      <!-- Fields -->
    </FieldGroup>
  </FieldSet>
</template>

FieldLegend

FieldSet 的图例元素。切换到 label 变体以与标签大小对齐。

🌐 Legend element for a FieldSet. Switch to the label variant to align with label sizing.

属性类型默认值
variant"legend" | "label""legend"
classstring
<FieldLegend variant="label">
Notification Preferences
</FieldLegend>

FieldLegend 有两个变体:legendlabellabel 变体适用于标签大小和对齐。如果你有嵌套的 FieldSet,这很方便。

🌐 The FieldLegend has two variants: legend and label. The label variant applies label sizing and alignment. Handy if you have nested FieldSet.

FieldGroup

布局封装器,可堆叠 Field 组件并启用容器查询以实现响应式方向。

🌐 Layout wrapper that stacks Field components and enables container queries for responsive orientations.

属性类型默认值
classstring
<template>
  <FieldGroup class="@container/field-group flex flex-col gap-6">
    <Field><!-- Fields --></Field>
    <Field><!-- Fields --></Field>
  </FieldGroup>
</template>

字段

🌐 Field

单个字段的核心封装器。提供方向控制、无效状态样式和间距。

🌐 The core wrapper for a single field. Provides orientation control, invalid state styling, and spacing.

属性类型默认值
orientation"vertical" | "horizontal" | "responsive""vertical"
classstring
data-invalidboolean
<Field orientation="horizontal">
  <FieldLabel for="remember">Remember me</FieldLabel>
  <Switch id="remember" />
</Field>

FieldContent

当标签位于控件旁边时,将控件和描述分组的弹性列。如果没有描述,则不需要。

🌐 Flex column that groups control and descriptions when the label sits beside the control. Not required if you have no description.

属性类型默认值
classstring
<Field>
  <Checkbox id="notifications" />
  <FieldContent>
    <FieldLabel for="notifications">Notifications</FieldLabel>
    <FieldDescription>Email, SMS, and push options.</FieldDescription>
  </FieldContent>
</Field>

FieldLabel

标签样式适用于直接输入和嵌套的 Field 子项。

🌐 Label styled for both direct inputs and nested Field children.

属性类型默认值
classstring
asChildbooleanfalse
<FieldLabel for="email">
Email
</FieldLabel>

FieldTitle

FieldContent 内以标签样式呈现标题。

🌐 Renders a title with label styling inside FieldContent.

属性类型默认值
classstring
<FieldContent>
  <FieldTitle>Enable Touch ID</FieldTitle>
  <FieldDescription>Unlock your device faster.</FieldDescription>
</FieldContent>

FieldDescription

帮助文本槽,可在水平布局中自动平衡长行。

🌐 Helper text slot that automatically balances long lines in horizontal layouts.

属性类型默认值
classstring
<FieldDescription>
We never share your email with anyone.
</FieldDescription>

FieldSeparator

用于在 FieldGroup 内部分隔部分的视觉分隔符。可接受可选的内联内容。

🌐 Visual divider to separate sections inside a FieldGroup. Accepts optional inline content.

属性类型默认值
classstring
<FieldSeparator>
Or continue with
</FieldSeparator>

FieldError

可访问的错误容器,可接受子元素或 errors 数组(例如,来自 vee-validate)。

🌐 Accessible error container that accepts children or an errors array (e.g., from vee-validate).

属性类型默认值
errorsArray<{ message?: string } | undefined>
classstring
<FieldError :errors="errors.username" />

errors 数组包含多个消息时,该组件会自动渲染一个列表。

🌐 When the errors array contains multiple messages, the component renders a list automatically.

FieldError 也接受由任何实现了 标准模式 的验证器产生的问题,包括 Zod、Valibot 和 ArkType。将 schema 结果中的 issues 数组直接传递,以在各个库之间呈现统一的错误列表。