Docs

Input

The single-line text control for short_text, email, phone, url and number fields.

A styled <input> bound to a field. Field renders it for short_text, email, phone, url and number; import it directly when you compose a field by hand.

Preview

Usage

// mirio/forms/newsletter.ts
import { defineForm } from '@trymirio/mirio/schema';

export const newsletter = defineForm({
  slug: 'newsletter',
  name: 'Newsletter',
  pages: [{ fields: [{ key: 'email', type: 'email', label: 'Work email', placeholder: '[email protected]', autocomplete: 'email', required: true }] }],
});

// Rendered by <Form> automatically, or by hand:
import { Form, Field, Input, Submit } from '@trymirio/mirio';

<Form schema={newsletter} client={mirio}>
  <Field name="email" />          {/* label + help + <Input /> + error */}
  <Submit />
</Form>

Props

Prop Type Default Description
name string required The field key.
type string by field type Overrides the HTML type: email→email, phone→tel, url→url, number→text (with inputMode="decimal", or numeric when integer: true), otherwise text.
className string control classes Merged onto the <input>.
…<input> attributes Everything except name, value, onChange (those come from the field). placeholder defaults to the schema's placeholder.

Renders <input data-mirio="input">. For a hidden field, Input renders HiddenInput (<input type="hidden" data-mirio="hidden">) instead.

autocomplete comes from the schema's autocomplete, else a default: email for email fields, tel for phone, url for url, and name / given-name / family-name / organization when a short_text key looks like one. Values are normalized on submit (trimmed, emails lower-cased, phones to E.164, URLs given https://), so the input itself never reformats what the visitor types.

Variants and states

const fields = [
  { key: 'name', type: 'short_text', label: 'Full name', help: 'As it appears on your badge.', autocomplete: 'name', required: true },
  { key: 'website', type: 'url', label: 'Website', placeholder: 'acme.com', defaultValue: 'https://acme.com' },
  { key: 'seats', type: 'number', label: 'Seats', integer: true, min: 1, max: 500, required: true },
];
  • Required: the label gets the required indicator and the input aria-required.
  • With help: help renders below the label and is linked via aria-describedby.
  • Prefilled: defaultValue, prefill: { query } (from the URL) or initialValues on Form.
  • Error: after a failed submit, aria-invalid="true" turns the border red and FieldError appears. Format errors (bad email, bad URL) also show on blur; "required" waits for submit.
  • Disabled: pass disabled when composing; the control dims and ignores input.

Customization

  • Reads --mirio-bg, --mirio-fg, --mirio-border, --mirio-ring (focus ring, 25 % alpha), --mirio-error (invalid border), --mirio-muted-fg (placeholder), --mirio-radius.
  • className overrides resolve by utility: className="h-12 text-base" replaces min-h-10 text-[15px]; className="rounded-none" replaces rounded-mirio.
  • CSS hook: [data-mirio-root] [data-mirio="input"], plus [aria-invalid="true"] for the error state.
  • classNames={{ input: '…' }} on Form or MirioProvider styles Input, Textarea, Select and DatePicker together; they share one set of control classes.

Accessibility

Labelled by its Label through htmlFor; help and error text are in aria-describedby; aria-required and aria-invalid reflect state; inputMode gives phones the right keyboard for number fields. Enter submits (or advances a multi-step form).

Field, Textarea, Label, Help, FieldError, Schema: field types