Skip to content

Extra

DateRangePickerSheet

A FormaUI date-range picker presented in a modal bottom sheet — Material 3's inline DateRangePicker hosted in a FormaBottomSheet instead of the M3 DatePickerDialog, with hoisted M3 state, confirm/dismiss button slots, and the calendar-to-text-input mode toggle. The picker's scrollable month list is bounded by the sheet so months scroll internally while the buttons stay on-screen.

dev.formaui.components.datepicker

Calendar mode (internally scrolling month list)Text-input mode (initialDisplayMode or the mode toggle)With dismiss buttonMode toggle hiddenCustom colors

Preview

This toggle is site chrome only — the preview has its own light/dark switch inside.

Live preview

Live preview — ~37 MB development build

Usage

val state = rememberDateRangePickerState()
if (open) {
    FormaDateRangePickerSheet(
        onDismissRequest = { open = false },
        state = state,
        confirmButton = {
            FormaButton(
                onClick = {
                    onPicked(state.selectedStartDateMillis, state.selectedEndDateMillis)
                    open = false
                },
                enabled = state.selectedEndDateMillis != null,
            ) { Text("OK") }
        },
    )
}

FormaDateRangePickerSheet

Hosts M3's stable DateRangePicker in a FormaBottomSheet above an end-aligned button row. State is the caller's DateRangePickerState and the component wires nothing to the button slots — the confirm slot reads state.selectedStartDateMillis / state.selectedEndDateMillis itself (so it can disable itself until a complete range is picked). The default colors make the picker's own container transparent so it sits directly on the sheet surface.

onDismissRequestrequiredType() -> UnitDefaultrequiredDescriptioncalled when the sheet is dismissed (scrim tap, back press, or swipe down) — hide the sheet by no longer composing it. There is no separate cancel callback; treat a dismiss as closed-without-confirming.
staterequiredTypeDateRangePickerStateDefaultrequiredDescriptionthe hoisted Material 3 state; create it with rememberDateRangePickerState. Read state.selectedStartDateMillis and state.selectedEndDateMillis (UTC epoch millis, Long?) in the confirm slot's click handler. The picker's locale is captured when the state is created (Material 3 behavior).
confirmButtonrequiredType@Composable () -> UnitDefaultrequiredDescriptionthe primary action slot (required), typically a FormaButton. The component attaches no click handling or label — the slot owns both.
modifierTypeModifierDefaultModifierDescriptionthe Modifier applied to the sheet.
dismissButtonType(@Composable () -> Unit)?DefaultnullDescriptionthe optional secondary/cancel action slot, shown before confirmButton.
showModeToggleTypeBooleanDefaulttrueDescriptionwhether the picker shows Material 3's calendar-to-text-input mode toggle.
skipPartiallyExpandedTypeBooleanDefaulttrueDescriptionwhether the sheet skips the half-expanded state and opens fully. Defaults to true — deliberately unlike FormaBottomSheet — because the half-expanded state clips the calendar grid.
shapeTypeShape?DefaultnullDescriptionthe sheet container shape. When null, Material 3's top-rounded default is used.
colorsTypeDatePickerColors?DefaultnullDescriptionthe DatePickerColors for the picker. When null, Material 3's defaults are used with a transparent picker container so the picker sits directly on the sheet surface (avoiding a container-on-container seam). A supplied value is passed through untouched.

Supporting API

rememberDateRangePickerStatefunction (Material 3)
The component defines no state type of its own — callers create and own the picker state via Material 3's rememberDateRangePickerState (initial range, selectableDates, yearRange, initialDisplayMode, saveability) and read selectedStartDateMillis / selectedEndDateMillis from it.

Accessibility

Inherits Material 3's DateRangePicker semantics — day cells expose full-date content descriptions with range start/end announcements, the mode toggle has its own content description, and navigation controls are labeled — plus ModalBottomSheet's back-press and scrim dismiss handling; the button slots are caller-supplied (typically FormaButtons with M3's 48dp minimum touch target).