Skip to main content

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:

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
/>
);
}