Keyboard shortcut: Ctrl + K
Get started

Fieldset

VFieldset groups related controls in a native <fieldset> named by its legend, with a hint and an error message.

Usage

vue
Plan

You can change it at any time.

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

const plan = ref('free')
</script>

<template>
  <VFieldset legend="Plan" hint="You can change it at any time.">
    <VRadio v-model="plan" name="plan" value="free" label="Free" />
    <VRadio v-model="plan" name="plan" value="pro" label="Pro" />
    <VRadio v-model="plan" name="plan" value="team" label="Team" />
  </VFieldset>
</template>

Examples

Horizontal

orientation="horizontal" lays the controls out in a wrapping row.

vue
Notifications
<script setup lang="ts">
import { VCheckbox, VFieldset } from 'vectis-ui'
</script>

<template>
  <VFieldset legend="Notifications" orientation="horizontal">
    <VCheckbox label="Email" />
    <VCheckbox label="Text message" />
    <VCheckbox label="Push" />
  </VFieldset>
</template>

Error and required

error replaces the hint, describes the group and is announced when it appears. A group cannot carry aria-invalid: bind the slot’s invalid and required on the controls.

vue
Plan
<script setup lang="ts">
import { ref } from 'vue'
import { VButton, VFieldset, VRadio } from 'vectis-ui'

const plan = ref<string>()
const error = ref<string>()

function submit() {
  error.value = plan.value ? undefined : 'Choose a plan to continue.'
}

function pick(value: string) {
  plan.value = value
  error.value = undefined
}
</script>

<template>
  <div class="demo">
    <VFieldset v-slot="{ invalid, required }" legend="Plan" :error="error" required>
      <VRadio
        v-for="value in ['Free', 'Pro', 'Team']"
        :key="value"
        :model-value="plan"
        name="plan"
        :value="value"
        :label="value"
        :invalid="invalid"
        :required="required"
        @update:model-value="pick(value)"
      />
    </VFieldset>
    <VButton @click="submit">Continue</VButton>
  </div>
</template>

<style scoped>
.demo {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--vectis-space-4);
}
</style>

Hidden legend

hideLegend hides the legend visually. It still names the group for screen readers.

vue
Notifications
<script setup lang="ts">
import { VCheckbox, VFieldset } from 'vectis-ui'
</script>

<template>
  <VFieldset legend="Notifications" hide-legend orientation="horizontal">
    <VCheckbox label="Email" />
    <VCheckbox label="Text message" />
  </VFieldset>
</template>

API

Props

PropTypeDefault
legendstringnone
Legend naming the group.
hintstringnone
Help text below the group, linked through aria-describedby.
errorstringnone
Error message shown in place of the hint, linked through aria-describedby and announced when it appears. Sets the slot’s invalid.
requiredbooleanfalse
Adds an asterisk after the legend and sets the slot’s required.
hideLegendbooleanfalse
Hides the legend visually while keeping it as the group name.
orientationFieldsetOrientation'vertical' | 'horizontal''vertical'
Lays the controls out in a column or a wrapping row.

Slots

SlotType
default{ invalid: boolean; required: boolean; }
The controls. Bind invalid and required on them.