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