Skip to content

Field validation

In review
Live · web

The vocabulary: one tone per state, never color alone

Shown in the session list. Optional.

Saved. This name is available.

This name is close to another session.

A session name is required.

On the field: required, error, warning, success

Spaces become hyphens: auth-flow.

Workspace found.

Live: type the email, watch it validate

Multiple rules: the checklist resolves as you type

  • At least 12 characters
  • One uppercase letter
  • One number

Edited 0 times · email invalid · password 1/3 rules. The island is live.

// Web: React, consuming @dizyx/nockerl-tokens. (Web is the laggard platform; this is the intended API,
// not yet exported from @dizyx/nockerl-react (promotion tracked). The message + icon + border are one
// bundled status layer on the field: error/warning/success/neutral, never color alone.)
export function SessionForm() {
const [email, setEmail] = useState('');
const valid = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email);
const status = email === '' ? 'neutral' : valid ? 'success' : 'error';
return (
<>
<ValidatedField label="Session name" required value={name} onValueChange={setName}
status="error" message="A session name is required." />
<ValidatedField label="Notify email" type="email" leadingIcon="@"
value={email} onValueChange={setEmail}
status={status}
message={status === 'error' ? 'Enter a valid email address.' : 'We send run summaries here.'} />
{/* counter + over-limit error, and a multi-rule checklist */}
<ValidatedField label="Title" value={title} onValueChange={setTitle} maxLength={32} />
<ValidatedField label="New password" type="password" value={pwd} onValueChange={setPwd}
status={pwdOk ? 'success' : 'error'}
issues={[{ label: 'At least 12 characters', ok: pwd.length >= 12 }]} />
</>
);
}
PropTypeDefaultDescription
label *stringPersistent visible label, bound to the input via htmlFor / id.
value *stringControlled value of the field.
onValueChange(value: string) => voidChange handler. Re-run validation here to update status / message live.
status'neutral' | 'error' | 'warning' | 'success''neutral'Validation state. Drives the message tone, the status glyph, and the field border. neutral = the resting helper line, no border recolor. Warm status tokens only, never the brand cyan.
messagestringThe single line under the field (helper / error / warning / success copy). Pairs with a glyph so it is never color alone. The error message renders role="alert" and is wired via aria-describedby.
issues{ label: string; ok: boolean }[]Multiple rules rendered as a live checklist (e.g. password requirements). When set, replaces message.
requiredbooleanfalseAdds a status-colored * after the label and sets the input required.
maxLengthnumberShows a right-aligned character counter; turns to the error treatment (counter + border) when over the cap.
leadingIconstringOptional glyph inside the well, before the text.
type'text' | 'email' | 'password' | …'text'Underlying input type / keyboard.