Files
calendar/packages/ui/components/form/date-range-picker/dateRangeLogic.ts
T
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1c3ced5b70 fix: simplify date range picker to Airbnb-style selection (#25386)
* feat: simplify date range picker to Airbnb-style selection

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: apply Airbnb-style selection to allowPastDates branch

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: extract date range selection logic and add unit tests

- Extract date range selection logic into pure function (dateRangeLogic.ts)
- Remove unused allowPastDates parameter from selection logic
- Add comprehensive unit tests (11 test cases covering all scenarios)
- Simplify DateRangePicker component (30+ lines -> 5 lines)
- Improve separation of concerns: allowPastDates only controls calendar date restrictions

* style update

* feat: add hover highlighting for date range selection

When a start date is selected and user hovers over other dates,
the potential range between start and hovered date now shows
bg-emphasis background for better visual feedback.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* memoize hovering range and update styles

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-03 14:52:25 +00:00

37 lines
1021 B
TypeScript

export type DateRange = {
startDate?: Date;
endDate?: Date;
};
export type CalculateNewDateRangeParams = {
startDate?: Date;
endDate?: Date;
clickedDate: Date;
};
/**
* Determines the new date range based on user's date selection.
* Implements Airbnb-style date range selection behavior.
*
* @param params - Object containing startDate, endDate, and clickedDate
* @returns The new date range state
*/
export function calculateNewDateRange({
startDate,
endDate,
clickedDate,
}: CalculateNewDateRangeParams): DateRange {
// Airbnb-style: when both dates are set, any click starts a new range
if (!startDate || endDate) {
// No start date OR both dates set -> start fresh
return { startDate: clickedDate, endDate: undefined };
} else {
// Have start but no end -> complete the range (swap if needed)
if (clickedDate < startDate) {
return { startDate: clickedDate, endDate: startDate };
} else {
return { startDate: startDate, endDate: clickedDate };
}
}
}