npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@symbiot.dev/react-native-swipeday

v1.1.0

Published

A lightweight customizable swipeable list component designed to swipe through days, ideal for calendar-based UIs in React Native.

Readme

react-native-swipeday is a horizontally swipeable React Native component that displays individual days. It enables smooth left and right swiping to navigate between days, making it ideal for daily planners, calendars, habit trackers, and similar apps. Unlike a timeline, each slide focuses on a single full day, giving you complete control over the day's content. The component is built with full support for iOS, Android, Web, Expo, and Expo Go, making it highly versatile and easy to integrate across platforms.


📱 Demo


✨ Key Features

📅 Swipeable Day View – Navigate horizontally through days with optional snapping.
👥 Group-Based Layout – Organize your day view by teams, rooms, users, etc.
🎨 Custom Renderers – Inject your own headers, day content, or group layout via render props.
📱 Cross-Platform Support – Works seamlessly across:

  • iOS & Android
  • Web via React Native Web
  • Expo & Expo Go

🧠 Minimal & Extensible – Lightweight core with deep customization hooks.
🚀 Performance Friendly – Virtualized scrolling and render control for optimal responsiveness.


🧠 Ideal For

  • 👥 Employee shift planners
  • 🛎️ Booking views by room, therapist, stylist, etc.
  • 📆 Grouped daily timelines
  • 🧑‍🏫 Class schedules split by instructor or location
  • 📦 Delivery or service assignments by region
  • 🛠 Field service or technician dispatch views
  • 🧭 Any multi-entity day-based scheduling need

📦 Installation

npm install @symbiot.dev/react-native-swipeday date-fns react-native-reanimated react-native-gesture-handler
# or
yarn add @symbiot.dev/react-native-swipeday date-fns react-native-reanimated react-native-gesture-handler

# for web support
npm i react-native-web
# or
yarn add react-native-web
import { SwipeDay } from '@symbiot.dev/react-native-swipeday';

// ... and voilà 💫
<SwipeDay />

🎨 SwipeDayThemePropsTheming & Appearance

You can customize the look and feel of SwipeDay using the theme prop. It supports both global styles and scheme-based overrides for 'light' and 'dark' modes.

🧩 Structure

The SwipeDayThemeProps type supports three layers:

  1. Global Styling (applies to all schemes unless overridden)
  2. Per-scheme Overrides – Use light and dark keys to define specific values
  3. Theme Scheme Selector – Control active theme using scheme
type SwipeDayThemeProps = SwipeDayStyle & {
  scheme?: 'light' | 'dark';
  light?: SwipeDayStyle;
  dark?: SwipeDayStyle;
};

🧱 Available Styling Props

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | Default Value | |------------------------------|-------------------------------------------|:------:|:----------:|:------:|-----------------------------------| | backgroundColor | Main background color of the grid view | ✅ | ✅ | ✅ | light: #FFFFFF, dark: #000000 | | dayHeaderBackgroundColor | Background for the day-of-week header bar | ✅ | ✅ | ✅ | light: #FFFFFF, dark: #000000 | | dayHeaderTextColor | Text color for day-of-week labels | ✅ | ✅ | ✅ | light: #000000, dark: #FFFFFF | | groupHeaderBackgroundColor | Background for the group header bar | ✅ | ✅ | ✅ | light: #FFFFFF, dark: #000000 | | groupHeaderTextColor | Text color for group labels | ✅ | ✅ | ✅ | light: #000000, dark: #FFFFFF | | verticalLineColor | Color of vertical grid lines | ✅ | ✅ | ✅ | light: #F1F1F1, dark: #303030 | | horizontalLineColor | Color of horizontal grid lines | ✅ | ✅ | ✅ | light: #F1F1F1, dark: #303030 |

<SwipeDay
  //...
  theme={{
    backgroundColor: '#f0f0f0', // for light and dark mode
  }}
/>

// ----

<SwipeDay
  //...
  theme={{
    backgroundColor: '#f0f0f0', // only applies to light mode
    dark: {
      backgroundColor: '#020202',
    },
  }}
/>

📐 SwipeDayDimensionsPropsLayout & Dimensions

Control the physical dimensions of key areas inside the SwipeDay. All values are in pixels and optional — sensible defaults are provided.

🧱 Available Dimension Props

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | Default Value | |----------------------|-------------------------------------------|:------:|:----------:|:------:|---------------| | width | SwipeDay width | ✅ | ✅ | ✅ | system | | dayHeaderHeight | Height of the day header (weekday labels) | ✅ | ✅ | ✅ | 50 | | groupHeaderHeight | Height of the group header (group labels) | ✅ | ✅ | ✅ | 30 | | horizontalLineSize | Height of horizontal divider lines | ✅ | ✅ | ✅ | 0.5 |

