shadcn.io is not affiliated with official shadcn/ui
Shadcn Password Input for React and Tailwind
A field for entering secure text.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/password-input.jsonpnpm dlx shadcn@latest add https://kit.dev/r/password-input.jsonnpx shadcn@latest add https://kit.dev/r/password-input.jsonyarn shadcn@latest add https://kit.dev/r/password-input.jsonThis component depends on Input Group. Install it first if you haven't already.
Install the following dependencies:
bun add @ark-ui/react lucide-reactpnpm add @ark-ui/react lucide-reactnpm install @ark-ui/react lucide-reactyarn add @ark-ui/react lucide-reactCopy and paste the following code into your project.
"use client";
import {
PasswordInput as ArkPasswordInput,
usePasswordInputContext,
} from "@ark-ui/react/password-input";
import { EyeIcon, EyeOffIcon } from "lucide-react";
import type React from "react";
import { cn } from "@/lib/utils";
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
type InputGroupProps,
} from "@/components/ui/input-group";
export const usePasswordInput = usePasswordInputContext;
interface PasswordInputProps
extends React.ComponentProps<typeof ArkPasswordInput.Root>,
Pick<InputGroupProps, "size"> {}
export const PasswordInput = (props: PasswordInputProps) => {
const { size = "md", className, ...rest } = props;
return (
<ArkPasswordInput.Root
className={cn(
"group/password-input",
"w-full",
"flex flex-col items-start gap-2",
className
)}
data-size={size}
data-slot="password-input"
{...rest}
/>
);
};
export const PasswordInputGroup = (
props: React.ComponentProps<typeof ArkPasswordInput.Control>
) => {
const { className, ...rest } = props;
return (
<ArkPasswordInput.Control asChild data-slot="password-input-control">
<InputGroup
className={cn(
"in-data-[size=lg]:h-9 in-data-[size=sm]:h-7",
"data-disabled:pointer-events-none data-disabled:opacity-64",
className
)}
{...rest}
/>
</ArkPasswordInput.Control>
);
};
export const PasswordInputInput = (
props: React.ComponentProps<typeof ArkPasswordInput.Input>
) => (
<ArkPasswordInput.Input asChild data-slot="password-input-input" {...props}>
<InputGroupInput />
</ArkPasswordInput.Input>
);
export const PasswordInputTrigger = (
props: React.ComponentProps<typeof ArkPasswordInput.VisibilityTrigger>
) => {
const { children, ...rest } = props;
return (
<InputGroupAddon align="inline-end">
<ArkPasswordInput.VisibilityTrigger
asChild
data-slot="password-input-visibility-trigger"
>
<InputGroupButton size="icon-xs" variant="ghost" {...rest}>
{children ?? <PasswordInputIndicator />}
</InputGroupButton>
</ArkPasswordInput.VisibilityTrigger>
</InputGroupAddon>
);
};
export const PasswordInputIndicator = (
props: React.ComponentProps<typeof ArkPasswordInput.Indicator>
) => {
const { children, ...rest } = props;
return (
<ArkPasswordInput.Indicator
data-slot="password-input-indicator"
fallback={<EyeOffIcon />}
{...rest}
>
{children ?? <EyeIcon />}
</ArkPasswordInput.Indicator>
);
};Update the import paths to match your project setup.
Anatomy
PasswordInput
├── PasswordInputInput
├── PasswordInputLabel
├── PasswordInputGroup
├── PasswordInputIndicator
└── PasswordInputTriggerUsage
import {
PasswordInput,
PasswordInputGroup,
PasswordInputInput,
PasswordInputTrigger,
} from "@/components/ui/password-input";<PasswordInput className="w-full max-w-64">
<PasswordInputGroup>
<PasswordInputInput placeholder="Enter password" />
<PasswordInputTrigger />
</PasswordInputGroup>
</PasswordInput>Accessibility
| Key | Description |
|---|---|
Enter | Activate the focused control. |
Space | Activate the focused control. |
Demos
Auto Hide
Autocomplete
Controlled
Controlled Visibility
Custom Indicator
Disabled
Field
Invalid
Size Lg
Size Md
Size Sm
API Reference
PasswordInput
div
PropType
AttributeType
PasswordInputInput
input
PropType
AttributeType
PasswordInputGroup
div
PropType
AttributeType
PasswordInputIndicator
span
PropType
AttributeType
PasswordInputTrigger
button
PropType
AttributeType