Skip to content

React Calendar

3.18KB gzipped

The Calendar component is a lightweight React date picker. It supports single date selection, date ranges, and optional time picking. Built for forms, filters, and any interface requiring date input. Includes keyboard navigation for accessibility. Can be displayed inline or as a popup attached to input fields.

  • Single date or range selection
  • Date and time picking
  • Inline display or popup on focus
  • Keyboard navigation (arrows, enter, esc)
  • Input element binding with auto-sync
  • Excel-style numeric dates
  • ISO and custom date formats
  • Responsive design
  • Accessible (ARIA labels, keyboard support)
  • Form date inputs
  • Date range filters
  • Booking systems
  • Scheduling interfaces
  • Event date selection
  • Deadline pickers
npm install @calendarjs/react
PropertyDescription
type?: 'default' | 'auto' | 'picker' | 'inline'Display mode. Default: 'default'.
format?: stringDate format string (Excel-like, e.g. dd/mm/yyyy).
range?: booleanEnables date range selection. Default: false.
value?: number | string | Date | ArraySelected date value. Accepts an ISO string, an Excel serial number, a Date, or [start, end] for range mode.
numeric?: booleanReturns value as an Excel serial number instead of an ISO string. Default: false.
footer?: booleanShows the calendar footer. Default: true.
time?: booleanDisplays hour and minute picker. Default: false.
grid?: booleanEnables grid mode. Default: false.
placeholder?: stringPlaceholder text for the input field.
disabled?: booleanDisables calendar interaction. Default: false.
startingDay?: numberSets the first day of the week (0 = Sunday, 6 = Saturday). Default: 0.
validRange?: number[] | string[] | FunctionRestricts selectable dates. Accepts [from, to] (numbers or ISO strings), or a predicate (day, month, year, item) => boolean returning truthy to disable a cell.
data?: Array<{ date: string }>Calendar events data.
wheel?: booleanUpdates the view using the mouse wheel. Default: true.
input?: HTMLInputElement | RefObject | 'auto'Binds the calendar to an input element ('auto' auto-detects).
initInput?: booleanCreates events and assigns calendar classes to the input. Default: true.

Use the camelCase names in React (e.g. onChange instead of onchange). The wrapper drops the leading self argument — the instance is available via the forwarded ref.

EventDescription
onChangeFired when the date value changes
onChange?: (value: string | number) => void
onUpdateFired when the calendar view updates
onUpdate?: (value: string | number) => void
onOpenFired when the calendar opens
onOpen?: () => void
onCloseFired when the calendar closes. origin identifies the source: 'button', 'escape', 'focusout', or any custom string passed via close({ origin }).
onClose?: (origin: string) => void
onInputChangeNative DOM change event on the bound input element
onInputChange?: (e: React.ChangeEvent<HTMLInputElement>) => void

Access the instance via useRef() and call methods on ref.current.

MethodDescription
getValue(): string | numberGet current value
setValue(value: string | number): voidSet date value
open(): voidOpen calendar
close(options?: object): voidClose calendar
isClosed(): boolean | undefinedReturns true/false for modal types; undefined for 'inline'.
setView(view: 'days' | 'months' | 'years'): voidChange calendar view
next(): voidGo to next month/year
prev(): voidGo to previous month/year
reset(): voidReset value and close
update(): voidAccept selected value
KeyAction
Arrow keysNavigate dates
EnterSelect date
EscClose calendar
Page Up/DownPrevious/next month
HomeFirst day of month
EndLast day of month

Supported input formats:

  • ISO: "2024-01-15" or "2024-01-15 14:30:00"
  • Date object: new Date()
  • Numeric: 45000 (with numeric: true)
import React, { useState } from 'react';
import { Calendar } from '@calendarjs/react';

export default function App() {
    const [date, setDate] = useState('2024-01-15');

    return (
        <Calendar
            type="inline"
            value={date}
            onChange={setDate}
        />
    );
}
import React, { useRef } from 'react';
import { Calendar } from '@calendarjs/react';

export default function App() {
    const inputRef = useRef();

    return (
        <>
            <input type="text" ref={inputRef} />
            <Calendar range={true} input={inputRef} />
        </>
    );
}
import React from 'react';
import { Calendar } from '@calendarjs/react';

export default function App() {
    return (
        <Calendar
            type="inline"
            value={new Date()}
            onChange={(value) => {
                console.log('Selected date:', value);
                // Send to API, update state, etc.
            }}
        />
    );
}

Include time picker with the calendar:

import React from 'react';
import { Calendar } from '@calendarjs/react';

export default function App() {
    return (
        <Calendar
            type="inline"
            value="2024-01-15 14:30"
            time={true}
        />
    );
}

Use Excel-style serial numbers:

import React, { useState } from 'react';
import { Calendar } from '@calendarjs/react';

export default function App() {
    const [serial, setSerial] = useState(45000);

    return (
        <Calendar
            numeric={true}
            value={serial}
            onChange={(value) => {
                console.log('Serial number:', value);
                setSerial(value);
            }}
        />
    );
}

Attach to an input and show on focus:

import React, { useRef } from 'react';
import { Calendar } from '@calendarjs/react';

export default function App() {
    const inputRef = useRef();

    return (
        <>
            <input type="text" ref={inputRef} placeholder="Select date" />
            <Calendar input={inputRef} />
        </>
    );
}

Pass value plus onChange and the parent state becomes the source of truth:

import { useCallback, useState } from 'react';
import { Calendar } from '@calendarjs/react';

export default function App() {
    const [date, setDate] = useState('2025-01-15');

    // Memoize so the wrapper's prop diff sees a stable reference.
    const onChange = useCallback((value) => setDate(value), []);

    return (
        <Calendar
            type="inline"
            value={date}
            onChange={onChange}
        />
    );
}

The hook returns a callback ref plus a reactive instance — null before mount, the live instance after. Useful for custom navigation toolbars:

import { useState } from 'react';
import { Calendar, useCalendar } from '@calendarjs/react';

export default function App() {
    const { ref, instance } = useCalendar();
    const [date, setDate] = useState('2025-01-15');

    return (
        <>
            <div style={{ display: 'flex', gap: 8 }}>
                <button disabled={!instance} onClick={() => instance.prev()}>Prev</button>
                <button disabled={!instance} onClick={() => instance.setValue(new Date())}>Today</button>
                <button disabled={!instance} onClick={() => instance.next()}>Next</button>
            </div>

            <Calendar ref={ref} type="inline" value={date} onChange={setDate} />
        </>
    );
}

data-*, aria-*, and role are forwarded onto the wrapper <div> — handy for Playwright, React Testing Library, and screen readers:

<Calendar
    type="inline"
    value="2025-01-15"
    data-testid="booking-calendar"
    aria-label="Reservation date"
/>

CalendarJS is a complete calendar and scheduling solution (like Google Calendar) that includes:

  • Calendar - Date picker component (this page)
  • Schedule - Event scheduler with day/week/month views, drag & drop
  • Timeline - Chronological event display

If you only need basic date picking for forms (not full calendar/scheduling functionality), consider these lightweight alternatives from our ecosystem:

For projects requiring a minimal footprint for simple form date inputs, jSuites Calendar offers a lightweight JavaScript calendar plugin with core date picking functionality. Ideal when you only need basic date selection without CalendarJS's scheduling, timeline, and event management features.

When to use jSuites Calendar:

  • You need minimal bundle size (~2KB) for basic forms
  • Simple date input fields (no scheduling/events needed)
  • You're already using other jSuites components

When to use CalendarJS instead:

  • You're building a scheduling system (like Google Calendar)
  • You need event management with drag & drop
  • You want timeline views and calendar displays
  • You need advanced features (Schedule, Timeline components)

View jSuites Calendar Documentation →


If you're building reactive applications, the LemonadeJS Calendar provides a reactive wrapper with two-way data binding.

When to use LemonadeJS Calendar:

  • You're building with reactive architecture
  • You need automatic state synchronization
  • You want seamless Vue/React-like integration

View LemonadeJS Calendar Documentation →


Data Grid Integration: Jspreadsheet Date Column

Section titled “Data Grid Integration: Jspreadsheet Date Column”

For spreadsheet and data grid applications, Jspreadsheet integrates calendar functionality directly into table cells with formula support and Excel-like date operations.

When to use Jspreadsheet Date Column:

  • You're building a data grid or spreadsheet
  • You need date formulas and calculations
  • You want Excel-like date handling

View Jspreadsheet Pro Date Documentation →


The open-source Jspreadsheet CE also integrates calendar functionality into data grid cells. Perfect for:

  • Open-source projects requiring spreadsheet functionality
  • Basic data grid calendar needs
  • Community-driven development

View Jspreadsheet CE Date Documentation →


FeatureCalendarJSjSuitesLemonadeJSJspreadsheet ProJspreadsheet CE
Bundle Size3.18KB~2KB~4KBPart of gridPart of grid
Date Range Selection✓✓✓✓✓
Time Picker✓✓✓✓✓
Event Scheduling✓✓----
Timeline Views✓✓----
Reactive Data Binding--✓--
Formula Support---✓✓
Keyboard Navigation✓✓✓✓✓✓✓✓
ARIA Support✓✓-✓✓✓✓Basic
LicenseMITMITMITCommercialMIT
Best ForCalendars & SchedulingSimple formsReactive AppsPro data gridsCE data grids