<SwipeDay
  //...
  width={300}
/>;

📅 SwipeDayDatetimePropsDate & Time Configuration

Set the visible time range, number of days, start date, and other calendar-related behaviors.
These props give you precise control over how the SwipeDay renders days and time slots.

🧱 Available Datetime Props

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | Default Value | |----------------|-------------------------------------------------------------|:------:|:----------:|:------:|---------------| | startDate | The starting datetime for the initial calendar state | ✅ | ✅ | ✅ | new Date() | | weekStartsOn | Day the week starts on (0=Sun, 1=Mon, etc.) | ✅ | ✅ | ✅ | 0 (Sunday) | | hiddenDays | Days of the week to hide (e.g., [0, 6] to hide Sun & Sat) | ✅ | ✅ | ✅ | [] | | numberOfDays | Number of days to render in the view | ✅ | ✅ | ✅ | 1 | | minDate | Earliest date to allow navigation | ✅ | ✅ | ✅ | | | maxDate | Latest date to allow navigation | ✅ | ✅ | ✅ | |

<SwipeDay
  //...
  weekStartsOn={1} // starts on Monday
  numberOfDays={3}
  hiddenDays={[0, 6]} // exclude weekends (Sun,Sut)
/>;

🎮 SwipeDayControllerPropsInteraction & Display Toggles

Control user interaction features like swiping, snapping, and visibility of UI components like the headers.

🧱 Available Controller Props

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | Default Value | |------------------------|------------------------------------------------------------------|:------:|:----------:|:------:|---------------| | swipeable | Enable swiping between days or weeks | ✅ | ✅ | ✅ | false | | snappable | Snap scroll/drag to the nearest date(or group in groupable mode) | ✅ | ✅ | ✅ | false | | debounceable | Delays date change handler to avoid rapid successive triggers. | ✅ | ✅ | ✅ | false | | rtl | Enable right-to-left layout (for RTL languages) | ✅ | ✅ | ✅ | false | | isDayHeaderVisible | Toggle visibility of the top day-of-week header | ✅ | ✅ | ✅ | true | | isGroupHeaderVisible | Toggle visibility of the top group header | ✅ | ✅ | ✅ | true |

<SwipeDay
  //...
  swipeable // swipe actions turned on
  scrollable // user can scroll
  snappable // date/group snapping enabled
/>

🔧 SwipeDayScrollPropsScroll and Refresh Control

These types control the scroll and refresh behavior for day-based components, allowing flexible configuration either globally, per group, or per specific date.

🔍 SwipeDayScrollProp

Defines the scroll or refresh state and can be one of the following:

  • boolean — enable or disable scrolling/refreshing globally.
  • Record<string, boolean> — keyed by group IDs to enable or disable per group.
  • Array<{ groupId: string; date: string; value: boolean }> — fine-grained control by group and date.

🧱 SwipeDayScrollProps

Props that manage scroll and refresh capabilities:

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | Default Value | |---------------|----------------------------------------------------------------|:------:|:----------:|:------:|---------------| | scrollable | Controls if day scrolling is enabled, with flexible options. | ✅ | ✅ | ✅ | false | | refreshable | Controls if pull-to-refresh is enabled, with flexible options. | ✅ | ✅ | ➖ | false | | refreshing | Indicates the refreshing state, useful for UI feedback. | ✅ | ✅ | ➖ | false |

📦 Example Usage

<SwipeDay
  //...
  scrollable // enable scroll for all days
/>

📦 SwipeGayGroupPropsGroups

Configure how groups are handled in the SwipeGay component.

🧱 Available Props

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | Default Value | |------------------|-----------------------------------------------------|:------:|:----------:|:------:|---------------| | groupable | Controls days splitting by groups | ✅ | ✅ | ✅ | false | | numberOfGroups | Optional number of groups to display | ✅ | ✅ | ✅ | groups size | | groups | Optional array of group objects (SwipeGayGroup[]) | ✅ | ✅ | ✅ | [] |

Example Usage

const groups = [
  { id: 1, name: 'Group A' },
  { id: 2, name: 'Group B' },
];

<SwipeGayComponent
  //...
  numberOfGroups={2}
  groups={groups}
/>

SwipeDayFormatterPropsText Formatting

Customize how dates and times appear within the SwipeDay component using format strings (e.g., dd, HH:mm, EEE).
These follow date-fns formatting syntax.

