0.11.0 • Published 6 months ago

@imharshal/react-date-range-picker v0.11.0

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

@imharshal/react-date-range-picker

Link to Live Demo (Storybook)

A flexible, feature-rich date range picker component for React applications with modern design, extensive configuration options, and timezone customizations. This library supports single and range date selection, time pickers, custom themes, and more.

npm version npm downloads license


Table of Contents


Features

  • Flexible Date Selection: Single date or date range selection
  • Time Picker: Optional time selection with 12/24 hour format support
  • Predefined Ranges: Built-in common ranges (Today, Last 7 Days, etc.)
  • Custom Ranges: Define your own named date ranges
  • Theme Support: Default theme with customization options
  • Timezone Awareness: Works with any timezone using moment-timezone
  • Responsive Positioning: Smart positioning based on available screen space
  • Locale Support: Customizable date formats and labels
  • Auto-resize Input: Input field that adjusts to content width
  • Mobile Friendly: Responsive design works on all devices
  • Keyboard Navigation: Accessible keyboard controls
  • Extensive Customization: Configure almost any aspect of appearance and behavior
  • Programmatic Control: Ref forwarding for controlling the picker programmatically
  • Tooltip Support: Configurable tooltips for additional context

Installation

Install the library using npm or yarn:

npm install @imharshal/react-date-range-picker

or

yarn add @imharshal/react-date-range-picker

Basic Usage

import React from 'react';
import DateRangePicker from '@imharshal/react-date-range-picker';

const App = () => {
  const handleApply = ({ startDate, endDate, chosenLabel }) => {
    console.log('Selected Range:', startDate, endDate, chosenLabel);
  };

  return (
    <DateRangePicker onApply={handleApply} placeholder="Select a date range" />
  );
};

export default App;

TypeScript Support

This library includes TypeScript support for better type safety and developer experience. Below are the interfaces for the DateRangePicker component and its options:

DateRangePickerProps

interface DateRangePickerProps {
  // Core functionality
  startDate?: Date | string | moment.Moment;
  endDate?: Date | string | moment.Moment;
  onApply?: (range: {
    startDate: moment.Moment;
    endDate: moment.Moment;
    chosenLabel: string;
  }) => void;
  onCancel?: () => void;

  // Display and behavior
  timeZone?: string;
  theme?: string;
  customTheme?: {
    primary?: string;
    secondary?: string;
    background?: string;
    text?: string;
    border?: string;
    hover?: string;
    [key: string]: string;
  };
  disabled?: boolean;
  placeholder?: string;
  ariaLabel?: string;

  // Styling
  inputClassName?: string;

  // Ranges
  ranges?: {
    [key: string]: [moment.Moment, moment.Moment];
  };

  // Advanced configuration
  options?: DateRangePickerOptions;
}

DateRangePickerOptions

interface DateRangePickerOptions {
  // Selection behavior
  singleDatePicker?: boolean;
  autoApply?: boolean;
  linkedCalendars?: boolean;
  autoUpdateInput?: boolean;
  alwaysShowCalendars?: boolean;
  chosenLabel?: string; // Label for the selected range (e.g., 'Last 7 Days')

  // Display settings
  showInputField?: boolean;
  showFullDateRangeLabel?: boolean;
  showDropdowns?: boolean;
  showCustomRangeLabel?: boolean;
  showRanges?: boolean;

  // Time related
  timePicker?: boolean;
  timePicker24Hour?: boolean;
  timePickerIncrement?: number;
  timePickerSeconds?: boolean;

  // Positioning
  opens?: 'left' | 'center' | 'right';
  drops?: 'up' | 'down' | 'auto';

  // Date restrictions
  minDate?: Date | string | moment.Moment;
  maxDate?: Date | string | moment.Moment;

  // Custom styling
  icon?: React.ReactNode;
  buttonClasses?: string;
  applyButtonClasses?: string;
  cancelButtonClasses?: string;
  mainContainerClassName?: string;
  inputContainerClassName?: string;
  labelContainerClassName?: string;
  iconClassName?: string;
  labelClassName?: string;
  inputStyle?: React.CSSProperties;

  // Custom attributes
  mainContainerAttr?: object;
  inputContainerAttr?: object;
  labelContainerAttr?: object;
  inputAttr?: object;

  // Tooltip
  showTooltip?: boolean;
  tooltip?: {
    show?: boolean;
    showSelectedRange?: boolean;
    content?: React.ReactNode;
    containerClassName?: string;
    contentClassName?: string;
    containerAttr?: object;
  };

  // Localization
  locale?: {
    format?: string;
    separator?: string;
    applyLabel?: string;
    cancelLabel?: string;
    customRangeLabel?: string;
    [key: string]: string;
  };
}

These interfaces provide a comprehensive overview of all the props and options supported by the DateRangePicker component, making it easier to integrate into TypeScript projects.


