feat: Cập nhật giao diện các trang xác thực với nền vũ trụ và hiệu ứng kínhmorphism, cải thiện trải nghiệm người dùng và thêm chức năng hiển thị mật khẩu cho trường nhập liệu.
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
TextField as AriaTextField,
|
||||
Label,
|
||||
@@ -24,6 +24,8 @@ import {
|
||||
type TextFieldProps as AriaTextFieldProps,
|
||||
} from 'react-aria-components';
|
||||
import { cn } from '@/shared/utils';
|
||||
import { Eye, EyeOff } from 'lucide-react';
|
||||
import { Button } from '../button/button';
|
||||
|
||||
export interface InputProps extends Omit<AriaTextFieldProps, 'children'> {
|
||||
/**
|
||||
@@ -130,6 +132,35 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
// EN: Internal state for password visibility
|
||||
// VI: State nội bộ cho việc hiển thị mật khẩu
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
// EN: Determine the actual input type
|
||||
// VI: Xác định type thực tế của input
|
||||
const inputType = type === 'password' && showPassword ? 'text' : type;
|
||||
|
||||
// EN: Determine the right element for password toggle
|
||||
// VI: Xác định element bên phải cho nút gạt mật khẩu
|
||||
const finalRightElement =
|
||||
type === 'password' ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-8 w-8 p-0 hover:bg-white/10 text-text-tertiary"
|
||||
onPress={() => setShowPassword(!showPassword)}
|
||||
aria-label={showPassword ? 'Hide password' : 'Show password'}
|
||||
>
|
||||
{showPassword ? (
|
||||
<EyeOff className="h-4 w-4" />
|
||||
) : (
|
||||
<Eye className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
) : (
|
||||
rightElement
|
||||
);
|
||||
|
||||
return (
|
||||
<AriaTextField
|
||||
className={cn('group flex flex-col gap-1.5', className)}
|
||||
@@ -160,7 +191,7 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
|
||||
<AriaInput
|
||||
ref={ref}
|
||||
type={type}
|
||||
type={inputType}
|
||||
placeholder={placeholder}
|
||||
className={cn(
|
||||
// Base glass input styles
|
||||
@@ -185,15 +216,15 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
leftElement && 'pl-10',
|
||||
|
||||
// Right element padding
|
||||
rightElement && 'pr-10',
|
||||
finalRightElement && 'pr-10',
|
||||
|
||||
inputClassName
|
||||
)}
|
||||
/>
|
||||
|
||||
{rightElement && (
|
||||
{finalRightElement && (
|
||||
<div className="absolute right-3 flex items-center text-text-tertiary">
|
||||
{rightElement}
|
||||
{finalRightElement}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user