Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/now-prop: allows dev to specify the current date (example use… #955

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/react-calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ Displays a complete, interactive calendar.
| tileDisabled | Pass a function to determine if a certain day should be displayed as disabled. | n/a | `({ activeStartDate, date, view }) => date.getDay() === 0` |
| value | Calendar value. Can be either one value or an array of two values. If you wish to use react-calendar in an uncontrolled way, use `defaultValue` instead. | n/a | <ul><li>Date: `new Date()`</li><li>String: `2017-01-01`</li><li>An array of dates: `[new Date(2017, 0, 1), new Date(2017, 7, 1)]`</li><li>An array of strings: `['2017-01-01', '2017-08-01']`</li></ul> |
| view | Determines which calendar view shall be opened. Does not disable navigation. Can be `"month"`, `"year"`, `"decade"` or `"century"`. If you wish to use react-calendar in an uncontrolled way, use `defaultView` instead. | The most detailed view allowed | `"year"` |
| now | Current date used as now, allows to display an offsetted time as today | `new Date()` |

### MonthView, YearView, DecadeView, CenturyView

Expand Down
9 changes: 9 additions & 0 deletions packages/react-calendar/src/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,13 @@ export type CalendarProps = {
* @example 'year'
*/
view?: View;
/**
* Determines which date to show as the current date on the calendar
*
* @default new Date()
* @example 'year'
*/
now?: Date;
};

function toDate(value: Date | string): Date {
Expand Down Expand Up @@ -656,6 +663,7 @@ const Calendar: React.ForwardRefExoticComponent<CalendarProps & React.RefAttribu
tileDisabled,
value: valueProps,
view: viewProps,
now,
} = props;

const [activeStartDateState, setActiveStartDateState] = useState<Date | null | undefined>(
Expand Down Expand Up @@ -1024,6 +1032,7 @@ const Calendar: React.ForwardRefExoticComponent<CalendarProps & React.RefAttribu
tileDisabled,
value,
valueType,
now,
};

switch (view) {
Expand Down
3 changes: 2 additions & 1 deletion packages/react-calendar/src/DecadeView/Years.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type YearsProps = {
Omit<React.ComponentProps<typeof Year>, 'classes' | 'currentDecade' | 'date'>;

export default function Years(props: YearsProps): React.ReactElement {
const { activeStartDate, hover, showNeighboringDecade, value, valueType, ...otherProps } = props;
const { activeStartDate, hover, showNeighboringDecade, value, valueType, now, ...otherProps } = props;
const start = getBeginOfDecadeYear(activeStartDate);
const end = start + (showNeighboringDecade ? 11 : 9);

Expand All @@ -50,6 +50,7 @@ export default function Years(props: YearsProps): React.ReactElement {
start={start}
value={value}
valueType={valueType}
now={now}
/>
);
}
11 changes: 10 additions & 1 deletion packages/react-calendar/src/MonthView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ type MonthViewProps = {
* @example true
*/
showWeekNumbers?: boolean;
/**
* Determines which date to show as the current date on the calendar
*
* @default new Date()
* @example 'year'
*/
now?: Date;
} & Omit<
React.ComponentProps<typeof Weekdays> &
React.ComponentProps<typeof WeekNumbers> &
Expand All @@ -52,6 +59,7 @@ export default function MonthView(props: MonthViewProps): React.ReactElement {
formatWeekday,
onClickWeekNumber,
showWeekNumbers,
now,
...childProps
} = props;

Expand All @@ -63,6 +71,7 @@ export default function MonthView(props: MonthViewProps): React.ReactElement {
formatWeekday={formatWeekday}
locale={locale}
onMouseLeave={onMouseLeave}
now={now}
/>
);
}
Expand All @@ -84,7 +93,7 @@ export default function MonthView(props: MonthViewProps): React.ReactElement {
}

function renderDays() {
return <Days calendarType={calendarType} {...childProps} />;
return <Days calendarType={calendarType} now={now} {...childProps} />;
}

const className = 'react-calendar__month-view';
Expand Down
2 changes: 2 additions & 0 deletions packages/react-calendar/src/MonthView/Days.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default function Days(props: DaysProps): React.ReactElement {
showNeighboringMonth,
value,
valueType,
now,
...otherProps
} = props;

Expand Down Expand Up @@ -118,6 +119,7 @@ export default function Days(props: DaysProps): React.ReactElement {
start={start}
value={value}
valueType={valueType}
now={now}
/>
);
}
10 changes: 9 additions & 1 deletion packages/react-calendar/src/MonthView/Weekdays.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ type WeekdaysProps = {
*/
locale?: string;
onMouseLeave?: () => void;
/**
* Determines which date to show as the current date on the calendar
*
* @default new Date()
* @example 'year'
*/
now?: Date;
};

export default function Weekdays(props: WeekdaysProps): React.ReactElement {
Expand All @@ -49,6 +56,7 @@ export default function Weekdays(props: WeekdaysProps): React.ReactElement {
formatWeekday = defaultFormatWeekday,
locale,
onMouseLeave,
now,
} = props;

const anyDate = new Date();
Expand All @@ -72,7 +80,7 @@ export default function Weekdays(props: WeekdaysProps): React.ReactElement {
key={weekday}
className={clsx(
weekdayClassName,
isCurrentDayOfWeek(weekdayDate) && `${weekdayClassName}--current`,
isCurrentDayOfWeek(weekdayDate, now) && `${weekdayClassName}--current`,
isWeekend(weekdayDate, calendarType) && `${weekdayClassName}--weekend`,
)}
>
Expand Down
3 changes: 3 additions & 0 deletions packages/react-calendar/src/TileGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type TileGroupProps = {
step?: number;
value?: Value;
valueType: RangeType;
now?: Date;
};

export default function TileGroup({
Expand All @@ -32,6 +33,7 @@ export default function TileGroup({
step = 1,
value,
valueType,
now,
}: TileGroupProps): React.ReactElement {
const tiles = [];
for (let point = start; point <= end; point += step) {
Expand All @@ -45,6 +47,7 @@ export default function TileGroup({
hover,
value,
valueType,
now,
}),
date,
}),
Expand Down
3 changes: 2 additions & 1 deletion packages/react-calendar/src/YearView/Months.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type MonthsProps = {
Omit<React.ComponentProps<typeof Month>, 'classes' | 'date'>;

export default function Months(props: MonthsProps): React.ReactElement {
const { activeStartDate, hover, value, valueType, ...otherProps } = props;
const { activeStartDate, hover, value, valueType, now, ...otherProps } = props;
const start = 0;
const end = 11;
const year = getYear(activeStartDate);
Expand Down Expand Up @@ -45,6 +45,7 @@ export default function Months(props: MonthsProps): React.ReactElement {
start={start}
value={value}
valueType={valueType}
now={now}
/>
);
}
5 changes: 3 additions & 2 deletions packages/react-calendar/src/shared/dates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,11 @@ export function getDecadeLabel(
* Returns a boolean determining whether a given date is the current day of the week.
*
* @param {Date} date Date.
* @param {Date} now optional defaults to new Date()
* @returns {boolean} Whether a given date is the current day of the week.
*/
export function isCurrentDayOfWeek(date: Date): boolean {
return date.getDay() === new Date().getDay();
export function isCurrentDayOfWeek(date: Date, now?: Date): boolean {
return date.getDay() === (now ?? new Date()).getDay();
}

/**
Expand Down
3 changes: 2 additions & 1 deletion packages/react-calendar/src/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export function getTileClasses(args: {
hover?: Date | null;
value?: Value;
valueType?: RangeType;
now?: Date;
}): string[] {
if (!args) {
throw new Error('args is required');
Expand All @@ -93,7 +94,7 @@ export function getTileClasses(args: {
return classes;
}

const now = new Date();
const now = args.now ?? new Date();
const dateRange = (() => {
if (Array.isArray(date)) {
return date;
Expand Down
6 changes: 5 additions & 1 deletion test/Test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import './Test.css';

import type { LooseValue, Value, View } from './shared/types.js';

const now = new Date();
// Now can be changed to test the calendar in a different instant
// const now = new Date();

const now = new Date(2024, 7, 31);

const tileClassName = ({ date, view }: { date: Date; view: View }) => {
switch (view) {
Expand Down Expand Up @@ -122,6 +125,7 @@ export default function Test() {
className: 'myCustomCalendarClassName',
locale,
maxDate,
now,
maxDetail,
minDate,
minDetail,
Expand Down