import React, { ReactElement, useState, useEffect, useCallback, ChangeEvent, FocusEvent, } from 'react'; import parse from 'date-fns/fp/parse'; import isValid from 'date-fns/fp/isValid'; import formatDate from 'date-fns/fp/format'; import css from '../../utils/css'; import Input from '../Input'; import Dropdown from '../Dropdown'; import Calendar from './Calendar'; import { IconName } from '../Icon'; import { DatePickerContainer } from './StyledDatePicker'; import { CommonProps } from '../common'; export interface MonthPickerProps extends CommonProps { /** * Specify the [automated assistance](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) in filling out form field values by the browser. */ autoComplete?: string; /** * Whether the picker is disabled. */ disabled?: boolean; /** * Month and Year format (ex: MM/yyyy). Following date-fns's format (https://date-fns.org/v2.16.1/docs/format). */ format?: string; /** * Whether the input is invalid. */ invalid?: boolean; /** * The latest date user can select. */ maxDate?: Date; /** * The earliest date user can select. */ minDate?: Date; /** * Name of element, is used to refer to the form data for submission. */ name?: string; /** * onBlur event handler. */ onBlur?: (e: FocusEvent) => void; /** * onChange event handler. */ onChange?: (value: string) => void; /** * Placeholder text in the absence of any value. */ placeholder?: string; /** * Name of Icon or an Icon element to render on the left side of the input, before the user's cursor. */ prefix?: IconName | ReactElement; /** * Whether or not Input's value is read only. */ readonly?: boolean; /** * The size of the input box. */ size?: 'small' | 'medium' | 'large'; /** * Current selected month which must be in correct format. If value is invalid, it will be skipped. */ value?: string; } const DEFAULT_MONTH_FORMAT = 'MM/yyyy'; const MonthPicker = ({ autoComplete, value, onChange, onBlur, minDate, maxDate, size = 'medium', invalid = false, placeholder, prefix, disabled = false, format = DEFAULT_MONTH_FORMAT, readonly, name, id, className, style, sx = {}, 'data-test-id': dataTestId, }: MonthPickerProps): ReactElement => { const [open, setOpen] = useState(false); const [selectedMonth, setSelectedMonth] = useState(); const isValidMonth = isValid(selectedMonth); const dateFormat = format !== undefined ? format : DEFAULT_MONTH_FORMAT; const openCalendar = useCallback(() => setOpen(true), [setOpen]); const closeCalendar = useCallback(() => setOpen(false), [setOpen]); const onSelectMonth = useCallback( (newDate: Date): void => { if (onChange !== undefined) { const formattedDate = formatDate(dateFormat, newDate); onChange(formattedDate); } closeCalendar(); }, [dateFormat, onChange, closeCalendar] ); const onInputChange = useCallback( (e: ChangeEvent): void => { const target = e.target as HTMLInputElement; if (target.value !== undefined && onChange !== undefined) { onChange(target.value); } }, [onChange] ); useEffect(() => { setSelectedMonth( parse(new Date(), dateFormat, value !== undefined ? value : '') ); }, [dateFormat, setSelectedMonth, value]); const dateInput = ( ); const calendar = ( ); return ( ); }; export default MonthPicker;