Date Range Filter

A controlled date-range picker with responsive calendars, quick presets, and explicit clear and apply actions.

Calendar and preset selections stay in a draft until Apply is pressed, preventing partial ranges from repeatedly filtering a table.

Choose a preset or a custom range.

Applied filter

Saturday, August 1, 2026 through Friday, August 7, 2026

If selected dates lose contrast on hover, update both endpoint classes:

range-calendar-day.svelte
hover:text-foreground hover:text-primary-foreground

Installation

pnpm dlx shadcn-svelte@latest add http://sveltekit-prerender/r/date-range-filter.json

Step-by-step guide

The component is controlled and table-agnostic. Start with local state, then connect that state to a table column only when needed.

Create the range state

Import the component value type and initialize an optional range.

filters.svelte

Render the controlled filter

Bind the value for the shortest setup. It changes only after Apply or Clear.

filters.svelte

Register TanStack's date filter

For a table column, enable filtering and register filterFn_inDateRange. Both endpoints are inclusive.

table.svelte.ts

Send the applied range to the column

Translate the component's named range into the [start, end] tuple expected by the table filter.

filters.svelte

Custom presets

Replace the built-in choices with domain-specific ranges. Each preset receives the current local date when selected, so relative ranges do not become stale.

Choose a custom preset

Calendar only and date limits

Pass presets={false} for a focused calendar. This example also limits the selectable dates, starts weeks on Monday, and uses British English date formatting.

Calendar only · 2026 dates · weeks start on Monday

Behavior

The default presets are Today, Last 7 days, Last 30 days, and This month. An applied range can be removed directly from the clear button beside the trigger. Dates are returned at local midnight. Two months appear on desktop and the component switches to one month below the mobile breakpoint. min and max constrain the calendar and disable presets outside those boundaries.

Accessibility

The trigger announces the applied range and the adjacent clear control has a filter-specific accessible label. The popover restores focus on close, while the range calendar provides keyboard day navigation, month controls, selected-range semantics, and localized labels.

Props

Date range filter props

NameTypeDefaultDescription
value
DateRangeFilterValue | undefined undefined Bindable applied range. Draft calendar changes do not update it until Apply.
onValueChange
(value) => void undefined Called when a range is applied or cleared.
title
string "Date" Filter name displayed in the trigger.
placeholder
string "Select date range" Trigger text shown before a range is applied.
presets
DateRangeFilterPreset[] | false default presets Preset choices, or false to render the calendar without presets.
min
Date undefined Earliest selectable date.
max
Date undefined Latest selectable date.
numberOfMonths
number 2 Months displayed on desktop. Mobile always displays one.
weekStartsOn
0 | 1 | 2 | 3 | 4 | 5 | 6 0 First day of the calendar week.
locale
string "en-US" Locale for calendar labels and date formatting.
clearText
string "Clear" Clear action label.
applyText
string "Apply" Apply action label.
disabled
boolean false Disables the filter trigger.
open
boolean false Bindable popover open state.
class
string undefined Classes applied to the trigger button.
contentClass
string undefined Classes applied to the popover content.

DateRangeFilterValue

NameTypeDefaultDescription
start
Date | undefined required Inclusive start date at local midnight.
end
Date | undefined required Inclusive end date at local midnight.

DateRangeFilterPreset

NameTypeDefaultDescription
label
string required Preset button label.
getValue
(referenceDate: Date) => DateRangeFilterValue required Builds the preset range from the current local date.