A label, a hint, an error, and the wiring between them.
Import it from rei-kit:
import { FormField } from 'rei-kit'
Open FormField in the live documentation, where every prop below is a control you can change, in four materials and ten palettes.
<script setup lang="ts">
import { ref } from 'vue'
import { FormField } from 'rei-kit'
const name = ref('')
const error = ref('')
</script>
<template>
<FormField label="Username" hint="Letters and numbers only" :error="error">
<template #default="{ id, describedBy, invalid }">
<input
:id="id"
v-model="name"
class="control rounded-card px-3 py-2"
:aria-describedby="describedBy"
:aria-invalid="invalid"
/>
</template>
</FormField>
</template>
| Prop | Type | Required or default | What it is for |
|---|---|---|---|
label | string | yes | |
error | string | '' | |
hint | string | '' | |
size | 'sm' | 'md' | 'md' | `sm` for a control that sits inside something else — a toolbar, a filter row, a settings line — rather than in a form of its own. It exists because every hand-written select in all three apps was the small one, and the kit only had the large one. A part is not reusable if reaching for it costs a size somebody chose on purpose. |
labelHidden | boolean | false | Hides the label visually but keeps it for assistive tech. For fields whose surrounding row already names them — dropping the label entirely would leave the control with no accessible name at all. |
fieldId | string | undefined | The control's `id`, when the app needs to address it from outside — an `ErrorSummary` linking to the field it is about, a label elsewhere on the page. Generated when it is not given, which is almost always. |
rei-kit is an accessible Vue 3 and Tailwind CSS 4 component library: 106 components, themed by role rather than by colour on three independent axes — ten WCAG-checked palettes, four materials and light or dark, each switched with one attribute. Typed, tested, SSR-safe, no runtime dependencies, MIT.