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
}}
/>
);
}
Oct 2023
Su | Mo | Tu | We | Th | Fr | Sa |
---|---|---|---|---|---|---|
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 | 31 |
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 }} />;
}
October 2023
Su | Mo | Tu | We | Th | Fr | Sa |
---|---|---|---|---|---|---|
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}
/>
);
}
October 2023
Su | Mo | Tu | We | Th | Fr | Sa | |
---|---|---|---|---|---|---|---|
Please pick a day. |
Disable rows in the past
Implement a custom component to hide the rows of past weeks.
import React from 'react';
import { differenceInCalendarDays } from 'date-fns';
import { DayPicker, Row, RowProps } from 'react-day-picker';
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
/>
);
}
October 2023
Su | Mo | Tu | We | Th | Fr | Sa |
---|---|---|---|---|---|---|
18 | 19 | 20 | 21 | |||
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | 1 | 2 | 3 | 4 |