Skip to content

Commit

Permalink
feat: add autoSelectEndDateIn prop in DateRangePicker component
Browse files Browse the repository at this point in the history
affects: @medly-components/core, @medly-components/forms
  • Loading branch information
gmukul01 committed Sep 8, 2024
1 parent 0b227a6 commit de430c3
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { KeyboardArrowLeftIcon, KeyboardArrowRightIcon } from '@medly-components/icons';
import { WithStyle, useMediaQuery } from '@medly-components/utils';
import { add } from 'date-fns';
import type { FC } from 'react';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTheme } from 'styled-components';
Expand All @@ -22,6 +23,7 @@ const Component: FC<Props> = memo(props => {
minSelectableDate,
maxSelectableDate,
withSingleMonth,
autoSelectEndDateIn,
...restProps
} = props,
{ startDate, endDate } = selectedDates;
Expand All @@ -40,6 +42,11 @@ const Component: FC<Props> = memo(props => {
handleDateSelection = useCallback(
(date: Date) => {
if (focusedElement === `START_DATE`) {
if (autoSelectEndDateIn) {
onDateSelection({ startDate: date, endDate: add(date, { days: autoSelectEndDateIn }) });
onFocusChange?.('START_DATE');
return;
}
if (selectedDates.endDate && date >= selectedDates.endDate) {
onDateSelection({ startDate: selectedDates.endDate, endDate: date });
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ export type Props = Omit<HTMLProps<HTMLDivElement>, 'size'> & {
withSingleMonth?: boolean;
focusedElement?: FOCUS_ELEMENT;
onFocusChange?: (element: FOCUS_ELEMENT) => void;
autoSelectEndDateIn?: number;
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { DateRangePicker } from './DateRangePicker';
import { defaultTheme } from '@medly-components/theme';
import { Preview, Story, Meta, Props } from '@storybook/addon-docs/blocks';
import { Meta, Preview, Props, Story } from '@storybook/addon-docs/blocks';
import { boolean, select, text } from '@storybook/addon-knobs';
import { useState } from 'react';
import { DateRangePicker } from './DateRangePicker';
import {
placement,
DateRangePickerWithStateForDoc,
displayFormats,
ThemeInterface,
FormWithDateRangePicker,
DateRangePickerWithStateForDoc
placement,
ThemeInterface
} from './DateRangePicker.stories';
import { useState } from 'react';
import { DateRangeType, DateRangeSelectionEnum } from './types';
import { DateRangeSelectionEnum, DateRangeType } from './types';

<Meta
title="Core/DateRangePicker"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ describe('DateRangePicker', () => {
expect(mockOnChange).toHaveBeenCalledWith(dateToSelect);
});

it('should call onChange with expected start date and end date when autoSelectEndDateIn passed in', async () => {
const mockOnChange = jest.fn(),
dateToSelect: any = { endDate: new Date(2020, 1, 10), startDate: new Date(2020, 1, 3) },
{ startDateInput } = renderComponent({
value: { startDate: new Date(2020, 1, 13), endDate: new Date(2020, 1, 5) },
onChange: mockOnChange,
autoSelectEndDateIn: 7
});
fireEvent.click(screen.getByTitle('contract-calendar-icon'));
fireEvent.focus(startDateInput);
fireEvent.mouseOver(screen.getByTitle(dateToSelect.startDate.toDateString()));
fireEvent.change(startDateInput, { target: { value: '02 / 03 / 2020' } });
await waitFor(() => expect(mockOnChange).toHaveBeenCalledWith(dateToSelect));
});

it('should change display month on selecting startDate out of displayed months', async () => {
const { startDateInput } = renderComponent({
value: { startDate: new Date(2020, 5, 2), endDate: null }
Expand Down Expand Up @@ -367,6 +382,23 @@ describe('DateRangePicker', () => {
await waitFor(() => expect(startDateInput).toHaveFocus());
});

it('should auto select endDate on selecting the start date', async () => {
const mockOnChange = jest.fn(),
initialDates = { startDate: new Date(2020, 1, 2), endDate: new Date(2020, 1, 9) },
datesToSelect: any = { endDate: new Date(2020, 1, 10), startDate: new Date(2020, 1, 3) };

renderComponent({
value: initialDates,
onChange: mockOnChange,
autoSelectEndDateIn: 7
});
fireEvent.click(screen.getByTitle('contract-calendar-icon'));
fireEvent.click(screen.getByTitle(datesToSelect.startDate.toDateString()));
await waitFor(() =>
expect(mockOnChange).toHaveBeenCalledWith({ endDate: datesToSelect.endDate, startDate: datesToSelect.startDate })
);
});

it('should call focus and blur handlers if passed', async () => {
const mockOnFocus = jest.fn(),
mockOnChange = jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const DateRangePicker: FC<DateRangeProps> = memo(props => {
customDateRangeOptions,
onPopupClose,
autoComplete,
autoSelectEndDateIn,
...restProps
} = props;
const startDateRef = useRef<HTMLInputElement>(null),
Expand Down Expand Up @@ -136,6 +137,7 @@ export const DateRangePicker: FC<DateRangeProps> = memo(props => {
autoComplete={autoComplete}
minSelectableDate={minSelectableDate!}
maxSelectableDate={maxSelectableDate!}
autoSelectEndDateIn={autoSelectEndDateIn}
/>
{isActive &&
(activePopover === PopoverTypes.CALENDAR ? (
Expand All @@ -150,6 +152,7 @@ export const DateRangePicker: FC<DateRangeProps> = memo(props => {
onFocusChange={onFocusChange}
minSelectableDate={minSelectableDate!}
maxSelectableDate={maxSelectableDate!}
autoSelectEndDateIn={autoSelectEndDateIn}
/>
) : (
<CustomDateRangeOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ export const DateRangeTextFields: FC<Props> = memo(props => {
activePopover,
onCustomRangeIconClick,
outerClickValidator,
autoComplete
autoComplete,
autoSelectEndDateIn
} = props,
{
mask,
Expand Down Expand Up @@ -143,6 +144,7 @@ export const DateRangeTextFields: FC<Props> = memo(props => {
label={endDateLabel}
onKeyPress={onKeyPress}
{...commonTextProps}
disabled={!!autoSelectEndDateIn || commonTextProps.disabled}
/>
{showTooltipForHelperAndErrorText && (
<HelperAndErrorTextTooltip id={id} errorText={errorText || builtInErrorMessage} helperText={helperText} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ export type Props = {
autoComplete?: string;
minSelectableDate: Date;
maxSelectableDate: Date;
autoSelectEndDateIn?: number;
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getFormattedDate, parseToDate } from '@medly-components/utils';
import { add } from 'date-fns';
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { isValidDate } from '../../Calendar/helper';
import getMaskedValue from '../../TextField/getMaskedValue';
Expand All @@ -20,7 +21,8 @@ export const useDateRangeTextFieldsHandlers = (props: Props) => {
onDateChange,
setFocusedElement,
minSelectableDate,
maxSelectableDate
maxSelectableDate,
autoSelectEndDateIn
} = props;

const [builtInErrorMessage, setErrorMessage] = useState(''),
Expand Down Expand Up @@ -89,8 +91,12 @@ export const useDateRangeTextFieldsHandlers = (props: Props) => {
setStartDateText(maskedValue);
setStartDateMaskLabel(maskedLabel);
if (parsedDate.toString() !== 'Invalid Date') {
data !== null && !errorMessage && setFocusedElement('END_DATE');
!errorMessage && setErrorMessage('');
if (autoSelectEndDateIn && data !== null) {
onDateChange({ startDate: parsedDate, endDate: add(parsedDate, { days: autoSelectEndDateIn }) });
return;
}
data !== null && !errorMessage && setFocusedElement('END_DATE');
onDateChange({ ...selectedDates, startDate: parsedDate });
}
} else {
Expand All @@ -103,7 +109,7 @@ export const useDateRangeTextFieldsHandlers = (props: Props) => {
}
}
},
[selectedDates, onDateChange]
[selectedDates, onDateChange, autoSelectEndDateIn]
),
validateOnTextFieldBlur = useCallback(
(event: React.FocusEvent<HTMLInputElement>) => {
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/components/DateRangePicker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,6 @@ export type DateRangeProps = Omit<HTMLProps<HTMLInputElement>, 'prefix' | 'size'
showTooltipForHelperAndErrorText?: boolean;
/** Provide date range selection custom options */
customDateRangeOptions?: Array<{ label: string; value: DateRangeSelectionEnum }>;
/** Provide the number of days to auto select after start date*/
autoSelectEndDateIn?: number;
};

0 comments on commit de430c3

Please sign in to comment.