@lazerlen/legend-calendar 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +29 -0
- package/.turbo/turbo-build.log +19 -0
- package/.turbo/turbo-lint.log +14 -0
- package/.turbo/turbo-test.log +261 -0
- package/.turbo/turbo-typecheck.log +1 -0
- package/CHANGELOG.md +127 -0
- package/dist/index.d.mts +679 -0
- package/dist/index.d.ts +679 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +47 -0
- package/src/components/Calendar.stories.tsx +226 -0
- package/src/components/Calendar.tsx +224 -0
- package/src/components/CalendarItemDay.tsx +385 -0
- package/src/components/CalendarItemEmpty.tsx +30 -0
- package/src/components/CalendarItemWeekName.tsx +67 -0
- package/src/components/CalendarList.stories.tsx +326 -0
- package/src/components/CalendarList.tsx +373 -0
- package/src/components/CalendarRowMonth.tsx +62 -0
- package/src/components/CalendarRowWeek.tsx +46 -0
- package/src/components/CalendarThemeProvider.tsx +43 -0
- package/src/components/HStack.tsx +67 -0
- package/src/components/VStack.tsx +67 -0
- package/src/components/index.ts +108 -0
- package/src/developer/decorators.tsx +54 -0
- package/src/developer/loggginHandler.tsx +6 -0
- package/src/developer/useRenderCount.ts +7 -0
- package/src/helpers/dates.test.ts +567 -0
- package/src/helpers/dates.ts +163 -0
- package/src/helpers/functions.ts +327 -0
- package/src/helpers/numbers.ts +11 -0
- package/src/helpers/strings.ts +2 -0
- package/src/helpers/tokens.ts +71 -0
- package/src/helpers/types.ts +3 -0
- package/src/hooks/useCalendar.test.ts +381 -0
- package/src/hooks/useCalendar.ts +351 -0
- package/src/hooks/useCalendarList.test.ts +382 -0
- package/src/hooks/useCalendarList.tsx +291 -0
- package/src/hooks/useDateRange.test.ts +128 -0
- package/src/hooks/useDateRange.ts +94 -0
- package/src/hooks/useOptimizedDayMetadata.test.ts +582 -0
- package/src/hooks/useOptimizedDayMetadata.ts +93 -0
- package/src/hooks/useTheme.ts +14 -0
- package/src/index.ts +24 -0
- package/tsconfig.json +13 -0
- package/tsup.config.ts +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Calendar.tsx","../src/components/CalendarItemDay.tsx","../../../node_modules/mitt/src/index.ts","../src/hooks/useOptimizedDayMetadata.ts","../src/hooks/useCalendar.ts","../src/helpers/dates.ts","../src/helpers/numbers.ts","../src/hooks/useTheme.ts","../src/helpers/tokens.ts","../src/components/CalendarThemeProvider.tsx","../src/components/CalendarItemEmpty.tsx","../src/components/CalendarItemWeekName.tsx","../src/components/CalendarRowMonth.tsx","../src/components/CalendarRowWeek.tsx","../src/components/HStack.tsx","../src/components/VStack.tsx","../src/helpers/strings.ts","../src/components/CalendarList.tsx","../src/hooks/useCalendarList.tsx","../src/helpers/functions.ts","../src/components/index.ts","../src/hooks/useDateRange.ts"],"sourcesContent":["import { memo, useEffect } from \"react\";\nimport type { ColorSchemeName, PressableProps } from \"react-native\";\n\nimport type {\n CalendarItemDayContainerProps,\n CalendarItemDayProps,\n} from \"@/components/CalendarItemDay\";\nimport {\n CalendarItemDayContainer,\n CalendarItemDayWithContainer,\n} from \"@/components/CalendarItemDay\";\nimport type { CalendarItemEmptyProps } from \"@/components/CalendarItemEmpty\";\nimport { CalendarItemEmpty } from \"@/components/CalendarItemEmpty\";\nimport type { CalendarItemWeekNameProps } from \"@/components/CalendarItemWeekName\";\nimport { CalendarItemWeekName } from \"@/components/CalendarItemWeekName\";\nimport type { CalendarRowMonthProps } from \"@/components/CalendarRowMonth\";\nimport { CalendarRowMonth } from \"@/components/CalendarRowMonth\";\nimport type { CalendarRowWeekProps } from \"@/components/CalendarRowWeek\";\nimport { CalendarRowWeek } from \"@/components/CalendarRowWeek\";\nimport { CalendarThemeProvider } from \"@/components/CalendarThemeProvider\";\nimport { VStack } from \"@/components/VStack\";\nimport { uppercaseFirstLetter } from \"@/helpers/strings\";\nimport type { BaseTheme } from \"@/helpers/tokens\";\nimport type { UseCalendarParams } from \"@/hooks/useCalendar\";\nimport { useCalendar } from \"@/hooks/useCalendar\";\nimport { activeDateRangesEmitter } from \"@/hooks/useOptimizedDayMetadata\";\n\nexport type PressableLike = React.ComponentType<\n Pick<PressableProps, \"children\" | \"style\" | \"disabled\"> & {\n onPress: () => void;\n }\n>;\n\nexport interface CalendarTheme {\n rowMonth?: CalendarRowMonthProps[\"theme\"];\n rowWeek?: CalendarRowWeekProps[\"theme\"];\n itemWeekName?: CalendarItemWeekNameProps[\"theme\"];\n itemEmpty?: CalendarItemEmptyProps[\"theme\"];\n itemDayContainer?: CalendarItemDayContainerProps[\"theme\"];\n /**\n * The theme for the day. `base` is applied before any state, allowing you to\n * set a base value once and use it for all states.\n */\n itemDay?: CalendarItemDayProps[\"theme\"];\n}\n\nexport type CalendarOnDayPress = (dateId: string) => void;\n\nexport interface CalendarProps extends UseCalendarParams {\n /**\n * A unique identifier for this calendar instance. This is useful if you\n * need to render more than one calendar at once. This allows Legend Calendar\n * to scope its state to the given instance.\n *\n * No need to get fancy with `uuid` or anything like that - a simple static\n * string is enough.\n *\n * If not provided, Legend Calendar will use a default value which will hoist\n * the state in a global scope.\n */\n calendarInstanceId?: string;\n /**\n * The spacing between each calendar row (the month header, the week days row,\n * and the weeks row)\n * @defaultValue 8\n */\n calendarRowVerticalSpacing?: number;\n /**\n * The spacing between each day in the weeks row.\n * @defaultValue 8\n */\n calendarRowHorizontalSpacing?: number;\n /**\n * The height of each day cell.\n * @defaultValue 32\n */\n calendarDayHeight?: number;\n /**\n * The height of the week day's header.\n * @defaultValue calendarDayHeight\n */\n calendarWeekHeaderHeight?: number;\n /**\n * The height of the month header.\n * @defaultValue 20\n */\n calendarMonthHeaderHeight?: number;\n /**\n * When set, Legend Calendar will use this color scheme instead of the system's\n * value (`light|dark`). This is useful if your app doesn't support dark-mode,\n * for example.\n *\n * We don't advise using this prop - ideally, your app should reflect the\n * user's preferences.\n * @defaultValue undefined\n */\n calendarColorScheme?: ColorSchemeName;\n /**\n * The callback to be called when a day is pressed.\n */\n onCalendarDayPress: CalendarOnDayPress;\n /** Theme to customize the calendar component. */\n theme?: CalendarTheme;\n /** Optional component to replace the default <Pressable> component. */\n CalendarPressableComponent?: PressableLike;\n}\n\nconst BaseCalendar = memo(function BaseCalendar(props: CalendarProps) {\n const {\n calendarInstanceId,\n calendarRowVerticalSpacing = 8,\n calendarRowHorizontalSpacing = 8,\n calendarDayHeight = 32,\n calendarMonthHeaderHeight = 20,\n calendarWeekHeaderHeight = calendarDayHeight,\n onCalendarDayPress,\n theme,\n CalendarPressableComponent,\n ...buildCalendarParams\n } = props;\n\n const { calendarRowMonth, weeksList, weekDaysList } =\n useCalendar(buildCalendarParams);\n\n return (\n <VStack\n alignItems=\"center\"\n spacing={calendarRowVerticalSpacing as keyof BaseTheme[\"spacing\"]}\n >\n <CalendarRowMonth\n height={calendarMonthHeaderHeight}\n theme={theme?.rowMonth}\n >\n {uppercaseFirstLetter(calendarRowMonth)}\n </CalendarRowMonth>\n <CalendarRowWeek spacing={8} theme={theme?.rowWeek}>\n {weekDaysList.map((weekDay, i) => (\n <CalendarItemWeekName\n height={calendarWeekHeaderHeight}\n key={i}\n theme={theme?.itemWeekName}\n >\n {weekDay}\n </CalendarItemWeekName>\n ))}\n </CalendarRowWeek>\n {weeksList.map((week, index) => (\n <CalendarRowWeek key={index}>\n {week.map((dayProps) => {\n if (dayProps.isDifferentMonth) {\n return (\n <CalendarItemDayContainer\n dayHeight={calendarDayHeight}\n daySpacing={calendarRowHorizontalSpacing}\n isStartOfWeek={dayProps.isStartOfWeek}\n key={dayProps.id}\n metadata={dayProps}\n theme={theme?.itemDayContainer}\n >\n <CalendarItemEmpty\n height={calendarDayHeight}\n theme={theme?.itemEmpty}\n />\n </CalendarItemDayContainer>\n );\n }\n\n return (\n <CalendarItemDayWithContainer\n CalendarPressableComponent={CalendarPressableComponent}\n calendarInstanceId={calendarInstanceId}\n containerTheme={theme?.itemDayContainer}\n dayHeight={calendarDayHeight}\n daySpacing={calendarRowHorizontalSpacing}\n key={dayProps.id}\n metadata={dayProps}\n onPress={onCalendarDayPress}\n theme={theme?.itemDay}\n >\n {dayProps.displayLabel}\n </CalendarItemDayWithContainer>\n );\n })}\n </CalendarRowWeek>\n ))}\n </VStack>\n );\n});\n\nexport const Calendar = memo(function Calendar(props: CalendarProps) {\n const {\n calendarInstanceId,\n calendarActiveDateRanges,\n calendarMonthId,\n calendarColorScheme,\n ...otherProps\n } = props;\n useEffect(() => {\n activeDateRangesEmitter.emit(\"onSetActiveDateRanges\", {\n instanceId: calendarInstanceId,\n ranges: calendarActiveDateRanges ?? [],\n });\n /**\n * While `calendarMonthId` is not used by the effect, we still need it in\n * the dependency array since [LegendList uses recycling\n * internally](https://legendapp.com/open-source/list/).\n *\n * This means `Calendar` can re-render with different props instead of\n * getting re-mounted. Without it, we would see staled/invalid data, as\n * reported by\n * [#11](https://github.com/MarceloPrado/flash-calendar/issues/11).\n */\n }, [calendarActiveDateRanges, calendarInstanceId, calendarMonthId]);\n\n return (\n <CalendarThemeProvider colorScheme={calendarColorScheme}>\n <BaseCalendar\n {...otherProps}\n calendarInstanceId={calendarInstanceId}\n calendarMonthId={calendarMonthId}\n />\n </CalendarThemeProvider>\n );\n});\n","import type { ReactNode } from \"react\";\nimport { useCallback, useMemo } from \"react\";\nimport type { TextProps, TextStyle, ViewStyle } from \"react-native\";\nimport { Pressable, StyleSheet, Text, View } from \"react-native\";\n\nimport type { BaseTheme } from \"@/helpers/tokens\";\nimport type { CalendarDayMetadata } from \"@/hooks/useCalendar\";\nimport { useOptimizedDayMetadata } from \"@/hooks/useOptimizedDayMetadata\";\nimport { useTheme } from \"@/hooks/useTheme\";\n\nimport type { PressableLike } from \"./Calendar\";\n\n// react-native-web/overrides.ts\ndeclare module \"react-native\" {\n interface PressableStateCallbackType {\n hovered?: boolean;\n focused?: boolean;\n }\n}\n\nconst styles = StyleSheet.create({\n baseContainer: {\n padding: 6,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: 16,\n flex: 1,\n },\n baseContent: {\n textAlign: \"center\",\n },\n});\n\nexport type DayState = \"idle\" | \"active\" | \"today\" | \"disabled\";\n\ninterface DayTheme {\n container: Omit<ViewStyle, \"borderRadius\">;\n content: TextStyle;\n}\ntype CalendarItemDayTheme = Record<\n DayState,\n (params: {\n isStartOfRange: boolean;\n isEndOfRange: boolean;\n isPressed: boolean;\n isHovered?: boolean;\n isFocused?: boolean;\n }) => DayTheme\n>;\n\nconst buildBaseStyles = (theme: BaseTheme): CalendarItemDayTheme => {\n const baseContent = {\n ...styles.baseContent,\n color: theme.colors.content.primary,\n };\n\n return {\n active: ({ isPressed, isHovered, isStartOfRange, isEndOfRange }) => {\n const baseStyles: DayTheme & { container: ViewStyle } =\n isPressed || isHovered\n ? {\n container: {\n ...styles.baseContainer,\n backgroundColor: theme.colors.background.tertiary,\n },\n content: {\n ...baseContent,\n color: theme.colors.content.primary,\n },\n }\n : {\n container: {\n ...styles.baseContainer,\n backgroundColor: theme.colors.background.inverse.primary,\n },\n content: {\n ...baseContent,\n color: theme.colors.content.inverse.primary,\n },\n };\n\n baseStyles.container.borderRadius = 0;\n if (isStartOfRange) {\n baseStyles.container.borderTopLeftRadius = 16;\n baseStyles.container.borderBottomLeftRadius = 16;\n }\n if (isEndOfRange) {\n baseStyles.container.borderTopRightRadius = 16;\n baseStyles.container.borderBottomRightRadius = 16;\n }\n if (!isStartOfRange && !isEndOfRange) {\n baseStyles.container.borderRadius = 0;\n }\n return baseStyles;\n },\n disabled: () => ({\n container: styles.baseContainer,\n content: {\n ...baseContent,\n color: theme.colors.content.disabled,\n },\n }),\n idle: ({ isPressed, isHovered }) => {\n return isPressed || isHovered\n ? {\n container: {\n ...styles.baseContainer,\n backgroundColor: theme.colors.background.tertiary,\n },\n content: {\n ...baseContent,\n color: theme.colors.content.primary,\n },\n }\n : {\n container: styles.baseContainer,\n content: baseContent,\n };\n },\n today: ({ isPressed, isHovered }) => {\n return isPressed || isHovered\n ? {\n container: {\n ...styles.baseContainer,\n backgroundColor: theme.colors.background.tertiaryPressed,\n },\n content: baseContent,\n }\n : {\n container: {\n ...styles.baseContainer,\n borderColor: theme.colors.borders.default,\n borderStyle: \"solid\",\n borderWidth: 1,\n },\n content: baseContent,\n };\n },\n };\n};\n\nexport interface CalendarItemDayProps {\n children: ReactNode;\n onPress: (id: string) => void;\n metadata: CalendarDayMetadata;\n theme?: Partial<\n Record<\n DayState | \"base\",\n (\n params: CalendarDayMetadata & {\n isPressed: boolean;\n isHovered?: boolean;\n isFocused?: boolean;\n }\n ) => Partial<DayTheme>\n >\n >;\n /** The cell's height */\n height: number;\n /** Optional TextProps to spread to the <Text> component. */\n textProps?: Omit<TextProps, \"children\" | \"onPress\">;\n /** Optional component to replace the default <Pressable> component. */\n CalendarPressableComponent?: PressableLike;\n}\n\n/**\n * The base calendar item day component. This component is responsible for\n * rendering each day cell, along with its event handlers.\n *\n * This is not meant to be used directly. Instead, use the\n * `CalendarItemDayWithContainer`, since it also includes the spacing between\n * each day.\n */\nexport const CalendarItemDay = ({\n onPress,\n children,\n theme,\n height,\n metadata,\n textProps,\n CalendarPressableComponent = Pressable as PressableLike,\n}: CalendarItemDayProps) => {\n const baseTheme = useTheme();\n const baseStyles = useMemo(() => {\n return buildBaseStyles(baseTheme);\n }, [baseTheme]);\n\n const handlePress = useCallback(() => {\n onPress(metadata.id);\n }, [metadata.id, onPress]);\n\n return (\n <CalendarPressableComponent\n disabled={metadata.state === \"disabled\"}\n onPress={handlePress}\n style={({\n pressed: isPressed,\n hovered: isHovered,\n focused: isFocused,\n }) => {\n const params = {\n isPressed,\n isHovered,\n isFocused,\n isEndOfRange: metadata.isEndOfRange ?? false,\n isStartOfRange: metadata.isStartOfRange ?? false,\n };\n const { container } = baseStyles[metadata.state](params);\n return {\n ...container,\n height,\n ...theme?.base?.({ ...metadata, isPressed }).container,\n ...theme?.[metadata.state]?.({ ...metadata, isPressed }).container,\n };\n }}\n >\n {({ pressed: isPressed, hovered: isHovered, focused: isFocused }) => {\n const params = {\n isPressed,\n isHovered,\n isFocused,\n isEndOfRange: metadata.isEndOfRange ?? false,\n isStartOfRange: metadata.isStartOfRange ?? false,\n };\n const { content } = baseStyles[metadata.state](params);\n return (\n <Text\n {...textProps}\n style={{\n ...content,\n ...(textProps?.style ?? ({} as object)),\n ...theme?.base?.({ ...metadata, isPressed, isHovered, isFocused })\n .content,\n ...theme?.[metadata.state]?.({\n ...metadata,\n isPressed,\n isHovered,\n isFocused,\n }).content,\n }}\n >\n {children}\n </Text>\n );\n }}\n </CalendarPressableComponent>\n );\n};\n\ninterface CalendarItemDayContainerTheme {\n /** An empty view that acts as a spacer between each day. The spacing is\n * controlled by the `daySpacing` prop. */\n spacer?: ViewStyle;\n /** An absolute positioned filler to join the active days together in a single\n * complete range. */\n activeDayFiller?: ViewStyle | ((params: CalendarDayMetadata) => ViewStyle);\n}\n\nexport interface CalendarItemDayContainerProps {\n children: ReactNode;\n isStartOfWeek: boolean;\n /**\n * If true, the active day filler/extension will be shown. The filler is used\n * as a visual effect to join the active days together in a complete range.\n */\n shouldShowActiveDayFiller?: boolean;\n theme?: CalendarItemDayContainerTheme;\n /**\n * The spacing between each day\n */\n daySpacing: number;\n /** The day's height */\n dayHeight: number;\n /** The metadata for the day, extracted from the calendar's state. */\n metadata?: CalendarDayMetadata;\n}\n\nexport const CalendarItemDayContainer = ({\n children,\n isStartOfWeek,\n shouldShowActiveDayFiller,\n theme,\n daySpacing,\n dayHeight,\n metadata,\n}: CalendarItemDayContainerProps) => {\n const baseTheme = useTheme();\n const spacerStyles = useMemo<ViewStyle>(() => {\n return {\n position: \"relative\",\n marginLeft: isStartOfWeek ? 0 : daySpacing,\n flex: 1,\n height: dayHeight,\n ...theme?.spacer,\n };\n }, [dayHeight, daySpacing, isStartOfWeek, theme?.spacer]);\n\n const activeDayFiller = useMemo<ViewStyle | null>(() => {\n if (!shouldShowActiveDayFiller) {\n return null;\n }\n\n return {\n position: \"absolute\",\n top: 0,\n bottom: 0,\n right: -(daySpacing + 1), // +1 to cover the 1px gap\n width: daySpacing + 2, // +2 to cover the 1px gap (distributes evenly on both sides)\n backgroundColor: baseTheme.colors.background.inverse.primary,\n ...(typeof theme?.activeDayFiller === \"function\" && !!metadata\n ? theme.activeDayFiller(metadata)\n : theme?.activeDayFiller),\n };\n }, [\n baseTheme.colors.background.inverse.primary,\n daySpacing,\n metadata,\n shouldShowActiveDayFiller,\n theme,\n ]);\n\n return (\n <View style={spacerStyles}>\n {children}\n {activeDayFiller ? <View style={activeDayFiller} /> : null}\n </View>\n );\n};\n\nexport interface CalendarItemDayWithContainerProps\n extends Omit<CalendarItemDayProps, \"height\">,\n Pick<CalendarItemDayContainerProps, \"daySpacing\" | \"dayHeight\"> {\n containerTheme?: CalendarItemDayContainerTheme;\n /**\n * A unique identifier for this calendar instance. This is useful if you\n * need to render more than one calendar at once. This allows Legend Calendar\n * to scope its state to the given instance.\n *\n * No need to get fancy with `uuid` or anything like that - a simple static\n * string is enough.\n *\n * If not provided, Legend Calendar will use a default value which will hoist\n * the state in a global scope.\n */\n calendarInstanceId?: string;\n}\n\nexport const CalendarItemDayWithContainer = ({\n children,\n metadata: baseMetadata,\n onPress,\n theme,\n dayHeight,\n daySpacing,\n containerTheme,\n calendarInstanceId,\n CalendarPressableComponent,\n}: CalendarItemDayWithContainerProps) => {\n const metadata = useOptimizedDayMetadata(baseMetadata, calendarInstanceId);\n\n return (\n <CalendarItemDayContainer\n dayHeight={dayHeight}\n daySpacing={daySpacing}\n isStartOfWeek={metadata.isStartOfWeek}\n metadata={metadata}\n shouldShowActiveDayFiller={\n metadata.isRangeValid && !metadata.isEndOfWeek\n ? !metadata.isEndOfRange\n : false\n }\n theme={containerTheme}\n >\n <CalendarItemDay\n CalendarPressableComponent={CalendarPressableComponent}\n height={dayHeight}\n metadata={metadata}\n onPress={onPress}\n theme={theme}\n >\n {children}\n </CalendarItemDay>\n </CalendarItemDayContainer>\n );\n};\n","export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n\tWildcardHandler<T>\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n\tall: EventHandlerMap<Events>;\n\n\ton<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n\ton(type: '*', handler: WildcardHandler<Events>): void;\n\n\toff<Key extends keyof Events>(\n\t\ttype: Key,\n\t\thandler?: Handler<Events[Key]>\n\t): void;\n\toff(type: '*', handler: WildcardHandler<Events>): void;\n\n\temit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n\temit<Key extends keyof Events>(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt<Events extends Record<EventType, unknown>>(\n\tall?: EventHandlerMap<Events>\n): Emitter<Events> {\n\ttype GenericEventHandler =\n\t\t| Handler<Events[keyof Events]>\n\t\t| WildcardHandler<Events>;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList<Events[keyof Events]>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList<Events>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n","import mitt from \"mitt\";\nimport { useEffect, useState } from \"react\";\n\nimport {\n getStateFields,\n type CalendarActiveDateRange,\n type CalendarDayMetadata,\n} from \"@/hooks/useCalendar\";\n\ninterface OnSetActiveDateRangesPayload {\n instanceId?: string;\n ranges: CalendarActiveDateRange[];\n}\n\n/**\n * An event emitter for the active date ranges. This notifies the calendar items\n * when their state changes, allowing just the affected items to re-render.\n *\n * While this is an implementation detail focused on improving performance, it's\n * exported in case you need to build your own calendar. Check the source code\n * for a reference implementation.\n */\nexport const activeDateRangesEmitter = mitt<{\n onSetActiveDateRanges: OnSetActiveDateRangesPayload;\n}>();\n\n/**\n * The default calendar instance ID. This is used when no instance ID is provided.\n */\nconst DEFAULT_CALENDAR_INSTANCE_ID = \"legend-calendar-default-instance\";\n\n/**\n * Returns an optimized metadata for a particular day. This hook listens to the\n * `activeDateRanges` emitter, enabling only the affected calendar items to\n * re-render.\n *\n * While this is an implementation detail focused on improving performance, it's\n * exported in case you need to build your own calendar. Check the source code\n * for a reference implementation.\n */\nexport const useOptimizedDayMetadata = (\n baseMetadata: CalendarDayMetadata,\n calendarInstanceId?: string\n) => {\n const [metadata, setMetadata] = useState(baseMetadata);\n\n const safeCalendarInstanceId =\n calendarInstanceId ?? DEFAULT_CALENDAR_INSTANCE_ID;\n\n // Ensure the metadata is updated when the base changes.\n useEffect(() => {\n setMetadata(baseMetadata);\n }, [baseMetadata]);\n\n useEffect(() => {\n const handler = (payload: OnSetActiveDateRangesPayload) => {\n const { ranges, instanceId = DEFAULT_CALENDAR_INSTANCE_ID } = payload;\n if (instanceId !== safeCalendarInstanceId) {\n // This event is not for this instance, ignore it.\n return;\n }\n\n // We're only interested in the active date ranges, no need to worry about\n // disabled states. These are already covered by the base metadata.\n const { isStartOfRange, isEndOfRange, isRangeValid, state } =\n getStateFields({\n id: metadata.id,\n calendarActiveDateRanges: ranges,\n });\n\n if (state === \"active\") {\n setMetadata((prev) => ({\n ...prev,\n isStartOfRange,\n isEndOfRange,\n isRangeValid,\n state,\n }));\n } else {\n // Resets the state when it's no longer active.\n setMetadata(baseMetadata);\n }\n };\n\n activeDateRangesEmitter.on(\"onSetActiveDateRanges\", handler);\n\n return () => {\n activeDateRangesEmitter.off(\"onSetActiveDateRanges\", handler);\n };\n }, [baseMetadata, safeCalendarInstanceId, metadata]);\n\n return metadata;\n};\n","import { useMemo } from \"react\";\n\nimport type { DayState } from \"@/components/CalendarItemDay\";\nimport {\n addDays,\n endOfMonth,\n fromDateId,\n isWeekend,\n startOfMonth,\n startOfWeek,\n subDays,\n toDateId,\n} from \"@/helpers/dates\";\nimport { range } from \"@/helpers/numbers\";\n\nconst getNumberOfEmptyCellsAtStart = (\n month: Date,\n firstDayOfWeek: \"sunday\" | \"monday\"\n) => {\n const startOfMonthDay = month.getDay();\n\n if (firstDayOfWeek === \"sunday\") {\n return startOfMonthDay;\n }\n\n return startOfMonthDay === 0 ? 6 : startOfMonthDay - 1;\n};\n\n/** All fields that affects the day's state. */\ninterface CalendarDayStateFields {\n /** Is this day disabled? */\n isDisabled: boolean;\n /** Is this the current day? */\n isToday: boolean;\n /** Is this the start of a range? */\n isStartOfRange: boolean;\n /** Is this the end of a range? */\n isEndOfRange: boolean;\n /** The state of the day */\n state: DayState;\n /** Is the range valid (has both start and end dates set)? */\n isRangeValid: boolean;\n}\n\n/**\n * The type of each day in the calendar. Has a few pre-computed properties to\n * help increase re-rendering performance.\n */\nexport type CalendarDayMetadata = {\n date: Date;\n /** The day displayed in the desired format from `calendarDayFormat` */\n displayLabel: string;\n /** Does this day belong to a different month? */\n isDifferentMonth: boolean;\n /** Is this the last day of the month? */\n isEndOfMonth: boolean;\n /** Is this the last day of the week? */\n isEndOfWeek: boolean;\n /** Is this the first day of the month? */\n isStartOfMonth: boolean;\n /** Is this the first day of the week? */\n isStartOfWeek: boolean;\n /** Is this day part of the weekend? */\n isWeekend: boolean;\n\n /** The ID of this date is the `YYYY-MM-DD` representation */\n id: string;\n} & CalendarDayStateFields;\n\n/**\n * An active date range to highlight in the calendar.\n */\nexport interface CalendarActiveDateRange {\n startId?: string;\n endId?: string;\n}\n\nexport interface UseCalendarParams {\n /**\n * The calendar's month. It can be any date within the month, since it gets\n * normalized to the first day of the month.\n *\n * **Tip**: To convert to date ID, use `toDateId(date)`.\n */\n calendarMonthId: string;\n /**\n * The minimum date allowed to be selected (inclusive). Dates earlier than\n * this will be disabled.\n *\n * **Tip**: To convert to date ID, use `toDateId(date)`.\n */\n calendarMinDateId?: string;\n /**\n * The maximum date allowed to be selected (inclusive). Dates later than this\n * will be disabled.\n *\n * **Tip**: To convert to date ID, use `toDateId(date)`.\n */\n calendarMaxDateId?: string;\n\n /**\n * The locale to use for the date formatting. If you're using custom\n * formatting functions, this value will be forwarded as the second argument.\n * @defaultValue \"en-US\"\n */\n calendarFormatLocale?: string;\n\n /**\n * A custom function to override the default month format (\"January 2022\").\n */\n getCalendarMonthFormat?: (date: Date, locale: string) => string;\n\n /**\n * A custom function to override the default month format (\"S\", \"M\", \"T\").\n */\n getCalendarWeekDayFormat?: (date: Date, locale: string) => string;\n /**\n * A custom function to override the default day format (\"1\", \"9\", \"17\").\n */\n getCalendarDayFormat?: (date: Date, locale: string) => string;\n /**\n * The day of the week to start the calendar with.\n * @defaultValue \"sunday\"\n */\n calendarFirstDayOfWeek?: \"sunday\" | \"monday\";\n /**\n * The active date ranges to highlight in the calendar.\n */\n calendarActiveDateRanges?: CalendarActiveDateRange[];\n /**\n * The disabled date IDs. Dates in this list will be in the `disabled` state\n * unless they are part of an active range.\n */\n calendarDisabledDateIds?: string[];\n}\n\ntype GetStateFields = Pick<\n UseCalendarParams,\n | \"calendarActiveDateRanges\"\n | \"calendarMinDateId\"\n | \"calendarMaxDateId\"\n | \"calendarDisabledDateIds\"\n> & {\n todayId?: string;\n id: string;\n};\n\n/**\n * Computes the state fields for a given date.\n */\nexport const getStateFields = ({\n todayId,\n id,\n calendarActiveDateRanges,\n calendarMinDateId,\n calendarMaxDateId,\n calendarDisabledDateIds,\n}: GetStateFields): CalendarDayStateFields => {\n const activeRange = calendarActiveDateRanges?.find(({ startId, endId }) => {\n // Regular range\n if (startId && endId) {\n return id >= startId && id <= endId;\n } else if (startId) {\n return id === startId;\n } else if (endId) {\n return id === endId;\n }\n return false;\n });\n\n const isRangeValid =\n activeRange?.startId !== undefined && activeRange.endId !== undefined;\n\n const isDisabled =\n (calendarDisabledDateIds?.includes(id) ||\n (calendarMinDateId && id < calendarMinDateId) ||\n (calendarMaxDateId && id > calendarMaxDateId)) === true;\n\n const isToday = todayId === id;\n\n const state: DayState = activeRange\n ? (\"active\" as const)\n : isDisabled\n ? \"disabled\"\n : isToday\n ? \"today\"\n : \"idle\";\n\n return {\n isStartOfRange: id === activeRange?.startId,\n isEndOfRange: id === activeRange?.endId,\n isRangeValid,\n state,\n isDisabled,\n isToday,\n };\n};\n\nconst getBaseCalendarMonthFormat = (date: Date, locale: string) => {\n return new Intl.DateTimeFormat(locale, {\n month: \"long\",\n year: \"numeric\",\n }).format(date);\n};\nconst getBaseCalendarWeekDayFormat = (date: Date, locale: string) => {\n return new Intl.DateTimeFormat(locale, {\n weekday: \"narrow\",\n }).format(date);\n};\n\nconst getBaseCalendarDayFormat = (date: Date, locale: string) => {\n return new Intl.DateTimeFormat(locale, {\n day: \"numeric\",\n }).format(date);\n};\n\n/**\n * Builds a calendar based on the given parameters.\n */\nexport const buildCalendar = (params: UseCalendarParams) => {\n const {\n calendarMonthId: monthId,\n calendarFirstDayOfWeek = \"sunday\",\n calendarFormatLocale = \"en-US\",\n getCalendarMonthFormat = getBaseCalendarMonthFormat,\n getCalendarWeekDayFormat = getBaseCalendarWeekDayFormat,\n getCalendarDayFormat = getBaseCalendarDayFormat,\n } = params;\n\n const month = fromDateId(monthId);\n const monthStart = startOfMonth(month);\n const monthStartId = toDateId(monthStart);\n const monthEnd = endOfMonth(month);\n const monthEndId = toDateId(monthEnd);\n\n const emptyDaysAtStart = getNumberOfEmptyCellsAtStart(\n monthStart,\n calendarFirstDayOfWeek\n );\n\n const startOfWeekIndex = calendarFirstDayOfWeek === \"sunday\" ? 0 : 1;\n const endOfWeekIndex = calendarFirstDayOfWeek === \"sunday\" ? 6 : 0;\n\n const todayId = toDateId(new Date());\n\n // The first day to iterate is the first day of the month minus the empty days at the start\n let dayToIterate = subDays(monthStart, emptyDaysAtStart);\n\n const weeksList: CalendarDayMetadata[][] = [\n [\n ...range(1, emptyDaysAtStart).map((): CalendarDayMetadata => {\n const id = toDateId(dayToIterate);\n\n const dayShape: CalendarDayMetadata = {\n date: dayToIterate,\n displayLabel: getCalendarDayFormat(\n dayToIterate,\n calendarFormatLocale\n ),\n id,\n isDifferentMonth: true,\n isEndOfMonth: false,\n isEndOfWeek: dayToIterate.getDay() === endOfWeekIndex,\n isStartOfMonth: false,\n isStartOfWeek: dayToIterate.getDay() === startOfWeekIndex,\n isWeekend: isWeekend(dayToIterate),\n ...getStateFields({\n ...params,\n todayId,\n id,\n }),\n };\n dayToIterate = addDays(dayToIterate, 1);\n return dayShape;\n }),\n ],\n ];\n\n // By this point, we're back at the start of the month\n while (dayToIterate.getMonth() === monthStart.getMonth()) {\n const currentWeek = weeksList[weeksList.length - 1];\n if (currentWeek.length === 7) {\n weeksList.push([]);\n }\n const id = toDateId(dayToIterate);\n weeksList[weeksList.length - 1].push({\n date: dayToIterate,\n displayLabel: getCalendarDayFormat(dayToIterate, calendarFormatLocale),\n id,\n isDifferentMonth: false,\n isEndOfMonth: id === monthEndId,\n isEndOfWeek: dayToIterate.getDay() === endOfWeekIndex,\n isStartOfMonth: id === monthStartId,\n isStartOfWeek: dayToIterate.getDay() === startOfWeekIndex,\n isWeekend: isWeekend(dayToIterate),\n ...getStateFields({\n ...params,\n todayId,\n id,\n }),\n });\n dayToIterate = addDays(dayToIterate, 1);\n }\n\n // Once all the days of the month have been added, we need to add the empty days at the end\n const lastWeek = weeksList[weeksList.length - 1];\n const emptyDaysAtEnd = 7 - lastWeek.length;\n lastWeek.push(\n ...range(1, emptyDaysAtEnd).map(() => {\n const id = toDateId(dayToIterate);\n const dayShape: CalendarDayMetadata = {\n date: dayToIterate,\n displayLabel: getCalendarDayFormat(dayToIterate, calendarFormatLocale),\n id,\n isDifferentMonth: true,\n isEndOfMonth: false,\n isEndOfWeek: dayToIterate.getDay() === endOfWeekIndex,\n isStartOfMonth: false,\n isStartOfWeek: dayToIterate.getDay() === startOfWeekIndex,\n isWeekend: isWeekend(dayToIterate),\n ...getStateFields({\n ...params,\n todayId,\n id,\n }),\n };\n dayToIterate = addDays(dayToIterate, 1);\n return dayShape;\n })\n );\n\n const startOfWeekDate = startOfWeek(month, calendarFirstDayOfWeek);\n const weekDaysList = range(1, 7).map((i) =>\n getCalendarWeekDayFormat(\n addDays(startOfWeekDate, i - 1),\n calendarFormatLocale\n )\n );\n\n return {\n weeksList,\n calendarRowMonth: getCalendarMonthFormat(month, calendarFormatLocale),\n weekDaysList,\n };\n};\n\n/**\n * Returns a memoized calendar based on the given parameters.\n */\nexport const useCalendar = (params: UseCalendarParams) =>\n useMemo(() => buildCalendar(params), [params]);\n","/**\n * Returns the date formatted as YYYY-MM-DD, ensuring timezone doesn't affect\n * the result.\n */\nexport function toDateId(date: Date) {\n const year = date.getFullYear();\n const month = date.getMonth() + 1; // getMonth() returns 0-11\n const day = date.getDate();\n\n // Pad single digit month and day with leading zeros\n const monthFormatted = month < 10 ? `0${month}` : month;\n const dayFormatted = day < 10 ? `0${day}` : day;\n\n return `${year}-${monthFormatted}-${dayFormatted}`;\n}\n\n/**\n * Converts a date ID to a `Date` object, correctly accounting for timezone.\n */\nexport function fromDateId(dateId: string) {\n const [year, month, day] = dateId.split(\"-\").map(Number);\n return new Date(year, month - 1, day);\n}\n\n/**\n * Returns the first day of the month for the given date.\n */\nexport function startOfMonth(date: Date) {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n}\n\n/**\n * Returns the last day of the month for the given date.\n */\nexport function endOfMonth(date: Date) {\n const nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 1);\n const lastDay = new Date(nextMonth.getTime() - 1);\n return new Date(lastDay);\n}\n\n/**\n * Returns the first day of the week for the given date.\n */\nexport function startOfWeek(\n baseDate: Date,\n firstDayOfWeek: \"monday\" | \"sunday\"\n): Date {\n // Clone the baseDate to avoid modifying the original date\n const date = new Date(baseDate.getTime());\n\n // Calculate the day of the week (0 for Sunday, 1 for Monday, etc.)\n const dayOfWeek = date.getDay();\n const isSunday = dayOfWeek === 0;\n\n if (isSunday && firstDayOfWeek === \"monday\") {\n date.setDate(date.getDate() - 6);\n return date;\n }\n\n // Calculate the difference between the current day and the first day of the week\n const diff = dayOfWeek - (firstDayOfWeek === \"monday\" ? 1 : 0);\n date.setDate(date.getDate() - diff);\n\n return date;\n}\n\n/**\n * Add `n` months to the given date.\n */\nexport function addMonths(date: Date, months: number) {\n const newDate = new Date(date);\n newDate.setMonth(newDate.getMonth() + months);\n return newDate;\n}\n\n/**\n * Subtract `n` months from the given date.\n */\nexport function subMonths(date: Date, months: number) {\n const newDate = new Date(date);\n newDate.setMonth(newDate.getMonth() - months);\n return newDate;\n}\n\n/**\n * Add `n` days to the given date.\n */\nexport function addDays(date: Date, days: number) {\n const newDate = new Date(date);\n newDate.setDate(newDate.getDate() + days);\n return newDate;\n}\n\n/**\n * Subtract `n` days from the given date.\n */\nexport function subDays(date: Date, days: number) {\n const newDate = new Date(date);\n newDate.setDate(newDate.getDate() - days);\n return newDate;\n}\n\n/**\n * Does the given date fall on a weekend?\n */\nexport function isWeekend(date: Date) {\n const day = date.getDay();\n return day === 0 || day === 6;\n}\n\n/**\n * Get the number of months between the given dates.\n */\nexport function differenceInMonths(laterDate: Date, earlierDate: Date) {\n const yearDiff = laterDate.getFullYear() - earlierDate.getFullYear();\n const monthDiff = laterDate.getMonth() - earlierDate.getMonth();\n\n return yearDiff * 12 + monthDiff;\n}\n\n/**\n * Get the number of weeks in the month for the given date.\n */\nexport function getWeeksInMonth(\n date: Date,\n firstDayOfWeek: \"monday\" | \"sunday\"\n) {\n const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);\n let dayOfWeek = firstDay.getDay();\n\n // Adjust the first day of the week\n if (firstDayOfWeek === \"monday\") {\n dayOfWeek = dayOfWeek === 0 ? 6 : dayOfWeek - 1;\n }\n\n const totalDays = new Date(\n date.getFullYear(),\n date.getMonth() + 1,\n 0\n ).getDate();\n\n return Math.ceil((dayOfWeek + totalDays) / 7);\n}\n\n/**\n * Get the week of the month of the given date. The week index is 1-based.\n */\nexport function getWeekOfMonth(\n date: Date,\n firstDayOfWeek: \"monday\" | \"sunday\"\n) {\n const firstDay = new Date(date.getFullYear(), date.getMonth(), 1);\n let dayOfWeek = firstDay.getDay();\n\n // Adjust the first day of the week\n if (firstDayOfWeek === \"monday\") {\n dayOfWeek = dayOfWeek === 0 ? 6 : dayOfWeek - 1;\n }\n\n const dayOfMonth = date.getDate();\n\n return Math.floor((dayOfWeek + dayOfMonth - 1) / 7) + 1;\n}\n","/**\n * Returns a list of numbers from `start` (inclusive) to `stop`\n * (inclusive). In mathematical terms, `range(a, b)` is equivalent to\n * the interval `[a, b]`.\n *\n * An optional `step` can be provided to control the size of the increemnt (defaults to `1`).\n *\n * Copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from\n */\nexport const range = (start: number, stop: number, step = 1) =>\n Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step);\n","import { useColorScheme } from \"react-native\";\n\nimport type { BaseTheme } from \"@/helpers/tokens\";\nimport { darkTheme, lightTheme } from \"@/helpers/tokens\";\nimport { useCalendarTheme } from \"@/components/CalendarThemeProvider\";\n\nexport const useTheme = (): BaseTheme => {\n const appearance = useColorScheme();\n const { colorScheme } = useCalendarTheme();\n\n const theme = colorScheme ?? appearance;\n\n return theme === \"dark\" ? darkTheme : lightTheme;\n};\n","const baseTokens = {\n spacing: {\n 0: 0,\n 2: 2,\n 4: 4,\n 6: 6,\n 8: 8,\n 12: 12,\n 16: 16,\n 20: 20,\n 24: 24,\n },\n} as const;\n\n/**\n * Minimal theme for the Legend Calendar component.\n * @internal\n */\nexport const lightTheme = {\n ...baseTokens,\n colors: {\n content: {\n disabled: \"#B0B0B0\",\n primary: \"#000000\",\n secondary: \"#212121\",\n inverse: {\n primary: \"#FFFFFF\",\n },\n },\n background: {\n primary: \"#FFFFFF\",\n tertiary: \"#EDEFEE\",\n tertiaryPressed: \"#D1D2D3\",\n inverse: {\n primary: \"#000000\",\n },\n },\n borders: {\n default: \"#E0E0E0\",\n },\n transparent: \"transparent\",\n },\n} as const;\n\nexport const darkTheme = {\n ...baseTokens,\n colors: {\n content: {\n disabled: \"#bdbdbd\",\n primary: \"#FFFFFF\",\n secondary: \"#e8e8e8\",\n inverse: {\n primary: \"#000000\",\n },\n },\n background: {\n primary: \"#000000\",\n tertiary: \"#111111\",\n tertiaryPressed: \"#212121\",\n inverse: {\n primary: \"#FFFFFF\",\n },\n },\n borders: {\n default: \"#5c5c5c\",\n },\n transparent: \"transparent\",\n },\n} as const;\n\nexport type BaseTheme = typeof lightTheme | typeof darkTheme;\n","import type { ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\nimport type { ColorSchemeName } from \"react-native\";\n\nexport interface CalendarThemeContextType {\n colorScheme?: ColorSchemeName;\n}\n\nconst CalendarThemeContext = createContext<CalendarThemeContextType>({\n colorScheme: undefined,\n});\n\nexport const CalendarThemeProvider = ({\n children,\n colorScheme,\n}: {\n children: ReactNode;\n /**\n * When set, Legend Calendar will use this color scheme instead of the system's\n * value (`light|dark`). This is useful if your app doesn't support dark-mode,\n * for example.\n *\n * We don't advise using this prop - ideally, your app should reflect the\n * user's preferences.\n */\n colorScheme?: ColorSchemeName;\n}) => {\n const calendarThemeContextValue = useMemo<CalendarThemeContextType>(\n () => ({ colorScheme }),\n [colorScheme]\n );\n\n return (\n <CalendarThemeContext.Provider value={calendarThemeContextValue}>\n {children}\n </CalendarThemeContext.Provider>\n );\n};\n\nexport const useCalendarTheme = () => {\n const context = useContext(CalendarThemeContext);\n return context;\n};\n","import { memo, useMemo } from \"react\";\nimport type { ViewStyle } from \"react-native\";\nimport { View, StyleSheet } from \"react-native\";\n\nconst styles = StyleSheet.create({\n container: {\n padding: 6,\n flex: 1,\n },\n});\n\nexport interface CalendarItemEmptyProps {\n /** The height of the cell. Should be the same as `CalendarItemDay`. */\n height: number;\n /** The theme of the empty cell, useful for customizing the component. */\n theme?: {\n container?: ViewStyle;\n };\n}\n\nexport const CalendarItemEmpty = memo(function CalendarItemEmpty(\n props: CalendarItemEmptyProps\n) {\n const { height, theme } = props;\n const containerStyles = useMemo(() => {\n return [{ ...styles.container, height }, theme?.container];\n }, [height, theme?.container]);\n\n return <View style={containerStyles} />;\n});\n","import type { ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextProps, TextStyle, ViewStyle } from \"react-native\";\nimport { StyleSheet, Text, View } from \"react-native\";\n\nimport { lightTheme } from \"@/helpers/tokens\";\nimport { useTheme } from \"@/hooks/useTheme\";\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: \"center\",\n flex: 1,\n justifyContent: \"center\",\n padding: lightTheme.spacing[6],\n },\n content: {},\n});\n\ninterface CalendarItemWeekNameTheme {\n container?: ViewStyle;\n content?: TextStyle;\n}\n\nexport interface CalendarItemWeekNameProps {\n children: ReactNode;\n /**\n * The height of the week name, needed to correctly measure the calendar's\n */\n height: number;\n /** The theme of the week name, useful for customizing the component. */\n theme?: CalendarItemWeekNameTheme;\n /** Optional TextProps to spread to the <Text> component. */\n textProps?: Omit<TextProps, \"children\">;\n}\n\nexport const CalendarItemWeekName = ({\n children,\n height,\n theme,\n textProps,\n}: CalendarItemWeekNameProps) => {\n const { colors } = useTheme();\n const { containerStyles, contentStyles } = useMemo(() => {\n const containerStyles = [styles.container, { height }, theme?.container];\n const contentStyles = [\n styles.content,\n { color: colors.content.primary },\n textProps?.style,\n theme?.content,\n ];\n return { containerStyles, contentStyles };\n }, [\n colors.content.primary,\n height,\n theme?.container,\n theme?.content,\n textProps?.style,\n ]);\n\n return (\n <View style={containerStyles}>\n <Text {...textProps} style={contentStyles}>\n {children}\n </Text>\n </View>\n );\n};\n","import type { ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport type { TextStyle, ViewStyle } from \"react-native\";\nimport { StyleSheet, Text, View } from \"react-native\";\n\nimport { useTheme } from \"@/hooks/useTheme\";\n\nconst styles = StyleSheet.create({\n container: {\n width: \"100%\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n content: {\n textAlign: \"center\",\n width: \"100%\",\n },\n});\n\ninterface CalendarRowMonthTheme {\n container?: ViewStyle;\n content?: TextStyle;\n}\n\nexport interface CalendarRowMonthProps {\n children: ReactNode;\n /**\n * The height of the month row, needed to correctly measure the calendar's\n * height.\n */\n height: number;\n /** The theme of the month row, useful for customizing the component. */\n theme?: CalendarRowMonthTheme;\n}\n\nexport const CalendarRowMonth = ({\n children,\n height,\n theme,\n}: CalendarRowMonthProps) => {\n const baseTheme = useTheme();\n const { containerStyles, contentStyles } = useMemo(() => {\n const containerStyles = [styles.container, { height }, theme?.container];\n const contentStyles = [\n styles.content,\n { color: baseTheme.colors.content.primary },\n theme?.content,\n ];\n return { containerStyles, contentStyles };\n }, [\n baseTheme.colors.content.primary,\n height,\n theme?.container,\n theme?.content,\n ]);\n\n return (\n <View style={containerStyles}>\n <Text style={contentStyles}>{children}</Text>\n </View>\n );\n};\n","import type { ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport type { ViewStyle } from \"react-native\";\nimport { StyleSheet } from \"react-native\";\n\nimport { HStack } from \"@/components/HStack\";\nimport type { BaseTheme } from \"@/helpers/tokens\";\n\nexport interface CalendarRowWeekProps {\n children: ReactNode;\n spacing?: keyof BaseTheme[\"spacing\"];\n theme?: CalendarRowWeekTheme;\n}\n\ninterface CalendarRowWeekTheme {\n container?: ViewStyle;\n}\n\nconst styles = StyleSheet.create({\n container: {\n width: \"100%\",\n },\n});\n\nexport const CalendarRowWeek = ({\n children,\n spacing = 0,\n theme,\n}: CalendarRowWeekProps) => {\n const { containerStyles } = useMemo(() => {\n return {\n containerStyles: { ...styles.container, ...(theme?.container ?? {}) },\n };\n }, [theme?.container]);\n return (\n <HStack\n alignItems=\"center\"\n grow\n justifyContent=\"space-between\"\n spacing={spacing}\n style={containerStyles}\n >\n {children}\n </HStack>\n );\n};\n","import { useMemo, type ReactNode } from \"react\";\nimport { StyleSheet, View, type ViewStyle } from \"react-native\";\n\nconst styles = StyleSheet.create({\n container: {\n alignItems: \"center\",\n flexDirection: \"row\",\n flexGrow: 0,\n flexShrink: 0,\n flexWrap: \"nowrap\",\n justifyContent: \"flex-start\",\n },\n});\n\nexport interface HStackProps {\n alignItems?: ViewStyle[\"alignItems\"];\n justifyContent?: ViewStyle[\"justifyContent\"];\n children: ReactNode;\n grow?: boolean;\n shrink?: boolean;\n spacing?: number;\n wrap?: ViewStyle[\"flexWrap\"];\n backgroundColor?: string;\n style?: ViewStyle;\n width?: ViewStyle[\"width\"];\n}\n\nexport const HStack = ({\n alignItems,\n children,\n justifyContent = \"flex-start\",\n grow = false,\n shrink = false,\n spacing = 0,\n wrap = \"nowrap\",\n backgroundColor,\n width,\n style = {},\n}: HStackProps) => {\n const containerStyles = useMemo<ViewStyle[]>(\n () => [\n styles.container,\n { gap: spacing },\n grow ? { flexGrow: 1 } : {},\n shrink ? { flexShrink: 1 } : {},\n wrap ? { flexWrap: wrap } : {},\n alignItems ? { alignItems } : {},\n justifyContent ? { justifyContent } : {},\n backgroundColor ? { backgroundColor } : {},\n width ? { width } : {},\n style,\n ],\n [\n alignItems,\n backgroundColor,\n grow,\n justifyContent,\n shrink,\n spacing,\n style,\n width,\n wrap,\n ]\n );\n\n return <View style={containerStyles}>{children}</View>;\n};\n","import {\n Children,\n Fragment,\n isValidElement,\n useMemo,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport { StyleSheet, View, type ViewStyle } from \"react-native\";\n\nconst styles = StyleSheet.create({\n container: {\n flexDirection: \"column\",\n },\n});\n\nexport interface VStackDividerProps {\n marginBottom: number;\n}\n\nexport interface VStackProps {\n children: ReactNode;\n spacing?: number;\n\n alignItems?: ViewStyle[\"alignItems\"];\n justifyContent?: ViewStyle[\"justifyContent\"];\n\n /** If the VStack should `flex: 1` to fill the parent's height */\n grow?: boolean;\n}\n\nfunction isFragment(\n child: ReactNode\n): child is ReactElement<{ children?: ReactNode }> {\n return isValidElement(child) && child.type === Fragment;\n}\n\nexport function VStack({\n children,\n spacing = 0,\n alignItems,\n justifyContent,\n grow,\n}: VStackProps) {\n const containerStyles = useMemo<ViewStyle>(\n () => ({\n ...styles.container,\n gap: spacing,\n alignItems,\n justifyContent,\n flex: grow ? 1 : undefined,\n }),\n [alignItems, grow, justifyContent, spacing]\n );\n\n return (\n <View style={containerStyles}>\n {Children.toArray(children)\n .map((c) => (isFragment(c) ? c.props.children : c))\n .flat()\n .filter((c) => c !== null && typeof c !== \"undefined\")\n .map((child, i) => (\n <Fragment key={i}>{child}</Fragment>\n ))}\n </View>\n );\n}\n","export const uppercaseFirstLetter = (value: string) =>\n value.charAt(0).toUpperCase() + value.slice(1);\n","import {\n LegendList as LegendListBase,\n type LegendListProps,\n type LegendListRef,\n} from \"@legendapp/list\";\nimport { memo, useCallback, useImperativeHandle, useMemo, useRef } from \"react\";\nimport { View } from \"react-native\";\n\nimport type { CalendarProps } from \"@/components/Calendar\";\nimport { Calendar } from \"@/components/Calendar\";\nimport { getWeekOfMonth, startOfMonth, toDateId } from \"@/helpers/dates\";\nimport type { CalendarMonth } from \"@/hooks/useCalendarList\";\nimport { getHeightForMonth, useCalendarList } from \"@/hooks/useCalendarList\";\n\n// Type assertion to make LegendList compatible with React 19\nconst LegendList = LegendListBase as <T>(\n props: LegendListProps<T> & { ref?: React.Ref<LegendListRef> }\n) => React.ReactElement;\n/**\n * Represents each `CalendarList` item. It's enhanced with the required\n * `Calendar` props to simplify building custom `Calendar` components.\n */\nexport type CalendarMonthEnhanced = CalendarMonth & {\n calendarProps: Omit<CalendarProps, \"calendarMonthId\">;\n};\n\nconst keyExtractor = (month: CalendarMonth) => month.id;\n\nexport interface CalendarListProps\n extends Omit<CalendarProps, \"calendarMonthId\">,\n Omit<\n LegendListProps<CalendarMonthEnhanced>,\n \"renderItem\" | \"data\" | \"children\"\n > {\n /**\n * How many months to show before the current month. Once the user scrolls\n * past this range and if they haven't exceeded the `calendarMinDateId`, new\n * months are prepended in this increment.\n * @defaultValue 12\n */\n calendarPastScrollRangeInMonths?: number;\n /**\n * How many months to show after the current month. Once the user scrolls\n * past this range and if they haven't exceeded the `calendarMaxDateId`, new\n * months are appended in this increment.\n * @defaultValue 12\n */\n calendarFutureScrollRangeInMonths?: number;\n\n /**\n * An additional height to use in the month's height calculation. Useful when\n * providing a custom `Calendar` component with extra content such as a\n * footer.\n */\n calendarAdditionalHeight?: number;\n\n /**\n * The vertical spacing between each `<Calendar />` component.\n * @defaultValue 20\n */\n calendarSpacing?: number;\n\n /**\n * The initial month to open the calendar to, as a `YYYY-MM-DD` string.\n * Defaults to the current month.\n *\n * **Tip**: To convert to date ID, use `toDateId(date)`.\n */\n calendarInitialMonthId?: string;\n\n /**\n * Overwrites the default `Calendar` component.\n *\n * **Important**: when providing a custom implementation, make sure to\n * manually set all the spacing and height props to ensure the list scrolls\n * to the right offset:\n * - calendarDayHeight\n * - calendarMonthHeaderHeight\n * - calendarWeekHeaderHeight\n * - calendarAdditionalHeight\n * - calendarRowVerticalSpacing\n * - calendarSpacing\n */\n renderItem?: LegendListProps<CalendarMonthEnhanced>[\"renderItem\"];\n}\n\ninterface ImperativeScrollParams {\n /**\n * An additional offset to add to the final scroll position. Useful when\n * you need to slightly change the final scroll position.\n */\n additionalOffset?: number;\n}\nexport interface CalendarListRef {\n scrollToMonth: (\n date: Date,\n animated: boolean,\n params?: ImperativeScrollParams\n ) => void;\n scrollToDate: (\n date: Date,\n animated: boolean,\n params?: ImperativeScrollParams\n ) => void;\n scrollToOffset: (offset: number, animated: boolean) => void;\n}\n\nexport const CalendarList = memo(function CalendarList({\n ref,\n ...props\n}: CalendarListProps & { ref?: React.Ref<CalendarListRef> }) {\n const {\n // List-related props\n calendarInitialMonthId,\n calendarPastScrollRangeInMonths = 12,\n calendarFutureScrollRangeInMonths = 12,\n calendarFirstDayOfWeek = \"sunday\",\n calendarFormatLocale,\n\n // Spacings\n calendarSpacing = 20,\n calendarRowHorizontalSpacing,\n calendarRowVerticalSpacing = 8,\n\n // Heights\n calendarMonthHeaderHeight = 20,\n calendarDayHeight = 32,\n calendarWeekHeaderHeight = calendarDayHeight,\n calendarAdditionalHeight = 0,\n\n // Other props\n calendarColorScheme,\n theme,\n onEndReached,\n onStartReached,\n ...otherProps\n } = props;\n\n const {\n calendarActiveDateRanges,\n calendarDisabledDateIds,\n calendarInstanceId,\n calendarMaxDateId,\n calendarMinDateId,\n getCalendarDayFormat,\n getCalendarMonthFormat,\n getCalendarWeekDayFormat,\n onCalendarDayPress,\n CalendarPressableComponent,\n ...flatListProps\n } = otherProps;\n\n const calendarProps = useMemo(\n (): CalendarMonthEnhanced[\"calendarProps\"] => ({\n calendarActiveDateRanges,\n calendarColorScheme,\n calendarDayHeight,\n calendarDisabledDateIds,\n calendarFirstDayOfWeek,\n calendarFormatLocale,\n calendarInstanceId,\n calendarMaxDateId,\n calendarMinDateId,\n calendarMonthHeaderHeight,\n calendarRowHorizontalSpacing,\n calendarRowVerticalSpacing,\n calendarWeekHeaderHeight,\n getCalendarDayFormat,\n getCalendarMonthFormat,\n getCalendarWeekDayFormat,\n onCalendarDayPress,\n theme,\n CalendarPressableComponent,\n }),\n [\n calendarColorScheme,\n calendarActiveDateRanges,\n calendarDayHeight,\n calendarDisabledDateIds,\n calendarFirstDayOfWeek,\n calendarFormatLocale,\n calendarMaxDateId,\n calendarMinDateId,\n calendarMonthHeaderHeight,\n calendarRowHorizontalSpacing,\n calendarRowVerticalSpacing,\n calendarWeekHeaderHeight,\n getCalendarDayFormat,\n getCalendarMonthFormat,\n getCalendarWeekDayFormat,\n calendarInstanceId,\n onCalendarDayPress,\n theme,\n CalendarPressableComponent,\n ]\n );\n\n const {\n initialMonthIndex,\n monthList,\n appendMonths,\n prependMonths,\n addMissingMonths,\n } = useCalendarList({\n calendarFirstDayOfWeek,\n calendarFutureScrollRangeInMonths,\n calendarPastScrollRangeInMonths,\n calendarInitialMonthId,\n calendarMaxDateId,\n calendarMinDateId,\n });\n\n const monthListWithCalendarProps = useMemo(() => {\n return monthList.map((month) => ({\n ...month,\n calendarProps,\n }));\n }, [calendarProps, monthList]);\n\n const handleOnEndReached = useCallback(\n (info: { distanceFromEnd: number }) => {\n appendMonths(calendarFutureScrollRangeInMonths);\n onEndReached?.(info);\n },\n [appendMonths, calendarFutureScrollRangeInMonths, onEndReached]\n );\n\n const handleOnStartReached = useCallback(\n (info: { distanceFromStart: number }) => {\n prependMonths(calendarPastScrollRangeInMonths);\n onStartReached?.(info);\n },\n [prependMonths, calendarPastScrollRangeInMonths, onStartReached]\n );\n\n const handleGetFixedItemSize = useCallback(\n (_index: number, item: CalendarMonth) => {\n return getHeightForMonth({\n calendarMonth: item,\n calendarSpacing,\n calendarDayHeight,\n calendarMonthHeaderHeight,\n calendarRowVerticalSpacing,\n calendarAdditionalHeight,\n calendarWeekHeaderHeight,\n });\n },\n [\n calendarAdditionalHeight,\n calendarDayHeight,\n calendarMonthHeaderHeight,\n calendarRowVerticalSpacing,\n calendarSpacing,\n calendarWeekHeaderHeight,\n ]\n );\n\n /**\n * Returns the offset for the given month (how much the user needs to\n * scroll to reach the month).\n */\n const getScrollOffsetForMonth = useCallback(\n (date: Date) => {\n const monthId = toDateId(startOfMonth(date));\n\n let baseMonthList = monthList;\n let index = baseMonthList.findIndex((month) => month.id === monthId);\n\n if (index === -1) {\n baseMonthList = addMissingMonths(monthId);\n index = baseMonthList.findIndex((month) => month.id === monthId);\n }\n\n return baseMonthList.slice(0, index).reduce((acc, month) => {\n const currentHeight = getHeightForMonth({\n calendarMonth: month,\n calendarSpacing,\n calendarDayHeight,\n calendarMonthHeaderHeight,\n calendarRowVerticalSpacing,\n calendarWeekHeaderHeight,\n calendarAdditionalHeight,\n });\n\n return acc + currentHeight;\n }, 0);\n },\n [\n addMissingMonths,\n calendarAdditionalHeight,\n calendarDayHeight,\n calendarMonthHeaderHeight,\n calendarRowVerticalSpacing,\n calendarSpacing,\n calendarWeekHeaderHeight,\n monthList,\n ]\n );\n\n const legendListRef = useRef<LegendListRef>(null);\n\n useImperativeHandle(ref, () => ({\n scrollToMonth(\n date,\n animated,\n { additionalOffset = 0 } = { additionalOffset: 0 }\n ) {\n // Wait for the next render cycle to ensure the list has been\n // updated with the new months.\n setTimeout(() => {\n legendListRef.current?.scrollToOffset({\n offset: getScrollOffsetForMonth(date) + additionalOffset,\n animated,\n });\n }, 0);\n },\n scrollToDate(\n date,\n animated,\n { additionalOffset = 0 } = {\n additionalOffset: 0,\n }\n ) {\n const currentMonthOffset = getScrollOffsetForMonth(date);\n const weekOfMonthIndex = getWeekOfMonth(date, calendarFirstDayOfWeek);\n const rowHeight = calendarDayHeight + calendarRowVerticalSpacing;\n\n let weekOffset = calendarWeekHeaderHeight + rowHeight * weekOfMonthIndex;\n\n /**\n * We need to subtract one vertical spacing to avoid cutting off the\n * desired date. A simple way of understanding why is imagining we\n * want to scroll exactly to the given date, but leave a little bit of\n * breathing room (`calendarRowVerticalSpacing`) above it.\n */\n weekOffset = weekOffset - calendarRowVerticalSpacing;\n\n legendListRef.current?.scrollToOffset({\n offset: currentMonthOffset + weekOffset + additionalOffset,\n animated,\n });\n },\n scrollToOffset(offset, animated) {\n legendListRef.current?.scrollToOffset({ offset, animated });\n },\n }));\n\n const calendarContainerStyle = useMemo(() => {\n return { paddingBottom: calendarSpacing };\n }, [calendarSpacing]);\n\n return (\n <LegendList\n data={monthListWithCalendarProps}\n estimatedItemSize={273}\n getFixedItemSize={handleGetFixedItemSize}\n initialScrollIndex={initialMonthIndex}\n keyExtractor={keyExtractor}\n onEndReached={handleOnEndReached}\n onStartReached={handleOnStartReached}\n recycleItems\n ref={legendListRef}\n renderItem={({ item }: { item: CalendarMonthEnhanced }) => (\n <View style={calendarContainerStyle}>\n <Calendar calendarMonthId={item.id} {...item.calendarProps} />\n </View>\n )}\n showsVerticalScrollIndicator={false}\n style={{ flex: 1 }}\n {...flatListProps}\n />\n );\n});\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport type { CalendarProps } from \"@/components/Calendar\";\nimport {\n fromDateId,\n toDateId,\n startOfMonth,\n addMonths,\n subMonths,\n differenceInMonths,\n getWeeksInMonth,\n} from \"@/helpers/dates\";\nimport type { UseCalendarParams } from \"@/hooks/useCalendar\";\nimport { pipe } from \"@/helpers/functions\";\n\nexport interface CalendarMonth {\n id: string;\n date: Date;\n numberOfWeeks: number;\n}\n\nconst buildMonthList = (\n startingMonth: Date,\n endingMonth: Date,\n firstDayOfWeek: CalendarProps[\"calendarFirstDayOfWeek\"] = \"sunday\"\n): CalendarMonth[] => {\n const startingMonthId = toDateId(startingMonth);\n const endingMonthId = toDateId(endingMonth);\n\n if (endingMonthId < startingMonthId) {\n return [];\n }\n\n const months = [\n {\n id: toDateId(startingMonth),\n date: startingMonth,\n numberOfWeeks: getWeeksInMonth(startingMonth, firstDayOfWeek),\n },\n ];\n\n if (startingMonthId === endingMonthId) {\n return months;\n }\n\n const numberOfMonths = differenceInMonths(endingMonth, startingMonth);\n\n for (let i = 1; i <= numberOfMonths; i++) {\n const month = addMonths(startingMonth, i);\n const numberOfWeeks = getWeeksInMonth(month, firstDayOfWeek);\n\n months.push({\n id: toDateId(month),\n date: month,\n numberOfWeeks,\n });\n }\n return months;\n};\n\nexport interface UseCalendarListParams\n extends Pick<UseCalendarParams, \"calendarMinDateId\" | \"calendarMaxDateId\"> {\n /**\n * The initial month to open the calendar to, as a `YYYY-MM-DD` string.\n * @defaultValue today\n */\n calendarInitialMonthId?: string;\n /**\n * How many months to show before the current month. Only applicable if\n * `calendarMinDateId` is not set.\n */\n calendarPastScrollRangeInMonths: number;\n /**\n * How many months to show after the current month. Applicable if\n * `calendarMaxDateId` is not set.\n */\n calendarFutureScrollRangeInMonths: number;\n calendarFirstDayOfWeek: \"monday\" | \"sunday\";\n}\n\nconst getEndingMonth = (\n calendarFutureScrollRange: number,\n calendarMaxDateId: string | undefined,\n baseDate: Date\n) => {\n const endingMonthFromRange = addMonths(baseDate, calendarFutureScrollRange);\n const newEndingMonthId = toDateId(endingMonthFromRange);\n const safeMaxDateId = calendarMaxDateId ?? newEndingMonthId;\n\n // We've exceeded the max date\n return startOfMonth(\n newEndingMonthId > safeMaxDateId\n ? fromDateId(safeMaxDateId)\n : endingMonthFromRange\n );\n};\n\nconst getStartingMonth = (\n calendarPastScrollRange: number,\n calendarMinDateId: string | undefined,\n baseDate: Date\n) => {\n const startingMonthFromRange = subMonths(baseDate, calendarPastScrollRange);\n const newStartingMonthId = toDateId(startingMonthFromRange);\n const safeMinDateId = calendarMinDateId ?? newStartingMonthId;\n\n // We've exceeded the min date.\n return safeMinDateId > newStartingMonthId\n ? // Normalize to start of month since each month ID is represented by the first day of month\n pipe(fromDateId(safeMinDateId), startOfMonth)\n : startingMonthFromRange;\n};\n\n/**\n * Returns a list of months to display in the calendar, and methods to append\n * and prepend months to the list.\n */\nexport const useCalendarList = ({\n calendarInitialMonthId,\n calendarPastScrollRangeInMonths,\n calendarFutureScrollRangeInMonths,\n calendarFirstDayOfWeek,\n calendarMaxDateId,\n calendarMinDateId,\n}: UseCalendarListParams) => {\n // Initialize key values\n const { initialMonth, initialMonthId } = useMemo(() => {\n const baseDate = calendarInitialMonthId\n ? fromDateId(calendarInitialMonthId)\n : fromDateId(toDateId(new Date()));\n\n // Normalize to start of month since each month ID is represented by the first day of month\n const baseStartOfMonth = startOfMonth(baseDate);\n\n return {\n initialMonth: baseStartOfMonth,\n initialMonthId: toDateId(baseStartOfMonth),\n };\n }, [calendarInitialMonthId]);\n\n const [monthList, setMonthList] = useState<CalendarMonth[]>(() => {\n const currentMonth = startOfMonth(initialMonth);\n\n const startingMonth = getStartingMonth(\n calendarPastScrollRangeInMonths,\n calendarMinDateId,\n currentMonth\n );\n\n const endingMonth = getEndingMonth(\n calendarFutureScrollRangeInMonths,\n calendarMaxDateId,\n currentMonth\n );\n\n return buildMonthList(startingMonth, endingMonth, calendarFirstDayOfWeek);\n });\n\n /**\n * Append new months to the list.\n */\n const appendMonths = useCallback(\n (numberOfMonths: number) => {\n // Last month + 1\n const startingMonth = addMonths(monthList[monthList.length - 1].date, 1);\n\n const endingMonth = getEndingMonth(\n Math.max(numberOfMonths - 1, 0),\n calendarMaxDateId,\n startingMonth\n );\n\n const hasReachedEndingMonth = monthList.find(\n (m) => m.id === toDateId(endingMonth)\n );\n if (hasReachedEndingMonth) {\n return monthList;\n }\n\n const newMonths = buildMonthList(\n startingMonth,\n endingMonth,\n calendarFirstDayOfWeek\n );\n\n const newMonthList = [...monthList, ...newMonths];\n setMonthList(newMonthList);\n return newMonthList;\n },\n [calendarFirstDayOfWeek, calendarMaxDateId, monthList]\n );\n\n const prependMonths = useCallback(\n (numberOfMonths: number) => {\n const endingMonth = subMonths(monthList[0].date, 1);\n\n const startingMonth = getStartingMonth(\n Math.max(numberOfMonths - 1, 0),\n calendarMinDateId,\n endingMonth\n );\n\n const newMonths = buildMonthList(\n startingMonth,\n endingMonth,\n calendarFirstDayOfWeek\n );\n\n const newMonthList = [...newMonths, ...monthList];\n setMonthList(newMonthList);\n return newMonthList;\n },\n [calendarFirstDayOfWeek, calendarMinDateId, monthList]\n );\n\n const addMissingMonths = useCallback(\n (targetMonthId: string) => {\n const firstMonth = monthList[0];\n const lastMonth = monthList[monthList.length - 1];\n\n if (targetMonthId > lastMonth.id) {\n return appendMonths(\n differenceInMonths(fromDateId(targetMonthId), lastMonth.date)\n );\n } else {\n return prependMonths(\n differenceInMonths(firstMonth.date, fromDateId(targetMonthId))\n );\n }\n },\n [appendMonths, monthList, prependMonths]\n );\n\n const initialMonthIndex = useMemo(() => {\n const index = monthList.findIndex((i) => i.id === initialMonthId);\n return index;\n }, [initialMonthId, monthList]);\n\n return {\n /**\n * The list of months to display in the calendar.\n */\n monthList,\n /**\n * The index of the initial month in the list.\n */\n initialMonthIndex,\n /**\n * Appends new months to the list.\n */\n appendMonths,\n /**\n * Prepends new months to the list.\n */\n prependMonths,\n /**\n * Adds missing months to the list, so that the target month is included.\n */\n addMissingMonths,\n };\n};\n\n/**\n * Returns the absolute height for a month, accounting for the spacings and\n * headers.\n */\nexport const getHeightForMonth = ({\n calendarRowVerticalSpacing: vSpacing,\n calendarDayHeight: day,\n calendarWeekHeaderHeight: weekName,\n calendarMonthHeaderHeight: header,\n calendarAdditionalHeight: extraHeight,\n calendarMonth,\n calendarSpacing,\n}: {\n calendarAdditionalHeight: number;\n calendarDayHeight: number;\n calendarMonthHeaderHeight: number;\n calendarRowVerticalSpacing: number;\n calendarWeekHeaderHeight: number;\n calendarMonth: CalendarMonth;\n calendarSpacing: number;\n}) => {\n const headerHeight = header + vSpacing + weekName + vSpacing;\n const daysHeight =\n day * calendarMonth.numberOfWeeks +\n // The last week doesn't have a bottom spacing (not referring to `calendarSpacing`)\n (calendarMonth.numberOfWeeks - 1) * vSpacing;\n\n return headerHeight + daysHeight + extraHeight + calendarSpacing;\n};\n","/**\n * Pipes the value of an expression into a pipeline of functions.\n *\n * See also [`flow`](#flow).\n *\n * @example\n * import { pipe } from 'fp-ts/function'\n *\n * const len = (s: string): number => s.length\n * const double = (n: number): number => n * 2\n *\n * // without pipe\n * assert.strictEqual(double(len('aaa')), 6)\n *\n * // with pipe\n * assert.strictEqual(pipe('aaa', len, double), 6)\n *\n * @remark copied from https://github.com/gcanti/fp-ts/blob/master/src/function.ts\n */\nexport function pipe<A>(a: A): A;\nexport function pipe<A, B>(a: A, ab: (a: A) => B): B;\nexport function pipe<A, B, C>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;\nexport function pipe<A, B, C, D>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D\n): D;\nexport function pipe<A, B, C, D, E>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E\n): E;\nexport function pipe<A, B, C, D, E, F>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F\n): F;\nexport function pipe<A, B, C, D, E, F, G>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G\n): G;\nexport function pipe<A, B, C, D, E, F, G, H>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H\n): H;\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I\n): I;\nexport function pipe<A, B, C, D, E, F, G, H, I, J>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J\n): J;\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K\n): K;\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L\n): L;\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M\n): M;\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M,\n mn: (m: M) => N\n): N;\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M,\n mn: (m: M) => N,\n no: (n: N) => O\n): O;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M,\n mn: (m: M) => N,\n no: (n: N) => O,\n op: (o: O) => P\n): P;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M,\n mn: (m: M) => N,\n no: (n: N) => O,\n op: (o: O) => P,\n pq: (p: P) => Q\n): Q;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M,\n mn: (m: M) => N,\n no: (n: N) => O,\n op: (o: O) => P,\n pq: (p: P) => Q,\n qr: (q: Q) => R\n): R;\n\nexport function pipe<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M,\n mn: (m: M) => N,\n no: (n: N) => O,\n op: (o: O) => P,\n pq: (p: P) => Q,\n qr: (q: Q) => R,\n rs: (r: R) => S\n): S;\n\nexport function pipe<\n A,\n B,\n C,\n D,\n E,\n F,\n G,\n H,\n I,\n J,\n K,\n L,\n M,\n N,\n O,\n P,\n Q,\n R,\n S,\n T\n>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n ij: (i: I) => J,\n jk: (j: J) => K,\n kl: (k: K) => L,\n lm: (l: L) => M,\n mn: (m: M) => N,\n no: (n: N) => O,\n op: (o: O) => P,\n pq: (p: P) => Q,\n qr: (q: Q) => R,\n rs: (r: R) => S,\n st: (s: S) => T\n): T;\nexport function pipe(\n a: unknown,\n ab?: Function,\n bc?: Function,\n cd?: Function,\n de?: Function,\n ef?: Function,\n fg?: Function,\n gh?: Function,\n hi?: Function\n): unknown {\n switch (arguments.length) {\n case 1:\n return a;\n case 2:\n return ab!(a);\n case 3:\n return bc!(ab!(a));\n case 4:\n return cd!(bc!(ab!(a)));\n case 5:\n return de!(cd!(bc!(ab!(a))));\n case 6:\n return ef!(de!(cd!(bc!(ab!(a)))));\n case 7:\n return fg!(ef!(de!(cd!(bc!(ab!(a))))));\n case 8:\n return gh!(fg!(ef!(de!(cd!(bc!(ab!(a)))))));\n case 9:\n return hi!(gh!(fg!(ef!(de!(cd!(bc!(ab!(a))))))));\n default: {\n // eslint-disable-next-line prefer-rest-params\n let ret = arguments[0];\n for (let i = 1; i < arguments.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, prefer-rest-params\n ret = arguments[i](ret);\n }\n return ret;\n }\n }\n}\n","import { Calendar as CalendarDefault } from \"@/components/Calendar\";\nimport {\n CalendarItemDay,\n CalendarItemDayContainer,\n CalendarItemDayWithContainer,\n} from \"@/components/CalendarItemDay\";\nimport { CalendarItemEmpty } from \"@/components/CalendarItemEmpty\";\nimport { CalendarItemWeekName } from \"@/components/CalendarItemWeekName\";\nimport { CalendarList } from \"@/components/CalendarList\";\nimport { CalendarRowMonth } from \"@/components/CalendarRowMonth\";\nimport { CalendarRowWeek } from \"@/components/CalendarRowWeek\";\nimport { HStack } from \"@/components/HStack\";\nimport { VStack } from \"@/components/VStack\";\n\n/**\n * This file houses the public API for the legend-calendar package.\n */\n\ntype CalendarItemDayNamespace = {\n Container: typeof CalendarItemDayContainer;\n WithContainer: typeof CalendarItemDayWithContainer;\n} & typeof CalendarItemDay;\n\nconst CalendarItemDayWithNamespace =\n CalendarItemDay as CalendarItemDayNamespace;\n\nCalendarItemDayWithNamespace.Container = CalendarItemDayContainer;\nCalendarItemDayWithNamespace.WithContainer = CalendarItemDayWithContainer;\nexport type {\n CalendarOnDayPress,\n CalendarProps,\n CalendarTheme,\n} from \"@/components/Calendar\";\nexport type {\n CalendarItemDayContainerProps,\n CalendarItemDayProps,\n CalendarItemDayWithContainerProps,\n} from \"@/components/CalendarItemDay\";\nexport type { CalendarItemEmptyProps } from \"@/components/CalendarItemEmpty\";\nexport type { CalendarItemWeekNameProps } from \"@/components/CalendarItemWeekName\";\nexport type {\n CalendarListProps,\n CalendarListRef,\n CalendarMonthEnhanced,\n} from \"@/components/CalendarList\";\nexport type { CalendarRowMonthProps } from \"@/components/CalendarRowMonth\";\nexport type { CalendarRowWeekProps } from \"@/components/CalendarRowWeek\";\nexport type { HStackProps } from \"@/components/HStack\";\nexport type { VStackProps } from \"@/components/VStack\";\n\ninterface CalendarItemNamespace {\n /**\n * Renders the day item of the calendar (e.g. `1`, `2`, `3`, etc.)\n */\n Day: typeof CalendarItemDayWithNamespace;\n /**\n * Renders the week day name item of the calendar (e.g. `Sun`, `Mon`, `Tue`, etc.)\n */\n WeekName: typeof CalendarItemWeekName;\n /**\n * Renders an empty item to fill the calendar's grid in the start or end of\n * the month.\n */\n Empty: typeof CalendarItemEmpty;\n}\n\nconst CalendarItemWithNamespace = {} as CalendarItemNamespace;\nCalendarItemWithNamespace.Day = CalendarItemDayWithNamespace;\n\nCalendarItemWithNamespace.WeekName = CalendarItemWeekName;\n\nCalendarItemWithNamespace.Empty = CalendarItemEmpty;\n\ninterface CalendarRowNamespace {\n /**\n * Renders the month row of the calendar (e.g. `January`, `February`, `March`, etc.)\n */\n Month: typeof CalendarRowMonth;\n /**\n * Renders each week row of the calendar, including the week day names.\n */\n Week: typeof CalendarRowWeek;\n}\n\nconst CalendarRowWithNamespace = {} as CalendarRowNamespace;\nCalendarRowWithNamespace.Month = CalendarRowMonth;\n\nCalendarRowWithNamespace.Week = CalendarRowWeek;\n\ntype CalendarNamespace = {\n Item: typeof CalendarItemWithNamespace;\n Row: typeof CalendarRowWithNamespace;\n List: typeof CalendarList;\n HStack: typeof HStack;\n VStack: typeof VStack;\n} & typeof CalendarDefault;\n\nconst CalendarWithNamespace = CalendarDefault as CalendarNamespace;\nCalendarWithNamespace.Item = CalendarItemWithNamespace;\nCalendarWithNamespace.Row = CalendarRowWithNamespace;\n\nCalendarWithNamespace.List = CalendarList;\n\n// Useful for customizing the layout of the calendar, re-exported for convenience\nCalendarWithNamespace.HStack = HStack;\nCalendarWithNamespace.VStack = VStack;\n\nexport const Calendar = CalendarWithNamespace;\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport type { CalendarOnDayPress } from \"@/components\";\nimport type { CalendarActiveDateRange } from \"@/hooks/useCalendar\";\n\n/**\n * A convenience hook to simplify managing a date range in the calendar in a\n * performant way.\n */\nexport const useDateRange = (\n initialDateRange: CalendarActiveDateRange = {\n startId: undefined,\n endId: undefined,\n }\n) => {\n const [dateRange, setDateRange] =\n useState<CalendarActiveDateRange>(initialDateRange);\n\n const onCalendarDayPress = useCallback<CalendarOnDayPress>(\n (dateId: string) => {\n setDateRange((prev) => {\n // Starting the first range\n if (!prev.startId && !prev.endId) {\n return {\n startId: dateId,\n endId: undefined,\n };\n } else if (prev.startId && prev.endId) {\n // Starting a new range\n return {\n startId: dateId,\n endId: undefined,\n };\n } else if (prev.startId && !prev.endId) {\n if (dateId < prev.startId) {\n return {\n startId: dateId,\n endId: prev.startId,\n };\n } else {\n return {\n ...prev,\n endId: dateId,\n };\n }\n }\n return {\n startId: dateId,\n endId: dateId,\n };\n });\n },\n []\n );\n\n const onClearDateRange = useCallback(() => {\n setDateRange({\n startId: undefined,\n endId: undefined,\n });\n }, []);\n\n return useMemo(() => {\n const calendarActiveDateRanges =\n !dateRange.startId && !dateRange.endId ? [] : [dateRange];\n const isDateRangeValid = !!(dateRange.startId && dateRange.endId);\n\n return {\n /**\n * The current date range.\n **/\n dateRange,\n /**\n * Derived from the current date range as a convenience when passing to\n * the `<Calendar.List />` component.\n */\n calendarActiveDateRanges,\n /**\n * Clears the current date range.\n */\n onClearDateRange,\n /**\n * Callback to pass to the `<Calendar.List />` component to handle date\n * range.\n */\n onCalendarDayPress,\n /**\n * Whether the current date range is valid (e.g. has both start and end\n * dates)\n */\n isDateRangeValid,\n };\n }, [dateRange, onCalendarDayPress, onClearDateRange]);\n};\n"],"mappings":"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","names":["memo","useEffect","useCallback","useMemo","Pressable","StyleSheet","Text","View","all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map","useEffect","useState","useMemo","toDateId","date","year","month","day","monthFormatted","dayFormatted","fromDateId","dateId","startOfMonth","endOfMonth","nextMonth","lastDay","startOfWeek","baseDate","firstDayOfWeek","dayOfWeek","diff","addMonths","months","newDate","subMonths","addDays","days","subDays","isWeekend","differenceInMonths","laterDate","earlierDate","yearDiff","monthDiff","getWeeksInMonth","totalDays","getWeekOfMonth","dayOfMonth","range","start","stop","step","_","i","getNumberOfEmptyCellsAtStart","month","firstDayOfWeek","startOfMonthDay","getStateFields","todayId","id","calendarActiveDateRanges","calendarMinDateId","calendarMaxDateId","calendarDisabledDateIds","activeRange","startId","endId","isRangeValid","isDisabled","isToday","state","getBaseCalendarMonthFormat","date","locale","getBaseCalendarWeekDayFormat","getBaseCalendarDayFormat","buildCalendar","params","monthId","calendarFirstDayOfWeek","calendarFormatLocale","getCalendarMonthFormat","getCalendarWeekDayFormat","getCalendarDayFormat","fromDateId","monthStart","startOfMonth","monthStartId","toDateId","monthEnd","endOfMonth","monthEndId","emptyDaysAtStart","startOfWeekIndex","endOfWeekIndex","dayToIterate","subDays","weeksList","range","dayShape","__spreadValues","isWeekend","__spreadProps","addDays","lastWeek","emptyDaysAtEnd","startOfWeekDate","startOfWeek","weekDaysList","i","useCalendar","useMemo","activeDateRangesEmitter","mitt_default","DEFAULT_CALENDAR_INSTANCE_ID","useOptimizedDayMetadata","baseMetadata","calendarInstanceId","metadata","setMetadata","useState","safeCalendarInstanceId","useEffect","handler","payload","ranges","instanceId","isStartOfRange","isEndOfRange","isRangeValid","state","getStateFields","prev","__spreadProps","__spreadValues","useColorScheme","baseTokens","lightTheme","__spreadProps","__spreadValues","darkTheme","createContext","useContext","useMemo","jsx","CalendarThemeContext","CalendarThemeProvider","children","colorScheme","calendarThemeContextValue","useCalendarTheme","useTheme","appearance","useColorScheme","colorScheme","useCalendarTheme","darkTheme","lightTheme","jsx","jsxs","styles","StyleSheet","buildBaseStyles","theme","baseContent","__spreadProps","__spreadValues","isPressed","isHovered","isStartOfRange","isEndOfRange","baseStyles","CalendarItemDay","onPress","children","height","metadata","textProps","CalendarPressableComponent","Pressable","baseTheme","useTheme","useMemo","handlePress","useCallback","isFocused","_a","_b","_c","_d","params","container","_e","content","Text","CalendarItemDayContainer","isStartOfWeek","shouldShowActiveDayFiller","daySpacing","dayHeight","spacerStyles","activeDayFiller","View","CalendarItemDayWithContainer","baseMetadata","containerTheme","calendarInstanceId","useOptimizedDayMetadata","memo","useMemo","View","StyleSheet","jsx","styles","StyleSheet","CalendarItemEmpty","memo","props","height","theme","containerStyles","useMemo","__spreadProps","__spreadValues","View","useMemo","StyleSheet","Text","View","jsx","styles","StyleSheet","lightTheme","CalendarItemWeekName","children","height","theme","textProps","colors","useTheme","containerStyles","contentStyles","useMemo","View","Text","__spreadProps","__spreadValues","useMemo","StyleSheet","Text","View","jsx","styles","StyleSheet","CalendarRowMonth","children","height","theme","baseTheme","useTheme","containerStyles","contentStyles","useMemo","View","Text","useMemo","StyleSheet","useMemo","StyleSheet","View","jsx","styles","HStack","alignItems","children","justifyContent","grow","shrink","spacing","wrap","backgroundColor","width","style","containerStyles","jsx","styles","StyleSheet","CalendarRowWeek","children","spacing","theme","containerStyles","useMemo","_a","__spreadValues","HStack","Children","Fragment","isValidElement","useMemo","StyleSheet","View","jsx","styles","StyleSheet","isFragment","child","isValidElement","Fragment","VStack","children","spacing","alignItems","justifyContent","grow","containerStyles","useMemo","__spreadProps","__spreadValues","View","Children","c","i","uppercaseFirstLetter","value","jsx","jsxs","BaseCalendar","memo","props","_a","calendarInstanceId","calendarRowVerticalSpacing","calendarRowHorizontalSpacing","calendarDayHeight","calendarMonthHeaderHeight","calendarWeekHeaderHeight","onCalendarDayPress","theme","CalendarPressableComponent","buildCalendarParams","__objRest","calendarRowMonth","weeksList","weekDaysList","useCalendar","VStack","CalendarRowMonth","uppercaseFirstLetter","CalendarRowWeek","weekDay","i","CalendarItemWeekName","week","index","dayProps","CalendarItemDayContainer","CalendarItemEmpty","CalendarItemDayWithContainer","Calendar","calendarActiveDateRanges","calendarMonthId","calendarColorScheme","otherProps","useEffect","activeDateRangesEmitter","CalendarThemeProvider","__spreadProps","__spreadValues","LegendListBase","memo","useCallback","useImperativeHandle","useMemo","useRef","View","useCallback","useMemo","useState","pipe","a","ab","bc","cd","de","ef","fg","gh","hi","ret","i","buildMonthList","startingMonth","endingMonth","firstDayOfWeek","startingMonthId","toDateId","endingMonthId","months","getWeeksInMonth","numberOfMonths","differenceInMonths","i","month","addMonths","numberOfWeeks","getEndingMonth","calendarFutureScrollRange","calendarMaxDateId","baseDate","endingMonthFromRange","newEndingMonthId","safeMaxDateId","startOfMonth","fromDateId","getStartingMonth","calendarPastScrollRange","calendarMinDateId","startingMonthFromRange","subMonths","newStartingMonthId","safeMinDateId","pipe","useCalendarList","calendarInitialMonthId","calendarPastScrollRangeInMonths","calendarFutureScrollRangeInMonths","calendarFirstDayOfWeek","initialMonth","initialMonthId","useMemo","baseStartOfMonth","monthList","setMonthList","useState","currentMonth","appendMonths","useCallback","m","newMonths","newMonthList","prependMonths","addMissingMonths","targetMonthId","firstMonth","lastMonth","initialMonthIndex","getHeightForMonth","vSpacing","day","weekName","header","extraHeight","calendarMonth","calendarSpacing","headerHeight","daysHeight","jsx","LegendList","LegendListBase","keyExtractor","month","CalendarList","memo","_a","_b","ref","props","__objRest","calendarInitialMonthId","calendarPastScrollRangeInMonths","calendarFutureScrollRangeInMonths","calendarFirstDayOfWeek","calendarFormatLocale","calendarSpacing","calendarRowHorizontalSpacing","calendarRowVerticalSpacing","calendarMonthHeaderHeight","calendarDayHeight","calendarWeekHeaderHeight","calendarAdditionalHeight","calendarColorScheme","theme","onEndReached","onStartReached","calendarActiveDateRanges","calendarDisabledDateIds","calendarInstanceId","calendarMaxDateId","calendarMinDateId","getCalendarDayFormat","getCalendarMonthFormat","getCalendarWeekDayFormat","onCalendarDayPress","CalendarPressableComponent","flatListProps","calendarProps","useMemo","initialMonthIndex","monthList","appendMonths","prependMonths","addMissingMonths","useCalendarList","monthListWithCalendarProps","__spreadProps","__spreadValues","handleOnEndReached","useCallback","info","handleOnStartReached","handleGetFixedItemSize","_index","item","getHeightForMonth","getScrollOffsetForMonth","date","monthId","toDateId","startOfMonth","baseMonthList","index","acc","currentHeight","legendListRef","useRef","useImperativeHandle","animated","additionalOffset","currentMonthOffset","weekOfMonthIndex","getWeekOfMonth","rowHeight","weekOffset","offset","calendarContainerStyle","View","Calendar","CalendarItemDayWithNamespace","CalendarItemDay","CalendarItemDayContainer","CalendarItemDayWithContainer","CalendarItemWithNamespace","CalendarItemWeekName","CalendarItemEmpty","CalendarRowWithNamespace","CalendarRowMonth","CalendarRowWeek","CalendarWithNamespace","Calendar","CalendarList","HStack","VStack","useCallback","useMemo","useState","useDateRange","initialDateRange","dateRange","setDateRange","useState","onCalendarDayPress","useCallback","dateId","prev","__spreadProps","__spreadValues","onClearDateRange","useMemo","calendarActiveDateRanges","isDateRangeValid"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lazerlen/legend-calendar",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "A better calendar for React Native.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "github.com/LeviWilliams/legend-calendar",
|
|
9
|
+
"directory": "packages/legend-calendar"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "Levi Williams",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"module": "./dist/index.mjs",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup --dts",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"clean": "rm -rf dist && rm -rf node_modules",
|
|
20
|
+
"dev": "tsup --watch --silent",
|
|
21
|
+
"lint": "eslint src",
|
|
22
|
+
"test": "bun test"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"mitt": "^3.0.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@lazerlen/eslint-config": "*",
|
|
29
|
+
"@lazerlen/tsconfig": "*",
|
|
30
|
+
"@legendapp/list": "^2.0.0",
|
|
31
|
+
"@testing-library/react-hooks": "^8.0.1",
|
|
32
|
+
"@types/bun": "^1.3.2",
|
|
33
|
+
"@types/react": "~19.1.10",
|
|
34
|
+
"date-fns": "^3.3.1",
|
|
35
|
+
"eslint": "^8.56.0",
|
|
36
|
+
"react": "19.1.0",
|
|
37
|
+
"react-native": "0.81.5",
|
|
38
|
+
"react-test-renderer": "~19.1.0",
|
|
39
|
+
"tsup": "^8.0.1",
|
|
40
|
+
"typescript": "~5.9.2"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@legendapp/list": "*",
|
|
44
|
+
"react": "*",
|
|
45
|
+
"react-native": "*"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-native";
|
|
2
|
+
import { addDays, subDays } from "date-fns";
|
|
3
|
+
import { format } from "date-fns/fp/format";
|
|
4
|
+
import { useRef, useState } from "react";
|
|
5
|
+
import { Text } from "react-native";
|
|
6
|
+
|
|
7
|
+
import { paddingDecorator } from "@/developer/decorators";
|
|
8
|
+
import { loggingHandler } from "@/developer/loggginHandler";
|
|
9
|
+
import { endOfMonth, startOfMonth, toDateId } from "@/helpers/dates";
|
|
10
|
+
import { useDateRange } from "@/hooks/useDateRange";
|
|
11
|
+
import { VStack } from "@/components/VStack";
|
|
12
|
+
|
|
13
|
+
import { Calendar } from "./Calendar";
|
|
14
|
+
|
|
15
|
+
const today = new Date();
|
|
16
|
+
|
|
17
|
+
const startOfThisMonth = startOfMonth(today);
|
|
18
|
+
const endOfThisMonth = endOfMonth(today);
|
|
19
|
+
|
|
20
|
+
const CalendarMeta: Meta<typeof Calendar> = {
|
|
21
|
+
title: "Calendar",
|
|
22
|
+
component: Calendar,
|
|
23
|
+
argTypes: {
|
|
24
|
+
calendarFirstDayOfWeek: {
|
|
25
|
+
control: {
|
|
26
|
+
type: "select",
|
|
27
|
+
},
|
|
28
|
+
options: ["monday", "sunday"],
|
|
29
|
+
},
|
|
30
|
+
onCalendarDayPress: { action: "onCalendarDayPress" },
|
|
31
|
+
calendarFormatLocale: { type: "string" },
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
args: {
|
|
35
|
+
calendarFirstDayOfWeek: "sunday",
|
|
36
|
+
calendarMonthId: toDateId(startOfThisMonth),
|
|
37
|
+
calendarFormatLocale: "en-US",
|
|
38
|
+
},
|
|
39
|
+
decorators: [paddingDecorator],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default CalendarMeta;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* This serves as a kitchen-sink test. It shows most day states working together:
|
|
46
|
+
* - Today
|
|
47
|
+
* - Active ranges (single + multiple days)
|
|
48
|
+
* - Disabled (min/max + specific dates)
|
|
49
|
+
* - Idle
|
|
50
|
+
*/
|
|
51
|
+
export const KichenSink: StoryObj<typeof Calendar> = {
|
|
52
|
+
args: {
|
|
53
|
+
calendarFirstDayOfWeek: "sunday",
|
|
54
|
+
calendarMonthId: toDateId(startOfThisMonth),
|
|
55
|
+
calendarDisabledDateIds: [
|
|
56
|
+
toDateId(addDays(today, 1)),
|
|
57
|
+
toDateId(subDays(today, 1)),
|
|
58
|
+
],
|
|
59
|
+
calendarMinDateId: toDateId(addDays(startOfThisMonth, 2)),
|
|
60
|
+
calendarMaxDateId: toDateId(subDays(endOfThisMonth, 2)),
|
|
61
|
+
calendarActiveDateRanges: [
|
|
62
|
+
{
|
|
63
|
+
startId: toDateId(addDays(startOfThisMonth, 3)),
|
|
64
|
+
endId: toDateId(addDays(startOfThisMonth, 8)),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
startId: toDateId(addDays(startOfThisMonth, 15)),
|
|
68
|
+
endId: toDateId(addDays(startOfThisMonth, 15)),
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const DisabledDates: StoryObj<typeof Calendar> = {
|
|
75
|
+
args: {
|
|
76
|
+
calendarDisabledDateIds: [
|
|
77
|
+
"2024-01-01",
|
|
78
|
+
"2024-01-02",
|
|
79
|
+
"2024-01-03",
|
|
80
|
+
"2024-01-16",
|
|
81
|
+
"2024-01-17",
|
|
82
|
+
],
|
|
83
|
+
calendarMonthId: "2024-01-01",
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const MinAndMaxDates: StoryObj<typeof Calendar> = {
|
|
88
|
+
args: {
|
|
89
|
+
calendarMonthId: "2024-03-01",
|
|
90
|
+
calendarMinDateId: "2024-03-10",
|
|
91
|
+
calendarMaxDateId: "2024-03-20",
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const ActiveDateRanges: StoryObj<typeof Calendar> = {
|
|
96
|
+
args: {
|
|
97
|
+
calendarActiveDateRanges: [
|
|
98
|
+
{ startId: "2024-01-04", endId: "2024-01-06" },
|
|
99
|
+
{ startId: "2024-01-10", endId: "2024-01-12" },
|
|
100
|
+
// Incomplete
|
|
101
|
+
{ startId: "2024-01-24" },
|
|
102
|
+
{ endId: "2024-01-29" },
|
|
103
|
+
],
|
|
104
|
+
calendarMonthId: "2024-01-01",
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const WithCustomLocale = (args: typeof KichenSink.args) => {
|
|
109
|
+
return (
|
|
110
|
+
<Calendar
|
|
111
|
+
{...args}
|
|
112
|
+
calendarFormatLocale="pt-BR"
|
|
113
|
+
calendarMonthId={toDateId(startOfThisMonth)}
|
|
114
|
+
onCalendarDayPress={loggingHandler("onCalendarDayPress")}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const WithCustomFormatting = (args: typeof KichenSink.args) => {
|
|
120
|
+
return (
|
|
121
|
+
<Calendar
|
|
122
|
+
{...args}
|
|
123
|
+
calendarMonthId={toDateId(startOfThisMonth)}
|
|
124
|
+
getCalendarDayFormat={format("dd")}
|
|
125
|
+
getCalendarMonthFormat={format("MMMM yyyy (LL/yyyy)")}
|
|
126
|
+
getCalendarWeekDayFormat={format("E")}
|
|
127
|
+
onCalendarDayPress={loggingHandler("onCalendarDayPress")}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const DatePicker = (args: typeof KichenSink.args) => {
|
|
133
|
+
const [activeDateId, setActiveDateId] = useState(
|
|
134
|
+
toDateId(addDays(startOfThisMonth, 3))
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<Calendar
|
|
139
|
+
{...args}
|
|
140
|
+
calendarActiveDateRanges={[
|
|
141
|
+
{ startId: activeDateId, endId: activeDateId },
|
|
142
|
+
]}
|
|
143
|
+
calendarMonthId={toDateId(startOfThisMonth)}
|
|
144
|
+
onCalendarDayPress={setActiveDateId}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const DateRangePicker = (args: typeof KichenSink.args) => {
|
|
150
|
+
const { calendarActiveDateRanges, onCalendarDayPress } = useDateRange({
|
|
151
|
+
startId: "2024-02-04",
|
|
152
|
+
endId: "2024-02-09",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<Calendar
|
|
157
|
+
{...args}
|
|
158
|
+
calendarActiveDateRanges={calendarActiveDateRanges}
|
|
159
|
+
calendarMonthId={toDateId(startOfThisMonth)}
|
|
160
|
+
onCalendarDayPress={onCalendarDayPress}
|
|
161
|
+
/>
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const ControlledColorScheme: StoryObj<typeof Calendar> = {
|
|
166
|
+
args: {
|
|
167
|
+
calendarColorScheme: "dark",
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export const LightModeOnly = () => {
|
|
172
|
+
const { calendarActiveDateRanges, onCalendarDayPress } = useDateRange({
|
|
173
|
+
startId: "2024-02-04",
|
|
174
|
+
endId: "2024-02-09",
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<Calendar
|
|
179
|
+
calendarActiveDateRanges={calendarActiveDateRanges}
|
|
180
|
+
calendarColorScheme="light"
|
|
181
|
+
calendarMonthId={toDateId(startOfThisMonth)}
|
|
182
|
+
onCalendarDayPress={onCalendarDayPress}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export const TwoCalendarsMounted = () => {
|
|
188
|
+
return (
|
|
189
|
+
<VStack spacing={48}>
|
|
190
|
+
<CalendarInstanceDemo instanceId="First" startingIndex={3} />
|
|
191
|
+
<CalendarInstanceDemo instanceId="Second" startingIndex={10} />
|
|
192
|
+
</VStack>
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
function CalendarInstanceDemo({
|
|
197
|
+
instanceId,
|
|
198
|
+
startingIndex,
|
|
199
|
+
}: {
|
|
200
|
+
instanceId: string;
|
|
201
|
+
startingIndex: number;
|
|
202
|
+
}) {
|
|
203
|
+
const [date, setDate] = useState(
|
|
204
|
+
toDateId(addDays(startOfThisMonth, startingIndex))
|
|
205
|
+
);
|
|
206
|
+
const rerender = useRef(0);
|
|
207
|
+
rerender.current += 1;
|
|
208
|
+
return (
|
|
209
|
+
<VStack spacing={8}>
|
|
210
|
+
<Calendar
|
|
211
|
+
calendarActiveDateRanges={[
|
|
212
|
+
{
|
|
213
|
+
startId: date,
|
|
214
|
+
endId: date,
|
|
215
|
+
},
|
|
216
|
+
]}
|
|
217
|
+
calendarInstanceId={instanceId}
|
|
218
|
+
calendarMonthId={date}
|
|
219
|
+
onCalendarDayPress={setDate}
|
|
220
|
+
/>
|
|
221
|
+
<Text>
|
|
222
|
+
{instanceId} date: {date} (re-renders: {rerender.current}⚡)
|
|
223
|
+
</Text>
|
|
224
|
+
</VStack>
|
|
225
|
+
);
|
|
226
|
+
}
|