Customising Ant Design's Date Picker with date-fns

Modifying Ant Design's Date Picker with the help of date-fns

·

4 min read

Customising Ant Design's Date Picker with 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 React

  • Date-fns (date-fns): A date manipulation library

  • Rc-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.