{
  "name": "PasswordInput",
  "source": "src/components/PasswordInput.tsx",
  "propsType": "PasswordInputProps",
  "description": "PasswordInput — a password field with a way to see what was typed.\n\nTHE TOGGLE IS A TOGGLE. Its name stays \"Show password\" and `aria-pressed`\nsays whether it is on, which is how a screen reader expects a toggle to\nbehave: a name that flips to \"Hide password\" reads as a different button.\nA polite status beside it also says \"Password shown\" or \"Password hidden\"\nwhen it changes, because some screen readers do not read a changed pressed\nstate aloud. It is a real tab stop, not the clear button's skipped one: it\nhas no keyboard shortcut to stand in for it.\n\nWHAT A SHOWN PASSWORD MUST NOT DO\n\n  Go to a spellchecker. A shown password is `type=\"text\"`, and browsers\n  spellcheck text fields, some by sending them to a server. Spellcheck,\n  autocorrect and autocapitalise are off whatever the state.\n\n  Be submitted shown. A password manager recognises a login by its\n  `type=\"password\"` field when the form is submitted; a shown one is not\n  offered for saving. Submitting the form hides it first.\n\nThe box IS Input's — the same `.ion-input` classes as SearchField and\nNumberInput — so a password field under an email field matches it.",
  "import": "import { PasswordInput } from 'ionbase-ui';",
  "status": "stable",
  "summary": "A password field with a Show password toggle. The toggle keeps its name and says its state with `aria-pressed`, and a polite status says \"Password shown\" or \"Password hidden\". A shown password is never spellchecked, and is hidden again before its form is submitted.",
  "useWhen": [
    "the user types a password, a passphrase or a PIN they must get right without seeing it",
    "signing in, signing up, changing a password, or confirming one before a sensitive action"
  ],
  "useInstead": [
    {
      "when": "the secret is shown once for the user to copy — a new API key",
      "use": "CodeSnippet",
      "why": "it is shown on purpose, in full, with a copy button; masking it and then offering to show it adds a step and nothing else"
    },
    {
      "when": "a one-time code sent by text or email",
      "use": "Input",
      "why": "a one-time code is read off another screen and typed; masking it only makes it harder to check. Use `inputMode=\"numeric\"` and `autoComplete=\"one-time-code\"`"
    }
  ],
  "composition": {
    "order": [
      "PasswordInput"
    ],
    "note": "Takes Input's `label`, `description`, `isInvalid` and `errorMessage`. `autoComplete` is `current-password` by default; pass `new-password` where one is being set.",
    "example": "<PasswordInput label=\"New password\" autoComplete=\"new-password\" description=\"At least 12 characters.\" />"
  },
  "variants": {
    "size": {
      "sm": {
        "use": "dense forms and dialogs"
      },
      "md": {
        "use": "the default"
      },
      "lg": {
        "use": "a sign-in page's main fields"
      }
    }
  },
  "a11y": {
    "requires": [
      "`label` — a visible one; a placeholder is not a label",
      "`revealLabel`, `shownMessage` and `hiddenMessage` translated"
    ],
    "guarantees": [
      "the toggle is a tab stop after the field, named `revealLabel` (\"Show password\") whatever the state; `aria-pressed` says whether the password is shown, and `aria-controls` points at the field",
      "a polite status says `shownMessage` or `hiddenMessage` when the toggle changes it, and nothing on first render",
      "a mouse press on the toggle leaves focus in the field; a keyboard press leaves it on the toggle; what was typed and the caret's place are kept",
      "spellcheck, autocorrect and autocapitalise are off, shown or hidden, and cannot be turned back on by a prop",
      "submitting the form hides the password before the form's own handler runs, so a password manager sees `type=\"password\"`",
      "`autoComplete` is `current-password` unless set; `new-password` lets a password manager offer to generate one",
      "`isDisabled` disables the toggle too; `isReadOnly` leaves it working",
      "the box is Input's, with Input's sizes and states"
    ],
    "notes": [
      "do not block paste into a password field: it breaks password managers, and WCAG 3.3.8 counts it against an accessible sign-in",
      "state the rules before the user types — \"At least 12 characters\" in `description` — rather than only in the error after"
    ]
  },
  "antiPatterns": [
    {
      "dont": "<Input type=\"password\" trailingIcon={<Eye />} /> with an onClick on the icon",
      "do": "<PasswordInput>",
      "why": "an icon is not a button: it cannot be focused or pressed from the keyboard, is not announced, and the shown password is spellchecked"
    },
    {
      "dont": "a toggle whose name flips between \"Show password\" and \"Hide password\"",
      "do": "one name, and `aria-pressed`",
      "why": "a screen reader reads a changed name as a different control, and the user cannot tell whether the press worked"
    },
    {
      "dont": "a \"Confirm password\" field under a new-password field",
      "do": "one PasswordInput the user can show",
      "why": "typing a password twice blind catches fewer mistakes than seeing it once, and costs every user a field"
    }
  ],
  "stylesheet": "src/styles/password-input.css",
  "tokens": [
    "--border-focus",
    "--border-width-thick",
    "--icon-default",
    "--icon-disabled",
    "--icon-secondary",
    "--ion-duration-base",
    "--ion-ease-out",
    "--ion-input-height",
    "--ion-input-icon-size",
    "--radius-sm",
    "--spacing-4",
    "--spacing-8",
    "--surface-default",
    "--surface-hover",
    "--surface-pressed"
  ],
  "props": {
    "size": {
      "type": "PasswordInputSize | undefined",
      "required": false,
      "origin": "own",
      "description": "Input's sizes: Small, Medium, Large.",
      "values": [
        "sm",
        "md",
        "lg"
      ],
      "default": "md"
    },
    "autoComplete": {
      "type": "\"off\" | \"current-password\" | \"new-password\" | undefined",
      "required": false,
      "origin": "own",
      "description": "Default `current-password`. Pass `new-password` on a sign-up or change\nform, so a password manager offers to generate one instead of filling\nthe old.",
      "values": [
        "off",
        "current-password",
        "new-password"
      ],
      "default": "current-password"
    },
    "isRevealed": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "Controlled: whether the password is shown."
    },
    "defaultRevealed": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "Uncontrolled: whether it starts shown. Default false.",
      "default": false
    },
    "onRevealedChange": {
      "type": "((isRevealed: boolean) => void) | undefined",
      "required": false,
      "origin": "own"
    },
    "revealLabel": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "The toggle's name. It does not change with the state — `aria-pressed`\nsays whether it is on. Default \"Show password\".",
      "default": "Show password"
    },
    "shownMessage": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "Announced when the password is shown. Default \"Password shown\".",
      "default": "Password shown"
    },
    "hiddenMessage": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "Announced when it is hidden again. Default \"Password hidden\".",
      "default": "Password hidden"
    },
    "className": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "Class names for the control box (`.ion-input`)."
    },
    "wrapperClassName": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "Class names for the `.ion-field` wrapper when a label or helper is shown."
    },
    "onChange": {
      "type": "((value: string) => void) | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the value changes."
    },
    "defaultValue": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "The default value (uncontrolled)."
    },
    "autoFocus": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "aria",
      "description": "Whether the element should receive focus on render."
    },
    "enterKeyHint": {
      "type": "\"done\" | \"enter\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
      "required": false,
      "origin": "aria",
      "description": "An enumerated attribute that defines what action label or icon to preset for the enter key on\nvirtual keyboards. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/enterkeyhint).",
      "values": [
        "done",
        "enter",
        "go",
        "next",
        "previous",
        "search",
        "send"
      ]
    },
    "id": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "The element's unique identifier. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id)."
    },
    "spellCheck": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "An enumerated attribute that defines whether the element may be checked for spelling errors.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck)."
    },
    "autoCorrect": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "An attribute that takes as its value a space-separated string that describes what, if any, type\nof autocomplete functionality the input should provide. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autocomplete)."
    },
    "inputMode": {
      "type": "\"none\" | \"search\" | \"text\" | \"url\" | \"tel\" | \"email\" | \"numeric\" | \"decimal\" | undefined",
      "required": false,
      "origin": "aria",
      "description": "Hints at the type of data that might be entered by the user while editing the element or its\ncontents. See\n[MDN](https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute).",
      "values": [
        "none",
        "search",
        "text",
        "url",
        "tel",
        "email",
        "numeric",
        "decimal"
      ]
    },
    "aria-activedescendant": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Identifies the currently active element when DOM focus is on a composite widget, textbox,\ngroup, or application."
    },
    "aria-autocomplete": {
      "type": "\"inline\" | \"list\" | \"none\" | \"both\" | undefined",
      "required": false,
      "origin": "aria",
      "description": "Indicates whether inputting text could trigger display of one or more predictions of the user's\nintended value for an input and specifies how predictions would be presented if they are made.",
      "values": [
        "inline",
        "list",
        "none",
        "both"
      ]
    },
    "aria-controls": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Identifies the element (or elements) whose contents or presence are controlled by the current\nelement."
    },
    "aria-describedby": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Identifies the element (or elements) that describes the object."
    },
    "aria-details": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Identifies the element (or elements) that provide a detailed, extended description for the\nobject."
    },
    "aria-errormessage": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Identifies the element that provides an error message for the object."
    },
    "aria-haspopup": {
      "type": "boolean | \"true\" | \"false\" | \"menu\" | \"listbox\" | \"tree\" | \"grid\" | \"dialog\" | undefined",
      "required": false,
      "origin": "aria",
      "description": "Indicates the availability and type of interactive popup element, such as menu or dialog, that\ncan be triggered by an element."
    },
    "aria-label": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Defines a string value that labels the current element."
    },
    "aria-labelledby": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Identifies the element (or elements) that labels the current element."
    },
    "onCopy": {
      "type": "ClipboardEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the user copies text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncopy)."
    },
    "onCut": {
      "type": "ClipboardEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the user cuts text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/oncut)."
    },
    "onPaste": {
      "type": "ClipboardEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the user pastes text. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/onpaste)."
    },
    "onCompositionEnd": {
      "type": "CompositionEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when a text composition system completes or cancels the current text\ncomposition session. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionend_event)."
    },
    "onCompositionStart": {
      "type": "CompositionEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when a text composition system starts a new text composition session.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event)."
    },
    "onCompositionUpdate": {
      "type": "CompositionEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when a new character is received in the current text composition\nsession. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionupdate_event)."
    },
    "onFocus": {
      "type": "((e: FocusEvent<HTMLInputElement, Element>) => void) | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the element receives focus."
    },
    "onBlur": {
      "type": "((e: FocusEvent<HTMLInputElement, Element>) => void) | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the element loses focus."
    },
    "onBeforeInput": {
      "type": "FormEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the input value is about to be modified. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event)."
    },
    "onInput": {
      "type": "FormEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the input value is modified. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event)."
    },
    "onKeyDown": {
      "type": "((e: KeyboardEvent) => void) | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when a key is pressed."
    },
    "onKeyUp": {
      "type": "((e: KeyboardEvent) => void) | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when a key is released."
    },
    "onSelect": {
      "type": "ReactEventHandler<HTMLInputElement> | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when text in the input is selected. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/select_event)."
    },
    "form": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "The `<form>` element to associate the input with.\nThe value of this attribute must be the id of a `<form>` in the same document.\nSee [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#form)."
    },
    "name": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "The name of the input element, used when submitting an HTML form. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname)."
    },
    "value": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "The current value (controlled)."
    },
    "maxLength": {
      "type": "number | undefined",
      "required": false,
      "origin": "aria",
      "description": "The maximum number of characters supported by the input. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefmaxlength)."
    },
    "minLength": {
      "type": "number | undefined",
      "required": false,
      "origin": "aria",
      "description": "The minimum number of characters required by the input. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefminlength)."
    },
    "pattern": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Regex pattern that the value of the input must match to be valid. See\n[MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefpattern)."
    },
    "placeholder": {
      "type": "string | undefined",
      "required": false,
      "origin": "aria",
      "description": "Temporary text that occupies the text input when it is empty."
    },
    "isDisabled": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "aria",
      "description": "Whether the input is disabled."
    },
    "isReadOnly": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "aria",
      "description": "Whether the input can be selected but not changed by the user."
    },
    "isRequired": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "aria",
      "description": "Whether user input is required on the input before form submission."
    },
    "isInvalid": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "aria",
      "description": "Whether the input value is invalid."
    },
    "validationState": {
      "type": "ValidationState | undefined",
      "required": false,
      "origin": "aria",
      "values": [
        "valid",
        "invalid"
      ],
      "tags": {
        "deprecated": "Use `isInvalid` instead."
      }
    },
    "validationBehavior": {
      "type": "\"aria\" | \"native\" | undefined",
      "required": false,
      "origin": "aria",
      "description": "Whether to use native HTML form validation to prevent form submission\nwhen the value is missing or invalid, or mark the field as required\nor invalid via ARIA.",
      "values": [
        "aria",
        "native"
      ],
      "tags": {
        "default": "'aria'"
      }
    },
    "validate": {
      "type": "((value: string) => ValidationError | true | null | undefined) | undefined",
      "required": false,
      "origin": "aria",
      "description": "A function that returns an error message if a given value is invalid.\nValidation errors are displayed to the user when the form is submitted\nif `validationBehavior=\"native\"`. For realtime validation, use the `isInvalid`\nprop instead."
    },
    "description": {
      "type": "ReactNode",
      "required": false,
      "origin": "aria",
      "description": "A description for the field. Provides a hint such as specific requirements for what to choose."
    },
    "errorMessage": {
      "type": "ReactNode | ((v: ValidationResult) => ReactNode)",
      "required": false,
      "origin": "aria",
      "description": "An error message for the field."
    },
    "onFocusChange": {
      "type": "((isFocused: boolean) => void) | undefined",
      "required": false,
      "origin": "aria",
      "description": "Handler that is called when the element's focus status changes."
    },
    "label": {
      "type": "ReactNode",
      "required": false,
      "origin": "aria",
      "description": "The content to display as the label."
    },
    "excludeFromTabOrder": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "aria",
      "description": "Whether to exclude the element from the sequential tab order. If true,\nthe element will not be focusable via the keyboard by tabbing. This should\nbe avoided except in rare scenarios where an alternative means of accessing\nthe element or its functionality via the keyboard is available."
    }
  },
  "propCounts": {
    "own": 10,
    "aria": 49,
    "dom": 265,
    "other": 0
  }
}
