From b210f8547f10f037e18a26a11e49149f0081576c Mon Sep 17 00:00:00 2001 From: Marcelo Terreiro Prado Date: Wed, 4 Dec 2024 12:55:36 -0300 Subject: [PATCH] Clarify referential equality (#72) * Clarify referential equality * fix ci --- .changeset/smart-pans-sleep.md | 2 + apps/docs/docs/fundamentals/usage.mdx | 47 ++++++++++++++++ .../CalendarGithubIssues.stories.tsx | 54 +++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 .changeset/smart-pans-sleep.md create mode 100644 apps/example/src/components/GithubIssues/CalendarGithubIssues.stories.tsx diff --git a/.changeset/smart-pans-sleep.md b/.changeset/smart-pans-sleep.md new file mode 100644 index 0000000..a845151 --- /dev/null +++ b/.changeset/smart-pans-sleep.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/apps/docs/docs/fundamentals/usage.mdx b/apps/docs/docs/fundamentals/usage.mdx index 5aaca4e..05a64d1 100644 --- a/apps/docs/docs/fundamentals/usage.mdx +++ b/apps/docs/docs/fundamentals/usage.mdx @@ -3,6 +3,7 @@ sidebar_position: 2 --- import Image from "@theme/IdealImage"; +import Admonition from "@theme/Admonition"; import { HStack } from "@site/src/components/HStack"; import basicCalendar from "./assets/basic-calendar.png"; import basicCalendarList from "./assets/basic-calendar-list.png"; @@ -225,6 +226,52 @@ export const CalendarCustomFormatting = () => { +#### Note on referential equality + +Due to Flash Calendar's architecture, it's important to make your date +formatting functions stable. You should move them outside the component +scope (preferred) or memoize them with `useCallback`. Refer to [Issue +69](https://github.com/MarceloPrado/flash-calendar/issues/69) for more. + + + + Make the formatting functions stable. + + ```tsx + const today = toDateId(new Date()); + + const Example = () => { + return ( + + + + ); + }; + + const formatWeekDay = (date: Date) => + format(date, "EEEEEE"); + ``` + + + + Break referential equality by inlining the formatting functions. + + ```tsx + + // prettier-ignore + format(date, "EEEEEE") + } + /> + ``` + + + + ## Min, max and disabled dates You can limit the range of selectable dates by using the `calendarMinDateId` and diff --git a/apps/example/src/components/GithubIssues/CalendarGithubIssues.stories.tsx b/apps/example/src/components/GithubIssues/CalendarGithubIssues.stories.tsx new file mode 100644 index 0000000..d8f7fb9 --- /dev/null +++ b/apps/example/src/components/GithubIssues/CalendarGithubIssues.stories.tsx @@ -0,0 +1,54 @@ +import { + Calendar, + toDateId, + useDateRange, +} from "@marceloterreiro/flash-calendar"; +import type { Meta } from "@storybook/react"; +import { addDays, format } from "date-fns"; +import { useEffect, useState } from "react"; +import { View } from "react-native"; + +const CalendarMeta: Meta = { + title: "Calendar/Github Issues", + decorators: [], +}; + +export default CalendarMeta; + +const today = toDateId(new Date()); +const todayPlusFive = toDateId(addDays(new Date(), 5)); + +// See more: https://github.com/MarceloPrado/flash-calendar/issues/69 +export const Issue69 = () => { + // This state is simplified for the example. In my case it would come from a context. + const [start, setStart] = useState(today); + const [end, setEnd] = useState(todayPlusFive); + + const { onCalendarDayPress, isDateRangeValid, calendarActiveDateRanges } = + useDateRange({ startId: start, endId: end }); // I am setting the default range here because I want the data from my context to be pre-selected here + + useEffect(() => { + // Every time the selected range changed I want to update my context (in this example the state) + if (isDateRangeValid && calendarActiveDateRanges.length > 0) { + const range = calendarActiveDateRanges[0]; + setStart(range.startId); + setEnd(range?.endId); + } + }, [calendarActiveDateRanges, isDateRangeValid]); + + return ( + + format(date, "EEEEEE")} + onCalendarDayPress={onCalendarDayPress} + /> + + ); +}; + +const formatWeekDay = (date: Date) => format(date, "EEEEEE");