Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/components/auth/__tests__/password-input.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { renderToStaticMarkup } from "react-dom/server"
import { describe, expect, it, vi } from "vitest"

import { PasswordInput } from "../password-input"

describe("PasswordInput", () => {
it("renders the auth toggle without finance button metadata", () => {
const markup = renderToStaticMarkup(
<PasswordInput id="sign-in-password" value="" onChange={vi.fn()} />
)

expect(markup).toContain('aria-label="Show password"')
expect(markup).toContain('type="button"')
expect(markup).not.toContain('data-variant="ghost"')
expect(markup).not.toContain('data-size="sm"')
expect(markup).not.toContain("active:not-aria-[haspopup]:translate-y-px")
})
})
15 changes: 8 additions & 7 deletions src/components/auth/password-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { type ComponentProps, useState } from "react"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { cn } from "@/lib/utils"

Expand All @@ -18,6 +17,7 @@ export function PasswordInput({
...props
}: PasswordInputProps) {
const [isVisible, setIsVisible] = useState(false)
const toggleLabel = `${isVisible ? "Hide" : "Show"} ${revealLabel}`

return (
<div className="relative">
Expand All @@ -28,21 +28,22 @@ export function PasswordInput({
type={isVisible ? "text" : "password"}
className={cn("pr-14", className)}
/>
<Button
<button
type="button"
variant="ghost"
size="sm"
disabled={disabled}
aria-controls={id}
aria-label={`${isVisible ? "Hide" : "Show"} ${revealLabel}`}
aria-label={toggleLabel}
aria-pressed={isVisible}
className="absolute top-1/2 right-1 h-7 -translate-y-1/2 px-2 text-[11px] text-muted-foreground hover:bg-transparent hover:text-foreground"
className={cn(
"group/button inline-flex shrink-0 cursor-pointer items-center justify-center rounded-none border border-transparent bg-clip-padding text-xs font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
"absolute top-1/2 right-1 h-7 -translate-y-1/2 gap-1 px-2 text-[11px] text-muted-foreground hover:bg-transparent"
)}
onClick={() => {
setIsVisible((currentValue) => !currentValue)
}}
>
{isVisible ? "Hide" : "Show"}
</Button>
</button>
</div>
)
}
Loading