Props and Options

Core Props

PropTypeDefaultDescription
onApplyFunctionnullCallback when the user applies the selected date range.
onCancelFunctionnullCallback when the user cancels the selection.
startDateMomentnullInitial start date.
endDateMomentnullInitial end date.
timeZoneStringAuto-detectedTimezone for date calculations.
placeholderString'Select date range'Placeholder text for the input field.
disabledBooleanfalseDisables the date picker.

Options (via options prop)

OptionTypeDefaultDescription
singleDatePickerBooleanfalseEnables single date selection mode.
timePickerBooleanfalseEnables time selection.
timePicker24HourBooleanfalseEnables 24-hour time format.
timePickerIncrementNumber5Time picker increment in minutes.
timePickerSecondsBooleanfalseEnables seconds selection in the time picker.
showInputFieldBooleantrueDisplays an input field for the date range.
showRangesBooleantrueDisplays predefined ranges.
rangesObjectPredefined RangesCustom predefined ranges.
localeObject{}Localization options (e.g., format, separator, applyLabel, etc.).
minDateMomentnullMinimum selectable date.
maxDateMomentnullMaximum selectable date.
autoApplyBooleanfalseAutomatically applies the selection without requiring a button click.
alwaysShowCalendarsBooleanfalseAlways shows the calendars.
opensString'right'Position of the picker ('left', 'right', 'center').
dropsString'auto'Drop direction ('up', 'down', 'auto').

Tooltip Options (via options.tooltip)

OptionTypeDefaultDescription
showBooleanfalseWhether to show the tooltip.
showSelectedRangeBooleanfalseWhether to display the selected range in the tooltip.
contentReactNodenullCustom content to display in the tooltip.
containerClassNameString''Custom class for the tooltip container.
contentClassNameString''Custom class for the tooltip content.
containerAttrObject{}Additional attributes for the tooltip container.

Customization Props

PropTypeDefaultDescription
themeString'default'Theme name. Available Themes ('light', 'dark')
customThemeObject{}Custom theme styles.
inputContainerClassNameString''Custom class for the input container field.
inputClassNameString''Custom class for the input field.
mainContainerClassNameString''Custom class for the main container.

Advanced Examples

Single Date Picker

<DateRangePicker
  options={{ singleDatePicker: true }}
  placeholder="Select a date"
/>

Time Picker

<DateRangePicker
  options={{
    timePicker: true,
    timePicker24Hour: true,
    timePickerIncrement: 15,
  }}
/>

Custom Ranges

<DateRangePicker
  options={{
    ranges: {
      Today: [moment(), moment()],
      'This Week': [moment().startOf('week'), moment().endOf('week')],
    },
  }}
/>

Custom Theme

<DateRangePicker
  theme="custom"
  customTheme={{
    '--color-range-bg': '#f0f0f0',
    '--color-primary': '#333',
  }}
/>

Disabled Picker

<DateRangePicker disabled={true} placeholder="Picker is disabled" />

Localization Example

<DateRangePicker
  options={{
    locale: {
      format: 'DD/MM/YYYY',
      separator: ' to ',
      applyLabel: 'Apply',
      cancelLabel: 'Cancel',
    },
  }}
/>

Tooltip Example

<DateRangePicker
  options={{
    showTooltip: true,
    tooltip: {
      show: true,
      showSelectedRange: true,
      content: 'Select a date range',
      containerClassName: 'custom-tooltip-container',
      contentClassName: 'custom-tooltip-content',
    },
  }}
  placeholder="Hover to see tooltip"
/>

Programmatic Control with Ref Forwarding

The DateRangePicker component supports ref forwarding, allowing you to programmatically control its behavior. Here's an example:

import React, { useRef } from 'react';
import DateRangePicker from '@imharshal/react-date-range-picker';

const App = () => {
  const pickerRef = useRef();

  const openPicker = () => {
    pickerRef.current.open();
  };

  const closePicker = () => {
    pickerRef.current.close();
  };

  const logSelectedDates = () => {
    console.log('Start Date:', pickerRef.current.getStartDate());
    console.log('End Date:', pickerRef.current.getEndDate());
  };

  return (
    <div>
      <button onClick={openPicker}>Open Picker</button>
      <button onClick={closePicker}>Close Picker</button>
      <button onClick={logSelectedDates}>Log Selected Dates</button>
      <DateRangePicker ref={pickerRef} placeholder="Select a date range" />
    </div>
  );
};

export default App;

Available Methods via Ref

MethodDescription
open()Opens the date range picker.
close()Closes the date range picker.
toggle()Toggles the open/close state of the picker.
isOpen()Returns whether the picker is currently open.
getStartDate()Returns the currently selected start date.
getEndDate()Returns the currently selected end date.
getDisplayFormat()Returns the display format for the dates.
getMoment()Returns the moment instance used by the picker.
setStartDate(date)Sets the start date programmatically.
setEndDate(date)Sets the end date programmatically.

