npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

use-date-input

v2.0.0

Published

React hooks for building date input and datepicker components.

Downloads

3

Readme

use-date-input

React hooks for building date input and datepicker components.

Installation

To use this hook you need to install date-fns.

yarn add date-fns
yarn add use-date-input

or with npm:

npm install date-fns
npm install use-date-input

useDateInput

useDateInput(props: UseDateInputProps): UseDateInput

Hook that manages state of masked date input.

Uses IMask for input masking and date-fns for date formatting and parsing.

Props

UseDateInputProps

| Name | Type | Description | | :------ | :------ | :------ | | dateFormat | string | date-fns date format, see https://date-fns.org/v2.22.1/docs/format | | maskBlocks? | MaskedDateOptions["blocks"] | Blocks defining each date part, see https://imask.js.org/guide.html#masked-date for more info | | onComplete? | (value?: Date) => void | This will execute when input satisfies given format (mask), usually this function should be used to update date value| | value? | Date | Date value of input |

Return value

UseDateInput

| Name | Type | Description | | :------ | :------ | :------ | | inputValue | string | Value of input element | | onKeyPress | KeyboardEventHandler | Apply to input element if you wish to autocomplete date when user presses enter key. Parsing is done using dateFns parse with dateFormat truncated to the length of current inputValue and using current date as reference. For example if today is 07/08/2021 and input value is 2, on enter press, input value will become 02/08/2021 | | ref | RefObject<HTMLInputElement> | Input element ref | | resetValueOnDelete | ChangeEventHandler<HTMLInputElement> | Will call onComplete with undefined value if e.target.value is falsy. Use it to reset value when user deletes the input. | | setInputValue | Dispatch<SetStateAction<string>> | Sets inputValue, note that you don't need to set input value on input element change, this is done internally by using IMask's accept event |

Usage

// define maskBlocks as constant or memoize in component
const maskBlocks = {
  dd: {
    mask: IMask.MaskedRange,
    from: 1,
    to: 31,
    maxLength: 2,
  },
  MM: {
    mask: IMask.MaskedRange,
    from: 1,
    to: 12,
    maxLength: 2,
  },
  yyyy: {
    mask: IMask.MaskedRange,
    from: 1900,
    to: 9999,
  },
};

const DateInput = () => {
  const [value, setValue] = useState<Date>();
  const { ref, inputValue, resetValueOnDelete } = useDateInput({
    value,
    dateFormat: "dd-MM-yyyy",
    maskBlocks,
    onComplete: setValue,
  });

  return <input ref={ref} value={inputValue} onChange={resetValueOnDelete} />;
};

useCalendar

useCalendar(props: UseCalendarProps): UseCalendar

Manages calendar state.

You can use this hook to render calendar view. Focused date state is used as reference to return calendar days.

Uses date-fns for date manipulation.

Props

UseCalendarProps

| Name | Type | Description | | :------ | :------ | :------ | | maxDate? | Date | Only dates before this date will be marked valid For best performance memoize this date, this will prevent recalculation of calendar days on each render. | | minDate? | Date | Only dates after this date will be marked valid. For best performance memoize this date, this will prevent recalculation of calendar days on each render. | | startDate? | Date | If provided calendar will start at the month of provided date | | validate? | (date: Date) => boolean | Validation function, dates that fail this test will be marked invalid. For best performance memoize this function, this will prevent recalculation of calendar days on each render. | | value? | Date | Datepicker value | | weekStartsOn? | 0 1 2 3 4 5 6 | Day that a week starts on. 0 - sunday, 1 - monday ..., default is 0 |

Return value

UseCalendar

| Name | Type | Description | | :------ | :------ | :------ | | days | UseDatepickerDay[] | Returns all dates that can be seen in calendar view along with flags for each date that indicate if it is in the same month as focused date and if it is valid (available for selection). Use this function to render month view of calendar. | | focusedDate | Date | First day of month that represents current calendar view | | isSelected | (date: Date) => boolean | Compares given date with value. | | months | Date[] | Dates representing each month in the same year as focusedDate. You can use this function render month selection for calendar view. | | nextMonth | () => void | Adds one month to focusedDate. Use it to move calendar view to next month. | | nextYear | () => void | Adds one year to focusedDate. Use it to move calendar view to next year. | | previousMonth | () => void | Subtracts one month from focusedDate. Use it to move calendar view to previous month. | | previousYear | () => void | Adds one month to focusedDate. Use it to move calendar view to next month. | | setFocusedDate | Dispatch<SetStateAction<Date>> | Changes focusedDate, make sure to only pass first day of the month dates. By changing focusedDate you are actually changing the reference point of calendar which means, once focused date is changed, days and months functions will use new focusedDate value as reference point. | | years? | Date[] | Dates representing eachYear from minDate to maxDate. Returns undefined if minDate or maxDate is not defined |

UseDatePickerDay

| Name | Type | Description | | :------ | :------ | :------ | | date | Date | Represents calendar day | | inMonth | boolean | Indicates if this date is in currently viewed calendar month | | isValid | boolean | If true this date can be selected according to provided min and max date and validate function |

Usage

