import * as React from 'react'; import { Action, CustomRender, CustomEventHandler, Values } from '../../commonTypes'; import { DivRefCurrent } from '../../components/Div'; import { COMPONENTS_NAMESPACES } from '../../constants'; import { PartialGlobalDefaultTheme } from '../../utils/useTheme'; import { VIEW_TYPES } from '../Calendar/constants'; import { CalendarClickHandler, CalendarConditions, CalendarBaseProps } from '../Calendar/types'; import { MaskedInputBaseProps } from '../MaskedInputBase/types'; import { stateActionTypes } from './actions'; import { COMPONENT_TYPES } from './constants'; import { ValidationProps } from '../../components/Validation/types'; export interface ChangeEvent { component: { date: Date | null; name?: string; value: string; }; } export interface BlurEvent extends React.FocusEvent { component: { date: Date | null; isValid?: boolean; name?: string; value: string; }; } export interface FocusEvent extends React.FocusEvent { component: { date: Date | null; name?: string; value: string; }; } export declare type TimeLimits = [number, number]; export interface DateTimeInputProps extends ValidationProps, CalendarBaseProps { /** Классы для компонента */ className?: string; /** Формат даты, по-умолчанию dd.MM.yyyy */ format?: string; /** Кастомная иконка календаря */ iconRender?: CustomRender; /** Кастомный инпут */ inputRender?: CustomRender; /** Выключенное состояние */ isDisabled?: boolean; /** Открытый календарь */ isOpen?: boolean; /** Поле является обязательным */ isRequired?: boolean; /** Максимальная дата */ max?: Date; /** Минимальная дата */ min?: Date; /** Имя компонента */ name?: string; /** Обработчик блюра */ onBlur?: (ev: BlurEvent) => void; /** Обработчик изменения */ onChange?: (ev: ChangeEvent) => void; /** Обработчик нажатия Enter */ onEnterPress?: (ev: ChangeEvent) => void; /** Обработчик фокуса */ onFocus?: (ev: FocusEvent) => void; /** Плейсхолдер инпута */ placeholder?: string; /** Тема для компонента */ theme?: PartialGlobalDefaultTheme[typeof COMPONENTS_NAMESPACES.dateTimeInput]; /** Максимальное время */ timeMax?: TimeLimits; /** Минимальное время */ timeMin?: TimeLimits; /** Тип компонента */ type?: Values; /** Значение в инпуте */ value?: string | Date | null; /** Кастомный враппер */ wrapperRender?: CustomRender; } export interface DateTimeInputState { date: Date | null; isFocused: boolean; isOpen: boolean; isValid: boolean; prevDate: Date | null; value: string; viewDate: Date; viewType: Values; } export interface DateTimeInputRefCurrent { input: HTMLInputElement | null; wrapper: HTMLDivElement | null; } export interface DateWithToDateMethod extends Date { toDate?: () => Date; } export interface DateShorthand { dateVal: number; hours: number; minutes: number; month: number; year: number; } export interface LeftRightKeyPressPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; ev: React.KeyboardEvent; isOpen: DateTimeInputProps['isOpen']; max: DateTimeInputProps['max']; min: DateTimeInputProps['min']; viewType: DateTimeInputState['viewType']; } export interface UpDownKeyPressPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; ev: React.KeyboardEvent; isOpen: DateTimeInputProps['isOpen']; max: DateTimeInputProps['max']; min: DateTimeInputProps['min']; viewType: DateTimeInputState['viewType']; } export interface EnterKeyPressPayload { date: DateTimeInputState['date']; dateShorthand: DateShorthand; dispatch: React.Dispatch; ev: React.KeyboardEvent; format: DateTimeInputProps['format']; isOpen: DateTimeInputProps['isOpen']; maskedInputRef: React.MutableRefObject; max: DateTimeInputProps['max']; min: DateTimeInputProps['min']; name: DateTimeInputProps['name']; onChange: DateTimeInputProps['onChange']; onEnterPress: DateTimeInputProps['onEnterPress']; timeMax: DateTimeInputProps['timeMax']; timeMin: DateTimeInputProps['timeMin']; type: DateTimeInputProps['type']; value: DateTimeInputState['value']; viewDate: DateTimeInputState['viewDate']; viewType: DateTimeInputState['viewType']; } export interface EscKeyPressPayload { dispatch: React.Dispatch; } export interface TabKeyPressPayload { dispatch: React.Dispatch; ev: React.KeyboardEvent; isOneMonthInRange: boolean; isOneYearInRange: boolean; isOpen: DateTimeInputProps['isOpen']; type?: Values; viewType: DateTimeInputState['viewType']; } export interface Handlers { handleBlur: CustomEventHandler; handleCalendarClick: CalendarClickHandler; handleCalendarIconMouseDown: CustomEventHandler>; handleCalendarKeyDown: CustomEventHandler>; handleCalendarMouseDown: CustomEventHandler>; handleChange: CustomEventHandler; handleFocus: CustomEventHandler; } export interface StateActionPayloads { SET_DATE: Date | null; SET_FOCUSED: boolean; SET_OPEN: boolean; SET_PREV_DATE: Date | null; SET_VALID: boolean; SET_VALUE: string; SET_VIEW_DATE: Date; SET_VIEW_TYPE: Values; } export declare type StateActionTypes = typeof stateActionTypes; export declare type AllActions = Values<{ [K in keyof typeof stateActionTypes]: Action; }>; export interface DatesPrevClickPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; isPrevButtonDisabled: boolean; min?: Date; viewDate: DateTimeInputState['viewDate']; } export interface DatesNextClickPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; isNextButtonDisabled: boolean; max?: Date; viewDate: DateTimeInputState['viewDate']; } export interface DatesSelectPayload { dateCell?: number; dateShorthand: DateShorthand; dispatch: React.Dispatch; format: DateTimeInputProps['format']; maskedInputRef: React.MutableRefObject; monthCell?: number; type: DateTimeInputProps['type']; updateDate: (newDate: Date) => void; } export interface MonthsPrevClickPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; isDateOutOfMinYearRange: boolean; min?: Date; viewDate: DateTimeInputState['viewDate']; } export interface MonthsNextClickPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; isDateOutOfMaxYearRange: boolean; max?: Date; viewDate: DateTimeInputState['viewDate']; } export interface MonthsSelectPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; isDateOutOfMinDecadeRange: boolean; max?: Date; min?: Date; monthCell?: number; viewDate: DateTimeInputState['viewDate']; } export interface YearsPrevClickPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; isDateOutOfMinDecadeRange: boolean; min?: Date; viewDate: DateTimeInputState['viewDate']; } export interface YearsNextClickPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; isDateOutOfMaxDecadeRange: boolean; max?: Date; viewDate: DateTimeInputState['viewDate']; } export interface YearsSelectPayload { dateShorthand: DateShorthand; dispatch: React.Dispatch; max?: Date; min?: Date; viewDate: DateTimeInputState['viewDate']; yearCell?: number; } export interface TitleClickPayload { dispatch: React.Dispatch; isOneMonthInRange: boolean; isOneYearInRange: boolean; viewType: DateTimeInputState['viewType']; } export interface TodayButtonClickPayload { dispatch: React.Dispatch; max?: Date; min?: Date; updateDate: (newDate: Date) => void; } export interface IconProps { className?: string; onMouseDown?: React.MouseEventHandler; } export interface WrapperProps { className?: string; onKeyDown?: React.KeyboardEventHandler; ref?: React.Ref; } export interface CustomElements { Icon: React.FC; Input: React.FC; Wrapper: React.FC; } export interface HandlersData { conditions: CalendarConditions; dispatch: React.Dispatch; maskedInputRef: React.MutableRefObject; props: DateTimeInputProps; state: DateTimeInputState; validate: (value: Date | null) => boolean; } export interface BlurData { dispatch: React.Dispatch; props: DateTimeInputProps; state: DateTimeInputState; validate: (value: Date | null) => boolean; } export interface EffectData { conditions: CalendarConditions; dispatch: React.Dispatch; props: DateTimeInputProps; state: DateTimeInputState; } export interface NormalizeValueArgs { format: string; max?: Date; min?: Date; value: string; } export interface NormalizeDateArgs { date: Date | null; max?: Date; min?: Date; type?: Values; }