0.0.4 • Published 1 year ago

sp-date-picker v0.0.4

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

sp-date-picker

Date picker components that allows you to select a day or date range. It comes with two components and utility functions to help you with date manipulation.

Demo

Installation

npm install sp-date-picker

Usage

DatePicker

import { useCallback, useMemo } from 'react'
import { DatePicker, getYearMonthDate, useDatePicker } from 'sp-date-picker'

const App = () => {
  // 1. Use the hook provided
  const datePicker = useDatePicker()

  // 2. Extract what you need from the hook
  const { handleOpen, startDate, endDate } = datePicker

  // 3. Create handlers that open/close the date picker
  const handleDatePickerOpen = useCallback(() => {
    handleOpen(true)
  }, [handleOpen])
  const handleDatePickerClose = useCallback(() => {
    handleOpen(false)
  }, [handleOpen])

  // ...

  const startDateString = useMemo(() => {
    return startDate ? getYearMonthDate(startDate) : ''
  }, [startDate])
  const endDateString = useMemo(() => {
    return endDate ? getYearMonthDate(endDate) : ''
  }, [endDate])

  return (
    <>
      {/* 4. Link handlers that open/close the date picker
          5. Make inputs controlled components */}
      <input
        type="text"
        placeholder="Start date"
        value={startDateString}
        onClick={handleDatePickerOpen}
      />
      <input
        type="text"
        placeholder="End date"
        value={endDateString}
        onClick={handleDatePickerOpen}
      />
      {/* 6. Pass the value returned from the hook to the date picker
          7. Don't forget to pass the onCloseClick handler */}
      <DatePicker {...datePicker} onCloseClick={handleDatePickerClose} />
    </>
  )
}

export default App

DayPicker

import { useCallback, useMemo } from 'react'
import { DayPicker, useDayPicker } from 'sp-date-picker'

const App = () => {
  // 1. Use the hook provided
  const dayPicker = useDayPicker()

  // 2. Extract what you need from the hook
  const { selectedDay, handleOpen } = dayPicker

  // 3. Create handlers that open/close the date picker
  const handleDayPickerOpen = useCallback(() => {
    handleOpen(true)
  }, [handleOpen])
  const handleDayPickerClose = useCallback(() => {
    handleOpen(false)
  }, [handleOpen])

  const selectedDayString = useMemo(() => {
    return selectedDay > 0 ? `Day ${selectedDay}` : ''
  }, [selectedDay])

  return (
    <>
      {/* 4. Link handlers that open/close the date picker
          5. Make input controlled component */}
      <input
        type="text"
        placeholder="Pick a day!"
        value={selectedDayString}
        onClick={handleDayPickerOpen}
      /> {/* 6. Pass the value returned from the hook to the day picker
          7. Don't forget to pass the onCloseClick handler */}
      <DayPicker {...dayPicker} onCloseClick={handleDayPickerClose} />
    </>
  )
}

export default App

Screenshots

range picker

day picker

Custom Styling

If you are willing to customize the styling of the date picker, you can use the id prop to pass in your own class name.

In the code

<DatePicker
  {...datePicker}
  onCloseClick={handleDatePickerClose}
  isRange
  // Pass in your own id to customize the styling
  // This is needed to make higer specificity
  id="demo"
/>

In the css

#demo .datepicker__day.selected {
  background-color: purple;
  border-color: purple;
}

#demo .datepicker__day-box:has(.selected) {
  background-color: purple;
}

#demo .datepicker__day-box:has(.between) {
  background-color: purple;
}

Target the id you passed in to the date picker and select the element you want to customize. You can see what selector you are looking for by inspecting the element in the browser.

Here are few examples of css selectors you can use to customize the styling.

Selector
.datepicker__day.selected
.datepicker__day-box:has(.selected)
.datepicker__day-box:has(.between)
.datepicker__day:hover
.datepicker__month.selected
.datepicker__footer__clear-date-button.datepicker__footer__button
.datepicker__footer__confirm-button.datepicker__footer__button

Try including the below css in your project to see how it looks like.

Custom Style

custom styling

CSS

#demo .datepicker__footer__clear-date-button.datepicker__footer__button span {
  color: gray;
}

#demo .datepicker__footer__confirm-button.datepicker__footer__button {
  background-color: #ffac2c;
}

#demo .datepicker__day.selected {
  background-color: #ffac2c;
  border-color: #ffac2c;
}

#demo .datepicker__day-box:has(.selected) {
  background-color: #fff1e6;
}

#demo .datepicker__day-box:has(.between) {
  background-color: #fff1e6;
}

Options

There are the props you might be interested in.

DatePicker

OptionRequiredDescriptionDefaultType
titleTitle of the date pickerPick dates range!string
date*Currently selected date (used on day picker)Date
startDate*Currently selected start date (used on range picker)Date
endDate*Currently selected end date (used on range picker)Date
open*Whether the date picker is open or notfalseboolean
onConfirmClick*Clled when confirm button is clicked({ date, startDate, endDate}) => void
onCloseClick*Called when close button is clicked() => void
onBackdropClickCalled when backdrop is clicked() => void
isRangeWhether the date picker is a range picker or nottrueboolean
disablePastWhether to disable past dates when start date is setfalseboolean
styleCSS styles to be applied to the date pickerCSSProperties
customSelectMonthMotionMotion to be applied to the month selectionAnimationProps (framer-motion)
customSelectDayMotionMotion to be applied to the day selectionAnimationProps (framer-motion)

DayPicker

OptionRequiredDescriptionDefaultType
titleTitle of the date pickerPick a day!string
selectedDay*Currently selected day-1number
open*Whether the date picker is open or notfalseboolean
onDayClick*Called when a day is clicked(day: number) => void
onCloseClick*Called when close button is clicked() => void
onBackdropClickCalled when backdrop is clicked() => void
styleCSS styles to be applied to the date pickerCSSProperties
customMotionMotion to be applied to the picker containerAnimationProps (framer-motion)

Most of props are given by the hook provided. Use javascript deconstruction to extract what you need. See the example below.

// DatePicker - a range picker
const datePicker = useDatePicker()
const { startDate, endDate } = datePicker

// DatePicker - a day picker
const datePicker = useDatePicker()
const { date } = datePicker

// DayPicker
const dayPicker = useDayPicker()
const { selectedDay } = dayPicker

Extract handlers to create open/close handlers.

const datePicker = useDatePicker()
const { handleOpen } = datePicker

const handleDatePickerOpen = useCallback(() => {
  handleOpen(true)
}, [handleOpen])

const handleDatePickerClose = useCallback(() => {
  handleOpen(false)
}, [handleOpen])

Date Utilities

FunctionDescription
getEmptyDaysReturns the number of empty days in a month prior to the very first day
getTotalDaysReturns the total number of days in a month
getDayNamesReturns an array of day names in default locale
getFirstSundayReturns the day that is the first Sunday of the month
isSundayCheck if a date is a Sunday
isSaturdayCheck if a date is a Saturday
isWeekendCheck if a date is a weekend (Saturday or Sunday)
getYearMonthDateGet a date format of YYYY-MM-DD
getYearMonthGet a date format of YYYY-MM
getYearGet a date format of YYYY
getMonthGet a date format of MM
getDateGet a date format of DD

Todo

  • Fix failing tests
  • Add more tests if needed