{"id":13679181,"url":"https://github.com/computerjazz/react-native-swipe-calendar","last_synced_at":"2025-08-09T20:03:16.982Z","repository":{"id":54604492,"uuid":"418342467","full_name":"computerjazz/react-native-swipe-calendar","owner":"computerjazz","description":"A swipeable calendar component for React Native.","archived":false,"fork":false,"pushed_at":"2022-11-19T23:03:44.000Z","size":225,"stargazers_count":117,"open_issues_count":7,"forks_count":13,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-13T19:42:01.526Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/computerjazz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["computerjazz"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2021-10-18T04:22:21.000Z","updated_at":"2025-05-23T13:52:16.000Z","dependencies_parsed_at":"2023-01-22T14:45:12.540Z","dependency_job_id":null,"html_url":"https://github.com/computerjazz/react-native-swipe-calendar","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/computerjazz/react-native-swipe-calendar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computerjazz%2Freact-native-swipe-calendar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computerjazz%2Freact-native-swipe-calendar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computerjazz%2Freact-native-swipe-calendar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computerjazz%2Freact-native-swipe-calendar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/computerjazz","download_url":"https://codeload.github.com/computerjazz/react-native-swipe-calendar/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computerjazz%2Freact-native-swipe-calendar/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269631157,"owners_count":24450144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-09T02:00:10.424Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T13:01:02.825Z","updated_at":"2025-08-09T20:03:16.848Z","avatar_url":"https://github.com/computerjazz.png","language":"TypeScript","funding_links":["https://github.com/sponsors/computerjazz"],"categories":["TypeScript"],"sub_categories":[],"readme":"# React Native Swipe Calendar\n\nA swipeable calendar component for React Native.\u003cbr /\u003e\nFully native interactions powered by [Reanimated 2](https://github.com/kmagiera/react-native-reanimated) and [React Native Gesture Handler](https://github.com/kmagiera/react-native-gesture-handler).\n\n![SwipeCalendar demo](https://i.imgur.com/5dsYg9M.gif)\n\n## Install\n\n1. Follow installation instructions for [reanimated](https://github.com/kmagiera/react-native-reanimated) and [react-native-gesture-handler](https://github.com/kmagiera/react-native-gesture-handler)\n2. `npm install` or `yarn add` `react-native-swipe-calendar`\n3. `import Calendar from 'react-native-swipe-calendar'`\n\n### Props\n\n```typescript\ntype HeaderComponent = (props: { date: Date }) =\u003e JSX.Element | null;\n\ntype DayLabelComponentType = (props: { date: Date }) =\u003e JSX.Element | null;\n\ntype DayComponentType = (props: {\n  date: Date;\n  isInDisplayedMonth: boolean;\n  isSelected: boolean;\n  isToday: boolean;\n}) =\u003e JSX.Element | null;\n\nexport type WeekComponentType = (props: {\n  days: Date[];\n}) =\u003e JSX.Element | null;\n\nexport type MonthComponentType = (props: {\n  weeks: Date[][];\n  firstDayOfMonth: Date;\n}) =\u003e JSX.Element | null;\n\nexport type PageInterval = \"day\" | \"week\" | \"month\";\n\nexport type CalendarProps = {\n  selectedDate?: Date | null; \n  onDateSelect?: OnDateSelect;\n  onPageChange?: (date: Date) =\u003e void;\n  currentDate?: Date;\n  HeaderComponent?: HeaderComponentType;\n  DayLabelComponent?: DayLabelComponentType;\n  DayComponent?: DayComponentType;\n  WeekComponent?: WeekComponentType;\n  MonthComponent?: MonthComponentType;\n  theme?: Partial\u003ctypeof DEFAULT_THEME\u003e;\n  pageBuffer?: number;\n  minDate?: Date;\n  maxDate?: Date;\n  pageInterpolator?: CalendarPageInterpolator;\n  simultaneousGestures?: (ComposedGesture | GestureType)[];\n  monthAnimCallbackNode?: Animated.SharedValue\u003cnumber\u003e;\n  gesturesDisabled?: boolean;\n  animationConfig?: Partial\u003cWithSpringConfig\u003e;\n  weekStartsOn?: WeekDayIndex;\n  pageInterval?: PageInterval;\n};\n\n```\n\n| Name             | Type                            |Description    |\n| :--------------- | :------------------------------ | :------- |\n| `selectedDate`   | `Date                           | null`                                         | Calendar date to be marked as \"selected\". |\n| `onDateSelect`   | `(date: Date) =\u003e void`          | Callback invoked when the a date is selected. |\n| `onPageChange`  | `(date: Date) =\u003e void`          | Callback invoked when the month is changed.   |\n| `currentDate`    | `Date`                          | Date to initialize the calendar with.         |\n| `theme`          | `Partial\u003ctypeof DEFAULT_THEME\u003e` | Overrides for default fonts and colors.       |\n| `HeaderComponent` | `HeaderComponentType`            | Custom replacement for Header component.      |\n| `DayComponent`   | `DayComponentType`              | Custom replacement for Day compoent.         |\n| `WeekComponent`   | `WeekComponentType`              | Custom replacement for Week compoent.         |\n| `MonthComponent`   | `MonthComponentType`              | Custom replacement for Month compoent.         |\n| `DayLabelComponent` | `DayLabelComponentType`            | Custom replacement for Day Label component (\"Su\", \"Mo\", etc).      |\n|`minDate`|`Date`|The minimum date the calendar will display|\n|`maxDate`|`Date`|The maximum date the calendar will display|\n|`pageInterpolator`|`typeof defaultPageInterpolator`| A worklet to customize page transition animations. Returns an animated style|\n|`animationConfig`|`Partial\u003cWithSpringConfig\u003e`| An animation spring config object to customize how page transitions animate.|\n|`simultaneousGestures`|`(ComposedGesture | GestureType)[]`| Any RNGH gestures that wrap the calendar.|\n|`weekStartsOn`|`number`| Index of the day week starts on.|\n|`pageInterval`|`\"month\" | \"week\" | \"day\"`| Time span of each page.|\n\n### Imperative Api\n\nAccess the imperative api by passing a `ref` to the `Calendar` component: \n\n```typescript\n\ntype ImperativeApiOptions = {\n  animated?: boolean;\n}\n\ntype CalendarImperativeApi = {\n  incrementPage: (options?: ImperativeApiOptions) =\u003e void;\n  decrementPage: (options?: ImperativeApiOptions) =\u003e void;\n  setPage: (date: Date, options?: ImperativeApiOptions) =\u003e void;\n}\n\n// Example\nfunction MyComponent() {\n\n  const calendarRef = useRef\u003cCalendarImperativeApi\u003e(null)\n  const onIncrementButtonPress = () =\u003e calendarRef.current?.incrementPage()\n  \n  return (\n    \u003c\u003e\n     \u003cCalendar ref={calendarRef} /\u003e\n     \u003cMyButton onPress={onIncrementButtonPress} /\u003e\n    \u003c/\u003e\n  )\n}\n\n```\n\n| Name             | Type                   | Description           |\n| :--------------- | :--------------------- | :-------------------- |\n| `incrementPage` | `(options: ImperativeApiOptions) =\u003e void`           | Go to next month.     |\n| `decrementPage` | `(options: ImperativeApiOptions) =\u003e void`           | Go to previous month. |\n| `setPage`       | `(date: Date, options: ImperativeApiOptions) =\u003e void` | Go to given month.    |\n\n### Hooks\n\nIf you render your own components via `DayComponent` prop or other custom view, you may need access to more internal state than is available on props. This state may be accessed via the exported `useCalendarContext()` hook. \n\n\u003eNOTE: Be careful about performance! Lots of instances of `DayComponent` are rendered at any given time. You may need to wrap memoized inner wrappers around your custom components.\n\n```typescript\ntype CalendarContextValue = {\n  referenceDate: Date,\n  selectedDate: Date | null | undefined,\n  onDateSelect: OnDateSelect,\n  DayComponent:  DayComponentType | undefined,\n  WeekComponent:  WeekComponentType | undefined,\n  MonthComponent:  MonthComponentType | undefined,\n  DayLabelComponent: DayLabelComponentType | undefined,\n  HeaderComponent: HeaderComponentType | undefined,\n  theme: typeof DEFAULT_THEME,\n  pageInterpolator: typeof defaultPageInterpolator,\n  weekStartsOn: number,\n}\n\n// Example\nfunction MyCustomDayComponent({ date, isSelected }) {\n  const { onDateSelect } = useCalendarContext()\n  \n  // Forward to the `onDateSelect` prop\n  const onDayPress = () =\u003e onDateSelect(date, { isSelected })\n  \n  return (\n  \u003cTouchableOpacity onPress={onDayPress}\u003e\n    \u003cText\u003e\n      {date.getDate()}\n    \u003c/Text\u003e\n  \u003c/TouchableOpacity\u003e\n  )\n}\n```\n\n\n#### Custom pageInterpolator\n\nThe `pageInterpolator` prop enables customization of page animations using a Reanimated \"worklet\" function. For example, the following `pageInterpolator` will scale up upcoming months and fade in as they enter, then rotate and fade out as they leave:\n\n```typescript\n// Example\nfunction pageInterpolator({ focusAnim }: CalendarPageInterpolatorParams) {\n  \"worklet\"\n  \n  const inputRange = [-1, 0, 1]\n  \n  // Ensure the current month has a higher zIndex than the surrounding months\n  const zIndex = interpolate(focusAnim.value, inputRange, [0, 99, 0])\n  \n  // Fade the current month as it enters/leaves focus\n  const opacity = interpolate(focusAnim.value, inputRange, [0, 1, 0])\n  \n  // Rotate the current month as it leaves focus\n  const rotationDeg = interpolate(focusAnim.value, inputRange, [360, 0, 0])\n  \n  // Scale up the incoming month\n  const scale = interpolate(focusAnim.value, inputRange, [2, 1, 0.25])\n  \n  return {\n    opacity,\n    zIndex,\n    transform: [{ rotate: `${rotationDeg}deg` }, { scale }]\n  }\n}\n```\n![pageInterpolator demo](https://i.imgur.com/GRGqygt.gif)\n\n\n### Example\n\nhttps://snack.expo.dev/@computerjazz/react-native-swipe-calendar\n\n```typescript\nimport React, {\n  useState,\n  useRef,\n} from \"react\";\nimport {\n  Text,\n  View,\n  StyleSheet,\n  LayoutAnimation,\n  TouchableOpacity,\n  Platform,\n  UIManager,\n} from \"react-native\";\nimport Calendar from \"react-native-swipe-calendar\";\n\nif (Platform.OS === \"android\") {\n  UIManager.setLayoutAnimationEnabledExperimental \u0026\u0026\n    UIManager.setLayoutAnimationEnabledExperimental(true);\n}\n\nexport default function App() {\n\n  const [currentDate, setCurrentDate] = useState(new Date());\n  const [selectedDate, setSelectedDate] = useState\u003cDate | null\u003e(null);\n  const calendarRef = useRef(null);\n  \n  return (\n    \u003cView style={styles.container}\u003e\n      \u003cCalendar\n        theme={{ todayIndicatorDotColor: \"blue\" }}\n        ref={calendarRef}\n        currentDate={currentDate}\n        onDateSelect={(date, { isSelected }) =\u003e setSelectedDate(isSelected ? null : date )}\n        selectedDate={selectedDate}\n        onPageChange={(date) =\u003e {\n          setCurrentDate(date);\n          LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);\n        }}\n      /\u003e\n      \u003cView style={styles.controlBar}\u003e\n        \u003cTouchableOpacity\n          style={styles.incDec}\n          onPress={() =\u003e calendarRef.current?.decrementPage()}\n        \u003e\n          \u003cText\u003e{\"\u003c\"}\u003c/Text\u003e\n        \u003c/TouchableOpacity\u003e\n        \u003cTouchableOpacity\n          style={styles.incDec}\n          onPress={() =\u003e calendarRef.current?.incrementPage()}\n        \u003e\n          \u003cText\u003e{\"\u003e\"}\u003c/Text\u003e\n        \u003c/TouchableOpacity\u003e\n      \u003c/View\u003e\n    \u003c/View\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: { \n    flex: 1, \n    backgroundColor: \"white\", \n    paddingTop: 100 \n  },\n  incDec: {\n    paddingHorizontal: 20,\n    padding: 10,\n    backgroundColor: \"lightgrey\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    borderRadius: 5,\n  },\n  controlBar: {\n    position: \"absolute\",\n    top: 100,\n    left: 0,\n    right: 0,\n    flexDirection: \"row\",\n    justifyContent: \"space-between\",\n  },\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomputerjazz%2Freact-native-swipe-calendar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcomputerjazz%2Freact-native-swipe-calendar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomputerjazz%2Freact-native-swipe-calendar/lists"}