chris-poe / react-datepicker

An accessible, internationalizable React datepicker

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

react-datepicker

An accessible, internationalizable React datepicker. Demo.

npm bundle size (scoped) npm (scoped) GitHub

Installation

yarn add @reecelucas/react-datepicker

Example Usage

Basic

<DatePicker onSelect={date => console.log(date)}>
  <DatePickerInput />

  <DatePickerCalendar>
    <DatePickerMonth />
    <DatePickerButton updateMonth={({ prev }) => prev()}>
      Prev Month
    </DatePickerButton>
    <DatePickerButton updateMonth={({ next }) => next()}>
      Next Month
    </DatePickerButton>
    <DatePickerTable />
  </DatePickerCalendar>
</DatePicker>

Initial Date

<DatePicker
  initialDate={new Date(2020, 10, 10)}
  onSelect={date => console.log(date)}
>
  {/* ... */}
</DatePicker>

Min Date

<DatePicker
  minDate={new Date(2020, 0, 1)}
  onSelect={date => console.log(date)}
>
  {/* ... */}
</DatePicker>

Max Date

<DatePicker
  maxDate={new Date(2020, 0, 1)}
  onSelect={date => console.log(date)}
>
  {/* ... */}
</DatePicker>

Date Range

<DatePicker
  minDate={new Date(Date.now())}
  maxDate={new Date(2020, 0, 1)}
  onSelect={date => console.log(date)}
>
  {/* ... */}
</DatePicker>

Exclude Dates

<DatePicker
  excludeDates={[new Date(2019, 6, 1), new Date(2019, 6, 2)]}
  onSelect={date => console.log(date)}
>
  {/* ... */}
</DatePicker>

Include Dates

<DatePicker
  includeDates={[new Date(2019, 6, 1), new Date(2019, 6, 2)]}
  onSelect={date => console.log(date)}
>
  {/* ... */}
</DatePicker>

Non-English Locale

Import the required date-fns locale and make sure to render a custom aria label for each day, using the renderDayLabel prop.

import { format } from 'date-fns';
import locale from 'date-fns/locale/fr';

<DatePicker
  locale={locale}
  onSelect={date => console.log(date)}
>
  {/* ... */}
  <DatePickerCalendar>
    {/* ... */}
    <DatePickerTable
      renderDayLabel={({ date, isSelected, isSelectable }) => {
        const status = isSelected ? 'Sélectionné. ' : `${isSelectable ? 'Disponible. ' : 'Indisponible. '}`;
        return `${status}${format(date, 'eeee, do MMMM yyyy', { locale })}.`;
      }}
    />
  </DatePickerCalendar>
</DatePicker>

Custom Month Format

Pass a valid date-fns format string.

<DatePicker onSelect={date => console.log(date)}>
  <DatePickerInput />

  <DatePickerCalendar>
    <DatePickerMonth dateFormat={'MMM, yyyy'} />
    {/* ... */}
  </DatePickerCalendar>
</DatePicker>

Render Day Content

import { getDate, isWeekend } from 'date-fns';

<DatePicker onSelect={date => console.log(date)}>
  {/* ... */}
  <DatePickerCalendar>
    {/* ... */}
    <DatePickerTable
      renderDayContent={date => (
        <span style={{ background: isWeekend(date) ? 'pink' : 'transparent' }}>
          {getDate(date)}
        </span>
      )}
    />
  </DatePickerCalendar>
</DatePicker>

Custom Input Date Format

Pass a valid date-fns format string.

<DatePicker onSelect={date => console.log(date)}>
  <DatePickerInput dateFormat={'MM/dd/yyyy'} />
  {/* ... */}
</DatePicker>

Custom Screen Reader Message

The DatePickerInput includes an aria-describedby attribute that references a visually hidden aria message (for use by screen readers). The default message is:

