# RangeFlow: Full Docs (LLM-friendly)
A React date range picker with a smooth drag slider, quick range tabs, and a popover calendar.
- Package: `rangeflow` (https://www.npmjs.com/package/rangeflow)
- Source: https://github.com/raminious/rangeflow
- Site: https://rangeflow.raminmousavi.dev
- License: MIT
- Peer deps: `react >=18`, `dayjs`
## Install
```bash
npm i rangeflow
# Or: pnpm add rangeflow / yarn add rangeflow / bun add rangeflow
```
Import the stylesheet once at your app root:
```tsx
// app/layout.tsx
import 'rangeflow/style.css'
```
All styles are scoped to `.rangeflow-date-picker`. Nothing leaks into global CSS.
## Quick start
```tsx
import { RangeFlow } from 'rangeflow'
import 'rangeflow/style.css'
import dayjs from 'dayjs'
import { useState } from 'react'
export function Activity() {
const [range, setRange] = useState({
from: dayjs().subtract(7, 'day').toDate(),
to: dayjs().toDate()
})
return (
)
}
```
- The `defaultRange` prop defines the outer window the slider spans.
- The `defaultSelected` prop defines the initial selection inside that window.
- The `onChange` callback fires on every drag or calendar pick.
## Props
| Prop | Type | Default | Required | Description |
| --- | --- | --- | --- | --- |
| `defaultRange` | `{ from: Date; to: Date }` | N/A | yes | Outer window the slider spans. |
| `defaultSelected` | `{ from: Date; to: Date }` | N/A | yes | Initial selection inside `defaultRange`. |
| `onChange` | `(range: { from: Date; to: Date }) => void` | N/A | yes | Fires on drag or calendar pick. |
| `ranges` | `RangeListItem[]` | 5 built-in presets | no | Quick range tabs above the slider. |
| `duration` | `{ min: number; max: number }` | N/A | no | Soft clamps (days) applied while dragging. |
| `disabled` | `{ before: Date } \| { after: Date } \| { before; after }` | N/A | no | Disables dates outside the boundary (slider + calendar). |
| `calendar` | `boolean` | `true` | no | Show the popover calendar trigger. |
| `CalendarProps` | `DayPickerProps` | N/A | no | Forwarded to the underlying react-day-picker. |
| `Slots` | `Slots` | N/A | no | Override individual render parts (see Slots). |
| `api` | `RangeFlowApi` | N/A | no | Imperative handle from `useRangeflow()`. |
## Hook: `useRangeflow()`
Returns an imperative handle for programmatic control.
| Method | Signature | Description |
| --- | --- | --- |
| `updateRange` | `(range: { from: Date; to: Date }) => void` | Replace the outer window. Re-fits the current selection. Does **not** call `onChange`. |
| `updateSelectedDates` | `(dates: { from: Date; to: Date }) => void` | Move the thumb to a new selection. Emits `onChange`. |
```tsx
import { RangeFlow, useRangeflow } from 'rangeflow'
function Example() {
const api = useRangeflow()
return (
<>
>
)
}
```
## Slots
| Slot | Props | Description |
| --- | --- | --- |
| `SelectedDate` | `{ from: string; to: string }` | Formatted date label in the picker bar. |
| `SliderValueLabel` | `{ label: string }` | Floating pill above the slider thumb. |
| `DateTickers` | `N/A` | Vertical ticks across the track. Replace with any viz (heatmap, sparkline). |
| `DateLabelsTrack` | `N/A` | Date labels row beneath the slider. |
| `RangeTabs` | `N/A` | Preset tabs in the picker bar. Full replacement. You own selection state. |
## Theming
Theme with a single CSS variable on the host element:
```css
.rangeflow-date-picker {
--rangeflow-accent: oklch(0.65 0.2 250);
}
```
All other tokens derive from this value. Dark mode is handled via `prefers-color-scheme` and the `data-theme` attribute.
## Classes
Component root class: `.rangeflow-date-picker`. Use it to scope any further overrides.
## Links
- GitHub: https://github.com/raminious/rangeflow
- Issues: https://github.com/raminious/rangeflow/issues
- npm: https://www.npmjs.com/package/rangeflow