{"slug":"password-input","title":"Password Input","description":"Used to request or confirm a password from users.","contentType":"component","framework":"svelte","content":"## Resources\n\n\n[Latest version: v1.39.1](https://www.npmjs.com/package/@zag-js/password-input)\n[Logic Visualizer](https://zag-visualizer.vercel.app/password-input)\n[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/password-input)\n\n\n\n**Features**\n\n- Includes button to toggle visibility of the password\n- Automatic focus restoration to the input\n- Resets visibility to hidden after form submission\n- Can ignore supported password managers\n\n## Installation\n\nInstall the password-input package:\n\n```bash\nnpm install @zag-js/password-input @zag-js/svelte\n# or\nyarn add @zag-js/password-input @zag-js/svelte\n```\n\n## Anatomy\n\nCheck the password-input anatomy and part names.\n\n> Each part includes a `data-part` attribute to help identify them in the DOM.\n\n\n\n## Usage\n\nImport the password-input package:\n\n```tsx\nimport * as passwordInput from \"@zag-js/password-input\"\n```\n\nThe password-input package exports two key functions:\n\n- `machine` - State machine logic.\n- `connect` - Maps machine state to JSX props and event handlers.\n\n> Pass a unique `id` to `useMachine` so generated element ids stay predictable.\n\nThen use the framework integration helpers:\n\n```svelte\n<script lang=\"ts\">\n  import * as passwordInput from \"@zag-js/password-input\"\n  import { normalizeProps, useMachine } from \"@zag-js/svelte\"\n  import { EyeIcon, EyeOffIcon } from \"lucide-svelte\"\n\n  const id = $props.id()\n  const service = useMachine(passwordInput.machine, { id })\n\n  const api = $derived(passwordInput.connect(service, normalizeProps))\n</script>\n\n<div {...api.getRootProps()}>\n  <label {...api.getLabelProps()}>Password</label>\n  <div {...api.getControlProps()}>\n    <input {...api.getInputProps()} />\n    <button {...api.getVisibilityTriggerProps()}>\n      <span {...api.getIndicatorProps()}>\n        {#if api.visible}\n          <EyeIcon />\n        {:else}\n          <EyeOffIcon />\n        {/if}\n      </span>\n    </button>\n  </div>\n</div>\n```\n\n### Setting the initial visibility\n\nSet `defaultVisible` to define the initial visibility.\n\n```tsx {3}\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  defaultVisible: true,\n})\n```\n\n### Controlling the visibility\n\nUse `visible` and `onVisibilityChange` to control visibility externally.\n\n```tsx {3-5}\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  visible: true,\n  onVisibilityChange(details) {\n    // details => { visible: boolean }\n    console.log(details.visible)\n  },\n})\n```\n\n### Ignoring password managers\n\nSet `ignorePasswordManagers` to `true` to ignore supported password managers.\n\nThis is useful when you want to ensure that the password input is not managed by\npassword managers. **Currently, this only works for 1Password, LastPass,\nBitwarden, Dashlane, and Proton Pass.**\n\n```tsx {3}\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  ignorePasswordManagers: true,\n})\n```\n\n**Why is this useful?**\n\n- You might want to use this primitive for non-login scenarios (e.g., \"secure\n  notes\", \"temporary passwords\")\n\n- In a verify password step, you might want to disable password managers for the\n  confirm password field to ensure manual entry\n\n- Building a security-sensitive app where password managers violate compliance\n  requirements.\n\n### Managing autocompletion\n\nSet `autoComplete` to control password autofill behavior.\n\n- `new-password` — The user is creating a new password.\n- `current-password` — The user is entering an existing password.\n\n```tsx {3}\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  autoComplete: \"new-password\",\n})\n```\n\n### Making the input required\n\nSet `required` to `true` to make the input required.\n\n```tsx {3}\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  required: true,\n})\n```\n\n### Making the input read only\n\nSet `readOnly` to `true` to make the input read only.\n\n```tsx {3}\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  readOnly: true,\n})\n```\n\n### Setting the input name\n\nSet `name` to include the password field in form submission.\n\n```tsx\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  name: \"password\",\n})\n```\n\n### Customizing accessibility labels\n\nUse `translations.visibilityTrigger` to customize the toggle button label.\n\n```tsx\nconst service = useMachine(passwordInput.machine, {\n  id: useId(),\n  translations: {\n    visibilityTrigger: (visible) =>\n      visible ? \"Hide password\" : \"Show password\",\n  },\n})\n```\n\n## Styling guide\n\nEach part includes a `data-part` attribute you can target in CSS.\n\n```css\n[data-scope=\"password-input\"][data-part=\"root\"] {\n  /* styles for the root part */\n}\n\n[data-scope=\"password-input\"][data-part=\"input\"] {\n  /* styles for the input part */\n}\n\n[data-scope=\"password-input\"][data-part=\"visibility-trigger\"] {\n  /* styles for the visibility trigger part */\n}\n\n[data-scope=\"password-input\"][data-part=\"indicator\"] {\n  /* styles for the indicator part */\n}\n\n[data-scope=\"password-input\"][data-part=\"control\"] {\n  /* styles for the control part */\n}\n\n[data-scope=\"password-input\"][data-part=\"label\"] {\n  /* styles for the label part */\n}\n```\n\n### Visibility State\n\nUse the `[data-state=\"visible\"]` and `[data-state=\"hidden\"]` attributes to style\nthe password input when it is visible or hidden.\n\n```css\n[data-scope=\"password-input\"][data-part=\"input\"][data-state=\"visible\"] {\n  /* styles for the visible state (for input) */\n}\n\n[data-scope=\"password-input\"][data-part=\"visibility-trigger\"][data-state=\"visible\"] {\n  /* styles for the visible state (for visibility trigger) */\n}\n```\n\n### Disabled State\n\nUse the `[data-disabled]` attribute to style the password input when it is\ndisabled.\n\n```css\n[data-scope=\"password-input\"][data-part=\"input\"][data-disabled] {\n  /* styles for the disabled state */\n}\n```\n\n### Invalid State\n\nUse the `[data-invalid]` attribute to style the password input when it is\ninvalid.\n\n```css\n[data-scope=\"password-input\"][data-part=\"input\"][data-invalid] {\n  /* styles for the invalid state */\n}\n```\n\n### Readonly State\n\nUse the `[data-readonly]` attribute to style the password input when it is read\nonly.\n\n```css\n[data-scope=\"password-input\"][data-part=\"input\"][data-readonly] {\n  /* styles for the readonly state */\n}\n```\n\n## Methods and Properties\n\n### Machine Context\n\nThe password-input machine exposes the following context properties:\n\n**`defaultVisible`**\nType: `boolean`\nDescription: The default visibility of the password input.\n\n**`visible`**\nType: `boolean`\nDescription: Whether the password input is visible.\n\n**`onVisibilityChange`**\nType: `(details: VisibilityChangeDetails) => void`\nDescription: Function called when the visibility changes.\n\n**`ids`**\nType: `Partial<{ input: string; visibilityTrigger: string; }>`\nDescription: The ids of the password input parts\n\n**`disabled`**\nType: `boolean`\nDescription: Whether the password input is disabled.\n\n**`invalid`**\nType: `boolean`\nDescription: The invalid state of the password input.\n\n**`readOnly`**\nType: `boolean`\nDescription: Whether the password input is read only.\n\n**`required`**\nType: `boolean`\nDescription: Whether the password input is required.\n\n**`translations`**\nType: `Partial<{ visibilityTrigger: (visible: boolean) => string; }>`\nDescription: The localized messages to use.\n\n**`ignorePasswordManagers`**\nType: `boolean`\nDescription: When `true`, the input will ignore password managers.\n\n**Only works for the following password managers**\n- 1Password, LastPass, Bitwarden, Dashlane, Proton Pass\n\n**`autoComplete`**\nType: `\"current-password\" | \"new-password\"`\nDescription: The autocomplete attribute for the password input.\n\n**`name`**\nType: `string`\nDescription: The name of the password input.\n\n**`dir`**\nType: `\"ltr\" | \"rtl\"`\nDescription: The document's text/writing direction.\n\n**`id`**\nType: `string`\nDescription: The unique identifier of the machine.\n\n**`getRootNode`**\nType: `() => ShadowRoot | Node | Document`\nDescription: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.\n\n### Machine API\n\nThe password-input `api` exposes the following methods:\n\n**`visible`**\nType: `boolean`\nDescription: Whether the password input is visible.\n\n**`disabled`**\nType: `boolean`\nDescription: Whether the password input is disabled.\n\n**`invalid`**\nType: `boolean`\nDescription: Whether the password input is invalid.\n\n**`focus`**\nType: `VoidFunction`\nDescription: Focus the password input.\n\n**`setVisible`**\nType: `(value: boolean) => void`\nDescription: Set the visibility of the password input.\n\n**`toggleVisible`**\nType: `VoidFunction`\nDescription: Toggle the visibility of the password input.","package":"@zag-js/password-input","editUrl":"https://github.com/chakra-ui/zag/edit/main/website/data/components/password-input.mdx"}