{"version":3,"file":"index29.mjs","sources":["../src/components/input/datepicker/index.tsx"],"sourcesContent":["import {\n  FunctionComponent,\n  ReactNode,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport TextFieldAtom from \"../../../atoms/textfield\";\nimport {\n  LabelPairedCalendarSmBoldIcon,\n  LabelPairedChevronDownSmBoldIcon,\n  LabelPairedChevronLeftSmBoldIcon,\n  LabelPairedChevronRightSmBoldIcon,\n} from \"@deriv/quill-icons\";\n\nimport { useClickOutside } from \"../../../../src/hooks/useClickOutside\";\nimport DropdownContainerAtom from \"../../../../src/atoms/dropdown/container\";\nimport \"react-calendar/dist/Calendar.css\";\nimport \"./Datepicker.css\";\nimport Calendar from \"react-calendar\";\nimport { format, parse } from \"date-fns\";\nimport { createRoot } from \"react-dom/client\";\nimport IconButton from \"../../buttons/icon\";\n\nexport type DatePickerType = {\n  className?: string;\n  label?: string;\n  placeholder?: string;\n  showCharacterCounter?: boolean;\n  message?: string;\n\n  /** Variant props */\n  indicator?: \"neutral\" | \"fail\" | \"success\";\n  state?: \"default\" | \"disabled\";\n  type?: \"outline\" | \"fill\";\n  size?: \"lg\" | \"md\" | \"sm\";\n  textAlignment?: \"left\" | \"center\";\n  variant?: \"labelled\" | \"labelless\";\n\n  /** Custom props */\n  isRequired?: boolean;\n  optionalText?: string;\n  maxLength?: number;\n  value?: string | number;\n  minDate?: string | Date;\n  maxDate?: string | Date;\n  onChange?: (value: string | number) => void;\n  dateFormat?:\n    | \"dd/mm/yyyy\"\n    | \"mm/dd/yyyy\"\n    | \"yyyy/mm/dd\"\n    | \"dd/mm/yy\"\n    | \"mm/dd/yy\"\n    | \"yyyy/mm/yy\"\n    | \"dd-mm-yyyy\"\n    | \"mm-dd-yyyy\"\n    | \"yyyy-mm-dd\"\n    | \"dd-mm-yy\"\n    | \"mm-dd-yy\";\n  messages?: {\n    text: string;\n    type: \"neutral\" | \"fail\" | \"success\";\n    icon?: ReactNode;\n  }[];\n};\n\nexport const Datepicker: FunctionComponent<DatePickerType> = ({\n  dateFormat = \"dd/mm/yyyy\",\n  size = \"md\",\n  minDate,\n  maxDate,\n  ...props\n}) => {\n  const [value, setValue] = useState(props.value);\n  const [isOpen, setIsOpen] = useState(false);\n  const datepickerRef = useRef<HTMLDivElement>(null);\n  const prevFormatRef = useRef(dateFormat);\n\n  const datepickerContainerOffets = {\n    sm: 15,\n    md: 20,\n    lg: 35,\n  };\n\n  const mapFormatString = (dateFormat: string) => {\n    return dateFormat\n      .replace(/yyyy/g, \"yyyy\")\n      .replace(/yy/g, \"yy\")\n      .replace(/mm/g, \"MM\")\n      .replace(/dd/g, \"dd\");\n  };\n\n  const parseToDate = (date?: string | Date) => {\n    if (!date) return undefined;\n    if (date instanceof Date) return date;\n    // Try to parse string to Date\n    const parsed = new Date(date);\n    return isNaN(parsed.getTime()) ? undefined : parsed;\n  };\n\n  // Helper to parse value according to dateFormat\n  const getValidDate = (\n    value: string | number | undefined,\n    dateFormat: string\n  ) => {\n    if (!value) return null;\n    if (typeof value === \"string\") {\n      const formatString = mapFormatString(dateFormat);\n      const parsed = parse(value, formatString, new Date());\n      return !isNaN(parsed.getTime()) ? parsed : null;\n    }\n    if (typeof value === \"number\") {\n      const date = new Date(value);\n      return !isNaN(date.getTime()) ? date : null;\n    }\n    return null;\n  };\n\n  const handleClick = (e) => {\n    if (props.state === \"disabled\") return;\n\n    if (!e.target.closest(\".quill-ui-next-calendar\")) {\n      setIsOpen(!isOpen);\n    }\n  };\n\n  const handleChange = (date: Date) => {\n    const formatString = mapFormatString(dateFormat);\n    const formattedDate = format(date, formatString);\n    datepickerRef.current?.focus();\n    setValue(formattedDate);\n    props.onChange?.(formattedDate);\n    setTimeout(() => {\n      setIsOpen(false);\n    }, 100);\n  };\n\n  // Update custom react-datepicker iconss\n  useEffect(() => {\n    if (isOpen) {\n      const calendar = document.querySelector(\".quill-ui-next-calendar\");\n      const setNavIcon = (selector: string, icon: React.ReactNode) => {\n        const nav = calendar?.querySelector(selector);\n        if (nav) {\n          nav.innerHTML = \"\"; // Clear existing children\n          const container = document.createElement(\"span\");\n          nav.appendChild(container);\n          createRoot(container).render(icon);\n        }\n      };\n      setNavIcon(\n        \".react-calendar__navigation__prev-button\",\n        <IconButton\n          style=\"tertiary\"\n          size=\"sm\"\n          icon={<LabelPairedChevronLeftSmBoldIcon />}\n          color=\"blackWhite\"\n        />\n      );\n      setNavIcon(\n        \".react-calendar__navigation__next-button\",\n        <IconButton\n          size=\"sm\"\n          style=\"tertiary\"\n          icon={<LabelPairedChevronRightSmBoldIcon />}\n          color=\"blackWhite\"\n        />\n      );\n    }\n  }, [isOpen]);\n\n  useEffect(() => {\n    if (value && prevFormatRef.current !== dateFormat) {\n      // Parse using the previous format\n      const prevFormatString = mapFormatString(prevFormatRef.current);\n      const date = parse(value as string, prevFormatString, new Date());\n      if (!isNaN(date.getTime())) {\n        // Format to the new format\n        const newFormatString = mapFormatString(dateFormat);\n        const newValue = format(date, newFormatString);\n        setValue(newValue);\n        props.onChange?.(newValue);\n      }\n      prevFormatRef.current = dateFormat;\n    }\n  }, [dateFormat]);\n\n  useClickOutside(\n    datepickerRef,\n    () => {\n      setIsOpen(false);\n    },\n    [\"quill-ui-next-calendar\"]\n  );\n\n  return (\n    <TextFieldAtom\n      ref={datepickerRef as unknown as React.Ref<HTMLInputElement>}\n      {...props}\n      size={size}\n      allowTyping={false}\n      placeholder={dateFormat}\n      iconLeft={<LabelPairedCalendarSmBoldIcon />}\n      iconRight={\n        <LabelPairedChevronDownSmBoldIcon\n          className={`quill-ui-next-rotatable ${\n            isOpen && \"quill-ui-next-rotate\"\n          }`}\n        />\n      }\n      onChange={(e: string | number) => {\n        setValue(e);\n        props.onChange?.(e);\n      }}\n      onClick={handleClick}\n      value={value}\n      className={`${props.state !== \"disabled\" && \"quill-ui-next-pointer\"}`}\n      customContent={\n        <DropdownContainerAtom\n          width=\"fit-content\"\n          textAlignment={props.textAlignment}\n          parent={datepickerRef}\n          isOpen={isOpen}\n          offsetTop={\n            props.variant === \"labelless\" ? datepickerContainerOffets[size] : 35\n          }\n          onActionSheetClose={() => setIsOpen(false)}\n          customContent={\n            <Calendar\n              value={getValidDate(value, dateFormat)}\n              onChange={(value, event) => {\n                if (value instanceof Date) handleChange(value);\n              }}\n              locale=\"en-GB\"\n              showNeighboringMonth={false}\n              className=\"quill-ui-next-calendar\"\n              minDate={parseToDate(minDate)}\n              maxDate={parseToDate(maxDate)}\n            />\n          }\n        />\n      }\n    />\n  );\n};\n\nexport default Datepicker;\n"],"names":["dateFormat","value","createRoot"],"mappings":"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"}