{"version":3,"sources":["../src/use-multi-date-picker.ts"],"sourcesContent":["import type { PropGetter } from \"@yamada-ui/core\"\nimport type { ChangeEvent, CSSProperties } from \"react\"\nimport type { UseCalendarProps } from \"./use-calendar\"\nimport type { UseCalendarPickerProps } from \"./use-calendar-picker\"\nimport { useControllableState } from \"@yamada-ui/use-controllable-state\"\nimport { handlerAll, isNumber, useUpdateEffect } from \"@yamada-ui/utils\"\nimport dayjs from \"dayjs\"\nimport { useCallback, useRef, useState } from \"react\"\nimport { isSameDate } from \"./calendar-utils\"\nimport { useCalendarPicker } from \"./use-calendar-picker\"\n\nconst getResolvedValue = (value: (Date | undefined)[]) => {\n  const timestamps = new Set(\n    value.map((date) => date?.getTime()).filter(Boolean),\n  ) as Set<number>\n\n  return Array.from(timestamps).map(\n    (timestamp) => new Date(timestamp),\n  ) as Date[]\n}\n\ninterface CalendarProps\n  extends Omit<\n    UseCalendarProps<Date[]>,\n    \"enableMultiple\" | \"enableRange\" | \"nextRef\" | \"prevRef\" | \"typeRef\"\n  > {}\n\ninterface UseMultiDatePickerOptions {\n  /**\n   * If `true`, the calendar component will be closed when value is max selected.\n   *\n   * @default true\n   */\n  closeOnMaxSelect?: boolean\n  /**\n   * If `true`, the calendar component will be closed when value is selected.\n   *\n   * @default false\n   */\n  closeOnSelect?: boolean\n}\n\nexport interface UseMultiDatePickerProps\n  extends UseCalendarPickerProps<CalendarProps>,\n    UseMultiDatePickerOptions {}\n\nexport const useMultiDatePicker = ({\n  closeOnMaxSelect = true,\n  closeOnSelect = false,\n  defaultValue = [],\n  excludeDate,\n  maxSelectValues,\n  placeholder,\n  value: valueProp,\n  onChange: onChangeProp,\n  ...rest\n}: UseMultiDatePickerProps) => {\n  const composition = useRef<boolean>(false)\n  const draftValue = useRef<Date | undefined>(undefined)\n  const [value, setValue] = useControllableState<Date[]>({\n    defaultValue,\n    value: valueProp,\n    onChange: onChangeProp,\n  })\n  const [inputValue, setInputValue] = useState<string>(\"\")\n  const resolvedValue = getResolvedValue([...value, draftValue.current])\n  const {\n    allowInput,\n    dateToString,\n    open,\n    pattern,\n    stringToDate,\n    formControlProps,\n    getCalendarProps,\n    getContainerProps,\n    getFieldProps,\n    getIconProps,\n    getPopoverProps,\n    inputProps,\n    onClose,\n  } = useCalendarPicker({\n    excludeDate,\n    ...rest,\n    defaultValue,\n    enableMultiple: true,\n    maxSelectValues,\n    value: resolvedValue,\n    onChange: (value: Date[]) => {\n      value = value.filter((value) => !isSameDate(value, draftValue.current))\n\n      setValue(value)\n      setInputValue(\"\")\n\n      draftValue.current = undefined\n\n      if (closeOnSelect && !!value.length) onClose()\n    },\n    onClear: () => {\n      setValue([])\n      setInputValue(\"\")\n    },\n    onClose: () => {\n      setInputValue(\"\")\n\n      rest.onClose?.()\n    },\n    onDelete: (ev) => {\n      if (inputValue.length) return\n\n      ev.preventDefault()\n      ev.stopPropagation()\n\n      setValue((prev) => prev.slice(0, -1))\n    },\n    onEnter: () => {\n      if (composition.current) return\n\n      const value = stringToDate(inputValue)\n\n      if (!!value && dayjs(value).isValid()) {\n        setValue((prev) => {\n          if (prev.length === maxSelectValues) return prev\n\n          const isSelected = prev.some((prevValue) =>\n            isSameDate(prevValue, value),\n          )\n\n          return !isSelected ? [...prev, value!] : prev\n        })\n      }\n\n      setInputValue(\"\")\n      draftValue.current = undefined\n    },\n  })\n\n  useUpdateEffect(() => {\n    setValue(valueProp ?? [])\n  }, [valueProp])\n\n  useUpdateEffect(() => {\n    if (!closeOnMaxSelect || !isNumber(maxSelectValues)) return\n\n    if (maxSelectValues <= value.length) onClose()\n  }, [value])\n\n  const onChange = useCallback(\n    (ev: ChangeEvent<HTMLInputElement>) => {\n      let inputValue = ev.target.value\n\n      if (!composition.current) inputValue = inputValue.replace(pattern, \"\")\n\n      setInputValue(inputValue)\n\n      const value = stringToDate(inputValue)\n\n      draftValue.current = dayjs(value).isValid() ? value : undefined\n    },\n    [pattern, stringToDate],\n  )\n\n  const onCompositionStart = useCallback(() => {\n    composition.current = true\n  }, [])\n\n  const onCompositionEnd = useCallback(() => {\n    composition.current = false\n\n    setInputValue((prev) => prev.replace(pattern, \"\"))\n  }, [pattern])\n\n  const getInputProps: PropGetter<\"input\"> = useCallback(\n    (props = {}, ref = null) => {\n      const style: CSSProperties = {\n        ...props.style,\n        ...inputProps.style,\n        ...(formControlProps.disabled || !allowInput\n          ? { pointerEvents: \"none\" }\n          : {}),\n      }\n\n      return {\n        placeholder,\n        tabIndex: !allowInput ? -1 : 0,\n        ...formControlProps,\n        ...inputProps,\n        ...props,\n        ref,\n        style,\n        value: inputValue,\n        onChange: handlerAll(props.onChange, onChange),\n        onCompositionEnd: handlerAll(props.onCompositionEnd, onCompositionEnd),\n        onCompositionStart: handlerAll(\n          props.onCompositionStart,\n          onCompositionStart,\n        ),\n      }\n    },\n    [\n      inputProps,\n      allowInput,\n      placeholder,\n      formControlProps,\n      inputValue,\n      onChange,\n      onCompositionStart,\n      onCompositionEnd,\n    ],\n  )\n\n  return {\n    dateToString,\n    open,\n    setValue,\n    value,\n    getCalendarProps,\n    getContainerProps,\n    getFieldProps,\n    getIconProps,\n    getInputProps,\n    getPopoverProps,\n    onClose,\n  }\n}\n\nexport type UseMultiDatePickerReturn = ReturnType<typeof useMultiDatePicker>\n"],"mappings":"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","names":["value","inputValue"]}