or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

customization.mddate-utilities.mdindex.mdinternationalization.mdmain-component.mdselection.mdstyling.md

selection.mddocs/

0

# Selection System

1

2

React Day Picker provides a type-safe selection system supporting single date, multiple dates, and date range selection with both controlled and uncontrolled modes.

3

4

## Capabilities

5

6

### Selection Modes

7

8

The library supports three main selection modes with optional required validation.

9

10

```typescript { .api }

11

/**

12

* Selection mode types

13

*/

14

type Mode = "single" | "multiple" | "range";

15

16

/**

17

* Type-safe selected value based on selection mode

18

*/

19

type SelectedValue<T extends DayPickerProps> =

20

T["mode"] extends "single" ? Date | undefined :

21

T["mode"] extends "multiple" ? Date[] | undefined :

22

T["mode"] extends "range" ? DateRange | undefined :

23

never;

24

25

/**

26

* Type-safe selection handler based on selection mode

27

*/

28

type SelectHandler<T extends DayPickerProps> = (

29

value: SelectedValue<T>,

30

triggerDate: Date,

31

modifiers: Modifiers,

32

e: React.MouseEvent

33

) => void;

34

```

35

36

### Single Date Selection

37

38

Select a single date from the calendar.

39

40

```typescript { .api }

41

/**

42

* Props for single date selection mode

43

*/

44

interface PropsSingle {

45

mode: "single";

46

/** The selected date */

47

selected?: Date;

48

/** The default selected date for uncontrolled mode */

49

defaultSelected?: Date;

50

/** Event handler when a date is selected */

51

onSelect?: (

52

date: Date | undefined,

53

triggerDate: Date,

54

modifiers: Modifiers,

55

e: React.MouseEvent

56

) => void;

57

}

58

59

/**

60

* Props for required single date selection

61

*/

62

interface PropsSingleRequired {

63

mode: "single";

64

required: true;

65

/** The selected date (required) */

66

selected?: Date;

67

/** The default selected date for uncontrolled mode (required) */

68

defaultSelected?: Date;

69

/** Event handler when a date is selected (cannot be undefined) */

70

onSelect?: (

71

date: Date,

72

triggerDate: Date,

73

modifiers: Modifiers,

74

e: React.MouseEvent

75

) => void;

76

}

77

```

78

79

**Usage Examples:**

80

81

```typescript

82

import React, { useState } from "react";

83

import { DayPicker } from "react-day-picker";

84

85

// Controlled single selection

86

function ControlledSingle() {

87

const [selected, setSelected] = useState<Date>();

88

89

return (

90

<DayPicker

91

mode="single"

92

selected={selected}

93

onSelect={setSelected}

94

/>

95

);

96

}

97

98

// Uncontrolled single selection

99

function UncontrolledSingle() {

100

return (

101

<DayPicker

102

mode="single"

103

defaultSelected={new Date()}

104

onSelect={(date) => console.log("Selected:", date)}

105

/>

106

);

107

}

108

109

// Required single selection

110

function RequiredSingle() {

111

const [selected, setSelected] = useState<Date>(new Date());

112

113

return (

114

<DayPicker

115

mode="single"

116

required

117

selected={selected}

118

onSelect={setSelected}

119

/>

120

);

121

}

122

```

123

124

### Multiple Date Selection

125

126

Select multiple individual dates from the calendar.

127

128

```typescript { .api }

129

/**

130

* Props for multiple date selection mode

131

*/

132

interface PropsMulti {

133

mode: "multiple";

134

/** The selected dates array */

135

selected?: Date[];

136

/** The default selected dates for uncontrolled mode */

137

defaultSelected?: Date[];

138

/** Minimum number of dates that must be selected */

139

min?: number;

140

/** Maximum number of dates that can be selected */

141

max?: number;

142

/** Event handler when dates are selected */

143

onSelect?: (

144

dates: Date[] | undefined,

145

triggerDate: Date,

146

modifiers: Modifiers,

147

e: React.MouseEvent

148

) => void;

149

}

150

151

/**

152

* Props for required multiple date selection

153

*/

154

interface PropsMultiRequired {

155

mode: "multiple";

156

required: true;

157

/** The selected dates array (required) */

158

selected?: Date[];

159

/** The default selected dates for uncontrolled mode (required) */

160

defaultSelected?: Date[];

161

/** Minimum number of dates that must be selected */

162

min?: number;

163

/** Maximum number of dates that can be selected */

164

max?: number;

165

/** Event handler when dates are selected (cannot be empty) */

166

onSelect?: (

167

dates: Date[],

168

triggerDate: Date,

169

modifiers: Modifiers,

170

e: React.MouseEvent

171

) => void;

172

}

173

```

174

175

**Usage Examples:**

176

177

```typescript

178

// Controlled multiple selection

179

function ControlledMultiple() {

180

const [selected, setSelected] = useState<Date[]>([]);

181

182

return (

183

<DayPicker

184

mode="multiple"

185

selected={selected}

186

onSelect={setSelected}

187

max={5} // limit to 5 dates

188

/>

189

);

190

}

191

192

// Multiple selection with constraints

193

function ConstrainedMultiple() {

194

const [selected, setSelected] = useState<Date[]>([]);

195

196

return (

197

<DayPicker

198

mode="multiple"

199

selected={selected}

200

onSelect={setSelected}

201

min={2}

202

max={7}

203

disabled={{ dayOfWeek: [0, 6] }} // disable weekends

204

/>

205

);

206

}

207

```

