import * as React from "react"; import { DateInputProps, DateInputState } from "./typings/DateInput"; import DropDown from "./DropDown"; import { dateClass, dropDownClassName, inputStyle, wrapperStyle, errorStyle } from "./styles/Date.styles"; import Calendar from "./Calendar"; import Input from "./Input"; import { Rifm } from "rifm"; import { startOfDay, format } from "date-fns"; import NativeDateInput from "./NativeDateInput"; import { UserAgentInfoContext } from "../utils/useragent"; import { cx } from "emotion"; const noop = () => {}; function dateFormat(str: string) { const clean = str.replace(/[^\d]+/gi, ""); const chars = clean.split(""); return chars.reduce( (r, v, index) => `${r}${v}${index === 1 || index === 3 ? "/" : ""}`.substr(0, 10), "" ); } const modifiers = { preventOverflow: { enabled: false }, flip: { enabled: false } }; export default class DateInput extends React.PureComponent< DateInputProps & typeof DateInput.defaultProps, DateInputState > { static defaultProps = { placement: "bottom-start" }; state: Readonly = { stringInput: "" }; static getDerivedStateFromProps( props: DateInputProps, state: DateInputState ): Partial | null { let newState: Partial | null = null; if (props.value !== state.propsValue) { newState = { propsValue: props.value, stringInput: props.value ? format(props.value, "dd/MM/yyyy") : "" }; } return newState; } private onCalendarDateChange = (date: Date) => { this.props.onChange(date.getTime()); }; private onInputChange = (input: string) => { this.setState({ stringInput: input }); // TODO: Modify when close to year 9999 if (input.length === 10) { // RIFM will ensure the length of the input. const date = startOfDay(new Date()); date.setFullYear( parseInt(input.substr(6, 4), 10), parseInt(input.substr(3, 5), 10) - 1, parseInt(input.substr(0, 2), 10) ); this.props.onChange(date.getTime()); } }; render() { const { calendarProps, inputProps, placeholder, value: propsValue, disabled, errorMessage, placement, wrapperClassName, initiallyOpen, onOutsideClick, controlled, isOpen } = this.props; const _wrapperClassName = cx(wrapperStyle, wrapperClassName); const _dropDownClassName = cx( dropDownClassName, this.props.dropDownClassName ); return ( ( {({ value, onChange }) => ( { if (disabled || controlled) return; toggleDropdown(); }} fixLabelAtTop {...inputProps} inputProps={{ placeholder: "DD/MM/YYYY", ...(inputProps && inputProps.inputProps), onChange }} className={cx(inputStyle, inputProps && inputProps.className)} disabled={disabled} /> )} )} className={_wrapperClassName} placement={placement} modifiers={modifiers} initiallyOpen={initiallyOpen} onOutsideClick={onOutsideClick} controlled={controlled} isOpen={isOpen} > {({ toggle }) => ( <> { this.onCalendarDateChange(date); if (controlled) { return; } toggle(); }} /> {errorMessage &&
{errorMessage}
} )}
); } } function checkDateInputSupport(): boolean { try { const input = document.createElement("input"); const type = "date"; input.setAttribute("type", "date"); input.value = "\x01"; return ( input.type === type && (input.value !== "\x01" || !input.checkValidity()) ); } catch (e) { return true; } } const hasDateInputSupport = /*@__PURE__*/ checkDateInputSupport(); // tslint:disable-next-line max-classes-per-file export class BrowserBasedDateInput extends React.PureComponent { static contextType = UserAgentInfoContext; render() { return ( {({ userAgent }: { userAgent: string }) => { if (/Android|iPhone|iPad/i.test(userAgent) && hasDateInputSupport) { return ; } return ; }} ); } }