Input
PortedSingle-line text field. Native <input> attributes and ref pass through.
import { Input } from "@etched/monet/input";
export function Preview() {
return <Input aria-label="Search runs" placeholder="Search runs" />;
}Installation
import { Input, InputArea } from "@etched/monet/input";Examples
Sizes
import { Input, type InputSize } from "@etched/monet/input";
const sizes: InputSize[] = ["sm", "base"];
export function Sizes() {
return (
<div className="row">
{sizes.map((s) => (
<Input key={s} size={s} aria-label={`Search, ${s}`} placeholder={`Search (${s})`} />
))}
</div>
);
}Labels and states
label, description and error wrap the input in a Field.
Shown on the run page.
Site TPE-9 does not exist.
import { Input } from "@etched/monet/input";
export function LabelsAndStates() {
return (
<div className="grid">
<Input label="Run ID" defaultValue="run_7f3a91c2" />
<Input label="Owner" placeholder="Name or email" description="Shown on the run page." />
<Input label="Site" defaultValue="TPE-9" error="Site TPE-9 does not exist." />
<Input label="Created by" defaultValue="system" disabled />
</div>
);
}Read-only
readOnly keeps the value clear and selectable, on a quieter fill. Use it for values the user may copy but not change; disabled is for controls that are off.
import { Input, InputArea } from "@etched/monet/input";
export function ReadOnly() {
return (
<div className="grid">
<Input label="Candidate ID" defaultValue="cand_2291a" readOnly />
<InputArea label="Referral note" rows={2} defaultValue="Worked with Ana on the clock tree at her last job." readOnly />
</div>
);
}Search and filter fields
passwordManagerIgnore keeps password managers from filling the field or offering to save it.
import { Input } from "@etched/monet/input";
export function SearchAndFilterFields() {
return <Input type="search" aria-label="Filter candidates" placeholder="Filter candidates" passwordManagerIgnore />;
}Input area
autoResize grows the field with its text between minRows and maxRows. onValueChange gets the new text on each change. Native attributes such as id reach the textarea.
Only the hiring team sees comments.
0 words
Add a reason before you reject.
import { useState } from "react";
import { InputArea } from "@etched/monet/input";
export function InputAreas() {
const [notes, setNotes] = useState("");
return (
<div className="grid">
<InputArea id="hiring-comment" label="Comment" rows={3} placeholder="Add a comment" description="Only the hiring team sees comments." />
<InputArea
label="Notes (grows from 2 to 6 rows)"
autoResize
minRows={2}
maxRows={6}
placeholder="Type several lines"
value={notes}
onValueChange={setNotes}
description={`${notes.split(/\s+/).filter(Boolean).length} words`}
/>
<InputArea label="Reason" error="Add a reason before you reject." />
</div>
);
}Character limit
limit shows the count under the field. Past the limit, the count and the field turn red; nothing is cut off.
63 / 140
76 / 60
import { InputArea } from "@etched/monet/input";
export function CharacterLimit() {
return (
<div className="grid">
<InputArea label="Note to the hiring manager" limit={140} defaultValue="Strong on clock trees; wants to stay close to silicon bring-up." />
<InputArea
label="Summary"
limit={60}
defaultValue="Led the clock tree rework on the last tape-out, and owned the bring-up plan."
/>
</div>
);
}Accessibility
- A native
input(Input) ortextarea(InputArea). Withlabel, the label names it, and a click on the label focuses it. descriptionanderrordescribe it througharia-describedby, and an error setsaria-invalid. The help text goes while an error shows.- With
limit, the "n / limit" count also describes the field, and past the limit the field getsaria-invalid. The count is not a live region. - Without
label, give it anaria-label. Aplaceholderis not a name.
API reference
InputArea
| Prop | Type | Default | Description |
|---|---|---|---|
| minRows | number | 1 | |
| maxRows | number | – | |
| onValueChange | (value: string) => void | – | Called with the new text on each change. |
| label | ReactNode | – | Visible label. Without one, give the control an aria-label. |
| labelTooltip | ReactNode | – | More about the field, behind an info button after the label. |
| labelTooltipLabel | string | "More information" | Names the info button. |
| description | ReactNode | – | Help text below the control. Hidden while an error shows. |
| error | FieldError | – | |
| size | "sm" | "base" | "base" | |
| autoResize | boolean | – | Grow and shrink with the text, between minRows and maxRows. |
| limit | number | – | Shows "n / limit" under the field. Typing past it is allowed: the count and the field turn red, so no text is cut off without notice. |
| className | string | – |
Input
| Prop | Type | Default | Description |
|---|---|---|---|
| label | ReactNode | – | Visible label. Without one, give the control an aria-label. |
| labelTooltip | ReactNode | – | More about the field, behind an info button after the label. |
| labelTooltipLabel | string | "More information" | Names the info button. |
| description | ReactNode | – | Help text below the control. Hidden while an error shows. |
| error | FieldError | – | |
| size | "sm" | "base" | "base" | |
| passwordManagerIgnore | boolean | – | Keeps password managers (1Password, Bitwarden, LastPass, Keeper) from filling the field or offering to save it. For search and filter fields. |
| className | string | – |