<>
  <p>
    Press the down arrow key to interact with the calendar and select a date.
    The following keyboard shortcuts can be used to change dates.
  </p>
  <ul>
    <li>Enter Key: select the date in focus.</li>
    <li>
      Right and left arrow keys: Move backward (left) and forward (right) by
      one day.
    </li>
    <li>
      Up and down arrow keys: Move backward (up) and forward (down) by one
      week.
    </li>
    <li>Page up and page down keys: Switch months.</li>
    <li>Home and end keys: go to the first or last day of a week.</li>
    <li>Escape key: Return to the date input field.</li>
  </ul>
</>

But you can render a custom message (E.g. written in another language if you're passing a locale) by passing a render function...

const renderScreenReaderMsg = () => (
  <p>
    I'm a custom screen reader message. I should describe how to interact with
    the date picker, playing special attention to the keyboard shortcuts that
    are available. This message won't be visible in the UI.
  </p>
);

<DatePicker onSelect={date => console.log(date)}>
  <DatePickerInput screenReaderMessage={renderScreenReaderMsg} />
  {/* ... */}
</DatePicker>

...Or by passing a JSX element

<DatePicker onSelect={date => console.log(date)}>
  <DatePickerInput
    screenReaderMessage={
      <p>
        I'm a custom screen reader message. I should describe how to interact with
        the date picker, playing special attention to the keyboard shortcuts that
        are available. This message won't be visible in the UI.
      </p>
    }
  />
  {/* ... */}
</DatePicker>

Props

DatePicker

children: React.ReactNode;
onSelect: (selectedDate: Date) => void;
initialDate?: Date; // Defaults to new Date(Date.now())
minDate?: Date;
maxDate?: Date;
excludeDates?: Date[];
includeDates?: Date[];
locale?: Locale; // date-fns `locale` object

Any props not listed above will be spread onto the underlying DatePicker element.

DatePickerInput

dateFormat?: string; // date-fns `format` string
screenReaderMessage?: JSX.Element | () => JSX.Element;

Any props not listed above will be spread onto the underlying DatePickerInput element.

DatePickerCalendar

children: React.ReactNode;

Any props not listed above will be spread onto the underlying DatePickerCalendar element.

DatePickerMonth

children?: (formattedDate: string) => JSX.Element;
dateFormat?: string; // date-fns `format` string

Any props not listed above will be spread onto the underlying DatePickerMonth element.

DatePickerButton

interface UpdateMonthParams {
  prev: () => void;
  next: () => void;
}

children: React.ReactNode;
updateMonth: ({ prev, next }: UpdateMonthParams) => void;

Any props not listed above will be spread onto the underlying DatePickerButton element.

DatePickerTable

interface RenderDayLabelParams {
  date: Date;
  isSelected: boolean;
  isSelectable: boolean;
}

renderDayLabel?: ({ date, isSelected, isSelectable }: RenderDayLabelParams) => string;
renderDayContent?: (date: Date) => React.ReactNode;

Any props not listed above will be spread onto the underlying DatePickerTable element.

Styling

react-datepicker doesn't provide any default styling; you're free to do what you want and use what you want.

// Example using CSS Modules
import * as styles from './styles';

<DatePicker
  className={styles.wrapper}
  onSelect={date => console.log(date)}
>
  <DatePickerInput className={styles.input} />

  <DatePickerCalendar>
    <DatePickerMonth className={styles.selectedMonth} />
    <DatePickerButton
      className={styles.button}
      updateMonth={({ prev }) => prev()}
    >
      Prev Month
    </DatePickerButton>
    <DatePickerButton
      className={styles.button}
      updateMonth={({ next }) => next()}
    >
      Next Month
    </DatePickerButton>
    <DatePickerTable className={styles.table} />
  </DatePickerCalendar>
</DatePicker>

LICENSE

MIT

About

An accessible, internationalizable React datepicker

License:MIT License


Languages

Language:TypeScript 98.4%Language:JavaScript 1.6%