# 字段标签

## 使用方法

单独拿出来用的标签，带可选、必填标记，也能挂一个提示。

`FieldLabel` 就是 `Field` 里管标签的那一半。被标注的东西自己不带标签时就直接用它：自己写的控件、一组输入框，或者库外面包的一层。`label` 和 `input-id` 都是必填，靠这个 id 标签才知道自己指向哪个控件。

```vue
<script setup lang="ts">
import { FieldLabel } from '@astryx-vue/core/Field'
import { ref } from 'vue'

const email = ref('')
</script>

<template>
  <div>
    <FieldLabel label="邮箱地址" input-id="email-input" is-required />
    <input id="email-input" v-model="email" type="email">
  </div>
</template>
```

`isRequired` 和 `isOptional` 会在标签后面写上「必填」或「可选」。放在带 `defaultOptionality` 的 `FormLayout` 里时只标少数派，所以默认必填的表单不用每个字段都写一遍。`description` 在标签下面加一行说明，点这行说明也会把焦点给到控件。`labelIcon` 在标签文字前面加一个小图标，`labelTooltip` 加一个提示按钮，里面的文字读屏也能读到。

被标注的是一组控件、不是一个输入框时，加 `isGroupLabel`。标签这时渲染成 `span` 而不是 `label`，点在标签上就不会莫名其妙地交给第一个控件。

```ts
import { FieldLabel } from '@astryx-vue/core/Field'
```

## 示例

常见的用法和不同的状态。

### 基础

单独使用的标签，带必填、可选标记和一行说明。被标注的控件自己不带标签时用它。

```vue
<script setup lang="ts">
import { FieldLabel } from '@astryx-vue/core/Field'
import { VStack } from '@astryx-vue/core/Stack'
</script>

<template>
  <VStack :gap="4" style="width: min(100%, 20rem)">
    <FieldLabel label="Email address" input-id="email-input" is-required />
    <FieldLabel
      label="Phone number"
      input-id="phone-input"
      is-optional
      description="Include country code for international numbers"
    />
    <FieldLabel
      label="API key"
      input-id="api-input"
      label-tooltip="Your API key can be found in the developer settings"
    >
      <template #labelIcon>
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
          <rect x="3" y="11" width="18" height="11" rx="2" />
          <path d="M7 11V7a5 5 0 0 1 10 0v4" />
        </svg>
      </template>
    </FieldLabel>
    <FieldLabel label="Disabled field" input-id="disabled-input" is-disabled />
  </VStack>
</template>
```

## 属性

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `label` | `string` | — | 标签文字。必填。 |
| `inputId` | `string` | — | 这个标签对应的控件 `id`。会变成 `for` 属性，也是生成标签 id 和说明 id 的基础。必填。 |
| `labelId` | `string` | ``${inputId}-label`` | 放在标签元素本身的 `id`。控件不是真正的 `label` 时，用控件的 `aria-labelledby` 指向它。 |
| `description` | `string` | — | 标签下面那行说明。点它会聚焦控件，除非是分组标签或者已经禁用。 |
| `descriptionId` | `string` | ``${inputId}-description`` | 放在说明上的 `id`。用控件的 `aria-describedby` 指向它。 |
| `isGroupLabel` | `boolean` | `false` | 把标签渲染成不带 `for` 的 `span`，用于一组控件而不是单个输入框。 |
| `isLabelHidden` | `boolean` | `false` | 标签在视觉上隐藏，读屏仍然能读到。 |
| `isDisabled` | `boolean` | `false` | 标签变淡，同时点说明也不会再聚焦控件。 |
| `isOptional` | `boolean` | `false` | 显示可选标记。和 `isRequired` 同时写时以它为准。 |
| `isRequired` | `boolean` | `false` | 显示必填标记。放在 `defaultOptionality="required"` 的 `FormLayout` 里时不再显示，因为必填就是默认。 |
| `labelIcon` | `IconName \| Component` | — | 标签文字前面的图标，放在 16px 的框里。外层是 `aria-hidden`，所以图标本身不该单独承载信息。 |
| `labelTooltip` | `string` | — | 标签行末尾那个提示按钮的文字。 |
| `optionalLabel` | `string` | `'Optional'` | 可选标记的文字。要本地化就改它。 |
| `requiredLabel` | `string` | `'Required'` | 必填标记的文字。要本地化就改它。 |

## 插槽

- `labelIcon`：标签文字前面的图标，位置和 `labelIcon` 属性一样，两个都写时用插槽。

## 暴露

- `element`：渲染出来的标签元素。