🧱 Available Formatter Props

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | Default Value | |-----------------------|----------------------------------------------------------------|:------:|:----------:|:------:|---------------| | dayHeaderTextFormat | Format for the day header labels (e.g., Mon, Apr 20) | ✅ | ✅ | ✅ | EEEEEE dd | | locale | Locale object from date-fns for internationalized formatting | ✅ | ✅ | ✅ | en |

import { zhCN } from 'date-fns/locale/zh-CN';

<SwipeDay
  //...
  locale={zhCN} // Chinese localization
/>;

🧭 SwipeDayActionsPropsUser Interaction Callbacks

Callbacks to handle user interactions within a swipeable day grid, such as taps, long presses, header presses, and data refreshes.

🧱 Available Action Callbacks

| Prop Name | Description | 🍏 iOS | 🤖 Android | 🌐 Web | |----------------------|--------------------------------------------------------|:------:|:----------:|:------:| | onLoad | Called once the component is initialized and ready | ✅ | ✅ | ✅ | | onChangeDate | Triggered when the selected date changes | ✅ | ✅ | ✅ | | onRefresh | Called when the grid requests a manual refresh of data | ✅ | ✅ | ➖ | | onGroupHeaderPress | Triggered when a group header is tapped | ✅ | ✅ | ✅ | | onDayHeaderPress | Called when the day header is tapped | ✅ | ✅ | ✅ | | onDayPress | Triggered when a day cell is tapped | ✅ | ✅ | ✅ | | onDayLongPress | Triggered on a long press of a day cell | ✅ | ✅ | ✅ |

import { useState } from 'react';

//...
const [selectedDate, setSelectedDate] = useState(new Date());

<SwipeDay
  //...
  onChangeDate={setSelectedDate} // Update selected date on swipe or tap
  onRefresh={({ date }) => console.log('Refreshing data for:', date)}
  onGroupHeaderPress={({ groupId }) => console.log('Group pressed:', groupId)}
  onDayLongPress={({ date }) => console.log('Long pressed:', date)}
/>

🎨 SwipeDayRenderPropsCustom Render Props API

Customize the visual presentation of the calendar by providing your own render functions.
Perfect for integrating your own UI components or applying tailored styles.

🧱 Available Render Props

| Prop | Description | Parameters | Returns | |---------------------|----------------------------------------------------------------------|------------------------------------|----------------| | renderGroupHeader | Custom renderer for the group header (e.g., a user or resource name) | { groupId: SwipeGayGroup['id'] } | ReactElement | | renderDayHeader | Custom renderer for the day header (e.g., a weekday label) | { date: Date } | ReactElement | | renderDay | Custom renderer for each individual day cell | { date: Date } | ReactElement |


🔧 SwipeDayRefImperative Control API

Control and interact with the SwipeDay instance programmatically using a React ref.
Great for custom toolbars, buttons, or dynamic navigation.

🧱 Available Ref Methods

| Method | Description | Returns | |-----------------|---------------------------------------------------------------------------------|---------------------| | getPrevDate() | Returns the previous valid date range (optionally ignoring minDate/maxDate) | Date \| undefined | | getNextDate() | Returns the next valid date range (optionally ignoring minDate/maxDate) | Date \| undefined | | prevDate() | Navigate to the previous available date | void | | nextDate() | Navigate to the next available date | void | | back() | Navigate backward through a specified number of days (numberOfDays) | void | | forward() | Navigate forward through a specified number of days (numberOfDays) | void |

import { useRef } from 'react';
import { SwipeDay, SwipeDayRef } from '@symbiot.dev/react-native-swipeday';

const swipeDayRef = useRef<SwipeDayRef>(null);

<SwipeDay
  //...
  ref={swipeDayRef}
/>

//...
<Pressable onPress={() => swipeDayRef.current?.forward()}>{/*...*/}</Pressable>

🌐 Platform Support

  • ✅ iOS
  • ✅ Android
  • ✅ Web
  • ✅ Expo & Expo Go

📦 Bundle Size

Lightweight and fast — see actual size on Bundlephobia.


💬 Contributing

Contributions welcome! Feel free to open issues, discussions, or suggestions.


🌟 Who's Using This?

Using react-native-swipeday in your app or product?
Feel free to share your project — it might be featured in this section!

✉️ Open pull request, or reach out directly to get included.


🚀 Got Ideas or Gaps to Fill?

Know of existing libraries or functionality that could be improved?
Have an idea for something completely new?

Symbiot is ready to take on the challenge — feedback, feature requests, or collaboration ideas are always welcome!

🧠 Let’s build better tools together. Start the conversation or contact via email.


🧾 License

MIT — Made with ❤️ by Symbiot