Skip to content

Calendar Events

Handle user interactions and integrate the React Calendar with your application logic.

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 date value changes
onChange?: (value: string | number) => void
onUpdateFired when calendar view updates
onUpdate?: (value: string | number) => void
onOpenFired when calendar opens
onOpen?: () => void
onCloseFired when calendar closes. origin identifies the source: 'button', 'escape', 'focusout', or any custom string passed via close({ origin }).
onClose?: (origin: string) => void

Handle date changes with the onChange event:

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

export default function App() {
    const [selected, setSelected] = useState('');

    return (
        <div>
            <Calendar
                type="inline"
                value={new Date()}
                onChange={(value) => setSelected(value)}
            />
            <p>Selected: {selected}</p>
        </div>
    );
}

Track calendar visibility:

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

export default function App() {
    const inputRef = useRef();
    const [status, setStatus] = useState('');

    return (
        <div>
            <input type="text" ref={inputRef} />
            <Calendar
                input={inputRef}
                onOpen={() => setStatus('Calendar opened')}
                onClose={() => setStatus('Calendar closed')}
            />
            <p>{status}</p>
        </div>
    );
}

The hook returns a callback ref plus a reactive instance. Combine it with onChange for both controlled and imperative access:

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

export default function App() {
    const { ref, instance } = useCalendar();
    const [selected, setSelected] = 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>
                <button disabled={!instance} onClick={() => instance.reset()}>Reset</button>
            </div>

            <Calendar ref={ref} type="inline" value={selected} onChange={setSelected} />
            <p>Selected: {selected}</p>
        </>
    );
}

Inline arrow functions reallocate every render. The wrapper's prop diff absorbs the no-op, but useCallback keeps it cheap:

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

export default function App() {
    const [selected, setSelected] = useState('2025-01-15');
    const onChange = useCallback((value) => setSelected(value), []);

    return <Calendar type="inline" value={selected} onChange={onChange} />;
}