Keyboard shortcut: Ctrl + K
Get started

Field

VField places a label, a hint and an error message around any control. Its slot provides fieldProps to bind on the control.

Usage

vue

We send the receipt to this address.

<script setup lang="ts">
import { ref } from 'vue'
import { VField, VInput } from 'vectis-ui'

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

<template>
  <VField v-slot="{ fieldProps }" label="Email" hint="We send the receipt to this address.">
    <VInput v-bind="fieldProps" v-model="email" type="email" />
  </VField>
</template>

Examples

Native control

Native elements and third-party components take the same fieldProps as library controls.

vue
<script setup lang="ts">
import { VField } from 'vectis-ui'
</script>

<template>
  <VField v-slot="{ fieldProps }" label="Country">
    <!-- The label's `for` matches the id inside fieldProps, which the rule cannot follow. -->
    <!-- eslint-disable-next-line vuejs-accessibility/form-control-has-label -->
    <select v-bind="fieldProps">
      <option>France</option>
      <option>Belgium</option>
      <option>Canada</option>
    </select>
  </VField>
</template>

Error

error shows a message in place of the hint, so the field does not grow, and marks the control invalid. The message is announced when it appears. required adds an asterisk and passes required to the control.

vue

Leave the field to check it.

<script setup lang="ts">
import { computed, ref } from 'vue'
import { VField, VInput } from 'vectis-ui'

const email = ref('')
const touched = ref(false)

const error = computed(() =>
  touched.value && !email.value.includes('@')
    ? 'Enter an email address that contains an @.'
    : undefined,
)
</script>

<template>
  <VField
    v-slot="{ fieldProps }"
    label="Email"
    hint="Leave the field to check it."
    :error="error"
    required
  >
    <VInput v-bind="fieldProps" v-model="email" @blur="touched = true" />
  </VField>
</template>

Label beside the control

labelPosition="start" places the label in its own column. In a narrow field, the label moves back above the control.

vue
<script setup lang="ts">
import { VField, VInput, VTextarea } from 'vectis-ui'
</script>

<template>
  <div class="form">
    <VField v-slot="{ fieldProps }" label="Full name" label-position="start" required>
      <VInput v-bind="fieldProps" autocomplete="name" />
    </VField>
    <VField v-slot="{ fieldProps }" label="About you" label-position="start">
      <VTextarea v-bind="fieldProps" />
    </VField>
  </div>
</template>

<style scoped>
.form {
  display: grid;
  flex: 1;
  gap: var(--vectis-space-4);
}
</style>

Hidden label

hideLabel hides the label visually. It still names the control for screen readers.

vue
<script setup lang="ts">
import { VField, VInput } from 'vectis-ui'
import { search } from 'vectis-ui/icons'
</script>

<template>
  <VField v-slot="{ fieldProps }" label="Search" hide-label>
    <VInput v-bind="fieldProps" type="search" :icon-start="search" />
  </VField>
</template>

API

Props

PropTypeDefault
labelstringnone
Label linked to the control through for.
hintstringnone
Help text below the control, linked through aria-describedby.
errorstringnone
Error message shown in place of the hint. Sets aria-invalid, is linked through aria-describedby and is announced when it appears.
requiredbooleanfalse
Adds an asterisk after the label and passes required to the control.
hideLabelbooleanfalse
Hides the label visually while keeping it as the accessible name.
labelPositionFieldLabelPosition'top' | 'start''top'
Places the label above the control or beside it.

Slots

SlotType
default{ fieldProps: FieldControlProps; }
The control. Bind fieldProps: id, descriptions, invalid state, required and the attributes set on the field other than class and style.

Types

Types used in the API tables. Import exported types from vectis-ui.

export type FieldControlProps = {
  id: string
  'aria-describedby'?: string
  'aria-invalid'?: 'true'
  required?: true
} & Record<string, unknown>

CSS variables

TokenValue
--vectis-control-size-field-label10rem
--vectis-control-size-field-control-min16rem