Custom Components
Use the components
prop to replace some of the internal components used by DayPicker with a custom implementation.
Components that can be changed are described in the CustomComponents interface.
note
Custom components are an advanced feature. Look at the components source to understand how the internal components are built.
DayPicker hooks​
When creating custom components, you will find useful the DayPicker hooks:
- useDayPicker - to get the props passed to DayPicker.
- useNavigation - to navigate between months and years.
- useDayRender - useful to render the day cell from a custom
Day
component. - useFocusContext - handle the focus between elements.
- useActiveModifiers - to get the modifiers applied to a day.
Examples​
Custom Caption​
Implement a custom Caption
component with next/previous buttons. Note the use of the useNavigation hook to navigate between months.
import React from 'react';
import { format } from 'date-fns';
import { CaptionProps, DayPicker, useNavigation } from 'react-day-picker';
function CustomCaption(props: CaptionProps) {
const { goToMonth, nextMonth, previousMonth } = useNavigation();
return (
<h2>
{format(props.displayMonth, 'MMM yyy')}
<button
disabled={!previousMonth}
onClick={() => previousMonth && goToMonth(previousMonth)}
>
Previous
</button>
<button
disabled={!nextMonth}
onClick={() => nextMonth && goToMonth(nextMonth)}
>
Next
</button>
</h2>
);
}
export default function App() {
return (
<DayPicker
components={{
Caption: CustomCaption
}}
/>
);
}
Wrapping the day​
Implement a custom DayContent
component
import React from 'react';
import { format } from 'date-fns';
import { DayContent, DayContentProps, DayPicker } from 'react-day-picker';
function DateTime(props: DayContentProps) {
const dateTime = format(props.date, 'yyyy-MM-dd');
return (
<time dateTime={dateTime}>
<DayContent {...props} />
</time>
);
}
export default function App() {
return <DayPicker components={{ DayContent: DateTime }} />;
}
Range selections with Shift key​
Implement a custom Day
component to select ranges while pressing the Shift key.
import React from 'react';
import { isSameDay } from 'date-fns';
import {
Button,
DateRange,
DayPicker,
DayProps,
useDayRender
} from 'react-day-picker';
function DayWithShiftKey(props: DayProps) {
const buttonRef = React.useRef<HTMLButtonElement>(null);
const dayRender = useDayRender(props.date, props.displayMonth, buttonRef);
if (dayRender.isHidden) {
return <></>;
}
if (!dayRender.isButton) {
return <div {...dayRender.divProps} />;
}
const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
if (
!dayRender.selectedDays ||
dayRender.activeModifiers.selected ||
e.shiftKey
) {
dayRender.buttonProps?.onClick?.(e);
}
};
return (
<Button {...dayRender.buttonProps} ref={buttonRef} onClick={handleClick} />
);
}
export default function App() {
const [range, setRange] = React.useState<DateRange>();
let footer = <p>Please pick a day.</p>;
if (range?.from && range?.to) {
if (isSameDay(range.from, range.to)) {
footer = <p>Press Shift to choose more days.</p>;
} else {
footer = (
<p>
{range.from.toLocaleDateString()}—{range.to.toLocaleDateString()}.
</p>
);
}
}
return (
<DayPicker
components={{
Day: DayWithShiftKey
}}
mode="range"
onSelect={setRange}
selected={range}
footer={footer}
/>
);
}
Disable rows in the past​
Implement a custom component to hide the rows of past weeks.
import React from 'react';
import { DayPicker, Row, RowProps } from 'react-day-picker';
import { differenceInCalendarDays } from 'date-fns';
function isPastDate(date: Date) {
return differenceInCalendarDays(date, new Date()) < 0;
}
function OnlyFutureRow(props: RowProps) {
const isPastRow = props.dates.every(isPastDate);
if (isPastRow) return <></>;
return <Row {...props} />;
}
export default function App() {
return (
<DayPicker
fromDate={new Date()}
components={{ Row: OnlyFutureRow }}
hidden={isPastDate}
showOutsideDays
/>
);
}