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 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-super-date-input

v1.0.8

Published

Highly customizable React date/time input component library

Downloads

845

Readme

react-super-date-input

npm version npm downloads bundle size TypeScript license

A highly customizable React date & time input library. Multiple picker types, selection modes, 6 built-in themes, manual text input, timezone support, and a full hook API — all in under 50KB.

📖 Full Documentation →  |  🎮 Live Demo →


Features

  • 🗓 8 picker typesdate, datetime, time, month, year, week, single range, multi-range
  • 3 selection modes — single, multiple, range
  • 🖊 Manual text input — type directly into the box with format validation
  • 📅 Multi-range calendar — select multiple independent date ranges, each in its own colour
  • 🎨 6 built-in themeslight, dark, obsidian, aurora, ember, sage, midnight, rose, forest, cyberpunk, ocean, minimal, slate, indigo, graphite, vercel, notion, github, linear, material + fully custom
  • 🕐 Time format switcher — lock to 12h, lock to 24h, or let users switch between both
  • 🌍 Timezone support — IST, EST, PST, UTC, GMT, JST, CET, AEST and more
  • 12 built-in quick ranges — Today, Last 7d, This Month, Last Year, etc.
  • 🔣 Custom icons — start / end positions
  • 📤 Input & output formats — parse typed input in one format, emit in another
  • Accessible — full ARIA attributes and keyboard navigation
  • 🪝 7 standalone hooks — use the logic without the UI
  • 📦 < 50KB — Day.js only, no other runtime dependencies

Live Demo

https://react-super-date.vercel.app/

Installation

npm install react-super-date-input
yarn add react-super-date-input
pnpm add react-super-date-input

