JSPM

@anasyd/react-native-modern-date-picker

1.2.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 16
  • Score
    100M100P100Q73780F
  • License MIT

A modern, customizable date picker for React Native & Expo with haptic feedback support (optional blur via expo-blur or @react-native-community/blur)

Package Exports

  • @anasyd/react-native-modern-date-picker
  • @anasyd/react-native-modern-date-picker/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@anasyd/react-native-modern-date-picker) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

@anasyd/react-native-modern-date-picker

Modern, fully-featured date and time picker for React Native & Expo with scroll-wheel time selection, age restrictions, time ranges, and custom theming.

Install

npm install @anasyd/react-native-modern-date-picker

Optional blur libs if you want a blur backdrop:

# Expo
npm install expo-blur

# Bare RN
npm install @react-native-community/blur

Changelog

See CHANGELOG.md for release notes.


Quick Start

import ModernDatePicker from "@anasyd/react-native-modern-date-picker";

<ModernDatePicker
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
/>;

Features

  • ๐Ÿ“… Date Picker - Month view calendar with year/month selection
  • โฐ Time Picker - iOS-style scroll wheels for hours, minutes, and AM/PM
  • ๐Ÿ”€ Multiple Modes - Date, time, or datetime combined
  • ๐Ÿ‘ค Age Restrictions - minAge and maxAge props (e.g., 18+ only)
  • โฑ๏ธ Time Ranges - minTime and maxTime for business hours, etc.
  • ๐Ÿ“ฑ Haptic Feedback - Smart haptic feedback on iOS/Android
  • ๐ŸŽจ Full Theming - Semantic color tokens, palette system, dark/light presets
  • ๐ŸŒ Internationalization - Locale support for dates and first day of week
  • ๐Ÿงช TypeScript - Full type safety
  • โšก Lightweight - No heavy dependencies

Picker Modes

Date Mode

Traditional calendar picker for selecting dates.

<ModernDatePicker
  mode="date"
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
  minDate={new Date(2020, 0, 1)}
  maxDate={new Date()}
/>

Time Mode

Scrollable time picker with hour/minute wheels. Supports 12/24 hour formats.

<ModernDatePicker
  mode="time"
  is24Hour={false}
  minuteInterval={15}
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
  minTime={{ hour: 9, minute: 0 }}  // 9:00 AM
  maxTime={{ hour: 17, minute: 0 }} // 5:00 PM
/>

DateTime Mode

Combined date and time selection. Pick date first, then switch to time.

<ModernDatePicker
  mode="datetime"
  is24Hour={false}
  minuteInterval={15}
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
/>

Date & Time Constraints

Age Restrictions

Use minAge and maxAge to restrict birth date selection:

// Only allow ages 18-65
<ModernDatePicker
  mode="date"
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
  minAge={18}  // Must be at least 18 years old
  maxAge={65}  // Cannot be older than 65
/>

Date Range

Use minDate and maxDate for custom date ranges:

<ModernDatePicker
  mode="date"
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
  minDate={new Date(2020, 0, 1)}
  maxDate={new Date()}  // Today
/>

Time Range

Use minTime and maxTime to restrict time selection (e.g., business hours):

<ModernDatePicker
  mode="time"
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
  minTime={{ hour: 9, minute: 0 }}   // 9:00 AM
  maxTime={{ hour: 17, minute: 30 }} // 5:30 PM
/>

Invalid times are visually disabled (crossed out with low opacity) and cannot be selected.


Theming

You can theme in two ways:

import {
  ThemeProvider,
  createTheme,
} from "@anasyd/react-native-modern-date-picker";

const theme = createTheme({
  preset: "light", // "light" | "dark"
  palette: {
    primary: "#ffffff",   // surfaces/background
    secondary: "#000000", // text/icons
    accent: "#2563eb",    // selection highlight
  },
  // optional fine tuning:
  // overrides: { colors: { divider: "#eaeaea" }, radii: { md: 14 } }
});

<ThemeProvider value={theme}>
  <ModernDatePicker
    open={open}
    onClose={() => setOpen(false)}
    value={value}
    onChange={setValue}
  />
</ThemeProvider>;

B) One-off: pass a theme input on the component

Useful for quick demos or if you don't want a provider.

<ModernDatePicker
  open={open}
  onClose={() => setOpen(false)}
  value={value}
  onChange={setValue}
  theme={{
    preset: "dark",
    palette: {
      primary: "#1f2937",
      secondary: "#ffffff",
      accent: "#f59e0b",
    },
  }}
/>

Palette to Semantic Token Mapping

When you define a theme with createTheme({ preset, palette }), the palette colors map to semantic tokens:

Palette Property Maps To Semantic Token Purpose
primary background, surface, header Surfaces and backgrounds
secondary foreground, mutedForeground Text and icon colors
accent accent, onAccent Selection highlights and their text

Semantic color tokens

Token Purpose
background Main sheet background
surface Calendar body surface
header Header surface
foreground Primary text color on surfaces
mutedForeground Subdued text
border Border color
divider Hairline dividers
accent Selection chip background
onAccent Text on top of accent
disabledForeground Disabled text