Predefined Ranges

By default, the following ranges are available:

  • Today
  • Yesterday
  • Last 7 Days
  • Last 30 Days
  • This Month
  • Last Month

You can override these ranges using the ranges option.

Using chosenLabel with Predefined Ranges

When a user selects a predefined range, the chosenLabel property is set to the name of the selected range (e.g., "Last 7 Days"). This label is:

  1. Returned in the onApply callback: { startDate, endDate, chosenLabel }
  2. Used for display when showInputField is set to false

For proper display when showInputField is set to false, you should:

const [dateRange, setDateRange] = useState({
  startDate: moment().subtract(7, 'days'),
  endDate: moment(),
  chosenLabel: 'Last 7 Days', // Initialize with the appropriate label
});

const handleApply = (range) => {
  setDateRange({
    startDate: range.startDate,
    endDate: range.endDate,
    chosenLabel: range.chosenLabel, // Store the chosen label
  });
};

<DateRangePicker
  startDate={dateRange.startDate}
  endDate={dateRange.endDate}
  onApply={handleApply}
  options={{
    showInputField: false,
    chosenLabel: dateRange.chosenLabel, // Pass chosenLabel to display correctly
  }}
/>;

Localization

You can customize labels and formats using the locale option:

<DateRangePicker
  options={{
    locale: {
      format: 'DD/MM/YYYY',
      separator: ' to ',
      applyLabel: 'Apply',
      cancelLabel: 'Cancel',
    },
  }}
/>

Events

onApply

Called when the user applies the selected date range.

const handleApply = ({ startDate, endDate, chosenLabel }) => {
  console.log('Selected Range:', startDate, endDate, chosenLabel);

  // When using with showInputField: false, remember to store chosenLabel
  setState({
    startDate,
    endDate,
    chosenLabel, // Store this to pass it back to the component
  });
};

onCancel

Called when the user cancels the selection.

const handleCancel = () => {
  console.log('Selection canceled');
};

Styling and Customization

The component includes default SCSS-based styling, which can be customized in the following ways:

  1. Theme Props: Use the theme and customTheme props to apply predefined or custom themes.
  2. Custom CSS Classes: Add your own CSS classes using props like mainContainerClassName, inputClassName, etc.
  3. Style Attributes: Inline styles can be applied using props like inputStyle.

You can override the default styles by importing your own SCSS file or using the customTheme prop to define specific styles.


Browser Support

The date range picker works in all modern browsers:

  • Chrome
  • Firefox
  • Safari
  • Edge
  • Opera

Dependencies

This library requires the following dependencies:

  • React 16.8+ (uses hooks)
  • moment-timezone
  • react-dom (for portals)

Troubleshooting

Issue: The picker does not open

  • Ensure the disabled prop is not set to true.
  • Verify that the onClick handler is not being overridden.

Issue: Incorrect date format

  • Check the locale.format option to ensure it matches your desired format.

Issue: Time picker not working

  • Ensure timePicker is set to true in the options prop.
  • Verify that timePicker24Hour and timePickerIncrement are correctly configured.

Issue: Predefined ranges not showing

  • Ensure showRanges is set to true in the options prop.
  • Verify that the ranges object is correctly defined.

Issue: Dates not updating in parent component

  • Ensure you're handling the onApply callback correctly.
  • Check that you're updating your state with the new values.

Issue: Range label not showing correctly with showInputField: false

  • Make sure to store and pass back the chosenLabel from the onApply callback:
    const handleApply = (range) => {
      setDateRange({
        startDate: range.startDate,
        endDate: range.endDate,
        chosenLabel: range.chosenLabel, // Store this value
      });
    };
  • Pass the chosenLabel back to the component in the options:
    <DateRangePicker
      options={{
        showInputField: false,
        chosenLabel: dateRange.chosenLabel,
      }}
    />

Issue: Calendar doesn't open/close properly

  • Check the browser console for errors.
  • Ensure you're not stopping event propagation incorrectly.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository.
  2. Create your feature branch:
    git checkout -b feature/amazing-feature
  3. Commit your changes:
    git commit -m 'Add some amazing feature'
  4. Push to the branch:
    git push origin feature/amazing-feature
  5. Open a Pull Request.

Credits

This library is inspired by:


License

This project is licensed under the MIT License.

0.11.0

6 months ago

0.10.0

6 months ago

0.9.0

8 months ago

0.8.0

8 months ago

0.7.0

8 months ago

0.6.0

8 months ago

0.5.0

8 months ago

0.4.0

8 months ago

0.3.0

8 months ago

0.2.0

8 months ago

0.1.0

8 months ago