Skip to content

Field

Give a control its label, hint and error message, connected so a screen reader reads them with it.

As in the passport.

Invoices are issued in it.

optional

Leave it empty to send them to the owner of the account; the address is checked before the first invoice goes out.

<script setup lang="ts">import { ref } from 'vue'import { UiStack, UiField, UiInput, UiSelect } from 'grani' const name = ref('') const note = ref('') // A select under its label: a click on the label opens its list, as a click on the select does.const billing = ref<string | null>('EUR') const currencies = [  { value: 'EUR', label: 'EUR' },  { value: 'USD', label: 'USD' },]</script> <template>  <UiStack class="w-full max-w-80">    <UiField label="Name" description="As in the passport.">      <UiInput v-model="name" placeholder="Anna Petrova" />    </UiField>    <UiField label="Billing currency" description="Invoices are issued in it.">      <UiSelect v-model="billing" :items="currencies" />    </UiField>    <UiField      label="The address the invoices for this account are sent to every month"      description="Leave it empty to send them to the owner of the account; the address is checked before the first invoice goes out."    >      <UiInput v-model="note" type="email" />      <template #meta>optional</template>    </UiField>  </UiStack></template>

Also called form field, form group, label with hint and error.

Usage

<UiField>…</UiField>

With GraniResolver in the Vite config, a template needs no import: set it up once.

API

Name · typeDefaultDescription
State
errorstringError text below the control, one string; it marks the control invalid. Empty means valid. Read out when it appears.
Behavior
labelstringVisible label above the control.
descriptionstringSupporting text below the control: a format, a limit, a unit. Hidden while error is present.
forstringId of the control the label points to; the description and error ids derive from it. Generated when omitted.
groupboolean= falsefalseThe control is a group of controls (radios, checkboxes): the field is a fieldset, the label its legend, and the group takes labelId for aria-labelledby. No #meta.
Form and access
requiredboolean= falsefalseAn asterisk after the label and aria-required on the control; in a group the legend says it once.

Anything else lands on the root element: native attributes, aria-*, data-testid.

When to use another component

When you needTake
Words on the left and the control on the rightList item as="label"
A control that carries its own wordsCheckbox, UiRadio or a Switch with text keeps them in its slot
A title over a section of fieldsHeader legend