Skip to main content

Selection

Pure functions for computing and applying selection state to calendar grids.

import type { Selection, Adapter, Grid } from '@gentleduck/calendar'
import { selectDay, applySelection } from '@gentleduck/calendar'
import type { Selection, Adapter, Grid } from '@gentleduck/calendar'
import { selectDay, applySelection } from '@gentleduck/calendar'

Functions

selectDay

Compute the new selection value when a user clicks a day. Pure function - does not mutate state.

selectDay(adapter: Adapter.IDateAdapter<TDate>, mode: Selection.SelectionMode, current: Selection.CalendarValue<TDate, M>, date: TDate, options?: { shiftKey?: boolean }) => Selection.CalendarValue<TDate, M>
selectDay(adapter: Adapter.IDateAdapter<TDate>, mode: Selection.SelectionMode, current: Selection.CalendarValue<TDate, M>, date: TDate, options?: { shiftKey?: boolean }) => Selection.CalendarValue<TDate, M>
ParamTypeDescription
adapterAdapter.IDateAdapter<TDate>Date adapter
modeSelection.SelectionMode'single', 'range', 'multi', or 'multi-range'
currentSelection.CalendarValue<TDate, M>Current selection value
dateTDateThe clicked date
options{ shiftKey?: boolean }Optional. When shiftKey is true in multi-range mode, extends the last range

Returns the updated selection value. Shape depends on mode:

ModeTypeDescription
'single'TDate | nullThe selected date, or null
'range'Selection.DateRange<TDate> | null{ from, to } range object
'multi'TDate[]Array of selected dates
'multi-range'Selection.DateRange<TDate>[]Array of range objects

applySelection

Decorate an array of weeks with selection flags (isSelected, isRangeStart, isRangeMiddle, isRangeEnd, isDisabled). This is what makes the data-* attributes work.

applySelection(
  weeks: Grid.ICalendarWeek<TDate>[],
  adapter: Adapter.IDateAdapter<TDate>,
  mode: Selection.SelectionMode,
  selected: Selection.CalendarValue<TDate, M>,
  constraints?: Selection.ISelectionConstraints<TDate> // default: {}
) => Grid.ICalendarWeek<TDate>[]
applySelection(
  weeks: Grid.ICalendarWeek<TDate>[],
  adapter: Adapter.IDateAdapter<TDate>,
  mode: Selection.SelectionMode,
  selected: Selection.CalendarValue<TDate, M>,
  constraints?: Selection.ISelectionConstraints<TDate> // default: {}
) => Grid.ICalendarWeek<TDate>[]
ParamTypeDescription
weeksGrid.ICalendarWeek<TDate>[]Raw weeks from buildCalendarMonth
adapterAdapter.IDateAdapter<TDate>Date adapter
modeSelection.SelectionModeSelection mode
selectedSelection.CalendarValue<TDate, M>Current selection
constraintsSelection.ISelectionConstraints<TDate>Optional. Disabled dates, fromDate, toDate. Defaults to {}

Selection.ISelectionConstraints:

PropertyTypeDescription
disabledTDate[] | (date) => booleanDisabled dates
fromDateTDateEarliest selectable date
toDateTDateLatest selectable date

Types

Selection.SelectionMode

type Selection.SelectionMode = 'single' | 'range' | 'multi' | 'multi-range'
type Selection.SelectionMode = 'single' | 'range' | 'multi' | 'multi-range'

Selection.CalendarValue<TDate, M>

Conditional type that resolves based on the selection mode:

type Selection.CalendarValue<TDate, M extends Selection.SelectionMode> =
  M extends 'single' ? TDate | null :
  M extends 'range' ? Selection.DateRange<TDate> | null :
  M extends 'multi' ? TDate[] :
  M extends 'multi-range' ? Selection.DateRange<TDate>[] :
  never
type Selection.CalendarValue<TDate, M extends Selection.SelectionMode> =
  M extends 'single' ? TDate | null :
  M extends 'range' ? Selection.DateRange<TDate> | null :
  M extends 'multi' ? TDate[] :
  M extends 'multi-range' ? Selection.DateRange<TDate>[] :
  never

Selection.DateRange<TDate>

type Selection.DateRange<TDate> = {
  from: TDate
  to: TDate | null
}
type Selection.DateRange<TDate> = {
  from: TDate
  to: TDate | null
}