Skip to content

Commit

Permalink
DateRange: Highlight secondary range in DateRange component (web)
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlosAvina committed Dec 11, 2024
1 parent 8283d30 commit 5ba537e
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 20 deletions.
21 changes: 21 additions & 0 deletions packages/gestalt-datepicker/src/DateRange.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,24 @@ html[dir="rtl"] .borderRight {
transform: translateY(-50%);
width: 3px;
}

/* secondary range styles */

:global ._gestalt .react-datepicker__day--in-range-secondary {
background-color: var(--color-background-datepicker-range-default);
font-weight: bold;
}

:global ._gestalt ._gestalt_daterange .react-datepicker__day--range-start {
background-color: var(--color-background-datepicker-button-selected-default);
border-radius: var(--rounding-datepicker-days);
color: var(--color-text-inverse);
position: relative;
}

:global ._gestalt ._gestalt_daterange .react-datepicker__day--range-end {
background-color: var(--color-background-datepicker-button-selected-default);
border-radius: var(--rounding-datepicker-days);
color: var(--color-text-inverse);
position: relative;
}
17 changes: 6 additions & 11 deletions packages/gestalt-datepicker/src/DateRange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ type Props = {
readOnly?: boolean;
};

enum DateRangeType {
export enum DateRangeType {
Primary,
Secondary,
}
Expand Down Expand Up @@ -358,16 +358,11 @@ function DateRange({
onSecondaryDateChange({ value: startDate }, { value: endDate });
}
}}
rangeEndDate={
selectedRange === DateRangeType.Primary
? dateValue.endDate
: secondaryDateValue?.endDate
}
rangeStartDate={
selectedRange === DateRangeType.Primary
? dateValue.startDate
: secondaryDateValue?.startDate
}
rangeEndDate={dateValue.endDate}
rangeStartDate={dateValue.startDate}
secondaryRangeEndDate={secondaryDateValue?.endDate}
secondaryRangeStartDate={secondaryDateValue?.startDate}
selectedRange={selectedRange}
/>
</Box>
{onSubmit && onCancel ? (
Expand Down
72 changes: 63 additions & 9 deletions packages/gestalt-datepicker/src/DateRange/InternalDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import ReactDatePicker, { registerLocale } from 'react-datepicker';
import { Icon, useDeviceType } from 'gestalt';
import { Props } from '../DatePicker';
import styles from '../DatePicker.css';
import { DateRangeType } from '../DateRange';

type ModifiedProps = Props & {
onChange: (arg1: { startDate: Date; endDate: Date }) => void;
selectedRange: DateRangeType;
secondaryRangeStartDate?: Date | null;
secondaryRangeEndDate?: Date | null;
};

const InternalDatePickerWithForwardRef = forwardRef<HTMLInputElement, ModifiedProps>(
Expand All @@ -20,6 +24,9 @@ const InternalDatePickerWithForwardRef = forwardRef<HTMLInputElement, ModifiedPr
onChange,
rangeEndDate,
rangeStartDate,
secondaryRangeStartDate,
secondaryRangeEndDate,
selectedRange,
}: ModifiedProps,
ref,
): ReactElement {
Expand All @@ -35,11 +42,6 @@ const InternalDatePickerWithForwardRef = forwardRef<HTMLInputElement, ModifiedPr
const [, setMonth] = useState<number | null | undefined>();
const [format, setFormat] = useState<string | null | undefined>();
const [updatedLocale, setUpdatedLocale] = useState<string | null | undefined>();
const [initRangeHighlight, setInitRangeHighlight] = useState<Date | null | undefined>();

useEffect(() => {
setInitRangeHighlight(rangeStartDate || rangeEndDate);
}, [rangeStartDate, rangeEndDate]);

useEffect(() => {
if (localeData && localeData.code) {
Expand All @@ -55,6 +57,42 @@ const InternalDatePickerWithForwardRef = forwardRef<HTMLInputElement, ModifiedPr
}
}, [localeData]);

function getDatesArray(startDate: Date, endDate: Date) {
// Ensure the input dates are valid Date objects
const start = new Date(startDate);
const end = new Date(endDate);

// Check if the start date is after the end date
if (start > end) {
return [];
}

const dates = [];
const currentDate = start;

// Loop through all dates from start to end
while (currentDate <= end) {
// Push the current date to the array
dates.push(new Date(currentDate));
// Increment the current date by one day
currentDate.setDate(currentDate.getDate() + 1);
}

return dates;
}

function generateHighliths(
startDate: Date | null | undefined,
endDate: Date | null | undefined,
) {
const datesArray = startDate && endDate ? getDatesArray(startDate, endDate) : [];
return [
{
'react-datepicker__day--in-range-secondary': datesArray,
},
];
}

return (
<div className="_gestalt">
<div className={isMobile ? undefined : '_gestalt_daterange'}>
Expand All @@ -73,9 +111,17 @@ const InternalDatePickerWithForwardRef = forwardRef<HTMLInputElement, ModifiedPr
calendarClassName={styles['react-datepicker-inline']}
dateFormat={format}
dayClassName={() => styles['react-datepicker__days']}
endDate={rangeEndDate ?? undefined}
endDate={
selectedRange === DateRangeType.Primary
? rangeEndDate ?? undefined
: secondaryRangeEndDate ?? undefined
}
excludeDates={excludeDates && [...excludeDates]}
highlightDates={initRangeHighlight ? [initRangeHighlight] : []}
highlightDates={
selectedRange === DateRangeType.Primary
? generateHighliths(secondaryRangeStartDate, secondaryRangeEndDate)
: generateHighliths(rangeStartDate, rangeEndDate)
}
id={id}
includeDates={includeDates && [...includeDates]}
inline
Expand All @@ -95,9 +141,17 @@ const InternalDatePickerWithForwardRef = forwardRef<HTMLInputElement, ModifiedPr
previousMonthButtonLabel={
<Icon accessibilityLabel="" color="default" icon="arrow-back" size={16} />
}
selected={rangeStartDate ?? undefined}
selected={
selectedRange === DateRangeType.Primary
? rangeStartDate ?? undefined
: secondaryRangeStartDate ?? undefined
}
selectsRange
startDate={rangeStartDate ?? undefined}
startDate={
selectedRange === DateRangeType.Primary
? rangeStartDate ?? undefined
: secondaryRangeStartDate ?? undefined
}
/>
</div>
</div>
Expand Down

0 comments on commit 5ba537e

Please sign in to comment.