fossui
Components

Date Picker

A field that opens a calendar in a dialog and shows the chosen date back in the trigger.

A date picker is a field that opens a calendar in a modal dialog and reads the chosen date back in its trigger. It comes in two shapes, one per named constructor: single for one day and range for a start-to-end span. Tapping the field (or pressing Enter, Space, or the down arrow) opens the calendar as a bottom sheet by default, or a centered card via presentation; a scrim tap or Escape dismisses it.

Date picker
import 'package:fossui/fossui.dart';

FossDatePicker.single(
  selected: _day,
  onSelected: (day) => setState(() => _day = day),
);

Date range

FossDatePicker.range selects a span over two taps. The first tap sets the start, the second sets the end, and onSelected fires with a FossDateRange. The trigger shows both ends once the range is complete.

Date picker range
FossDatePicker.range(
  selected: _range,
  onSelected: (range) => setState(() => _range = range),
);

Label format

The trigger label uses a built-in format (March 6th, 2026 for a single date, Jul 09, 2026 - Jul 16, 2026 for a range) with no date-library dependency. Pass a format callback for locale-aware output, and placeholder for the empty state.

FossDatePicker.single(
  selected: _day,
  placeholder: 'Select a date',
  format: (day) => DateFormat.yMMMMd().format(day),
  onSelected: (day) => setState(() => _day = day),
);

Bounds

minDate and maxDate cap the selectable span, and isDateEnabled disables individual days such as weekends or holidays. All three pass through to the embedded calendar.

FossDatePicker.single(
  selected: _day,
  minDate: DateTime.now(),
  isDateEnabled: (day) => day.weekday <= DateTime.friday,
  onSelected: (day) => setState(() => _day = day),
);

Presentation

The calendar opens as a bottom sheet by default. Pass FossDialogPresentation.centered for a centered card instead.

FossDatePicker.single(
  selected: _day,
  presentation: FossDialogPresentation.centered,
  onSelected: (day) => setState(() => _day = day),
);

Open state

Leave the open state to the picker, or control it with open and onOpenChange. By default the dialog closes on a pick (closeOnSelect), a single date on its tap and a range once both ends are set. Set closeOnSelect: false to keep it open.

FossDatePicker.single(
  selected: _day,
  open: _open,
  onOpenChange: (open) => setState(() => _open = open),
  closeOnSelect: false,
  onSelected: (day) => setState(() => _day = day),
);

One-off styling

Global retheming is the first choice, but a single picker can override its trigger with a FossDatePickerStyle. Every field is optional and falls back to the theme.

FossDatePicker.single(
  selected: _day,
  style: const FossDatePickerStyle(
    gap: 10,
  ),
  onSelected: (day) => setState(() => _day = day),
);

API

FossDatePicker.single

PropTypeDefaultDescription
selectedDateTime?requiredThe chosen day, or null for none.
onSelectedValueChanged<DateTime>requiredFires with the picked day.
formatString Function(DateTime)?nullOverrides the built-in label.

FossDatePicker.range

PropTypeDefaultDescription
selectedFossDateRange?requiredThe chosen span, or null for none.
onSelectedValueChanged<FossDateRange>requiredFires as the range is set over two taps.
formatString Function(FossDateRange)?nullOverrides the built-in label.

Shared props

PropTypeDefaultDescription
placeholderString'Pick a date'Shown while nothing is selected.
openbool?nullControlled open state; pair with onOpenChange.
onOpenChangeValueChanged<bool>?nullFires on every open or close request.
closeOnSelectbooltrueClose the dialog on a completed pick.
presentationFossDialogPresentationbottomSheetBottom sheet or centered card.
firstDayOfWeekintDateTime.mondayLeading column of the week (1 to 7).
minDateDateTime?nullEarliest selectable day.
maxDateDateTime?nullLatest selectable day.
isDateEnabledbool Function(DateTime)?nullDisables individual days.
enabledbooltrueWhether the trigger accepts input.
semanticsLabelString?nullAccessibility name for the trigger.
styleFossDatePickerStyle?nullPer-instance overrides on the theme.

Live demo

Open the interactive gallery to try single and range modes with live knobs.

On this page