Skip to content

Field

Label, control, hint and error with the ids wired. Controls inside pick up id, aria-describedby, aria-invalid and required.

FormsServer-rendered

Examples

Label and hint

The control takes its id from the Field; no need to repeat it.

Shown to agents in tool lists. Letters, numbers and dashes.

Example
<Field id="server-name" label="Server name" hint="Shown to agents in tool lists. Letters, numbers and dashes.">
  <Input name="name" value="github" />
</Field>

Required and error

Say what is wrong and how to fix it. The error sits above the hint and both are announced.

Enter a full URL starting with https://.

The MCP endpoint, usually ending in /mcp or /sse.

Example
<Field
  id="server-url"
  label="Server URL"
  required
  error="Enter a full URL starting with https://."
  hint="The MCP endpoint, usually ending in /mcp or /sse."
>
  <Input name="url" value="api.githubcopilot.com/mcp" mono />
</Field>

Inline

Label beside the control, for settings pages. Stacks again below 640px.

Tells the router when to pick this server.

Example
<Field id="routing-hint" label="Routing hint" inline hint="Tells the router when to pick this server.">
  <Input name="hint" placeholder="Use for GitHub issues, pull requests and code search" />
</Field>

Usage

Usage
import { Field } from '@switchboard/ui'

<Field id="server-url" label="Server URL" required error={errors.url}>
  <Input name="url" type="url" mono />
</Field>

Props

Every component also takes mix, for css() and mixins applied after its own style.

Field

Field props
PropTypeDefaultDescription
id*string–Id given to the control. Hint and error ids derive from it: `${id}-hint`, `${id}-error`.
label*RemixNode–Rendered as a <label for={id}>.
hintRemixNode–Help text under the control, linked with aria-describedby.
errorRemixNode–Error message with an alert icon. Marks the control aria-invalid and is listed first in aria-describedby.
requiredbooleanfalsePassed to the control as required.
inlineboolean–Label and control side by side. Stacked by default and below 640px.

Also accepts every <div> attribute except id. Input, Textarea, InputGroup, SecretInput, Select, Switch and Checkbox read its context; props set on the control win.

Accessibility

  • The <label for> points at the control, so clicking the label focuses it and screen readers read it as the name.
  • Hint and error are tied to the control with aria-describedby, error first, so they are read on focus.
  • An error sets aria-invalid="true" on the control; the message is text with an icon, not colour alone.
  • Ids must be unique on the page; when a form appears twice, prefix them.

Guidance

Do

  • Write errors that say what is wrong and how to fix it: "Enter a full URL starting with https://."
  • Keep labels short nouns; put guidance in the hint.

Don’t

  • Use a placeholder as the label.
  • Show an error before the person has submitted or left the field.
  • Wrap a RadioGroup in a Field; it has its own legend.