Password

Masked entry with a reveal toggle, and a requirements block that reports which rules a password meets as it is typed.

Forgot password

Must contain at least;

  • At least 1 symbol, not met
  • At least 1 uppercase, not met
  • At least 1 number, not met
  • At least 8 characters, not met
<PasswordInput
  size="md"
  label="Password"
  info="Use something you have not used elsewhere."
  forgotHref="/reset"
/>

Requirements

This is the part worth reading. Yöte does not decide what a good password is. The rules are yours, passed in as { label, test } pairs. The component runs each test against the current value, renders whether it passes, and counts how many do. That is the same line the rest of the library holds: validation state comes in as a prop, and this is the prop.

sign-up-form.tsx
import { PasswordInput } from 'yote-ui'

<PasswordInput
  label="Password"
  requirements={[
    { label: 'At least 12 characters', test: (v) => v.length >= 12 },
    { label: 'Not your email', test: (v) => !v.includes(email) },
  ]}
/>

Leave requirements unset and it uses the four below, so the field is useful with nothing configured. They are exported, so you can spread, filter or extend them rather than retyping.

import { DEFAULT_PASSWORD_REQUIREMENTS } from 'yote-ui'

// At least 1 symbol   /[^\w\s]/
// At least 1 uppercase  /[A-Z]/
// At least 1 number     /\d/
// At least 8 characters  v.length >= 8

<PasswordInput
  requirements={[
    ...DEFAULT_PASSWORD_REQUIREMENTS,
    { label: 'Not a common password', test: (v) => !COMMON.has(v) },
  ]}
/>

Pass requirements={[]}, or showRequirements={false}, and the whole block disappears. A sign-in field wants the input and nothing else.

Strength

The bar has one segment per rule, so it keeps working whether you pass three or six. The ramp is named rather than counted, and reads off data-strength on the requirements block.

data-strengthColourWhen
noneGreyNothing typed yet.
partialAmberOne rule up to all but one. Only the met segments fill.
strongGreenEvery rule passes.
invalidRedThe consumer says the entry is wrong. Colours the whole bar.

Two orderings are deliberate. invalid beats the count, because a green bar inside a red field claims the entry is fine and wrong at once. And disabled beats everything: a disabled field shows neutral marks, not greyed ticks, since a tick on a field nobody can type into reports an achievement that was never earned.

Props

PropTypeDefaultNotes
requirementsPasswordRequirement[]the four belowRules to report on. Pass [] to hide the block.
requirementsTitleReactNode"Must contain at least;"Heading above the list.
showRequirementsbooleantrueShow the strength bar and list.
revealablebooleantrueShow the reveal toggle.
forgotHrefstringRenders the forgot link under the field.
forgotLabelReactNode"Forgot password"Text for that link.
infostringInfo marker beside the label, with this as its tooltip.

Shared

PropTypeDefaultNotes
valuestringControlled value.
defaultValuestringInitial value when uncontrolled.
onChange(value: string) => voidReceives the value, never the event.
labelReactNodeRendered as a real <label> wired by htmlFor.
hintReactNodeHelper text under the field.
errorReactNodeError text. Implies invalid unless invalid says otherwise.
invalidbooleanForces the error styling on or off.
errorKeystring | numberChange it to replay the error animation.
disabledbooleanfalseGreys the field out.
readOnlybooleanfalseReads as filled, stays focusable.
size'sm' | 'md' | 'lg''md'Size scale, where the component defines one.
classNamesRecord<Part, string>Per-part class names.

Accessibility

The rule list is the accessible source of truth: each item announces its label and whether it is met, and the bar above it is hidden from assistive tech because it says the same thing in colour. The reveal control is a real toggle with aria-pressed, and the input keeps autocomplete="current-password" so managers still work.