InputsField group
Field group
A label, optional description, and one or more inputs. The container for any form field on the site.
Demo
Default is stack. The label is a label element set in ds-label style. The description sits below the label. The error replaces the description when present.
Default
We'll only contact you about the design system.
Error state
Error
Please enter a valid email address.
Row orientation
Row
Implementation
field-group.tsx
import { type ReactNode } from "react"
import { cn } from "@/lib/utils"
interface FieldGroupProps {
label: string
htmlFor?: string
description?: string
error?: string
required?: boolean
orientation?: "stack" | "row"
children: ReactNode
}
export function FieldGroup({
label,
htmlFor,
description,
error,
required,
orientation = "stack",
children,
}: FieldGroupProps) {
return (
<div className={cn("ds-field", orientation === "row" && "ds-field--row")}>
<label htmlFor={htmlFor} className="ds-label">
{label}
{required ? <span aria-hidden="true" className="ds-field__required">*</span> : null}
</label>
{children}
{error ? (
<p className="ds-field__error" role="alert">{error}</p>
) : description ? (
<p className="ds-field__description">{description}</p>
) : null}
</div>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | None | The fieldset legend |
description | string | None | Helper text below the legend |
error | string | None | Error text; takes precedence over description |
required | boolean | false | Adds a required marker to the legend |
orientation | "stack" | "row" | "stack" | Field layout |
Accessibility
- The
labelis a real label, not placeholder-as-label. - Error messages are announced via
role="alert". - Description is associated with the field via
aria-describedby(in the consumer's input). - Required fields are marked with a visible asterisk and the
requiredattribute on the input.