mirror of
https://github.com/ershisan99/flashcards-example-project.git
synced 2025-12-18 05:09:23 +00:00
refactor
This commit is contained in:
@@ -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),
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
Reference in New Issue
Block a user