CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-dates

A responsive and accessible date range picker component built with React

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

main-pickers.mddocs/

Main Date Pickers

Complete date picker components that combine input fields with calendar dropdowns. These are the primary components for most use cases, providing full user interaction with date selection.

Capabilities

DateRangePicker

Full-featured date range picker component with dual input fields and calendar display for selecting start and end dates.

/**
 * Date range picker component with input fields and calendar
 * @param props - DateRangePicker configuration
 * @returns DateRangePicker component
 */
function DateRangePicker(props: DateRangePickerProps): ReactElement;

interface DateRangePickerProps {
  // Required props
  startDateId: string;
  endDateId: string;
  onDatesChange: ({ startDate, endDate }: {
    startDate: moment.Moment | null;
    endDate: moment.Moment | null;
  }) => void;
  onFocusChange: (focusedInput: 'startDate' | 'endDate' | null) => void;

  // Date state
  startDate?: moment.Moment | null;
  endDate?: moment.Moment | null;
  focusedInput?: 'startDate' | 'endDate' | null;

  // Input customization
  startDatePlaceholderText?: string;
  endDatePlaceholderText?: string;
  startDateAriaLabel?: string;
  endDateAriaLabel?: string;
  disabled?: boolean;
  required?: boolean;
  readOnly?: boolean;
  screenReaderInputMessage?: string;
  showClearDates?: boolean;
  showDefaultInputIcon?: boolean;
  inputIconPosition?: 'before' | 'after';
  customInputIcon?: ReactNode;
  customArrowIcon?: ReactNode;
  customCloseIcon?: ReactNode;

  // Styling
  noBorder?: boolean;
  block?: boolean;
  small?: boolean;
  regular?: boolean;
  keepFocusOnInput?: boolean;

  // Calendar presentation
  orientation?: 'horizontal' | 'vertical';
  anchorDirection?: 'left' | 'right';
  openDirection?: 'down' | 'up';
  horizontalMargin?: number;
  withPortal?: boolean;
  withFullScreenPortal?: boolean;
  appendToBody?: boolean;
  disableScroll?: boolean;
  numberOfMonths?: number;
  keepOpenOnDateSelect?: boolean;
  reopenPickerOnClearDates?: boolean;
  renderCalendarInfo?: () => ReactNode;
  calendarInfoPosition?: 'top' | 'bottom' | 'before' | 'after';
  hideKeyboardShortcutsPanel?: boolean;
  daySize?: number;
  isRTL?: boolean;
  firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
  verticalHeight?: number;
  transitionDuration?: number;
  verticalSpacing?: number;
  horizontalMonthPadding?: number;

  // Navigation
  dayPickerNavigationInlineStyles?: object;
  navPosition?: 'navPositionTop' | 'navPositionBottom';
  navPrev?: ReactNode;
  navNext?: ReactNode;
  renderNavPrevButton?: (props: any) => ReactNode;
  renderNavNextButton?: (props: any) => ReactNode;
  onPrevMonthClick?: (newMonth: moment.Moment) => void;
  onNextMonthClick?: (newMonth: moment.Moment) => void;
  onClose?: ({ startDate, endDate }: {
    startDate: moment.Moment | null;
    endDate: moment.Moment | null;
  }) => void;

  // Day customization
  renderCalendarDay?: (props: any) => ReactNode;
  renderDayContents?: (day: moment.Moment, modifiers: Set<string>) => ReactNode;
  renderMonthElement?: (props: any) => ReactNode;
  renderMonthText?: (month: moment.Moment) => ReactNode;
  renderWeekHeaderElement?: (day: string) => ReactNode;
  minimumNights?: number;
  enableOutsideDays?: boolean;
  isDayBlocked?: (day: moment.Moment) => boolean;
  isOutsideRange?: (day: moment.Moment) => boolean;
  isDayHighlighted?: (day: moment.Moment) => boolean;
  minDate?: moment.Moment;
  maxDate?: moment.Moment;

