Single-line text input with FormField chrome, icons, and adornments.
Introduction
TextField is a complete form control: a label, input, and helper or error text in one component. It wraps FormField chrome around a native <input>, so you get consistent layout, validation styling, and adornments without assembling those pieces yourself.
For specialized inputs, use dedicated components instead of changing type alone—PasswordField, NumberField, Textarea, and Select each extend the same FormField pattern with behavior tuned to that input.
Import
import { TextField } from "@bridge-ui/vue/Components/TextField";import { TextField } from "@bridge-ui/react/Components/TextField";Basic usage
Provide a label and placeholder. Bind the value with value/onChange in React or v-model in Vue. For uncontrolled usage with an initial value, use defaultValue in React or default-value in Vue.
<script setup lang="ts">
import { ref } from "vue";
import { TextField } from "@bridge-ui/vue/Components/TextField";
const name = ref("Jane Doe");
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<TextField label="Email" placeholder="[email protected]" />
<TextField
v-model="name"
label="Display name"
description="This is how your name will appear."
/>
</div>
</template>
import { useState } from "react";
import { TextField } from "@bridge-ui/react/Components/TextField";
export default function TextFieldBasic() {
const [name, setName] = useState("Jane Doe");
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<TextField label="Email" placeholder="[email protected]" />
<TextField
value={name}
label="Display name"
description="This is how your name will appear."
onChange={(event) => setName(event.target.value)}
/>
</div>
);
}
Form props
Standard form attributes are supported through inherited FormField props and native input attributes:
- required — shows a red asterisk on the label. Pair with the native required attribute when validating with HTML forms.
- disabled — prevents interaction and applies disabled styling to the field shell and input.
- readonly — keeps the value visible and focusable but not editable.
Use description for helper text below the field. When error is set, the description is hidden and errorMessage is shown instead.
Variants
Control the field shell appearance with the variant prop. Available variants: outline (default), filled, notched, stacked, and underlined.
<script setup lang="ts">
import { TextField } from "@bridge-ui/vue/Components/TextField";
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<TextField
label="Outline"
variant="outline"
placeholder="Default variant"
/>
<TextField
label="Filled"
variant="filled"
placeholder="Filled background"
/>
<TextField
label="Notched"
variant="notched"
placeholder="Notched outline"
/>
<TextField label="Stacked" variant="stacked" placeholder="Stacked label" />
<TextField
label="Underlined"
variant="underlined"
placeholder="Underlined"
/>
</div>
</template>
import { TextField } from "@bridge-ui/react/Components/TextField";
export default function TextFieldVariants() {
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<TextField
label="Outline"
variant="outline"
placeholder="Default variant"
/>
<TextField
label="Filled"
variant="filled"
placeholder="Filled background"
/>
<TextField
label="Notched"
variant="notched"
placeholder="Notched outline"
/>
<TextField
label="Stacked"
variant="stacked"
placeholder="Stacked label"
/>
<TextField
label="Underlined"
variant="underlined"
placeholder="Underlined"
/>
</div>
);
}
Sizes
Control the field size with the size prop. Available sizes: 2xs, xs, sm, md (default), lg, xl, and 2xl.
<script setup lang="ts">
import { TextField } from "@bridge-ui/vue/Components/TextField";
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<TextField size="2xs" label="2xs" placeholder="2xs" />
<TextField size="xs" label="xs" placeholder="xs" />
<TextField size="sm" label="sm" placeholder="sm" />
<TextField size="md" label="md" placeholder="md" />
<TextField size="lg" label="lg" placeholder="lg" />
<TextField size="xl" label="xl" placeholder="xl" />
<TextField size="2xl" label="2xl" placeholder="2xl" />
</div>
</template>
import { TextField } from "@bridge-ui/react/Components/TextField";
export default function TextFieldSizes() {
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<TextField size="2xs" label="2xs" placeholder="2xs" />
<TextField size="xs" label="xs" placeholder="xs" />
<TextField size="sm" label="sm" placeholder="sm" />
<TextField size="md" label="md" placeholder="md" />
<TextField size="lg" label="lg" placeholder="lg" />
<TextField size="xl" label="xl" placeholder="xl" />
<TextField size="2xl" label="2xl" placeholder="2xl" />
</div>
);
}
Rounded
Use the rounded prop to control border radius. Available values: none, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, and full (defaults vary by component).
<script setup lang="ts">
import { TextField } from "@bridge-ui/vue/Components/TextField";
</script>
<template>
<div class="grid w-full max-w-2xl grid-cols-2 gap-4 sm:grid-cols-3">
<TextField label="none" rounded="none" placeholder="none" />
<TextField label="sm" rounded="sm" placeholder="sm" />
<TextField label="md" rounded="md" placeholder="md" />
<TextField label="2xl" rounded="2xl" placeholder="2xl" />
<TextField label="full" rounded="full" placeholder="full" />
</div>
</template>
import { TextField } from "@bridge-ui/react/Components/TextField";
export default function TextFieldRounded() {
return (
<div className="grid w-full max-w-2xl grid-cols-2 gap-4 sm:grid-cols-3">
<TextField label="none" rounded="none" placeholder="none" />
<TextField label="sm" rounded="sm" placeholder="sm" />
<TextField label="md" rounded="md" placeholder="md" />
<TextField label="2xl" rounded="2xl" placeholder="2xl" />
<TextField label="full" rounded="full" placeholder="full" />
</div>
);
}
Icons and adornments
Add an icon with startIcon or endIcon, or prefix/suffix text with start and end.
<script setup lang="ts">
import { Search } from "@lucide/vue";
import { TextField } from "@bridge-ui/vue/Components/TextField";
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<TextField label="Search" :start-icon="Search" placeholder="Search..." />
<TextField label="Website" start="https://" placeholder="example" />
<TextField end="EUR" label="Amount" placeholder="0.00" />
</div>
</template>
import { Search } from "lucide-react";
import { TextField } from "@bridge-ui/react/Components/TextField";
export default function TextFieldIconsAndAdornments() {
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<TextField label="Search" startIcon={Search} placeholder="Search..." />
<TextField label="Website" start="https://" placeholder="example" />
<TextField end="EUR" label="Amount" placeholder="0.00" />
</div>
);
}
Validation
Set error and errorMessage to show invalid styling and an error message below the field. Use required to show a red asterisk on the label.
<script setup lang="ts">
import { TextField } from "@bridge-ui/vue/Components/TextField";
</script>
<template>
<div class="flex w-full max-w-sm flex-col gap-4">
<TextField
error
label="Email"
placeholder="[email protected]"
error-message="Enter a valid email address."
/>
<TextField required label="Username" placeholder="johndoe" />
</div>
</template>
import { TextField } from "@bridge-ui/react/Components/TextField";
export default function TextFieldValidation() {
return (
<div className="flex w-full max-w-sm flex-col gap-4">
<TextField
error
label="Email"
placeholder="[email protected]"
errorMessage="Enter a valid email address."
/>
<TextField required label="Username" placeholder="johndoe" />
</div>
);
}
Related components
PasswordField, NumberField, Textarea, Select
Accessibility
For the field to be accessible, the input must be linked to its label and helper or error text:
- The label is associated with the input via htmlFor / id, using controlId (auto-generated when omitted).
- description and errorMessage are linked through aria-describedby on the input.
- When error is true, the input receives aria-invalid="true".
Provide a stable controlId when rendering client-only so labels associate correctly on first paint.
Anatomy
TextField composes FormField around a native <input>:
FormField (root)
├── Header — label, optional corner text, required indicator
├── Container — variant shell (outline, filled, …)
│ ├── Start adornment — optional prefix text or icon
│ ├── Input — native text input
│ └── End adornment — optional suffix text or icon
└── Footer — description (helper text) or error messageNative input attributes (type, placeholder, autoComplete, etc.) are forwarded to the inner <input> element.
API
| Prop | Type | Default | Description |
|---|---|---|---|
| v-model | string | — | Two-way binding for the input value. |
| default-value | string | — | Initial value for uncontrolled usage (without v-model). |
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | — | Input value. Use with onChange for controlled state. |
| defaultValue | string | — | Initial value for uncontrolled usage. |
| onChange | ChangeEventHandler<HTMLInputElement> | — | Native input change handler. |
TextField-specific
Native input attributes (type, placeholder, autoComplete, etc.) are merged onto the inner <input> element.
Inherited from FormField
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | Primary label text above the control. |
| description | string | — | Helper text below the control (hidden when invalid). |
| corner | string | — | Secondary label text at the inline end of the header row. |
| required | boolean | false | Shows a red asterisk on the label. |
| disabled | boolean | false | Whether the control is disabled. |
| readonly | boolean | false | Whether the control is read-only. |
| error | boolean | false | Applies invalid styling and hides description. |
| errorMessage | string | — | Error message below the control. |
| showErrorIcon | boolean | true | Shows an error icon when invalid. |
| hideErrorMessage | boolean | false | Does not reserve space for error messages. |
| variant | FormFieldVariant | "outline" | Visual variant of the field shell. |
| color | FormFieldColor | "primary" | Color applied to the field control. |
| size | FormFieldSize | "md" | Typography and control sizing. |
| rounded | FormFieldRounded | "md" | Border radius of the field control. |
| start | string | — | Inline-start text inside the field (prefix). |
| end | string | — | Inline-end text inside the field (suffix). |
| startIcon | IconSource | — | Icon at the inline start. |
| endIcon | IconSource | — | Icon at the inline end. |
| errorIcon | IconSource | "alert" | Icon shown when invalid and showErrorIcon is enabled. |
| controlId | string | — | Associates labels and helper text with the control. Auto-generated when omitted. |
| classes | FormFieldClasses | — | Class overrides per part. |
| customProps | FormFieldCustomProps | — | Props for each part. label accepts Label props (without children); error label colors come from Label. |
| slots | FormFieldSlots | — | React slots. Vue: #label, #corner, default, #description, #errorMessage, #start, #end. |