{"version":3,"file":"flatpickr-year-select-plugin.mjs","sources":["../src/plugin.ts"],"sourcesContent":["import type { Instance as FlatpickrInstance } from 'flatpickr/dist/types/instance';\nimport type { Plugin } from 'flatpickr/dist/types/options';\n\n/**\n * Configuration options for the year dropdown plugin\n */\nexport interface YearDropdownPluginConfig {\n  /** Number of years to show before the current year (default: 3) */\n  start?: number;\n  /** Number of years to show after the current year (default: 3) */\n  end?: number;\n}\n\n/**\n * Extended flatpickr instance with year select container\n */\ninterface ExtendedInstance extends FlatpickrInstance {\n  yearSelectContainer?: HTMLElement;\n  _createElement: FlatpickrInstance['_createElement'];\n  parseDate: FlatpickrInstance['parseDate'];\n}\n\n/**\n * Creates a flatpickr plugin that replaces the default year input with a dropdown select\n *\n * @param pluginConfig - Configuration options for the year range\n * @returns A flatpickr plugin function\n *\n * @example\n * ```typescript\n * import flatpickr from 'flatpickr';\n * import yearSelectPlugin from 'flatpickr-year-select-plugin';\n * import 'flatpickr-year-select-plugin/dist/yearSelectPlugin.min.css';\n *\n * flatpickr(\"#myInput\", {\n *   plugins: [\n *     yearSelectPlugin({\n *       start: 5,  // Show 5 years before current\n *       end: 5     // Show 5 years after current\n *     })\n *   ]\n * });\n * ```\n */\nconst yearDropdownPlugin = function (pluginConfig?: YearDropdownPluginConfig): Plugin {\n  const baseConfig: YearDropdownPluginConfig = {\n    start: pluginConfig && pluginConfig.start !== undefined ? pluginConfig.start : 3,\n    end: pluginConfig && pluginConfig.end !== undefined ? pluginConfig.end : 3,\n  };\n\n  return function (fp: FlatpickrInstance) {\n    if (!fp) return {};\n\n    const extended = fp as ExtendedInstance;\n    const config: YearDropdownPluginConfig = { ...baseConfig };\n    const parseDateValue = (value: unknown): Date | undefined => {\n      if (!value) return undefined;\n      const parseSingle = (val: unknown): Date | undefined => {\n        if (!val) return undefined;\n        if (val instanceof Date) return isNaN(val.getTime()) ? undefined : val;\n        if (typeof val === 'string' || typeof val === 'number') {\n          const parsed = extended.parseDate ? extended.parseDate(val) : new Date(val);\n          return parsed && !isNaN(parsed.getTime()) ? parsed : undefined;\n        }\n        return undefined;\n      };\n\n      if (Array.isArray(value)) {\n        for (const entry of value) {\n          const parsed = parseSingle(entry);\n          if (parsed) return parsed;\n        }\n        return undefined;\n      }\n\n      return parseSingle(value);\n    };\n\n    const getYearBounds = () => {\n      const minDate = parseDateValue(extended.config.minDate);\n      const maxDate = parseDateValue(extended.config.maxDate);\n      const minYearRaw = minDate?.getFullYear();\n      const maxYearRaw = maxDate?.getFullYear();\n      const minYear =\n        minYearRaw !== undefined && maxYearRaw !== undefined\n          ? Math.min(minYearRaw, maxYearRaw)\n          : minYearRaw;\n      const maxYear =\n        minYearRaw !== undefined && maxYearRaw !== undefined\n          ? Math.max(minYearRaw, maxYearRaw)\n          : maxYearRaw;\n      return { minYear, maxYear };\n    };\n\n    const clampYear = (year: number) => {\n      const { minYear, maxYear } = getYearBounds();\n      if (minYear !== undefined && year < minYear) return minYear;\n      if (maxYear !== undefined && year > maxYear) return maxYear;\n      return year;\n    };\n    const getYearRange = (year: number) => {\n      const { minYear, maxYear } = getYearBounds();\n      const clampedYear = clampYear(year);\n      const rawStart = config.start !== undefined ? clampedYear - config.start : clampedYear;\n      const rawEnd = config.end !== undefined ? clampedYear + config.end : clampedYear;\n      const start = minYear !== undefined ? Math.max(rawStart, minYear) : rawStart;\n      const end = maxYear !== undefined ? Math.min(rawEnd, maxYear) : rawEnd;\n      return { clampedYear, start, end };\n    };\n\n    const resolveInitialYear = () => {\n      const selectedYear = fp.selectedDates?.[0]?.getFullYear();\n      const defaultDate = parseDateValue(fp.config.defaultDate);\n      const defaultYear =\n        defaultDate && !isNaN(defaultDate.getTime()) ? defaultDate.getFullYear() : undefined;\n\n      return clampYear(\n        extended.currentYear ?? selectedYear ?? defaultYear ?? new Date().getFullYear()\n      );\n    };\n    const initialYear = resolveInitialYear();\n\n    const yearWrapper = document.createElement('div');\n    yearWrapper.classList.add('flatpickr-current-year');\n    const yearDropdown = document.createElement('select');\n    yearDropdown.classList.add('flatpickr-monthDropdown-years');\n    yearDropdown.setAttribute('aria-label', 'Year');\n    yearDropdown.setAttribute('name', 'year');\n    let suppressNextYearChange = false;\n\n    const createSelectElement = function (year: number) {\n      yearDropdown.innerHTML = '';\n\n      const { clampedYear, start, end } = getYearRange(year);\n\n      for (let i = start; i <= end; i++) {\n        const option = document.createElement('option');\n        option.value = String(i);\n        option.text = String(i);\n        yearDropdown.appendChild(option);\n      }\n      yearDropdown.value = String(clampedYear);\n      return clampedYear;\n    };\n\n    extended.yearSelectContainer = extended._createElement('div', 'flatpickr-years', '');\n\n    createSelectElement(initialYear);\n\n    yearDropdown.addEventListener('change', function (evt) {\n      const target = evt.target as HTMLSelectElement;\n      if (!target) return;\n      const year = target.options[target.selectedIndex].value;\n\n      extended.changeYear(Number(year));\n      extended.redraw();\n    });\n\n    yearWrapper.append(yearDropdown);\n    if (extended.yearSelectContainer) {\n      extended.yearSelectContainer.append(yearWrapper);\n    }\n\n    return {\n      onReady: function onReady() {\n        if (!extended.monthNav || !extended.calendarContainer) {\n          console.warn('flatpickr-year-select-plugin: Required elements not found');\n          return;\n        }\n\n        const name = extended.monthNav.className;\n        const yearInputCollection = extended.calendarContainer.getElementsByClassName(name);\n        const el = yearInputCollection[0];\n        if (!el || !el.parentNode || !extended.yearSelectContainer) return;\n        el.parentNode.insertBefore(extended.yearSelectContainer, el.parentNode.firstChild);\n\n        const { start, end } = getYearRange(initialYear);\n\n        if (!extended.config.minDate) extended.set('minDate', `${start}-01-01`);\n        if (!extended.config.maxDate) extended.set('maxDate', `${end}-12-31`);\n      },\n      onOpen: function onOpen(\n        _selectedDates: Date[],\n        _dateStr: string,\n        instance: FlatpickrInstance\n      ) {\n        const clampedYear = createSelectElement(instance.currentYear);\n        if (clampedYear !== instance.currentYear) {\n          suppressNextYearChange = true;\n          extended.changeYear(clampedYear);\n          extended.redraw();\n          suppressNextYearChange = false;\n        }\n      },\n      onYearChange: function onYearChange(\n        _selectedDates: Date[],\n        _dateStr: string,\n        instance: FlatpickrInstance\n      ) {\n        if (suppressNextYearChange) {\n          suppressNextYearChange = false;\n          createSelectElement(instance.currentYear);\n          return;\n        }\n        const clampedYear = createSelectElement(instance.currentYear);\n        if (clampedYear !== instance.currentYear) {\n          suppressNextYearChange = true;\n          extended.changeYear(clampedYear);\n          extended.redraw();\n          suppressNextYearChange = false;\n        }\n      },\n    };\n  };\n};\n\nexport default yearDropdownPlugin;\n"],"names":["yearDropdownPlugin","pluginConfig","baseConfig","fp","extended","config","parseDateValue","value","parseSingle","val","parsed","entry","getYearBounds","minDate","maxDate","minYearRaw","maxYearRaw","minYear","maxYear","clampYear","year","getYearRange","clampedYear","rawStart","rawEnd","start","end","initialYear","selectedYear","defaultDate","defaultYear","yearWrapper","yearDropdown","suppressNextYearChange","createSelectElement","i","option","evt","target","name","el","_selectedDates","_dateStr","instance"],"mappings":"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"}