  // Internationalization
  displayFormat?: (() => string) | string;
  monthFormat?: string;
  weekDayFormat?: string;
  phrases?: object;
  dayAriaLabelFormat?: string;

  // Initial state
  initialVisibleMonth?: () => moment.Moment;
}

Usage Examples:

import React, { useState } from "react";
import { DateRangePicker } from "react-dates";
import moment from "moment";

// Basic date range picker
function BasicDateRangePicker() {
  const [startDate, setStartDate] = useState(null);
  const [endDate, setEndDate] = useState(null);
  const [focusedInput, setFocusedInput] = useState(null);

  return (
    <DateRangePicker
      startDate={startDate}
      startDateId="start_date_input"
      endDate={endDate}
      endDateId="end_date_input"
      onDatesChange={({ startDate, endDate }) => {
        setStartDate(startDate);
        setEndDate(endDate);
      }}
      focusedInput={focusedInput}
      onFocusChange={setFocusedInput}
    />
  );
}

// Customized date range picker
function CustomDateRangePicker() {
  const [startDate, setStartDate] = useState(null);
  const [endDate, setEndDate] = useState(null);
  const [focusedInput, setFocusedInput] = useState(null);

  return (
    <DateRangePicker
      startDate={startDate}
      startDateId="trip_start"
      endDate={endDate}
      endDateId="trip_end"
      onDatesChange={({ startDate, endDate }) => {
        setStartDate(startDate);
        setEndDate(endDate);
      }}
      focusedInput={focusedInput}
      onFocusChange={setFocusedInput}
      
      // Validation
      minimumNights={2}
      isOutsideRange={(day) => moment().diff(day) > 0}
      isDayBlocked={(day) => day.day() === 0} // Block Sundays
      
      // Customization
      startDatePlaceholderText="Check In"
      endDatePlaceholderText="Check Out"
      numberOfMonths={2}
      showClearDates={true}
      
      // Portal rendering for overlays
      withPortal={true}
      
      // Custom rendering
      renderCalendarInfo={() => (
        <div>Select your travel dates</div>
      )}
    />
  );
}

SingleDatePicker

Single date selection component with input field and calendar display for selecting one date.

/**
 * Single date picker component with input field and calendar
 * @param props - SingleDatePicker configuration
 * @returns SingleDatePicker component
 */
function SingleDatePicker(props: SingleDatePickerProps): ReactElement;

interface SingleDatePickerProps {
  // Required props
  id: string;
  onDateChange: (date: moment.Moment | null) => void;
  onFocusChange: ({ focused }: { focused: boolean }) => void;

  // Date state
  date?: moment.Moment | null;
  focused?: boolean;

  // Input customization
  placeholder?: string;
  ariaLabel?: string;
  disabled?: boolean;
  required?: boolean;
  readOnly?: boolean;
  screenReaderInputMessage?: string;
  showClearDate?: boolean;
  showDefaultInputIcon?: boolean;
  inputIconPosition?: 'before' | 'after';
  customInputIcon?: ReactNode;
  customCloseIcon?: ReactNode;

  // Styling
  noBorder?: boolean;
  block?: boolean;
  small?: boolean;
  regular?: boolean;
  keepFocusOnInput?: boolean;

  // Calendar presentation
  orientation?: 'horizontal' | 'vertical';
  anchorDirection?: 'left' | 'right';
  openDirection?: 'down' | 'up';
  horizontalMargin?: number;
  withPortal?: boolean;
  withFullScreenPortal?: boolean;
  appendToBody?: boolean;
  disableScroll?: boolean;
  numberOfMonths?: number;
  keepOpenOnDateSelect?: boolean;
  reopenPickerOnClearDate?: boolean;
  renderCalendarInfo?: () => ReactNode;
  calendarInfoPosition?: 'top' | 'bottom' | 'before' | 'after';
  hideKeyboardShortcutsPanel?: boolean;
  daySize?: number;
  isRTL?: boolean;
  firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
  verticalHeight?: number;
  transitionDuration?: number;
  verticalSpacing?: number;
  horizontalMonthPadding?: number;