createTheme({ preset, palette, overrides }) computes these tokens for you and auto-contrasts text (WCAG-ish 4.5) to avoid unreadable combos.


Backdrop

Custom Blur Backdrop (Expo)

import { BlurView } from "expo-blur";
import { Animated, StyleSheet, Platform } from "react-native";

<ModernDatePicker
  open={open}
  onClose={onClose}
  renderBackdrop={(opacity) => (
    <Animated.View style={[StyleSheet.absoluteFill, { opacity }]}>
      <BlurView
        intensity={12}
        tint="dark"
        experimentalBlurMethod={
          Platform.OS === "android" ? "dimezisBlurView" : undefined
        }
        style={StyleSheet.absoluteFill}
      />
    </Animated.View>
  )}
/>;

Custom Blur Backdrop (Bare RN)

import { BlurView } from "@react-native-community/blur";
import { Animated, StyleSheet } from "react-native";

<ModernDatePicker
  open={open}
  onClose={onClose}
  renderBackdrop={(opacity) => (
    <Animated.View style={[StyleSheet.absoluteFill, { opacity }]}>
      <BlurView
        blurType="dark"
        blurAmount={12}
        style={StyleSheet.absoluteFill}
      />
    </Animated.View>
  )}
/>;

Backdrop Props

  • renderBackdrop(opacity) โ€“ custom backdrop node.
  • showDefaultBackdrop (default true) โ€“ toggle built-in dim.
  • backdropColor (default #000) โ€“ dim overlay color.

Props

Prop Type Default Description
open boolean โ€” Show/hide the picker.
onClose () => void โ€” Called when the picker requests to close.
value Date | null โ€” Selected date (controlled).
defaultValue Date โ€” Default date (uncontrolled).
onChange (date: Date) => void โ€” Fired on selection.
Date Constraints
minDate Date โ€” Minimum selectable date.
maxDate Date โ€” Maximum selectable date.
minAge number โ€” Minimum age in years (e.g., 18 for adults only).
maxAge number โ€” Maximum age in years (e.g., 65).
Time Constraints
minTime { hour: number; minute: number } โ€” Minimum time (e.g., { hour: 9, minute: 0 } for 9:00 AM).
maxTime { hour: number; minute: number } โ€” Maximum time (e.g., { hour: 17, minute: 0 } for 5:00 PM).
Picker Mode
mode 'date' | 'time' | 'datetime' 'date' Picker mode: date only, time only, or both.
is24Hour boolean true Use 24-hour format for time picker.
minuteInterval 1|2|3|4|5|6|10|12|15|20|30 1 Minute interval for time picker.
Theming
theme Theme | CreateThemeInput โ€” Provide a full theme or palette input. Uses provider/default.
Localization
locale string platform Locale (e.g., "en-US").
firstDayOfWeek 0โ€ฆ6 0 0=Sun, 1=Mon, โ€ฆ
Other
testID string โ€” Test identifier.
style StyleProp<ViewStyle> โ€” Container style.
animationSpeed number 220 Show/hide animation speed (ms).
renderBackdrop (opacity: Animated.Value) => React.ReactNode โ€” Custom backdrop.
showDefaultBackdrop boolean true Show built-in dim overlay.
backdropColor string #000 Color for built-in dim overlay.

Haptic Feedback

The picker automatically provides haptic feedback on:

  • Year scroll interactions (medium intensity)
  • Time picker scroll selections (light intensity)
  • AM/PM scroll changes (light intensity)

Platform Support

iOS:

  • Uses Expo Haptics if available with proper intensity levels
  • Falls back to native iOS HapticFeedback
  • Last resort: Minimal vibration (5ms)

Android:

  • Uses react-native-haptic-feedback if available for native haptic effects
  • Falls back to native Android haptic feedback
  • Last resort: Minimal vibration (3ms)

Optional Enhanced Haptics

For the best haptic experience, you can optionally install:

npm install react-native-haptic-feedback
# For React Native 0.60+, run:
cd ios && pod install

This provides native haptic effects like impactLight, impactMedium, and impactHeavy on both platforms.

Key Features:

  • โœ… Smart triggering: Only on actual value changes, not every scroll event
  • โœ… Proper haptics: Uses native haptic APIs, not loud vibration
  • โœ… Graceful fallbacks: Works on all devices with appropriate intensity
  • โœ… No spam: Prevents excessive haptic feedback during scrolling

Exports

import ModernDatePicker, {
  createTheme,
  extendTheme,
  ThemeProvider,
  useTheme,
} from "@anasyd/react-native-modern-date-picker";
  • createTheme(input) โ†’ builds a WCAG-safe theme from preset + palette (+ optional overrides).
  • extendTheme(base, overrides) โ†’ convenient theme layering (e.g., tweak accent for a section).
  • ThemeProvider / useTheme() โ†’ share theme via context (global or nested).
  • ModernDatePicker โ†’ the component.

License

MIT