This commit is contained in:
2024-06-01 16:51:52 +02:00
parent 4f96c7fef1
commit f5ab7e8281
2 changed files with 42 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
import { ComponentPropsWithoutRef, FC } from 'react' import { ComponentPropsWithoutRef } from 'react'
import { Check } from '@/assets/icons' import { Check } from '@/assets/icons'
import { Typography } from '@/components' import { Typography } from '@/components'
@@ -13,13 +13,13 @@ export type CheckboxProps = {
position?: 'default' | 'left' position?: 'default' | 'left'
} & ComponentPropsWithoutRef<typeof CheckboxRadix.Root> } & ComponentPropsWithoutRef<typeof CheckboxRadix.Root>
export const Checkbox: FC<CheckboxProps> = ({ export const Checkbox = ({
className, className,
disabled, disabled,
label, label,
position = 'default', position = 'default',
...rest ...rest
}) => { }: CheckboxProps) => {
const classNames = { const classNames = {
buttonWrapper: clsx(s.buttonWrapper, disabled && s.disabled, position === 'left' && s.left), buttonWrapper: clsx(s.buttonWrapper, disabled && s.disabled, position === 'left' && s.left),
container: clsx(s.container, className), container: clsx(s.container, className),

View File

@@ -1,4 +1,12 @@
import { ChangeEvent, ComponentProps, ComponentPropsWithoutRef, forwardRef, useState } from 'react' import {
ChangeEvent,
ComponentProps,
ComponentPropsWithoutRef,
forwardRef,
memo,
useCallback,
useState,
} from 'react'
import { Eye, VisibilityOff } from '@/assets' import { Eye, VisibilityOff } from '@/assets'
import { Typography } from '@/components' import { Typography } from '@/components'
@@ -14,7 +22,7 @@ export type TextFieldProps = {
onValueChange?: (value: string) => void onValueChange?: (value: string) => void
} & ComponentPropsWithoutRef<'input'> } & ComponentPropsWithoutRef<'input'>
export const TextField = forwardRef<HTMLInputElement, TextFieldProps>( const RawTextField = forwardRef<HTMLInputElement, TextFieldProps>(
( (
{ {
className, className,
@@ -30,25 +38,32 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
}, },
ref ref
) => { ) => {
const [showPassword, setShowPassword] = useState(false) const [revealPassword, setRevealPassword] = useState(false)
const isShowPasswordButtonShown = type === 'password' const isRevealPasswordButtonShown = type === 'password'
const finalType = getFinalType(type, showPassword) const finalType = getFinalType(type, revealPassword)
function handleChange(e: ChangeEvent<HTMLInputElement>) {
onChange?.(e)
onValueChange?.(e.target.value)
}
const classNames = { const classNames = {
error: clsx(s.error), error: clsx(s.error),
field: clsx(s.field, !!errorMessage && s.error, className), field: clsx(s.field, errorMessage && s.error, className),
fieldContainer: clsx(s.fieldContainer), fieldContainer: clsx(s.fieldContainer),
label: clsx(s.label, labelProps?.className), label: clsx(s.label, labelProps?.className),
root: clsx(s.root, containerProps?.className), root: clsx(s.root, containerProps?.className),
} }
const handleChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
onChange?.(e)
onValueChange?.(e.target.value)
},
[onChange, onValueChange]
)
const handleShowPasswordClick = useCallback(() => {
setRevealPassword(prev => !prev)
}, [])
return ( return (
<div className={classNames.root}> <div className={classNames.root}>
{label && ( {label && (
@@ -56,6 +71,7 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
{label} {label}
</Typography> </Typography>
)} )}
<div className={classNames.fieldContainer}> <div className={classNames.fieldContainer}>
<input <input
className={classNames.field} className={classNames.field}
@@ -65,20 +81,18 @@ export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
type={finalType} type={finalType}
{...restProps} {...restProps}
/> />
{isShowPasswordButtonShown && ( {isRevealPasswordButtonShown && (
<button <button className={s.showPassword} onClick={handleShowPasswordClick} type={'button'}>
className={s.showPassword} {revealPassword ? <VisibilityOff /> : <Eye />}
onClick={() => setShowPassword(prev => !prev)}
type={'button'}
>
{showPassword ? <VisibilityOff /> : <Eye />}
</button> </button>
)} )}
</div> </div>
<Typography className={classNames.error} variant={'error'}> {errorMessage && (
{errorMessage} <Typography className={classNames.error} variant={'error'}>
</Typography> {errorMessage}
</Typography>
)}
</div> </div>
) )
} }
@@ -91,3 +105,7 @@ function getFinalType(type: ComponentProps<'input'>['type'], showPassword: boole
return type return type
} }
export const TextField = memo(RawTextField)
TextField.displayName = 'TextField'