Customising Ant Design's Date Picker with date-fns
Modifying Ant Design's Date Picker with the help of date-fns
Introduction
If you're using Ant Design in your React project, you may already be familiar with its feature-rich Date Picker component. While it is highly customizable, you might want to further modify its behaviour to meet specific requirements. In this tutorial, we will explore how to replace Ant Design's default date manipulation library dayjs
, with date-fns
to gain even more control over date manipulation.
Install Required Packages
First, you'll need to install the following npm packages if you haven't already:
Ant Design (
antd
): A UI library for ReactDate-fns (
date-fns
): A date manipulation libraryRc-picker (
rc-picker
): A low-level picker library that Ant Design's Date Picker is based on
To install these packages, open your terminal and run the following commands:npm install antd
npm install date-fns
npm install rc-picker
What is rc-picker?
You might wonder why we are installing rc-picker
explicitly. Rc-picker is the low-level library that powers Ant Design's Date Picker component. It provides the fundamental building blocks for creating picker components. By importing and using it, we can customize how Ant Design's higher-level Date Picker works to suit our specific needs.
Importing Necessary Modules
Firstly, import the required modules from antd
, date-fns
, and rc-picker
. Ant Design uses a generator function for its Date Picker, and date-fns provides utility functions for date manipulation.
Here are the modules to import:
import generatePicker from 'antd/lib/date-picker/generatePicker';
import { addDays, addMonths, addYears, format, getWeek, isAfter, isValid, lastDayOfMonth, parse, setDate, setHours, setMinutes, setMonth, setSeconds, setYear } from 'date-fns';
import { GenerateConfig } from 'rc-picker/lib/generate';
import { enUS } from 'date-fns/locale';
Customizing the Date Picker
The next step is to define a DateFnsPicker.tsx
component. This component will use a generateConfig
object to tell the Date Picker how to interact with dates using date-fns.
Here is how to set it up. Create a DateFnsPicker.tsx
file and input the following:
const generateConfig: GenerateConfig<Date> = {
// Basic Date Getters
getNow: () => new Date(),
getWeekDay: date => date.getDay(),
getYear: date => date.getFullYear(),
getMonth: date => date.getMonth(),
getDate: date => date.getDate(),
getHour: date => date.getHours(),
getMinute: date => date.getMinutes(),
getSecond: date => date.getSeconds(),
// Date Manipulation
addYear: (date, diff) => addYears(date, diff),
addMonth: (date, diff) => addMonths(date, diff),
addDate: (date, diff) => addDays(date, diff),
setYear: (date, year) => setYear(date, year),
setMonth: (date, month) => setMonth(date, month),
setDate: (date, num) => setDate(date, num),
setHour: (date, hour) => setHours(date, hour),
setMinute: (date, minute) => setMinutes(date, minute),
setSecond: (date, second) => setSeconds(date, second),
// Comparison and Validation
isAfter: (date1, date2) => isAfter(date1, date2),
isValidate: date => isValid(date),
// Localization
locale: {
getWeekFirstDay: locale => 1,
getWeekFirstDate: locale => new Date(),
getWeek: (locale, date) => getWeek(date),
getShortWeekDays: locale => Array.from({ length: 7 }).map((_, day) => enUS.localize!.day(day, { width: 'abbreviated' })),
getShortMonths: locale => Array.from({ length: 12 }).map((_, month) => enUS.localize!.month(month, { width: 'abbreviated' })),
format: (locale, date, fmt) => format(date, fmt.replace('YYYY', 'yyyy').replace('DD', 'dd'), { locale: enUS }),
parse: (locale, text, formats) => parse(text, formats[0], new Date()),
},
};
export const DateFnsPicker = generatePicker<Date>(generateConfig);
This configuration consists of several parts:
Basic Date Getters: Functions to get parts of a date, such as the year, month, day, hour, minute, and second.
Date Manipulation: Functions to add or set parts of a date, such as adding/subtracting years, months, days, and setting specific date/time components.
Comparison and Validation: Functions to compare dates and validate if a date is valid.
Localization: Methods for locale-specific formatting and parsing of dates, like getting the week's first day, short month names, formatting, and parsing dates.
Integrating with Ant Design's Date Picker
After defining your custom configuration, you can now use it in conjunction with Ant Design's Date Picker. In another component:
import { DateFnsPicker } from './DateFnsPicker';
<DateFnsPicker
format="DD MMM YYYY h:mma"
disabledDate={isDateBeforeToday}
/>
Summary
In this tutorial, you learned how to transition from using dayjs
to date-fns
for Ant Design's Date Picker. This involved setting up a custom configuration that told the Date Picker how to perform various date-related operations using date-fns
.
By leveraging the flexibility of both Ant Design and date-fns
, you've achieved precise control over date handling within your front-end code.