208

209

### Date Range Selection

210

211

Select a continuous range of dates with start and end dates.

212

213

```typescript { .api }

214

/**

215

* Props for date range selection mode

216

*/

217

interface PropsRange {

218

mode: "range";

219

/** The selected date range */

220

selected?: DateRange;

221

/** The default selected range for uncontrolled mode */

222

defaultSelected?: DateRange;

223

/** Minimum number of days in the range */

224

min?: number;

225

/** Maximum number of days in the range */

226

max?: number;

227

/** Event handler when a range is selected */

228

onSelect?: (

229

range: DateRange | undefined,

230

triggerDate: Date,

231

modifiers: Modifiers,

232

e: React.MouseEvent

233

) => void;

234

}

235

236

/**

237

* Props for required date range selection

238

*/

239

interface PropsRangeRequired {

240

mode: "range";

241

required: true;

242

/** The selected date range (required) */

243

selected?: DateRange;

244

/** The default selected range for uncontrolled mode (required) */

245

defaultSelected?: DateRange;

246

/** Minimum number of days in the range */

247

min?: number;

248

/** Maximum number of days in the range */

249

max?: number;

250

/** Event handler when a range is selected (cannot be undefined) */

251

onSelect?: (

252

range: DateRange,

253

triggerDate: Date,

254

modifiers: Modifiers,

255

e: React.MouseEvent

256

) => void;

257

}

258

259

/**

260

* Date range interface

261

*/

262

interface DateRange {

263

from: Date | undefined;

264

to?: Date | undefined;

265

}

266

```

267

268

**Usage Examples:**

269

270

```typescript

271

// Controlled range selection

272

function ControlledRange() {

273

const [range, setRange] = useState<DateRange | undefined>();

274

275

return (

276

<DayPicker

277

mode="range"

278

selected={range}

279

onSelect={setRange}

280

numberOfMonths={2}

281

/>

282

);

283

}

284

285

// Range selection with constraints

286

function ConstrainedRange() {

287

const [range, setRange] = useState<DateRange | undefined>();

288

289

const handleSelect = (newRange: DateRange | undefined) => {

290

// Custom validation logic

291

if (newRange?.from && newRange?.to) {

292

const daysDiff = Math.abs(

293

newRange.to.getTime() - newRange.from.getTime()

294

) / (1000 * 60 * 60 * 24);

295

296

if (daysDiff > 14) {

297

alert("Range cannot exceed 14 days");

298

return;

299

}

300

}

301

setRange(newRange);

302

};

303

304

return (

305

<DayPicker

306

mode="range"

307

selected={range}

308

onSelect={handleSelect}

309

min={3} // minimum 3 days

310

max={14} // maximum 14 days

311

/>

312

);

313

}

314

315

// Range selection with custom styling

316

function StyledRange() {

317

const [range, setRange] = useState<DateRange | undefined>();

318

319

return (

320

<DayPicker

321

mode="range"

322

selected={range}

323

onSelect={setRange}

324

modifiersClassNames={{

325

range_start: "range-start",

326

range_middle: "range-middle",

327

range_end: "range-end"

328

}}

329

/>

330

);

331

}

332

```

333

334

### Selection Context Hook

335

336

Hook for accessing selection state in custom components.

337

338

```typescript { .api }

339

/**

340

* Hook providing access to the DayPicker context

341

* @returns DayPicker context with selection state and handlers

342

*/

343

function useDayPicker<T extends DayPickerProps>(): DayPickerContext<T>;

344

345

interface DayPickerContext<T extends DayPickerProps> {

346

/** The DayPicker props */

347

dayPickerProps: T;

348

/** Current selected value */

349

selected: SelectedValue<T>;

350

/** Selection handler function */

351

select: SelectHandler<T>;

352

/** Function to check if a date is selected */

353

isSelected?: (date: Date) => boolean;

354

/** Calendar months data */

355

months: CalendarMonth[];

356

/** Next navigable month */

357

nextMonth?: Date;

358

/** Previous navigable month */

359

previousMonth?: Date;

360

/** Navigate to specific month */

361

goToMonth: (month: Date) => void;

362

/** Get modifiers for a day */

363

getModifiers: (day: CalendarDay) => Modifiers;

364

/** Custom components */

365

components: CustomComponents;

366

/** CSS class names */

367

classNames: ClassNames;

368

/** CSS styles */

369

styles?: Partial<Styles>;

370

/** Accessibility labels */

371

labels: Labels;

372

/** Date formatters */

373

formatters: Formatters;

374

}

375

```

376

377

**Usage Example:**

378

379

```typescript

380

import { useDayPicker } from "react-day-picker";

381

382

function CustomFooter() {

383

const { selected, mode } = useDayPicker();

384

385

if (mode === "single" && selected) {

386

return <p>Selected: {selected.toDateString()}</p>;

387

}

388

389

if (mode === "range" && selected?.from) {

390

return (

391

<p>

392

{selected.from.toDateString()}

393

{selected.to ? ` - ${selected.to.toDateString()}` : " (select end date)"}

394

</p>

395

);

396

}

397

398

return <p>No date selected</p>;

399

}

400

401

// Usage in DayPicker

402

<DayPicker

403

mode="single"

404

components={{ Footer: CustomFooter }}

405

/>

406

```