refactor: refactor controlled components

This commit is contained in:
jinhojang6 2023-03-21 20:58:32 +09:00 committed by Jon
parent 9e6ef7bd8b
commit 03052f4004
2 changed files with 29 additions and 11 deletions

View File

@ -11,13 +11,13 @@ import { Month } from './Month'
import { useClickAway } from 'react-use' import { useClickAway } from 'react-use'
export type CalendarProps = Omit< export type CalendarProps = Omit<
React.HTMLAttributes<HTMLUListElement>, React.HTMLAttributes<HTMLDivElement>,
'label' 'label'
> & { > & {
open?: boolean open?: boolean
disabled?: boolean disabled?: boolean
value?: string value?: string
handleDateFieldChange: (data: Date) => void onChange: (data: Date) => void
handleRef: React.RefObject<HTMLElement> handleRef: React.RefObject<HTMLElement>
size?: 'large' | 'medium' size?: 'large' | 'medium'
onClose?: () => void onClose?: () => void
@ -28,16 +28,19 @@ export const Calendar: React.FC<CalendarProps> & {
} = ({ } = ({
open, open,
handleRef, handleRef,
value = null, value: _value,
size = 'large', size = 'large',
disabled = false, disabled = false,
handleDateFieldChange, onChange,
onClose, onClose,
children, children,
...props ...props
}) => { }) => {
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
const [style, setStyle] = useState<React.CSSProperties>({}) const [style, setStyle] = useState<React.CSSProperties>({})
const [value, setValue] = useState<Date | null>(
_value ? new Date(_value) : null,
)
useClickAway(ref, (event) => { useClickAway(ref, (event) => {
if (!open || event.composedPath().includes(handleRef.current!)) return if (!open || event.composedPath().includes(handleRef.current!)) return
@ -46,10 +49,23 @@ export const Calendar: React.FC<CalendarProps> & {
}) })
const handleDateChange = (data: OnDatesChangeProps) => { const handleDateChange = (data: OnDatesChangeProps) => {
handleDateFieldChange(data.startDate ?? new Date()) if (typeof _value !== 'undefined') {
onDateFocus(data.startDate ?? new Date()) if (typeof onChange !== 'undefined') {
onChange(data.startDate ?? new Date())
}
} else {
setValue(data.startDate)
}
} }
useEffect(() => {
onDateFocus(_value ? new Date(_value) : new Date())
}, [_value])
useEffect(() => {
onDateFocus(value ? new Date(value) : new Date())
}, [value])
const { const {
activeMonths, activeMonths,
isDateSelected, isDateSelected,

View File

@ -27,18 +27,20 @@ export type DatePickerProps = Omit<
export const DatePicker: React.FC<DatePickerProps> & { export const DatePicker: React.FC<DatePickerProps> & {
classes: typeof datePickerClasses classes: typeof datePickerClasses
} = ({ value, onChange, withCalendar = true, ...props }) => { } = ({ value: _value, onChange, withCalendar = true, ...props }) => {
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
const [openCalendar, setOpenCalendar] = useState(false) const [openCalendar, setOpenCalendar] = useState(false)
const [date, setDate] = useState<string>(value || '') const [date, setDate] = useState<string>(_value || '')
const handleDateFieldChange = (date: any) => { const handleDateFieldChange = (date: any) => {
const offset = new Date(date).getTimezoneOffset() const offset = new Date(date).getTimezoneOffset()
const formattedDate = new Date(date.getTime() - offset * 60 * 1000) const formattedDate = new Date(date.getTime() - offset * 60 * 1000)
const value = formattedDate.toISOString().split('T')[0] const value = formattedDate.toISOString().split('T')[0]
if (typeof onChange === 'function') { if (typeof _value !== 'undefined') {
onChange(value) if (typeof onChange !== 'undefined') {
onChange(value)
}
} else { } else {
setDate(value) setDate(value)
} }
@ -64,7 +66,7 @@ export const DatePicker: React.FC<DatePickerProps> & {
<Portal id="calendar"> <Portal id="calendar">
{withCalendar && ( {withCalendar && (
<Calendar <Calendar
handleDateFieldChange={handleDateFieldChange} onChange={handleDateFieldChange}
open={openCalendar} open={openCalendar}
onClose={() => setOpenCalendar(false)} onClose={() => setOpenCalendar(false)}
handleRef={ref} handleRef={ref}