The inline prop makes the <DatePicker> render as an
always-visible calendar without an input field.
To give users both the visual calendar and a text input (for copy/paste or
typing dates), render two <DatePicker> instances sharing the same state:
Input field: Set open={false} to render only the input without a popup
Visual calendar: Set inline to render the always-visible calendar
Both instances share the same selected, startDate, endDate, and
onChange props:
<DatePickerselected={from}onChange={handleDateChange}startDate={from}endDate={to}selectsRangelabel="Select start and end date"open={false}isClearable/><DatePickerselected={from}onChange={handleDateChange}startDate={from}endDate={to}selectsRangeinlinelabel=""hideLabelswapRange/>
November 2025
MondayM
TuesdayT
WednesdayW
ThursdayT
FridayF
SaturdayS
SundayS
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
Duration
Use <FormatDuration> to get a localized duration text
with a tooltip based on two Date objects.
<FormatDurationstart={from}end={to}/>
60 minutes24 hours
State and functions
In order to keep a date range in react state, we need to store a "from date" and
"to date".
The from and to dates should probably live outside our component, so they can be
used to filter data elsewhere in the app, let's make them props along with a way
to update them:
from: Date | null
to: Date | null
onChange: (dates: [Date | null, Date | null]) => void
We also want to highlight the active preset button. Let's make it a number in
days for buttons like "last 24 hours" = 1 day, and "last 365 days" = 365,
and a string for buttons like "Today" as "today" etc.
When picking dates with the datepickers, set both dates and clear any active preset button.
consthandleDateChange=([newFrom, newTo]:[Date |null, Date |null])=>{const fromStartOfDay = newFrom &&startOfDay(newFrom);const toEndOfDay = newTo &&endOfDay(newTo);onChange([fromStartOfDay, toEndOfDay]);// Clear active preset when user manually picks datessetActiveButton(undefined);};
Combined code example
importDatePickerfrom"@intility/bifrost-react-datepicker";importBoxfrom"@intility/bifrost-react/Box";importButtonfrom"@intility/bifrost-react/Button";importFormatDurationfrom"@intility/bifrost-react/FormatDuration";importGridfrom"@intility/bifrost-react/Grid";importInlinefrom"@intility/bifrost-react/Inline";import{addDays,endOfDay,endOfMonth,endOfWeek,endOfYear,startOfDay,startOfMonth,startOfWeek,startOfYear,}from"date-fns";import{useState}from"react";import"@intility/bifrost-react-datepicker/datepicker.css";exportdefaultfunctionInlineDateRangePresetDemo(){const[from,setFrom] = useState<Date | null>(null);const[to,setTo] = useState<Date | null>(null);return(<InlineDateRangePresetfrom={from}to={to}onChange={([newFrom,newTo])=>{setFrom(newFrom);setTo(newTo);}}/>);}functionPresetButton({children,onClick,active = false,}:{children?: React.ReactNode;onClick?: React.MouseEventHandler<HTMLButtonElement>;active?: boolean;}){return(<Buttonstyle={{textAlign:"left",fontWeight:"normal"}}state={active ? "default" : "neutral"}variant={active ? "filled" : "flat"}onClick={onClick}>{children}</Button>);}functionInlineDateRangePreset({from,to,onChange,}:{from: Date | null;to: Date | null;onChange:(dates:[Date | null, Date | null])=>void;}){const[activeButton,setActiveButton] = useState<
number | string | undefined
>();constsetDurationDays = (days: number)=>{constnewFrom = addDays(new Date(),days * -1);// set end date to "now" if that makes sense for your data// (includes future dates that we want to filter out)constnewTo = new Date();// otherwise, setting no end date might make sense for "last 24 hours" if// dataset has no future dates (like an auto-updating log table)// const newTo = null;onChange([newFrom,newTo]);setActiveButton(days);};consthandleDateChange = ([newFrom,newTo]:[Date | null, Date | null])=>{constfromStartOfDay = newFrom && startOfDay(newFrom);consttoEndOfDay = newTo && endOfDay(newTo);onChange([fromStartOfDay,toEndOfDay]);setActiveButton(undefined);};return(<Boxborderradius="s"backgroundstyle={{display:"inline-block"}}><Inlinegap={0}style={{flexWrap:"nowrap"}}><Boxpadding={12}><Gridgap={0}><PresetButtonactive={activeButton === "today"}onClick={()=>{constfromStartOfDay = startOfDay(new Date());consttoEndOfDay = endOfDay(new Date());onChange([fromStartOfDay,toEndOfDay]);setActiveButton("today");}}>
Today
</PresetButton><PresetButtonactive={activeButton === "week"}onClick={()=>{constnewFrom = startOfWeek(new Date(),{weekStartsOn:1});constnewTo = endOfWeek(new Date(),{weekStartsOn:1});onChange([newFrom,newTo]);setActiveButton("week");}}>
This week
</PresetButton><PresetButtonactive={activeButton === "month"}onClick={()=>{constnewFrom = startOfMonth(new Date());constnewTo = endOfMonth(new Date());setActiveButton("month");onChange([newFrom,newTo]);}}>
This month
</PresetButton><PresetButtonactive={activeButton === "year"}onClick={()=>{constnewFrom = startOfYear(new Date());constnewTo = endOfYear(new Date());setActiveButton("year");onChange([newFrom,newTo]);}}>
This year
</PresetButton><PresetButtonactive={activeButton === 1}onClick={()=>setDurationDays(1)}>
Last 24 hours
</PresetButton><PresetButtonactive={activeButton === 7}onClick={()=>setDurationDays(7)}>
Last 7 days
</PresetButton><PresetButtonactive={activeButton === 30}onClick={()=>setDurationDays(30)}>
Last 30 days
</PresetButton><PresetButtonactive={activeButton === 365}onClick={()=>setDurationDays(365)}>
Last 365 days
</PresetButton></Grid></Box><Boxbackground="base-2"paddingradiusTopRight="s"radiusBottomRight="s"borderLeftstyle={{alignSelf:"stretch"}}><Gridgap={16}><Grid><DatePickerselected={from}onChange={handleDateChange}startDate={from}endDate={to}selectsRangelabel="Select start and end date"open={false}isClearable/><DatePickerselected={from}onChange={handleDateChange}startDate={from}endDate={to}selectsRangeinlinelabel=""hideLabelswapRange/></Grid><div><spanclassName="bfc-base-2">Selected: </span>{from && to ? (<FormatDurationstart={from}// if `setDurationDays(N)` sets `newTo = new Date()`end={to}// if `setDurationDays(N)` sets `newTo = null`// end={to ?? new Date()}/>) : ("No range selected")}</div></Grid></Box></Inline></Box>);}
Since react-datepicker doesn't provide a way to pick two different times in
the same datepicker instance, we need two datepickers to be able to pick a range
between two datetime points:
importDatePickerfrom"@intility/bifrost-react-datepicker";importBoxfrom"@intility/bifrost-react/Box";importButtonfrom"@intility/bifrost-react/Button";importFormatDurationfrom"@intility/bifrost-react/FormatDuration";importGridfrom"@intility/bifrost-react/Grid";importInlinefrom"@intility/bifrost-react/Inline";import{addDays,endOfDay,endOfWeek,startOfDay,startOfWeek,}from"date-fns";import{useState}from"react";import"@intility/bifrost-react-datepicker/datepicker.css";exportdefaultfunctionInlineDateRangePresetDemo(){const[from,setFrom] = useState<Date | null>(null);const[to,setTo] = useState<Date | null>(null);return(<InlineDateTimeRangePresetfrom={from}to={to}onChange={([newFrom,newTo])=>{setFrom(newFrom);setTo(newTo);}}/>);}functionPresetButton({children,onClick,active = false,}:{children?: React.ReactNode;onClick?: React.MouseEventHandler<HTMLButtonElement>;active?: boolean;}){return(<Buttonstyle={{textAlign:"left",fontWeight:"normal"}}state={active ? "default" : "neutral"}variant={active ? "filled" : "flat"}onClick={onClick}>{children}</Button>);}functionInlineDateTimeRangePreset({from,to,onChange,}:{from: Date | null;to: Date | null;onChange:(dates:[Date | null, Date | null])=>void;}){const[activeButton,setActiveButton] = useState<
number | string | undefined
>();constsetDurationDays = (days: number)=>{constnewFrom = addDays(new Date(),days * -1);// set end date to "now" if that makes sense for your data// (includes future dates that we want to filter out)constnewTo = new Date();// otherwise, setting no end date might make sense for "last 24 hours" if// dataset has no future dates (like an auto-updating log table)// const newTo = null;onChange([newFrom,newTo]);setActiveButton(days);};return(<Boxborderradius="s"backgroundstyle={{display:"inline-block"}}><Inlinegap={0}style={{flexWrap:"nowrap"}}><Boxpadding={12}><Gridgap={0}><PresetButtonactive={activeButton === "today"}onClick={()=>{constfromStartOfDay = startOfDay(new Date());consttoEndOfDay = endOfDay(new Date());onChange([fromStartOfDay,toEndOfDay]);setActiveButton("today");}}>
Today
</PresetButton><PresetButtonactive={activeButton === "week"}onClick={()=>{constnewFrom = startOfWeek(new Date(),{weekStartsOn:1});constnewTo = endOfWeek(new Date(),{weekStartsOn:1});onChange([newFrom,newTo]);setActiveButton("week");}}>
This week
</PresetButton><PresetButtonactive={activeButton === 1}onClick={()=>setDurationDays(1)}>
Last 24 hours
</PresetButton><PresetButtonactive={activeButton === 7}onClick={()=>setDurationDays(7)}>
Last 7 days
</PresetButton></Grid></Box><Boxbackground="base-2"paddingradiusTopRight="s"radiusBottomRight="s"borderLeftstyle={{alignSelf:"stretch",display:"grid"}}><Inline><DatePickerlabel="From"showTimeSelectselected={from}selectsStartstartDate={from}endDate={to}maxDate={to || undefined}onChange={(newDate)=>{onChange([newDate,to]);setActiveButton(undefined);}}/><DatePickerlabel="To"showTimeSelectselected={to}selectsEndstartDate={from}endDate={to}minDate={from || undefined}onChange={(newDate)=>{onChange([from,newDate]);setActiveButton(undefined);}}/></Inline><Inlinealign="center"style={{alignSelf:"end"}}><Inline.Stretch><spanclassName="bfc-base-2">Selected: </span>{from && to ? (<FormatDurationstart={from}// if `setDurationDays(N)` sets `newTo = new Date()`end={to}// if `setDurationDays(N)` sets `newTo = null`// end={to ?? new Date()}/>) : ("No range selected")}</Inline.Stretch><Buttonsmallvariant="flat"state="neutral"onClick={()=>{onChange([null,null]);setActiveButton(undefined);}}disabled={!from && !to}>
Clear
</Button></Inline></Box></Inline></Box>);}