Skip to Content
APIAPI ReferenceuseSelection

useSelection

A companion hook for useCalendar that manages date selection state and enriches the calendar body with selection properties.

Import

import { useSelection } from '@h6s/calendar';

Usage

Single Selection

function MyCalendar() { const { headers, body, navigation, cursorDate } = useCalendar(); const selection = useSelection({ mode: 'single', body, }); return ( <table> <tbody> {selection.body.value.map(({ key, value: days }) => ( <tr key={key}> {days.map(({ key, value, isSelected, isDisabled }) => ( <td key={key}> <button onClick={() => selection.select(value)} disabled={isDisabled} style={{ fontWeight: isSelected ? 'bold' : 'normal' }} > {format(value, 'd')} </button> </td> ))} </tr> ))} </tbody> </table> ); }

Range Selection

function MyRangeCalendar() { const { headers, body, navigation, cursorDate } = useCalendar(); const selection = useSelection({ mode: 'range', body, }); return ( <table> <tbody> {selection.body.value.map(({ key, value: days }) => ( <tr key={key}> {days.map(({ key, value, isSelected, isRangeStart, isRangeEnd, isInRange }) => ( <td key={key}> <button onClick={() => selection.select(value)} className={[ isRangeStart && 'range-start', isRangeEnd && 'range-end', isInRange && 'in-range', isSelected && 'selected', ].filter(Boolean).join(' ')} > {format(value, 'd')} </button> </td> ))} </tr> ))} </tbody> </table> ); }

Multiple Selection

function MyMultiCalendar() { const { headers, body, navigation, cursorDate } = useCalendar(); const selection = useSelection({ mode: 'multiple', body, max: 5, }); return ( <div> <p>Selected: {selection.selected.length} / 5</p> {/* Render calendar using selection.body ... */} </div> ); }

Parameters

function useSelection(options: SelectionOptions)

Common Options

OptionTypeDescription
mode'single' | 'range' | 'multiple'Selection mode (must remain constant across renders)
bodyCalendarBodyThe body returned from useCalendar
disabledMatcher | Matcher[]Dates to disable from selection

Single Mode Options

OptionTypeDefaultDescription
requiredbooleanfalsePrevent deselecting the current selection

Range Mode Options

OptionTypeDescription
minnumberMinimum number of days in the range
maxnumberMaximum number of days in the range

Multiple Mode Options

OptionTypeDescription
minnumberMinimum number of selected dates
maxnumberMaximum number of selected dates

Return Value

Single Mode

{ selected: Date | undefined; select: (date: Date) => void; deselect: () => void; isSelected: (date: Date) => boolean; isDisabled: (date: Date) => boolean; body: CalendarBody<Cell & { isSelected: boolean; isDisabled: boolean }>; }

Range Mode

{ selected: DateRange | undefined; // { from: Date; to?: Date } select: (date: Date) => void; deselect: () => void; isSelected: (date: Date) => boolean; isDisabled: (date: Date) => boolean; isRangeStart: (date: Date) => boolean; isRangeEnd: (date: Date) => boolean; isInRange: (date: Date) => boolean; body: CalendarBody<Cell & { isSelected: boolean; isDisabled: boolean; isRangeStart: boolean; isRangeEnd: boolean; isInRange: boolean; }>; }

Multiple Mode

{ selected: Date[]; select: (date: Date) => void; deselect: (date: Date) => void; isSelected: (date: Date) => boolean; isDisabled: (date: Date) => boolean; body: CalendarBody<Cell & { isSelected: boolean; isDisabled: boolean }>; }

The body returned from useSelection enriches each cell with selection properties. Use selection.body instead of the original body from useCalendar when rendering.

Matcher

The disabled option accepts one or more Matcher values to determine which dates should be disabled.

type Matcher = | Date // Exact date | Date[] // List of dates | { before: Date } // All dates before | { after: Date } // All dates after | { from: Date; to: Date } // Date range | { dayOfWeek: number[] } // Days of week (0=Sun, 6=Sat) | ((date: Date) => boolean); // Custom function

Examples

// Disable weekends useSelection({ mode: 'single', body, disabled: { dayOfWeek: [0, 6] } }); // Disable past dates useSelection({ mode: 'single', body, disabled: { before: new Date() } }); // Disable specific dates useSelection({ mode: 'single', body, disabled: [new Date(2024, 11, 25), new Date(2024, 11, 31)] }); // Combine multiple matchers useSelection({ mode: 'range', body, disabled: [ { dayOfWeek: [0, 6] }, { before: new Date() }, ], });

Type Exports

import type { DateRange, Matcher, SelectionCellProps, RangeSelectionCellProps, SelectionOptions, SingleSelectionOptions, RangeSelectionOptions, MultipleSelectionOptions, SingleSelectionReturn, RangeSelectionReturn, MultipleSelectionReturn, } from '@h6s/calendar';
Last updated on