Skip to content

Commit

Permalink
DatePicker: pass ref to main button
Browse files Browse the repository at this point in the history
  • Loading branch information
robines committed Nov 16, 2024
1 parent 7f4b8b9 commit 755bdd9
Showing 1 changed file with 44 additions and 48 deletions.
92 changes: 44 additions & 48 deletions frontend/src/Components/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Icon } from '@iconify/react';
import classNames from 'classnames';
import { format } from 'date-fns';
import React, { useMemo } from 'react';
import React, { forwardRef, useMemo } from 'react';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Button, MiniCalendar } from '~/Components';
import { MiniCalendar } from '~/Components';
import { useClickOutside } from '~/hooks';
import { KEY } from '~/i18n/constants';
import styles from './DatePicker.module.scss';
Expand All @@ -21,56 +21,52 @@ type DatePickerProps = {
maxDate?: Date;
};

export function DatePicker({
value: initialValue,
onChange,
disabled,
label,
buttonClassName,
minDate,
maxDate,
}: DatePickerProps) {
const isControlled = initialValue !== undefined;
export const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(
({ value: initialValue, onChange, disabled, label, buttonClassName, minDate, maxDate }, ref) => {
const isControlled = initialValue !== undefined;

const [date, setDate] = useState<Date | null>(null);
const [open, setOpen] = useState(false);
const [date, setDate] = useState<Date | null>(null);
const [open, setOpen] = useState(false);

const { t } = useTranslation();
const { t } = useTranslation();

const clickOutsideRef = useClickOutside<HTMLDivElement>(() => setOpen(false));
const clickOutsideRef = useClickOutside<HTMLDivElement>(() => setOpen(false));

const value = useMemo(() => {
if (isControlled) {
return initialValue;
}
return date;
}, [isControlled, initialValue, date]);
const value = useMemo(() => {
if (isControlled) {
return initialValue;
}
return date;
}, [isControlled, initialValue, date]);

function handleChange(d: Date | null) {
setDate(d);
onChange?.(d);
}
function handleChange(d: Date | null) {
setDate(d);
onChange?.(d);
}

return (
<div className={styles.container} ref={clickOutsideRef}>
<button
type="button"
className={classNames(styles.button, buttonClassName)}
onClick={() => setOpen((v) => !v)}
disabled={disabled}
>
<Icon icon="material-symbols:calendar-month-outline-rounded" />
{value ? format(value, 'PPP') : <span>{label ?? t(KEY.pick_a_date)}</span>}
</button>
<div className={classNames(styles.popover, !open && styles.hidden)}>
<MiniCalendar
baseDate={value || new Date()}
onChange={handleChange}
minDate={minDate}
maxDate={maxDate}
displayLabel
/>
return (
<div className={styles.container} ref={clickOutsideRef}>
<button
type="button"
className={classNames(styles.button, buttonClassName)}
onClick={() => setOpen((v) => !v)}
disabled={disabled}
ref={ref}
>
<Icon icon="material-symbols:calendar-month-outline-rounded" />
{value ? format(value, 'PPP') : <span>{label ?? t(KEY.pick_a_date)}</span>}
</button>
<div className={classNames(styles.popover, !open && styles.hidden)}>
<MiniCalendar
baseDate={value || new Date()}
onChange={handleChange}
minDate={minDate}
maxDate={maxDate}
displayLabel
/>
</div>
</div>
</div>
);
}
);
},
);
DatePicker.displayName = 'DatePicker';

0 comments on commit 755bdd9

Please sign in to comment.