  // Navigation
  dayPickerNavigationInlineStyles?: object;
  navPosition?: 'navPositionTop' | 'navPositionBottom';
  navPrev?: ReactNode;
  navNext?: ReactNode;
  renderNavPrevButton?: (props: any) => ReactNode;
  renderNavNextButton?: (props: any) => ReactNode;
  onPrevMonthClick?: (newMonth: moment.Moment) => void;
  onNextMonthClick?: (newMonth: moment.Moment) => void;
  onClose?: (date: moment.Moment | null) => void;

  // Day customization
  renderCalendarDay?: (props: any) => ReactNode;
  renderDayContents?: (day: moment.Moment, modifiers: Set<string>) => ReactNode;
  renderMonthElement?: (props: any) => ReactNode;
  renderMonthText?: (month: moment.Moment) => ReactNode;
  renderWeekHeaderElement?: (day: string) => ReactNode;
  enableOutsideDays?: boolean;
  isDayBlocked?: (day: moment.Moment) => boolean;
  isOutsideRange?: (day: moment.Moment) => boolean;
  isDayHighlighted?: (day: moment.Moment) => boolean;

  // Internationalization
  displayFormat?: (() => string) | string;
  monthFormat?: string;
  weekDayFormat?: string;
  phrases?: object;
  dayAriaLabelFormat?: string;

  // Initial state
  initialVisibleMonth?: () => moment.Moment;
}

Usage Examples:

import React, { useState } from "react";
import { SingleDatePicker } from "react-dates";
import moment from "moment";

// Basic single date picker
function BasicSingleDatePicker() {
  const [date, setDate] = useState(null);
  const [focused, setFocused] = useState(false);

  return (
    <SingleDatePicker
      date={date}
      onDateChange={setDate}
      focused={focused}
      onFocusChange={({ focused }) => setFocused(focused)}
      id="date_picker"
    />
  );
}

// Customized single date picker
function CustomSingleDatePicker() {
  const [date, setDate] = useState(null);
  const [focused, setFocused] = useState(false);

  return (
    <SingleDatePicker
      date={date}
      onDateChange={setDate}
      focused={focused}
      onFocusChange={({ focused }) => setFocused(focused)}
      id="appointment_date"
      
      // Validation
      isOutsideRange={(day) => {
        // Only allow future dates and weekdays
        return moment().diff(day) > 0 || day.day() === 0 || day.day() === 6;
      }}
      
      // Customization
      placeholder="Select appointment date"
      showClearDate={true}
      numberOfMonths={1}
      
      // Custom rendering
      renderDayContents={(day, modifiers) => {
        if (modifiers.has('blocked')) {
          return <span style={{ color: 'red' }}>{day.format('D')}</span>;
        }
        return day.format('D');
      }}
    />
  );
}

Common Props

Validation Functions

All pickers support these validation functions:

  • isDayBlocked: Returns true for dates that should be unselectable
  • isOutsideRange: Returns true for dates outside the allowed range
  • isDayHighlighted: Returns true for dates that should be visually highlighted

Styling Options

  • noBorder: Removes input field borders
  • block: Makes the component full width
  • small: Uses smaller styling variant
  • regular: Uses default styling

Portal Rendering

  • withPortal: Renders calendar in a portal (useful for z-index issues)
  • withFullScreenPortal: Renders calendar in fullscreen portal (mobile-friendly)
  • appendToBody: Appends portal to document body

Accessibility

All components include comprehensive accessibility features:

  • ARIA labeling for screen readers
  • Keyboard navigation support
  • Focus management
  • Customizable announcements

Install with Tessl CLI

npx tessl i tessl/npm-react-dates

docs

calendar-components.md

calendar-controllers.md

index.md

input-components.md

main-pickers.md

utilities.md

tile.json