Installation
Complete project setup first. Your configuration
must select react/radix and include your Design System ID.
pnpm exec frontfriend download date-slider -f react --primitive radixReview dependencies reported by the downloader and keep your source changes in version control.
Usage
import {
DateSliderTrigger,
DateSlider,
DateSliderContent,
} from "@/components/ui/date-slider";
const format = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
function Readout({ value }: { value: unknown }) {
const range = value as
| {
start?: Date;
end?: Date;
}
| undefined;
if (
range &&
typeof range === "object" &&
!(range instanceof Date) &&
range.start
) {
return (
<span className="text-neutral-mid">
{format.format(range.start)}
{range.end ? ` - ${format.format(range.end)}` : ""}
</span>
);
}
return (
<span className="text-neutral-mid">
{value instanceof Date ? format.format(value) : "No date selected"}
</span>
);
}
<div className="flex flex-col items-start gap-3">
<DateSlider>
<DateSliderTrigger presets triggerText="Pick a date" variant="default" dialog dialogTitle="Choose a date" dialogButtonText="Apply" />
<DateSliderContent>
{(value) => <Readout value={value} />}
</DateSliderContent>
</DateSlider>
</div>; Examples
Default
import {
DateSliderTrigger,
DateSlider,
DateSliderContent,
} from "@/components/ui/date-slider";
const format = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
function Readout({ value }: { value: unknown }) {
const range = value as
| {
start?: Date;
end?: Date;
}
| undefined;
if (
range &&
typeof range === "object" &&
!(range instanceof Date) &&
range.start
) {
return (
<span className="text-neutral-mid">
{format.format(range.start)}
{range.end ? ` - ${format.format(range.end)}` : ""}
</span>
);
}
return (
<span className="text-neutral-mid">
{value instanceof Date ? format.format(value) : "No date selected"}
</span>
);
}
<div className="flex flex-col items-start gap-3">
<DateSlider>
<DateSliderTrigger presets triggerText="Pick a date" />
<DateSliderContent>
{(value) => <Readout value={value} />}
</DateSliderContent>
</DateSlider>
</div>; Range
import {
DateSliderTrigger,
DateSlider,
DateSliderContent,
} from "@/components/ui/date-slider";
const format = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
function Readout({ value }: { value: unknown }) {
const range = value as
| {
start?: Date;
end?: Date;
}
| undefined;
if (
range &&
typeof range === "object" &&
!(range instanceof Date) &&
range.start
) {
return (
<span className="text-neutral-mid">
{format.format(range.start)}
{range.end ? ` - ${format.format(range.end)}` : ""}
</span>
);
}
return (
<span className="text-neutral-mid">
{value instanceof Date ? format.format(value) : "No date selected"}
</span>
);
}
<div className="flex flex-col items-start gap-3">
<DateSlider>
<DateSliderTrigger presets triggerText="Pick a date" variant="range" />
<DateSliderContent>
{(value) => <Readout value={value} />}
</DateSliderContent>
</DateSlider>
</div>; Weeks
import {
DateSliderTrigger,
DateSlider,
DateSliderContent,
} from "@/components/ui/date-slider";
const format = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
function Readout({ value }: { value: unknown }) {
const range = value as
| {
start?: Date;
end?: Date;
}
| undefined;
if (
range &&
typeof range === "object" &&
!(range instanceof Date) &&
range.start
) {
return (
<span className="text-neutral-mid">
{format.format(range.start)}
{range.end ? ` - ${format.format(range.end)}` : ""}
</span>
);
}
return (
<span className="text-neutral-mid">
{value instanceof Date ? format.format(value) : "No date selected"}
</span>
);
}
<div className="flex flex-col items-start gap-3">
<DateSlider>
<DateSliderTrigger presets triggerText="Pick a date" variant="weeks" />
<DateSliderContent>
{(value) => <Readout value={value} />}
</DateSliderContent>
</DateSlider>
</div>; Months
import {
DateSliderTrigger,
DateSlider,
DateSliderContent,
} from "@/components/ui/date-slider";
const format = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
function Readout({ value }: { value: unknown }) {
const range = value as
| {
start?: Date;
end?: Date;
}
| undefined;
if (
range &&
typeof range === "object" &&
!(range instanceof Date) &&
range.start
) {
return (
<span className="text-neutral-mid">
{format.format(range.start)}
{range.end ? ` - ${format.format(range.end)}` : ""}
</span>
);
}
return (
<span className="text-neutral-mid">
{value instanceof Date ? format.format(value) : "No date selected"}
</span>
);
}
<div className="flex flex-col items-start gap-3">
<DateSlider>
<DateSliderTrigger presets triggerText="Pick a date" variant="months" />
<DateSliderContent>
{(value) => <Readout value={value} />}
</DateSliderContent>
</DateSlider>
</div>; Years
import {
DateSliderTrigger,
DateSlider,
DateSliderContent,
} from "@/components/ui/date-slider";
const format = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
function Readout({ value }: { value: unknown }) {
const range = value as
| {
start?: Date;
end?: Date;
}
| undefined;
if (
range &&
typeof range === "object" &&
!(range instanceof Date) &&
range.start
) {
return (
<span className="text-neutral-mid">
{format.format(range.start)}
{range.end ? ` - ${format.format(range.end)}` : ""}
</span>
);
}
return (
<span className="text-neutral-mid">
{value instanceof Date ? format.format(value) : "No date selected"}
</span>
);
}
<div className="flex flex-col items-start gap-3">
<DateSlider>
<DateSliderTrigger presets triggerText="Pick a date" variant="years" />
<DateSliderContent>
{(value) => <Readout value={value} />}
</DateSliderContent>
</DateSlider>
</div>; Custom Trigger
import {
DateSlider,
DateSliderTrigger,
DateSliderContent,
} from "@/components/ui/date-slider";
import { Button } from "@/components/ui/button";
const format = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
function Readout({ value }: { value: unknown }) {
const range = value as
| {
start?: Date;
end?: Date;
}
| undefined;
if (
range &&
typeof range === "object" &&
!(range instanceof Date) &&
range.start
) {
return (
<span className="text-neutral-mid">
{format.format(range.start)}
{range.end ? ` - ${format.format(range.end)}` : ""}
</span>
);
}
return (
<span className="text-neutral-mid">
{value instanceof Date ? format.format(value) : "No date selected"}
</span>
);
}
<div className="flex flex-col items-start gap-3">
<DateSlider>
<DateSliderTrigger presets triggerText="Pick a date">
<Button variant="tertiary" size="sm" icon="Calendar" />
</DateSliderTrigger>
<DateSliderContent>
{(value) => <Readout value={value} />}
</DateSliderContent>
</DateSlider>
</div>; API reference
Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Radix UI.
DateSlider
| Prop | Type | Default | Description |
|---|---|---|---|
defaultEndDate | Date | — | |
defaultMonth | number | — | |
defaultStartDate | Date | — | |
defaultValue | DateSliderValue | — | |
defaultYear | number | — | |
onValueChange | (value: DateSliderValue) => void | — | |
value | DateSliderValue | — |
DateSliderContent
| Prop | Type | Default | Description |
|---|---|---|---|
defaultEndDate | Date | — | |
defaultMonth | number | — | |
defaultStartDate | Date | — | |
defaultValue | DateSliderValue | — | |
defaultYear | number | — | |
dialog | boolean | — | |
dialogButtonText | string | — | |
dialogTitle | string | — | |
formatOptions | DateFormatOptions | — | |
locale | string | — | |
onValueChange | (value: DateSliderValue) => void | — | |
presets | boolean | — | |
presetsValues | PresetOption[] | — | |
triggerText | string | — | |
value | DateSliderValue | — | |
variant | DateSliderVariant | — |
DateSliderTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | |
dialog | boolean | true | Whether the label opens a picker dialog. |
dialogButtonText | string | — | |
dialogTitle | string | — | |
formatOptions | DateFormatOptions | DEFAULT_FORMAT | |
locale | string | "en-US" | |
presets | boolean | false | Show the preset selector inside the dialog. |
presetsValues | PresetOption[] | DEFAULT_PRESETS | |
triggerText | string | — | |
variant | DateSliderVariant | — | Which period the arrows step and the dialog selects. |
Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.