Peer dependencies (install if you don't have them):

npm install react react-dom

Quick Start

import { DateInput, RangePicker, TimePicker } from 'react-super-date-input'

// Single date
<DateInput
  label="Start Date"
  theme="obsidian"
  onChange={(date) => console.log(date)}
/>

// Date range with quick tabs
<RangePicker
  theme="aurora"
  quickRanges={['today', 'last7days', 'thisMonth']}
  onChange={({ from, to }) => console.log(from, to)}
/>

// Time with timezone
<TimePicker
  availableFormats={['12h', '24h']}
  timezone="IST"
  showTimezone
  onChange={(time, tz) => console.log(time, tz)}
/>

Components

<DateInput>

The core picker — handles single date, multiple dates, and date+time.

import { DateInput } from 'react-super-date-input'

// Single
<DateInput
  type="date"
  value={date}
  onChange={(d) => setDate(d as Date)}
  theme="obsidian"
  clearable
/>

// Multiple dates
<DateInput
  mode="multiple"
  value={dates}
  onChange={(d) => setDates(d as Date[])}
  theme="sage"
/>

// Date + Time (12h)
<DateInput
  type="datetime"
  timeFormat="12h"
  value={dt}
  onChange={(d) => setDt(d as Date)}
/>

// Manual text input with custom formats
<DateInput
  allowManualInput
  inputFormat="DD-MM-YYYY"
  displayFormat="DD-MM-YYYY"
  outputFormat="YYYY-MM-DD"
  placeholder="DD-MM-YYYY"
  onChange={(d) => console.log(d)} // receives "2024-06-15" string
/>

// Inline (no popup)
<DateInput inline onChange={(d) => console.log(d)} />

| Prop | Type | Default | Description | |------|------|---------|-------------| | type | "date" | "datetime" | "date" | Picker type | | mode | "single" | "multiple" | "single" | Selection mode | | value | Date \| Date[] \| null | — | Controlled value | | defaultValue | Date \| Date[] | — | Uncontrolled default | | allowManualInput | boolean | false | Enables typing in the input box | | inputFormat | string | "MM/DD/YYYY" | Day.js format for parsing typed text | | displayFormat | string | same as inputFormat | Format shown in the box | | outputFormat | string | — | If set, onChange returns a string instead of Date | | timeFormat | "12h" | "24h" | "12h" | For datetime type only | | showSeconds | boolean | false | Show seconds spinner | | minDate | Date | — | Dates before this are disabled | | maxDate | Date | — | Dates after this are disabled | | disabledDates | Date[] \| (d: Date) => boolean | — | Specific dates to disable | | inline | boolean | false | Render calendar inline, no popup | | clearable | boolean | true | Show ✕ clear button | | closeOnSelect | boolean | true | Auto-close after picking | | theme | BuiltInTheme \| DateInputTheme | "light" | Theme name or custom object | | disabled | boolean | false | Disables interaction | | readOnly | boolean | false | Display only | | label | string | — | Label above input | | placeholder | string | — | Placeholder text | | icon | ReactNode | — | Custom icon | | iconPosition | "start" | "end" | "start" | Icon placement |


<RangePicker>

Dual-panel range picker with hover preview and quick range tabs.

import { RangePicker } from 'react-super-date-input'

<RangePicker
  value={{ from, to }}
  onChange={({ from, to }) => setRange({ from, to })}
  fromLabel="Check in"
  toLabel="Check out"
  quickRanges={['today', 'last7days', 'last30days', 'thisMonth', 'lastMonth']}
  theme="aurora"
/>

| Prop | Type | Description | |------|------|-------------| | value | { from: Date \| null, to: Date \| null } | Controlled range | | onChange | (range: DateRange) => void | Called when both dates selected | | fromLabel | string | Label for the start input | | toLabel | string | Label for the end input | | separatorIcon | ReactNode | Custom separator (default ) | | quickRanges | (BuiltInQuickRange \| QuickRange)[] | Quick select tabs | | showQuickRanges | boolean | Show/hide tabs row | | inline | boolean | Always-visible dual calendar |

Built-in quick range keys:

"today" "yesterday" "last7days" "last14days" "last30days" "last90days" "thisWeek" "lastWeek" "thisMonth" "lastMonth" "thisYear" "lastYear"

Custom quick range:

const sprint = {
  label: 'Current Sprint',
  getValue: () => ({ from: new Date('2024-06-01'), to: new Date('2024-06-14') })
}
<RangePicker quickRanges={[sprint, 'last30days']} />

<MultiRangePicker>

Select multiple independent date ranges — each rendered in a distinct colour.

import { MultiRangePicker } from 'react-super-date-input'

<MultiRangePicker
  value={ranges}
  onChange={setRanges}
  maxRanges={4}
  rangeColors={['#6366f1', '#f97316', '#10b981', '#e11d48']}
  theme="obsidian"
/>

| Prop | Type | Description | |------|------|-------------| | value | DateRange[] | Controlled array of ranges | | onChange | (ranges: DateRange[]) => void | Called on every change | | maxRanges | number | Cap on number of ranges (oldest dropped when exceeded) | | rangeColors | string[] | Hex colours cycled per range | | showQuickRanges | boolean | Show quick tab pills | | inline | boolean | Always-visible calendar |


<TimePicker>

Spinner-based time picker with format switcher and timezone selector.

import { TimePicker } from 'react-super-date-input'

// Lock to one format — no switcher shown
<TimePicker availableFormats="12h" />
<TimePicker availableFormats="24h" showSeconds />

// Both formats — user can switch between them
<TimePicker
  availableFormats={['12h', '24h']}
  timezone="IST"
  showTimezone
  onChange={(time, tz) => console.log(time, tz)}
/>

| Prop | Type | Default | Description | |------|------|---------|-------------| | availableFormats | "12h" | "24h" | ["12h","24h"] | ["12h","24h"] | Lock to one or show tabs for both | | showSeconds | boolean | false | Show seconds spinner | | timezone | TimezoneString | "UTC" | Default timezone | | showTimezone | boolean | true | Show timezone pill row | | autoDetectTimezone | boolean | false | Auto-detect from browser |

Supported timezones: UTC GMT IST EST PST CST MST JST CET AEST


<MonthPicker> · <YearPicker> · <WeekPicker>

import { MonthPicker, YearPicker, WeekPicker } from 'react-super-date-input'

<MonthPicker
  value={{ month: 5, year: 2024 }}   // month is 0-indexed
  onChange={({ month, year }) => console.log(month, year)}
  theme="ember"
/>

<YearPicker
  value={2024}
  onChange={(year) => console.log(year)}
/>

<WeekPicker
  value={{ week: 22, year: 2024 }}
  onChange={({ week, year }) => console.log(week, year)}
/>

Theming

Built-in themes

<DateInput theme="light" />
<DateInput theme="dark" />
<DateInput theme="obsidian" />
<DateInput theme="aurora" />
<DateInput theme="ember" />
<DateInput theme="sage" />
<DateInput theme="midnight" />
<DateInput theme="rose" />
<DateInput theme="forest" />
<DateInput theme="cyberpunk" />
<DateInput theme="ocean" />
<DateInput theme="minimal" />
<DateInput theme="slate" />
<DateInput theme="indigo" />
<DateInput theme="graphite" />
<DateInput theme="vercel" />
<DateInput theme="notion" />
<DateInput theme="github" />
<DateInput theme="linear" />
<DateInput theme="material" />

Custom theme

Pass a partial object — it merges onto the light base so you only override what you need:

import type { DateInputTheme } from 'react-super-date-input'

const myTheme: DateInputTheme = {
  accent:       '#e11d48',
  accentHover:  '#be123c',
  border:       '#fecdd3',
  bgInput:      '#fff1f2',
  radius:       '6px',
  fontFamily:   "'Inter', sans-serif",
}

<DateInput theme={myTheme} />

All available tokens:

| Token | Controls | |-------|----------| | bgInput | Input box background | | bgPopup | Popup/dropdown background | | accent | Selected day, active buttons | | accentHover | Hover on accent elements | | accentText | Text on accent background | | accentLight | Lighter accent for chips/tags | | accentBg | Very light accent background | | rangeBg | In-range days background | | rangeEdgeBg | Range start/end background | | textPrimary | Main text | | textMuted | Labels, headers | | textDisabled | Disabled state text | | border | Input and popup borders | | borderFocus | Focused input border | | focusRing | Focus ring shadow | | todayIndicator | Dot under today's date | | radius | Border radius everywhere | | fontFamily | Monospace input font | | displayFontFamily | Month/year heading font | | shadow | Popup drop shadow |


Hooks

Use the underlying logic without the UI components:

import {
  useDateState,
  useMultipleDateState,
  useRangeSelection,
  useTimeState,
  useCalendar,
  useTimezone,
  useClickOutside,
} from 'react-super-date-input'

// Single date
const { value, setValue, clear, formatted, isValid } = useDateState(new Date())

// Multiple dates
const { values, toggle, add, remove, clear, has } = useMultipleDateState()

// Range (state machine — idle → selecting → idle)
const { from, to, select, clear, isInRange, phase } = useRangeSelection()

// Time
const { hours, minutes, seconds, setTime, formatted, toDate } = useTimeState({ hours: 9, minutes: 0 })

// Calendar navigation
const { year, month, prevMonth, nextMonth, goTo, days } = useCalendar(2024, 0)

// Timezone
const { timezone, setTimezone, convert, format, detected } = useTimezone('IST')

// Click outside
useClickOutside(ref, () => setOpen(false))

Format Tokens (Day.js)

| Token | Output | |-------|--------| | MM | 01 – 12 | | DD | 01 – 31 | | YYYY | 2024 | | M | 1 – 12 | | D | 1 – 31 | | MMM | Jan – Dec | | MMMM | January – December | | HH | 00 – 23 | | hh | 01 – 12 | | mm | 00 – 59 | | ss | 00 – 59 | | A | AM / PM |


TypeScript

Fully typed — all props, return values, and theme tokens are exported:

import type {
  DateRange,
  DateInputTheme,
  BuiltInTheme,
  TimeValue,
  MonthValue,
  WeekValue,
  QuarterValue,
  TimezoneString,
  BuiltInQuickRange,
  QuickRange,
  PickerType,
  SelectionMode,
  TimeFormat,
} from 'react-super-date-input'

Accessibility

  • role="combobox" on every input trigger
  • aria-expanded, aria-haspopup, aria-selected, aria-disabled on all interactive elements
  • role="dialog" + aria-modal on popups
  • Full keyboard navigation — Enter/Space to select, Escape to close
  • Labels linked via htmlFor / id
  • Themeable focus ring via focusRing token

Browser Support

Works in all modern browsers. Requires React 17 or higher.


License

MIT © Shitiz Garg