diff --git a/package.json b/package.json index 161a466..2beb240 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@schemavaults/ui", - "version": "0.14.3", + "version": "0.14.4", "private": false, "license": "UNLICENSED", "description": "React.js UI components for SchemaVaults frontend applications", diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts index 2da7daa..348df23 100644 --- a/src/components/ui/index.ts +++ b/src/components/ui/index.ts @@ -16,6 +16,9 @@ export type * from "./button"; export * from "./input"; export type * from "./input"; +export * from "./password-input"; +export type * from "./password-input"; + export * from "./file-input"; export type * from "./file-input"; diff --git a/src/components/ui/password-input/PasswordInput.stories.tsx b/src/components/ui/password-input/PasswordInput.stories.tsx new file mode 100644 index 0000000..0e05548 --- /dev/null +++ b/src/components/ui/password-input/PasswordInput.stories.tsx @@ -0,0 +1,47 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { fn } from "@storybook/test"; + +import PasswordInput from "./password-input"; + +const meta = { + title: "Components/PasswordInput", + component: PasswordInput, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], + argTypes: { + placeholder: { + type: "string", + control: { + type: "text", + }, + description: "Placeholder text for the password input", + }, + }, + args: { + onChange: (): void => { + fn(); + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; + +export const WithPlaceholder: Story = { + args: { + placeholder: "Enter your password", + }, +}; + +export const Disabled: Story = { + args: { + placeholder: "Disabled password input", + disabled: true, + }, +}; diff --git a/src/components/ui/password-input/index.ts b/src/components/ui/password-input/index.ts new file mode 100644 index 0000000..01c47fe --- /dev/null +++ b/src/components/ui/password-input/index.ts @@ -0,0 +1,3 @@ +export * from "./password-input"; +export type * from "./password-input"; +export { PasswordInput as default } from "./password-input"; diff --git a/src/components/ui/password-input/password-input.tsx b/src/components/ui/password-input/password-input.tsx new file mode 100644 index 0000000..a633e08 --- /dev/null +++ b/src/components/ui/password-input/password-input.tsx @@ -0,0 +1,43 @@ +"use client"; + +import { useState, type ReactElement } from "react"; +import { Eye, EyeOff, KeyRound } from "lucide-react"; + +import { Input, type InputProps } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; + +export interface PasswordInputProps + extends Omit {} + +const PasswordInput = ({ + ...props +}: PasswordInputProps): ReactElement => { + const [visible, setVisible] = useState(false); + + const ToggleIcon = visible ? EyeOff : Eye; + + return ( + setVisible((prev) => !prev)} + aria-label={visible ? "Hide password" : "Show password"} + > + + + } + {...props} + /> + ); +}; +PasswordInput.displayName = "PasswordInput"; + +export { PasswordInput }; + +export default PasswordInput;