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

refactor: simplify props, contexts #2211

Merged
merged 16 commits into from
Jun 20, 2024
Merged
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
8 changes: 6 additions & 2 deletions examples/CustomCaption.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from "react";

import { format } from "date-fns";
import { MonthCaptionProps, DayPicker, useCalendar } from "react-day-picker";
import {
MonthCaptionProps,
DayPicker,
useCalendarContext
} from "react-day-picker";

function CustomMonthCaption(props: MonthCaptionProps) {
const { goToMonth, nextMonth, previousMonth } = useCalendar();
const { goToMonth, nextMonth, previousMonth } = useCalendarContext();
return (
<h2>
{format(props.month.date, "MMM yyy")}
Expand Down
7 changes: 5 additions & 2 deletions examples/CustomMultiple.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React, { useState } from "react";

import { isSameDay } from "date-fns";
import { DayMouseEventHandler, DayPicker } from "react-day-picker";
import { DayEventHandler, DayPicker } from "react-day-picker";

export function CustomMultiple() {
const [value, setValue] = useState<Date[]>([]);

const handleDayClick: DayMouseEventHandler = (day, modifiers) => {
const handleDayClick: DayEventHandler<React.MouseEvent> = (
day,
modifiers
) => {
const newValue = [...value];
if (modifiers.selected) {
const index = value.findIndex((d) => isSameDay(day, d));
Expand Down
2 changes: 1 addition & 1 deletion examples/CustomSingle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { DayPicker, DayPickerProps, type Mode } from "react-day-picker";

export function CustomSingle() {
const [selectedDate, setSelectedDate] = useState<Date | undefined>();
const modifiers: DayPickerProps<Mode>["modifiers"] = {};
const modifiers: DayPickerProps["modifiers"] = {};
if (selectedDate) {
modifiers.selected = selectedDate;
}
Expand Down
4 changes: 2 additions & 2 deletions examples/CustomWeek.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ beforeEach(() => {

describe("when a day is clicked", () => {
beforeEach(async () => {
await act(() => user.click(gridcell(today)));
await user.click(gridcell(today));
});
test("the whole week should appear selected", () => {
const week = [
Expand All @@ -33,7 +33,7 @@ describe("when a day is clicked", () => {
});
describe("when clicking the day again", () => {
beforeEach(async () => {
await act(() => user.click(gridcell(today)));
await user.click(gridcell(today));
});
test("the whole week should not be selected", () => {
const week = [
Expand Down
4 changes: 2 additions & 2 deletions examples/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useId, useRef, useState } from "react";

import { format, isValid, parse } from "date-fns";
import { DayPicker, type SelectHandler } from "react-day-picker";
import { DayPicker } from "react-day-picker";

export function Dialog() {
const dialogRef = useRef<HTMLDialogElement>(null);
Expand Down Expand Up @@ -45,7 +45,7 @@ export function Dialog() {
* Function to handle the DayPicker select event: update the input value and
* the selected date, and set the month.
*/
const handleDayPickerSelect: SelectHandler<"single"> = (date) => {
const handleDayPickerSelect = (date: Date | undefined) => {
if (!date) {
setInputValue("");
setSelectedDate(undefined);
Expand Down
2 changes: 1 addition & 1 deletion examples/Input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from "react";

import { format } from "date-fns";

import { act, render, screen } from "@/test/render";
import { render, screen } from "@/test/render";
import { user } from "@/test/user";

import { Input } from "./Input";
Expand Down
8 changes: 6 additions & 2 deletions examples/Keyboard.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React, { useState } from "react";

import { DayPicker, type DayPickerProps } from "react-day-picker";
import {
DayPicker,
type DayPickerProps,
type PropsSingle
} from "react-day-picker";

export function Keyboard(props: DayPickerProps<"single">) {
export function Keyboard(props: DayPickerProps & PropsSingle) {
const [selected, setSelected] = useState<Date | undefined>(undefined);
return (
<DayPicker
Expand Down
11 changes: 2 additions & 9 deletions examples/MultipleMinMax.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ import { addDays } from "date-fns";
import { DayPicker } from "react-day-picker";

export function MultipleMinMax() {
const defaultSelected = [new Date(), addDays(new Date(), 1)];
return (
<DayPicker
defaultSelected={defaultSelected}
mode="multiple"
min={2}
max={5}
/>
);
const selected = [new Date(), addDays(new Date(), 1)];
return <DayPicker selected={selected} mode="multiple" min={2} max={5} />;
}
2 changes: 1 addition & 1 deletion examples/None.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import React from "react";
import { DayPicker } from "react-day-picker";

export function None() {
return <DayPicker mode="default" />;
return <DayPicker />;
}
2 changes: 1 addition & 1 deletion examples/Range.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe("when a day in the range is clicked", () => {
describe("when a day in the range is clicked again", () => {
const day = days[2];
beforeEach(async () => act(() => user.click(gridcell(day))));
test("no day should be selected (??)", () => {
test("no day should be selected", () => {
expect(getAllSelectedDays()).toHaveLength(0);
});
test("should match the snapshot", () => {
Expand Down
6 changes: 3 additions & 3 deletions examples/RangeShiftKey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { isSameDay } from "date-fns";
import {
DateRange,
DayPicker,
type DayProps,
useSelection
useRangeContext,
type DayProps
} from "react-day-picker";

function DayWithShiftKey(props: DayProps) {
const { selected } = useSelection<"range">();
const { selected } = useRangeContext();
const onClick = props.rootProps?.onClick;

const handleClick: MouseEventHandler<HTMLDivElement> = (e) => {
Expand Down
5 changes: 4 additions & 1 deletion examples/Single.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ describe("when a day is clicked", () => {
});
test("should appear as selected", () => {
expect(gridcell(day)).toHaveAttribute("aria-selected", "true");
expect(gridcell(day)).toHaveFocus();
expect(gridcell(day)).toHaveClass("rdp-selected");
});
describe("when the day is clicked again", () => {
beforeEach(async () => {
await user.click(gridcell(day));
});
test("should appear as not selected", () => {
test("should not appear as selected", () => {
expect(gridcell(day)).not.toHaveAttribute("aria-selected");
expect(gridcell(day)).not.toHaveClass("rdp-selected");
});
});
});
2 changes: 1 addition & 1 deletion examples/TestCase2047.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function TestCase2047() {
const [selected, setSelected] = React.useState<Date>(defaultSelected);
return (
<DayPicker
defaultMonth={new Date(2024, 5, 10)}
defaultMonth={defaultMonth}
mode="single"
required
selected={selected}
Expand Down
6 changes: 2 additions & 4 deletions examples/Testcase1567.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from "react";

import { DateRange, DayPicker, SelectHandler } from "react-day-picker";
import { DateRange, DayPicker } from "react-day-picker";

/**
* Test case for issue #1567
Expand All @@ -13,9 +13,7 @@ export function TestCase1567() {
to: new Date(2022, 9, 1)
});

const handleChange: SelectHandler<"range"> = (
range: DateRange | undefined
) => {
const handleChange = (range: DateRange | undefined) => {
range && setSelected(range);
};
return (
Expand Down
10 changes: 5 additions & 5 deletions examples/__snapshots__/Range.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ exports[`should match the snapshot 1`] = `
aria-colindex="1"
aria-label=""
aria-selected="true"
class="rdp-day rdp-focusable rdp-range_start rdp-selected"
class="rdp-day rdp-range_start rdp-selected rdp-focusable"
role="gridcell"
tabindex="0"
>
Expand All @@ -356,7 +356,7 @@ exports[`should match the snapshot 1`] = `
aria-colindex="2"
aria-label=""
aria-selected="true"
class="rdp-day rdp-focusable rdp-range_middle rdp-selected"
class="rdp-day rdp-range_middle rdp-selected rdp-focusable"
role="gridcell"
tabindex="-1"
>
Expand All @@ -370,7 +370,7 @@ exports[`should match the snapshot 1`] = `
aria-colindex="3"
aria-label=""
aria-selected="true"
class="rdp-day rdp-focusable rdp-range_middle rdp-selected"
class="rdp-day rdp-range_middle rdp-selected rdp-focusable"
role="gridcell"
tabindex="-1"
>
Expand All @@ -384,7 +384,7 @@ exports[`should match the snapshot 1`] = `
aria-colindex="4"
aria-label=""
aria-selected="true"
class="rdp-day rdp-focusable rdp-range_middle rdp-selected"
class="rdp-day rdp-range_middle rdp-selected rdp-focusable"
role="gridcell"
tabindex="-1"
>
Expand All @@ -398,7 +398,7 @@ exports[`should match the snapshot 1`] = `
aria-colindex="5"
aria-label=""
aria-selected="true"
class="rdp-day rdp-focusable rdp-range_end rdp-selected"
class="rdp-day rdp-range_end rdp-selected rdp-focusable"
role="gridcell"
tabindex="-1"
>
Expand Down
12 changes: 11 additions & 1 deletion react-day-picker.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@
"**/node_modules": true,
"**/versioned_docs": true
},
"jest.runMode": "on-save"
"jest.runMode": "on-demand",
"git.showProgress": true,
"scm.diffDecorationsGutterVisibility": "hover",
"scm.diffDecorationsGutterPattern": {
"modified": false
},
"scm.diffDecorationsGutterWidth": 1,
"scm.diffDecorations": "none",
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
}
11 changes: 3 additions & 8 deletions src/DayPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import React from "react";

import { Calendar } from "./components/Calendar";
import { ContextProviders } from "./contexts/root";
import type { DayPickerProps, Mode } from "./types";
import { ContextProviders } from "./contexts/providers";
import type { DayPickerProps } from "./types";

/**
* DayPicker is a React component to create date pickers, calendars, and date
* inputs for web applications.
*
* @template T - The {@link Mode | selection mode}. Defaults to `"default"`.
* @template R - Whether the selection is required. Defaults to `false`.
* @group Components
* @see http://daypicker.dev
*/
export function DayPicker<
T extends Mode = "default",
R extends boolean = false
>(props: DayPickerProps<T, R>) {
export function DayPicker(props: DayPickerProps) {
return (
<ContextProviders {...props}>
<Calendar />
Expand Down
40 changes: 26 additions & 14 deletions src/UI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import type { CustomComponents, ClassNames, Styles } from "./types";
* The UI elements composing DayPicker. These elements are mapped to
* {@link CustomComponents}, the {@link ClassNames} and the {@link Styles} used by
* DayPicker.
*
* Some of these elements are extended by flags and modifiers.
*/
export enum UI {
/** The previous button in the navigation. */
Expand All @@ -17,7 +19,10 @@ export enum UI {
Calendar = "calendar",
/** The Chevron SVG element used by navigation buttons and dropdowns. */
Chevron = "chevron",
/** The grid cell with the day's date. Extended by {@link DayModifier}. */
/**
* The grid cell with the day's date. Extended by {@link DayFlag} and
* {@link SelectionFlag}.
*/
Day = "day",
/** The element containing the formatted day's date, inside the grid cell. */
DayDate = "day_date",
Expand Down Expand Up @@ -60,38 +65,45 @@ export enum UI {
YearsDropdown = "years_dropdown"
}

/** The modifiers for the {@link UI.Day}. */
export enum DayModifier {
/** The flags for the {@link UI.Day}. */
export enum DayFlag {
/** The day is disabled */
disabled = "disabled",
/** The day is hidden */
hidden = "hidden",
/** The day is outside the current month */
outside = "outside",
/** The day is focusable. */
focusable = "focusable",
/** The day is focused. */
focused = "focused",
/** The day is today. */
today = "today"
}

/**
* The state that can be applied to the {@link UI.Day} element when in selection
* mode.
*/
export enum SelectionState {
/** The day is at the end of a selected range. */
range_end = "range_end",
/** The day is at the middle of a selected range. */
range_middle = "range_middle",
/** The day is at the start of a selected range. */
range_start = "range_start",
/** The day is selected. */
selected = "selected",
/** The day is focusable. */
focusable = "focusable",
/** The day is focused. */
focused = "focused",
/** The day is today. */
today = "today"
selected = "selected"
}

/** Flags that can be applied to the {@link UI.Calendar} element. */
export enum CalendarFlag {
/** Assigned when the week numbers are show. */
hasWeekNumbers = "has_week_numbers",
has_week_numbers = "has_week_numbers",
/** Assigned when the weekdays are hidden. */
noWeekdays = "no_weekdays",
no_weekdays = "no_weekdays",
/** Assigned when the calendar has multiple months. */
hasMultipleMonths = "has_multiple_months"
has_multiple_months = "has_multiple_months"
}

/** Flags that can be applied to the {@link UI.Chevron} element. */
Expand All @@ -106,5 +118,5 @@ export enum WeekNumberFlag {
* Assigned when the week number is interactive, i.e. has an
* `onWeekNumberClick` event attached to it.
*/
isInteractive = "week_number_interactive"
week_number_interactive = "week_number_interactive"
}
5 changes: 1 addition & 4 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import React, { ButtonHTMLAttributes } from "react";

// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type { PropsBase } from "../types";
import React, { type ButtonHTMLAttributes } from "react";

/**
* Render the button elements in the calendar.
Expand Down
Loading
Loading