const Calendar = () => {
  const [value, setValue] = useState<Date>();
  const { previousYear, nextYear, focusedDate, previousMonth, nextMonth, days, isSelected } = useCalendar({ value });

  return (
    <div style={{ width: "420px" }}>
      <div style={{ width: "100%" }}>
        <button onClick={previousYear}>{"<"}</button>
        {format(focusedDate, "yyyy")}
        <button onClick={nextYear}>{">"}</button>
      </div>
      <div style={{ width: "100%" }}>
        <button onClick={previousMonth}>{"<"}</button>
        {format(focusedDate, "MMMM")}
        <button onClick={nextMonth}>{">"}</button>
      </div>
      <div style={{ display: "flex", flexWrap: "wrap" }}>
        {days.map(({ date, inMonth }) => (
          <button
            disabled={!inMonth}
            style={{ width: "60px", backgroundColor: isSelected(date) ? "aliceblue" : "initial" }}
            key={date.toDateString()}
            onClick={() => setValue(date)}>
            {format(date, "d")}
          </button>
        ))}
      </div>
    </div>
  );
};

useDatepicker

useDatepicker<T>(props: UseCalendarProps & UseDropdownProps): UseCalendar & UseDropdown<T>

Combines useCalendar and useDropdown hooks into one.

Props

| Name | Type | Description | | :------ | :------ | :------ | | additionalRefs? | RefObject<HTMLElement>[] | These refs will be used when determining what constitutes a click outside of dropdown. | | disabled? | boolean | If true, open and close will do nothing | | onClose? | () => void | Executed when close is called | | onOpen? | () => void | Executed when open is called | | maxDate? | Date | Only dates before this date will be marked valid For best performance memoize this date, this will prevent recalculation of calendar days on each render. | | minDate? | Date | Only dates after this date will be marked valid. For best performance memoize this date, this will prevent recalculation of calendar days on each render. | | startDate? | Date | If provided calendar will start at the month of provided date | | validate? | (date: Date) => boolean | Validation function, dates that fail this test will be marked invalid. For best performance memoize this function, this will prevent recalculation of calendar days on each render. | | value? | Date | Datepicker value | | weekStartsOn? | 0 1 2 3 4 5 6 | Day that a week starts on. 0 - sunday, 1 - monday ..., default is 0 |

Return value

| Name | Type | Description | | :------ | :------ | :------ | | dropdownRef | RefObject<T> | Ref for dropdown element | | isOpen | boolean | Dropdown state | | open | () => void | Sets isOpen to true | | close | () => void | Sets isOpen to false | | days | UseDatepickerDay[] | Returns all dates that can be seen in calendar view along with flags for each date that indicate if it is in the same month as focused date and if it is valid (available for selection). Use this function to render month view of calendar. | | focusedDate | Date | First day of month that represents current calendar view | | isSelected | (date: Date) => boolean | Compares given date with value. | | months | Date[] | Dates representing each month in the same year as focusedDate. You can use this function render month selection for calendar view. | | nextMonth | () => void | Adds one month to focusedDate. Use it to move calendar view to next month. | | nextYear | () => void | Adds one year to focusedDate. Use it to move calendar view to next year. | | previousMonth | () => void | Subtracts one month from focusedDate. Use it to move calendar view to previous month. | | previousYear | () => void | Adds one month to focusedDate. Use it to move calendar view to next month. | | setFocusedDate | Dispatch<SetStateAction<Date>> | Changes focusedDate, make sure to only pass first day of the month dates. By changing focusedDate you are actually changing the reference point of calendar which means, once focused date is changed, days and months functions will use new focusedDate value as reference point. | | years? | Date[] | Dates representing eachYear from minDate to maxDate. Returns undefined if minDate or maxDate is not defined |

Usage

const DateInputWithDatepicker = () => {
  const [value, setValue] = useState<Date>();
  const { ref, inputValue, resetValueOnDelete } = useDateInput({
    value,
    dateFormat: "dd-MM-yyyy",
    maskBlocks,
    onComplete: setValue,
  });
  const {
    isOpen,
    open,
    days,
    previousYear,
    nextYear,
    previousMonth,
    nextMonth,
    focusedDate,
    dropdownRef,
    isSelected,
  } = useDatepicker<HTMLDivElement>({
    value,
  });

  return (
    <div ref={dropdownRef}>
      <input ref={ref} value={inputValue} onChange={resetValueOnDelete} onFocus={open} />
      {isOpen && (
        <div style={{ width: "420px" }}>
          <div style={{ width: "100%" }}>
            <button onClick={previousYear}>{"<"}</button>
            {format(focusedDate, "yyyy")}
            <button onClick={nextYear}>{">"}</button>
          </div>
          <div style={{ width: "100%" }}>
            <button onClick={previousMonth}>{"<"}</button>
            {format(focusedDate, "MMMM")}
            <button onClick={nextMonth}>{">"}</button>
          </div>
          <div style={{ display: "flex", flexWrap: "wrap" }}>
            {days.map(({ date, inMonth }) => (
              <button
                disabled={!inMonth}
                style={{ width: "60px", backgroundColor: isSelected(date) ? "aliceblue" : "initial" }}
                key={date.toDateString()}
                onClick={() => setValue(date)}>
                {format(date, "d")}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};