Browse Source

feat: add password-input custom component

satnaing 2 years ago
parent
commit
4f2d63215d

+ 38 - 0
src/components/password-input.tsx

@@ -0,0 +1,38 @@
+import * as React from 'react'
+import { cn } from '@/lib/utils'
+import { Button } from './ui/button'
+import { IconEye, IconEyeOff } from '@tabler/icons-react'
+
+export interface PasswordInputProps
+  extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {}
+
+const PasswordInput = React.forwardRef<HTMLInputElement, PasswordInputProps>(
+  ({ className, ...props }, ref) => {
+    const [showPassword, setShowPassword] = React.useState(false)
+    return (
+      <div className='relative rounded-md'>
+        <input
+          type={showPassword ? 'text' : 'password'}
+          className={cn(
+            'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
+            className
+          )}
+          ref={ref}
+          {...props}
+        />
+        <Button
+          type='button'
+          size='icon'
+          variant='ghost'
+          className='absolute right-1 top-1/2 h-6 w-6 -translate-y-1/2 rounded-md text-muted-foreground'
+          onClick={() => setShowPassword((prev) => !prev)}
+        >
+          {showPassword ? <IconEye size={18} /> : <IconEyeOff size={18} />}
+        </Button>
+      </div>
+    )
+  }
+)
+PasswordInput.displayName = 'PasswordInput'
+
+export { PasswordInput }

+ 3 - 2
src/pages/auth/components/sign-up-form.tsx

@@ -18,6 +18,7 @@ import {
   IconBrandGithub,
   IconLoader2,
 } from '@tabler/icons-react'
+import { PasswordInput } from '@/components/password-input'
 
 interface SignUpFormProps extends HTMLAttributes<HTMLDivElement> {}
 
@@ -88,7 +89,7 @@ export function SignUpForm({ className, ...props }: SignUpFormProps) {
                 <FormItem className='space-y-1'>
                   <FormLabel>Password</FormLabel>
                   <FormControl>
-                    <Input placeholder='********' {...field} type='password' />
+                    <PasswordInput placeholder='********' {...field} />
                   </FormControl>
                   <FormMessage />
                 </FormItem>
@@ -101,7 +102,7 @@ export function SignUpForm({ className, ...props }: SignUpFormProps) {
                 <FormItem className='space-y-1'>
                   <FormLabel>Confirm Password</FormLabel>
                   <FormControl>
-                    <Input placeholder='********' {...field} type='password' />
+                    <PasswordInput placeholder='********' {...field} />
                   </FormControl>
                   <FormMessage />
                 </FormItem>

+ 11 - 10
src/pages/auth/components/user-auth-form.tsx

@@ -1,9 +1,13 @@
 import { HTMLAttributes, useState } from 'react'
-import { cn } from '@/lib/utils'
-import { zodResolver } from '@hookform/resolvers/zod'
 import { useForm } from 'react-hook-form'
+import { Link } from 'react-router-dom'
 import { z } from 'zod'
-import { Button } from '@/components/ui/button'
+import { zodResolver } from '@hookform/resolvers/zod'
+import {
+  IconBrandFacebook,
+  IconBrandGithub,
+  IconLoader2,
+} from '@tabler/icons-react'
 import {
   Form,
   FormControl,
@@ -12,13 +16,10 @@ import {
   FormLabel,
   FormMessage,
 } from '@/components/ui/form'
+import { Button } from '@/components/ui/button'
 import { Input } from '@/components/ui/input'
-import { Link } from 'react-router-dom'
-import {
-  IconBrandFacebook,
-  IconBrandGithub,
-  IconLoader2,
-} from '@tabler/icons-react'
+import { PasswordInput } from '@/components/password-input'
+import { cn } from '@/lib/utils'
 
 interface UserAuthFormProps extends HTMLAttributes<HTMLDivElement> {}
 
@@ -90,7 +91,7 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
                     </Link>
                   </div>
                   <FormControl>
-                    <Input placeholder='********' {...field} type='password' />
+                    <PasswordInput placeholder='********' {...field} />
                   </FormControl>
                   <FormMessage />
                 </FormItem>