@reachweb/alpine-calendar 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alpine-calendar.es.js","sources":["../src/core/calendar-date.ts","../src/core/constraints.ts","../src/core/grid.ts","../src/core/selection.ts","../src/input/formatter.ts","../src/input/parser.ts","../src/input/mask.ts","../src/plugin/template.ts","../src/plugin/calendar-component.ts","../src/core/presets.ts","../src/positioning/popup.ts","../src/index.ts"],"sourcesContent":["/**\n * CalendarDate — a timezone-safe date value object.\n *\n * Stores year/month/day as plain integers. No internal `Date` object.\n * The only place we touch native `Date` / `Intl.DateTimeFormat` is in\n * `toNativeDate()`, `fromNativeDate()`, `today()`, and `format()`.\n */\nexport class CalendarDate {\n readonly year: number\n readonly month: number // 1-12\n readonly day: number // 1-31\n\n constructor(year: number, month: number, day: number) {\n this.year = year\n this.month = month\n this.day = day\n }\n\n // ---------------------------------------------------------------------------\n // Factory methods\n // ---------------------------------------------------------------------------\n\n /** Resolve \"today\" in a given IANA timezone (fallback: browser default). */\n static today(timezone?: string): CalendarDate {\n const now = new Date()\n if (timezone) {\n return CalendarDate.fromNativeDate(now, timezone)\n }\n return new CalendarDate(now.getFullYear(), now.getMonth() + 1, now.getDate())\n }\n\n /** Create from a native Date, interpreting it in the given timezone. */\n static fromNativeDate(date: Date, timezone?: string): CalendarDate {\n if (timezone) {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n }).formatToParts(date)\n\n let year = 0\n let month = 0\n let day = 0\n for (const part of parts) {\n if (part.type === 'year') year = Number(part.value)\n else if (part.type === 'month') month = Number(part.value)\n else if (part.type === 'day') day = Number(part.value)\n }\n return new CalendarDate(year, month, day)\n }\n return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate())\n }\n\n /** Create from an ISO string (YYYY-MM-DD). Returns null for invalid formats or out-of-range values. */\n static fromISO(iso: string): CalendarDate | null {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(iso)\n if (!match) return null\n const year = Number(match[1])\n const month = Number(match[2])\n const day = Number(match[3])\n if (month < 1 || month > 12) return null\n if (day < 1 || day > daysInMonth(year, month)) return null\n return new CalendarDate(year, month, day)\n }\n\n // ---------------------------------------------------------------------------\n // Serialization\n // ---------------------------------------------------------------------------\n\n /** Convert to a native Date (midnight local time). */\n toNativeDate(): Date {\n return new Date(this.year, this.month - 1, this.day)\n }\n\n /** Serialize to ISO string YYYY-MM-DD. */\n toISO(): string {\n const y = String(this.year).padStart(4, '0')\n const m = String(this.month).padStart(2, '0')\n const d = String(this.day).padStart(2, '0')\n return `${y}-${m}-${d}`\n }\n\n /** Unique string key for use in Sets/Maps. */\n toKey(): string {\n return this.toISO()\n }\n\n // ---------------------------------------------------------------------------\n // Comparison helpers\n // ---------------------------------------------------------------------------\n\n isSame(other: CalendarDate): boolean {\n return this.year === other.year && this.month === other.month && this.day === other.day\n }\n\n isBefore(other: CalendarDate): boolean {\n if (this.year !== other.year) return this.year < other.year\n if (this.month !== other.month) return this.month < other.month\n return this.day < other.day\n }\n\n isAfter(other: CalendarDate): boolean {\n if (this.year !== other.year) return this.year > other.year\n if (this.month !== other.month) return this.month > other.month\n return this.day > other.day\n }\n\n /** Inclusive range check: start <= this <= end. */\n isBetween(start: CalendarDate, end: CalendarDate): boolean {\n return !this.isBefore(start) && !this.isAfter(end)\n }\n\n /**\n * Number of days from this date to another.\n * Positive when `other` is after `this`, negative when before.\n * Uses UTC to avoid DST issues.\n */\n diffDays(other: CalendarDate): number {\n const a = Date.UTC(this.year, this.month - 1, this.day)\n const b = Date.UTC(other.year, other.month - 1, other.day)\n return Math.round((b - a) / 86_400_000)\n }\n\n // ---------------------------------------------------------------------------\n // Arithmetic (returns new CalendarDate — immutable)\n // ---------------------------------------------------------------------------\n\n addDays(days: number): CalendarDate {\n const d = this.toNativeDate()\n d.setDate(d.getDate() + days)\n return CalendarDate.fromNativeDate(d)\n }\n\n /** Add months with day clamping (e.g. Jan 31 + 1 month = Feb 28/29). */\n addMonths(months: number): CalendarDate {\n let newMonth = this.month - 1 + months\n const newYear = this.year + Math.floor(newMonth / 12)\n newMonth = ((newMonth % 12) + 12) % 12 // normalize to 0-11\n const maxDay = daysInMonth(newYear, newMonth + 1)\n const newDay = Math.min(this.day, maxDay)\n return new CalendarDate(newYear, newMonth + 1, newDay)\n }\n\n addYears(years: number): CalendarDate {\n const maxDay = daysInMonth(this.year + years, this.month)\n const newDay = Math.min(this.day, maxDay)\n return new CalendarDate(this.year + years, this.month, newDay)\n }\n\n startOfMonth(): CalendarDate {\n return new CalendarDate(this.year, this.month, 1)\n }\n\n endOfMonth(): CalendarDate {\n return new CalendarDate(this.year, this.month, daysInMonth(this.year, this.month))\n }\n\n // ---------------------------------------------------------------------------\n // Formatting\n // ---------------------------------------------------------------------------\n\n /**\n * Format the date using Intl.DateTimeFormat options.\n *\n * @param options - Intl.DateTimeFormat options (e.g. { month: 'long', year: 'numeric' })\n * @param locale - BCP 47 locale string (default: browser locale)\n */\n format(options: Intl.DateTimeFormatOptions, locale?: string): string {\n const d = this.toNativeDate()\n return new Intl.DateTimeFormat(locale, options).format(d)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Return the number of days in a given month (1-12). */\nexport function daysInMonth(year: number, month: number): number {\n // Day 0 of the next month = last day of this month\n return new Date(year, month, 0).getDate()\n}\n\n/**\n * Return the ISO 8601 week number for a given date.\n *\n * ISO weeks start on Monday. Week 1 is the week containing the year's first Thursday.\n * Returns a number between 1 and 53.\n */\nexport function getISOWeekNumber(date: CalendarDate): number {\n const d = new Date(Date.UTC(date.year, date.month - 1, date.day))\n // ISO day: Monday=1, Sunday=7\n const dayNum = d.getUTCDay() || 7\n // Set to the Thursday of this ISO week\n d.setUTCDate(d.getUTCDate() + 4 - dayNum)\n // January 1st of that Thursday's year\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1))\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7)\n}\n","import { CalendarDate } from './calendar-date'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Constraint properties that can be set globally or overridden per rule.\n *\n * All properties are optional — only specified constraints are enforced.\n */\nexport interface DateConstraintProperties {\n /** Earliest selectable date (inclusive). */\n minDate?: CalendarDate\n /** Latest selectable date (inclusive). */\n maxDate?: CalendarDate\n /** Specific dates to disable (blacklist). */\n disabledDates?: CalendarDate[]\n /** Days of the week to disable (0 = Sunday, 1 = Monday, …, 6 = Saturday). */\n disabledDaysOfWeek?: number[]\n /** Specific dates to force-enable (overrides disabledDates and disabledDaysOfWeek). */\n enabledDates?: CalendarDate[]\n /** Days of the week to enable (whitelist — all other days are disabled). */\n enabledDaysOfWeek?: number[]\n /** Specific months to disable (1 = January, …, 12 = December). */\n disabledMonths?: number[]\n /** Months to enable (whitelist — all other months are disabled). */\n enabledMonths?: number[]\n /** Specific years to disable. */\n disabledYears?: number[]\n /** Years to enable (whitelist — all other years are disabled). */\n enabledYears?: number[]\n /** Minimum range length in days (inclusive). Only used in range mode. */\n minRange?: number\n /** Maximum range length in days (inclusive). Only used in range mode. */\n maxRange?: number\n}\n\n/**\n * A period-specific constraint rule that overrides global settings.\n *\n * When checking a date, matching rules are resolved by priority (highest wins).\n * Among rules with equal priority, the first matching rule wins (array order).\n * Unset properties inherit from the global configuration.\n *\n * Rules can match by date range (`from`/`to`) or by recurring months\n * (`months`). If `months` is set, the rule applies to those months\n * every year without needing explicit date ranges.\n */\nexport interface DateConstraintRule extends DateConstraintProperties {\n /** Start of the period this rule applies to (inclusive). */\n from?: CalendarDate\n /** End of the period this rule applies to (inclusive). */\n to?: CalendarDate\n /** Recurring months this rule applies to (1=Jan, …, 12=Dec). Matches every year. */\n months?: number[]\n /** Priority for conflict resolution. Higher values win. Default: 0. */\n priority?: number\n}\n\n/**\n * Full constraint configuration with global defaults and optional period rules.\n *\n * Backward compatible: all original properties (minDate, maxDate,\n * disabledDates, disabledDaysOfWeek) continue to work as before.\n */\nexport interface DateConstraintOptions extends DateConstraintProperties {\n /** Period-specific constraint overrides. Highest priority matching rule wins; ties broken by array order. */\n rules?: DateConstraintRule[]\n}\n\n// ---------------------------------------------------------------------------\n// Precomputation\n// ---------------------------------------------------------------------------\n\ninterface PrecomputedSets {\n disabledKeys: Set<string> | undefined\n disabledDays: Set<number> | undefined\n enabledKeys: Set<string> | undefined\n enabledDays: Set<number> | undefined\n disabledMonths: Set<number> | undefined\n enabledMonths: Set<number> | undefined\n disabledYears: Set<number> | undefined\n enabledYears: Set<number> | undefined\n}\n\ninterface PrecomputedRule {\n from: CalendarDate | undefined\n to: CalendarDate | undefined\n recurringMonths: Set<number> | undefined\n minDate: CalendarDate | undefined\n maxDate: CalendarDate | undefined\n minRange: number | undefined\n maxRange: number | undefined\n sets: PrecomputedSets\n hasMinDate: boolean\n hasMaxDate: boolean\n priority: number\n originalIndex: number\n}\n\nfunction precomputeSets(opts: DateConstraintProperties): PrecomputedSets {\n return {\n disabledKeys: opts.disabledDates\n ? new Set(opts.disabledDates.map((d) => d.toKey()))\n : undefined,\n disabledDays: opts.disabledDaysOfWeek ? new Set(opts.disabledDaysOfWeek) : undefined,\n enabledKeys: opts.enabledDates ? new Set(opts.enabledDates.map((d) => d.toKey())) : undefined,\n enabledDays: opts.enabledDaysOfWeek ? new Set(opts.enabledDaysOfWeek) : undefined,\n disabledMonths: opts.disabledMonths ? new Set(opts.disabledMonths) : undefined,\n enabledMonths: opts.enabledMonths ? new Set(opts.enabledMonths) : undefined,\n disabledYears: opts.disabledYears ? new Set(opts.disabledYears) : undefined,\n enabledYears: opts.enabledYears ? new Set(opts.enabledYears) : undefined,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core disabled check\n// ---------------------------------------------------------------------------\n\nfunction checkDisabled(\n date: CalendarDate,\n minDate: CalendarDate | undefined,\n maxDate: CalendarDate | undefined,\n sets: PrecomputedSets,\n): boolean {\n // 1. Boundary check (absolute — always enforced)\n if (minDate && date.isBefore(minDate)) return true\n if (maxDate && date.isAfter(maxDate)) return true\n\n // 2. enabledDates force-enables specific dates (bypass all other checks)\n if (sets.enabledKeys && sets.enabledKeys.has(date.toKey())) return false\n\n // 3. Year-level constraints\n if (sets.enabledYears && !sets.enabledYears.has(date.year)) return true\n if (sets.disabledYears && sets.disabledYears.has(date.year)) return true\n\n // 4. Month-level constraints\n if (sets.enabledMonths && !sets.enabledMonths.has(date.month)) return true\n if (sets.disabledMonths && sets.disabledMonths.has(date.month)) return true\n\n // Compute day-of-week once if needed\n const needsDow = sets.enabledDays !== undefined || sets.disabledDays !== undefined\n const dow = needsDow ? date.toNativeDate().getDay() : -1\n\n // 5. enabledDaysOfWeek whitelist — if set, only these days are allowed\n if (sets.enabledDays && !sets.enabledDays.has(dow)) return true\n\n // 6. disabledDates blacklist\n if (sets.disabledKeys && sets.disabledKeys.has(date.toKey())) return true\n\n // 7. disabledDaysOfWeek blacklist\n if (sets.disabledDays && sets.disabledDays.has(dow)) return true\n\n return false\n}\n\n// ---------------------------------------------------------------------------\n// Rule matching\n// ---------------------------------------------------------------------------\n\n/** Check if a date matches a precomputed rule (date-range or recurring months). */\nfunction matchesRule(rule: PrecomputedRule, date: CalendarDate): boolean {\n // Date-range rule: from/to both set\n if (rule.from && rule.to) {\n return date.isBetween(rule.from, rule.to)\n }\n // Recurring months rule\n if (rule.recurringMonths) {\n return rule.recurringMonths.has(date.month)\n }\n return false\n}\n\n/**\n * Find the best matching rule for a date: highest priority wins,\n * ties broken by original array order (first match).\n */\nfunction findBestRule(rules: PrecomputedRule[], date: CalendarDate): PrecomputedRule | undefined {\n let best: PrecomputedRule | undefined\n for (const rule of rules) {\n if (!matchesRule(rule, date)) continue\n if (!best || rule.priority > best.priority) {\n best = rule\n }\n // Equal priority: first match wins (lower originalIndex)\n // Since we iterate in order, first found at a given priority is kept\n }\n return best\n}\n\n// ---------------------------------------------------------------------------\n// createDateConstraint\n// ---------------------------------------------------------------------------\n\n/**\n * Create a single `isDateDisabled` function from a set of constraint options.\n *\n * The returned function checks all configured constraints (including\n * period-specific rules) and returns `true` if the date should be\n * disabled (not selectable).\n *\n * @example\n * ```ts\n * const isDisabled = createDateConstraint({\n * minDate: new CalendarDate(2025, 1, 1),\n * maxDate: new CalendarDate(2025, 12, 31),\n * disabledDaysOfWeek: [0, 6],\n * rules: [{\n * from: new CalendarDate(2025, 6, 1),\n * to: new CalendarDate(2025, 8, 31),\n * enabledDaysOfWeek: [1, 2, 3, 4, 5], // weekdays only in summer\n * }],\n * })\n * ```\n */\nexport function createDateConstraint(\n options: DateConstraintOptions,\n): (date: CalendarDate) => boolean {\n const { minDate, maxDate, rules } = options\n\n // Precompute global sets\n const globalSets = precomputeSets(options)\n\n // Precompute rule sets\n const precomputedRules: PrecomputedRule[] | undefined = rules?.map((rule, index) => ({\n from: rule.from,\n to: rule.to,\n recurringMonths: rule.months ? new Set(rule.months) : undefined,\n minDate: rule.minDate,\n maxDate: rule.maxDate,\n minRange: rule.minRange,\n maxRange: rule.maxRange,\n sets: precomputeSets(rule),\n hasMinDate: rule.minDate !== undefined,\n hasMaxDate: rule.maxDate !== undefined,\n priority: rule.priority ?? 0,\n originalIndex: index,\n }))\n\n // Fast path: no rules\n if (!precomputedRules || precomputedRules.length === 0) {\n return (date: CalendarDate): boolean => checkDisabled(date, minDate, maxDate, globalSets)\n }\n\n // With rules: find the best matching rule (highest priority), merge, and check\n return (date: CalendarDate): boolean => {\n const rule = findBestRule(precomputedRules, date)\n\n if (!rule) {\n return checkDisabled(date, minDate, maxDate, globalSets)\n }\n\n // Rule overrides global where explicitly set\n const effectiveMinDate = rule.hasMinDate ? rule.minDate : minDate\n const effectiveMaxDate = rule.hasMaxDate ? rule.maxDate : maxDate\n\n const mergedSets: PrecomputedSets = {\n disabledKeys:\n rule.sets.disabledKeys !== undefined ? rule.sets.disabledKeys : globalSets.disabledKeys,\n disabledDays:\n rule.sets.disabledDays !== undefined ? rule.sets.disabledDays : globalSets.disabledDays,\n enabledKeys:\n rule.sets.enabledKeys !== undefined ? rule.sets.enabledKeys : globalSets.enabledKeys,\n enabledDays:\n rule.sets.enabledDays !== undefined ? rule.sets.enabledDays : globalSets.enabledDays,\n disabledMonths:\n rule.sets.disabledMonths !== undefined\n ? rule.sets.disabledMonths\n : globalSets.disabledMonths,\n enabledMonths:\n rule.sets.enabledMonths !== undefined ? rule.sets.enabledMonths : globalSets.enabledMonths,\n disabledYears:\n rule.sets.disabledYears !== undefined ? rule.sets.disabledYears : globalSets.disabledYears,\n enabledYears:\n rule.sets.enabledYears !== undefined ? rule.sets.enabledYears : globalSets.enabledYears,\n }\n\n return checkDisabled(date, effectiveMinDate, effectiveMaxDate, mergedSets)\n }\n}\n\n// ---------------------------------------------------------------------------\n// createRangeValidator\n// ---------------------------------------------------------------------------\n\n/**\n * Create a range validation function.\n *\n * Returns a function that checks whether a range [start, end] satisfies\n * the minRange/maxRange constraints. Rule matching is based on the\n * start date — the rule that contains the start date determines the\n * applicable range limits.\n *\n * Range length is counted inclusively: a range from Jan 1 to Jan 3 is\n * 3 days long.\n *\n * @example\n * ```ts\n * const isValid = createRangeValidator({\n * minRange: 3,\n * maxRange: 14,\n * rules: [{\n * from: new CalendarDate(2025, 5, 1),\n * to: new CalendarDate(2025, 10, 31),\n * minRange: 5, // stricter minimum in summer\n * }],\n * })\n *\n * isValid(new CalendarDate(2025, 3, 1), new CalendarDate(2025, 3, 3)) // true (3 >= 3)\n * isValid(new CalendarDate(2025, 6, 1), new CalendarDate(2025, 6, 3)) // false (3 < 5)\n * ```\n */\nexport function createRangeValidator(\n options: DateConstraintOptions,\n): (start: CalendarDate, end: CalendarDate) => boolean {\n const { minRange, maxRange, rules } = options\n\n // No range constraints at all → always valid\n if (\n minRange === undefined &&\n maxRange === undefined &&\n (!rules || rules.every((r) => r.minRange === undefined && r.maxRange === undefined))\n ) {\n return () => true\n }\n\n // Precompute rules for range validation (reuse PrecomputedRule for findBestRule)\n const rangeRules: PrecomputedRule[] | undefined = rules?.map((rule, index) => ({\n from: rule.from,\n to: rule.to,\n recurringMonths: rule.months ? new Set(rule.months) : undefined,\n minDate: rule.minDate,\n maxDate: rule.maxDate,\n minRange: rule.minRange,\n maxRange: rule.maxRange,\n sets: precomputeSets(rule),\n hasMinDate: rule.minDate !== undefined,\n hasMaxDate: rule.maxDate !== undefined,\n priority: rule.priority ?? 0,\n originalIndex: index,\n }))\n\n return (start: CalendarDate, end: CalendarDate): boolean => {\n // Find rule based on start date (highest priority wins)\n let effectiveMinRange = minRange\n let effectiveMaxRange = maxRange\n\n if (rangeRules) {\n const rule = findBestRule(rangeRules, start)\n if (rule) {\n if (rule.minRange !== undefined) effectiveMinRange = rule.minRange\n if (rule.maxRange !== undefined) effectiveMaxRange = rule.maxRange\n }\n }\n\n // Inclusive day count\n const length = start.diffDays(end) + 1\n\n if (effectiveMinRange !== undefined && length < effectiveMinRange) return false\n if (effectiveMaxRange !== undefined && length > effectiveMaxRange) return false\n\n return true\n }\n}\n\n// ---------------------------------------------------------------------------\n// createMonthConstraint\n// ---------------------------------------------------------------------------\n\n/**\n * Create a single `isMonthDisabled` function from constraint options.\n *\n * A month is disabled when:\n * 1. The entire month falls outside [minDate, maxDate].\n * 2. The year is disabled (via disabledYears or not in enabledYears).\n * 3. The month number is disabled (via disabledMonths or not in enabledMonths).\n *\n * @example\n * ```ts\n * const isDisabled = createMonthConstraint({\n * minDate: new CalendarDate(2025, 3, 1),\n * disabledMonths: [1, 2], // no January or February\n * })\n * isDisabled(2025, 1) // true (January disabled)\n * isDisabled(2025, 6) // false\n * ```\n */\nexport function createMonthConstraint(\n options: DateConstraintOptions,\n): (year: number, month: number) => boolean {\n const { minDate, maxDate } = options\n\n const disabledMonthSet = options.disabledMonths ? new Set(options.disabledMonths) : undefined\n const enabledMonthSet = options.enabledMonths ? new Set(options.enabledMonths) : undefined\n const disabledYearSet = options.disabledYears ? new Set(options.disabledYears) : undefined\n const enabledYearSet = options.enabledYears ? new Set(options.enabledYears) : undefined\n\n return (year: number, month: number): boolean => {\n // 1. Boundary: entire month outside [minDate, maxDate]\n if (minDate) {\n const endOfMonth = new CalendarDate(year, month, 1).endOfMonth()\n if (endOfMonth.isBefore(minDate)) return true\n }\n if (maxDate) {\n const startOfMonth = new CalendarDate(year, month, 1)\n if (startOfMonth.isAfter(maxDate)) return true\n }\n\n // 2. Year constraints cascade to months\n if (enabledYearSet && !enabledYearSet.has(year)) return true\n if (disabledYearSet && disabledYearSet.has(year)) return true\n\n // 3. Month constraints\n if (enabledMonthSet && !enabledMonthSet.has(month)) return true\n if (disabledMonthSet && disabledMonthSet.has(month)) return true\n\n return false\n }\n}\n\n// ---------------------------------------------------------------------------\n// createYearConstraint\n// ---------------------------------------------------------------------------\n\n/**\n * Create a single `isYearDisabled` function from constraint options.\n *\n * A year is disabled when:\n * 1. The entire year falls outside [minDate, maxDate].\n * 2. The year is in disabledYears or not in enabledYears.\n *\n * @example\n * ```ts\n * const isDisabled = createYearConstraint({\n * disabledYears: [2020, 2021],\n * })\n * isDisabled(2020) // true\n * isDisabled(2025) // false\n * ```\n */\nexport function createYearConstraint(\n options: DateConstraintOptions,\n): (year: number) => boolean {\n const { minDate, maxDate } = options\n\n const disabledYearSet = options.disabledYears ? new Set(options.disabledYears) : undefined\n const enabledYearSet = options.enabledYears ? new Set(options.enabledYears) : undefined\n\n return (year: number): boolean => {\n // 1. Boundary: entire year outside [minDate, maxDate]\n if (minDate) {\n const endOfYear = new CalendarDate(year, 12, 31)\n if (endOfYear.isBefore(minDate)) return true\n }\n if (maxDate) {\n const startOfYear = new CalendarDate(year, 1, 1)\n if (startOfYear.isAfter(maxDate)) return true\n }\n\n // 2. Year constraints\n if (enabledYearSet && !enabledYearSet.has(year)) return true\n if (disabledYearSet && disabledYearSet.has(year)) return true\n\n return false\n }\n}\n\n// ---------------------------------------------------------------------------\n// Convenience\n// ---------------------------------------------------------------------------\n\n/**\n * Standalone check: is a date disabled by the given constraints?\n *\n * Convenience wrapper around `createDateConstraint` for one-off checks.\n */\nexport function isDateDisabled(date: CalendarDate, options: DateConstraintOptions): boolean {\n return createDateConstraint(options)(date)\n}\n\n// ---------------------------------------------------------------------------\n// Constraint messages (configurable tooltip text)\n// ---------------------------------------------------------------------------\n\n/**\n * Custom messages for each constraint reason. All properties are optional —\n * defaults are used for any omitted keys.\n */\nexport interface ConstraintMessages {\n beforeMinDate?: string\n afterMaxDate?: string\n disabledDate?: string\n disabledDayOfWeek?: string\n disabledMonth?: string\n disabledYear?: string\n notEnabledDate?: string\n notEnabledDayOfWeek?: string\n notEnabledMonth?: string\n notEnabledYear?: string\n}\n\nconst DEFAULT_MESSAGES: Required<ConstraintMessages> = {\n beforeMinDate: 'Before the earliest available date',\n afterMaxDate: 'After the latest available date',\n disabledDate: 'This date is not available',\n disabledDayOfWeek: 'This day of the week is not available',\n disabledMonth: 'This month is not available',\n disabledYear: 'This year is not available',\n notEnabledDate: 'This date is not available',\n notEnabledDayOfWeek: 'This day of the week is not available',\n notEnabledMonth: 'This month is not available',\n notEnabledYear: 'This year is not available',\n}\n\n// ---------------------------------------------------------------------------\n// createDisabledReasons\n// ---------------------------------------------------------------------------\n\nfunction collectReasons(\n date: CalendarDate,\n minDate: CalendarDate | undefined,\n maxDate: CalendarDate | undefined,\n sets: PrecomputedSets,\n msgs: Required<ConstraintMessages>,\n): string[] {\n const reasons: string[] = []\n\n // 1. Boundary check\n if (minDate && date.isBefore(minDate)) {\n reasons.push(msgs.beforeMinDate)\n return reasons // absolute — no further checks\n }\n if (maxDate && date.isAfter(maxDate)) {\n reasons.push(msgs.afterMaxDate)\n return reasons // absolute — no further checks\n }\n\n // 2. enabledDates force-enables (bypass)\n if (sets.enabledKeys && sets.enabledKeys.has(date.toKey())) return reasons\n\n // 3. Year-level\n if (sets.enabledYears && !sets.enabledYears.has(date.year)) {\n reasons.push(msgs.notEnabledYear)\n return reasons\n }\n if (sets.disabledYears && sets.disabledYears.has(date.year)) {\n reasons.push(msgs.disabledYear)\n return reasons\n }\n\n // 4. Month-level\n if (sets.enabledMonths && !sets.enabledMonths.has(date.month)) {\n reasons.push(msgs.notEnabledMonth)\n return reasons\n }\n if (sets.disabledMonths && sets.disabledMonths.has(date.month)) {\n reasons.push(msgs.disabledMonth)\n return reasons\n }\n\n // 5. Day-of-week\n const needsDow = sets.enabledDays !== undefined || sets.disabledDays !== undefined\n const dow = needsDow ? date.toNativeDate().getDay() : -1\n\n if (sets.enabledDays && !sets.enabledDays.has(dow)) {\n reasons.push(msgs.notEnabledDayOfWeek)\n }\n\n // 6. Specific dates\n if (sets.disabledKeys && sets.disabledKeys.has(date.toKey())) {\n reasons.push(msgs.disabledDate)\n }\n\n // 7. Day-of-week blacklist\n if (sets.disabledDays && sets.disabledDays.has(dow)) {\n reasons.push(msgs.disabledDayOfWeek)\n }\n\n return reasons\n}\n\n/**\n * Create a function that returns human-readable reasons why a date is\n * disabled. Returns an empty array for enabled dates.\n *\n * Uses the same logic as `createDateConstraint` (including period-specific\n * rules) but produces descriptive messages instead of a boolean.\n *\n * @example\n * ```ts\n * const getReasons = createDisabledReasons({\n * minDate: new CalendarDate(2025, 3, 1),\n * disabledDaysOfWeek: [0, 6],\n * })\n * getReasons(new CalendarDate(2025, 2, 28))\n * // → ['Before the earliest available date']\n * getReasons(new CalendarDate(2025, 3, 1))\n * // → [] (enabled)\n * getReasons(new CalendarDate(2025, 3, 2))\n * // → ['This day of the week is not available'] (Sunday)\n * ```\n */\nexport function createDisabledReasons(\n options: DateConstraintOptions,\n messages?: ConstraintMessages,\n): (date: CalendarDate) => string[] {\n const { minDate, maxDate, rules } = options\n const msgs = { ...DEFAULT_MESSAGES, ...messages }\n\n // Precompute global sets\n const globalSets = precomputeSets(options)\n\n // Precompute rule sets\n const precomputedRules: PrecomputedRule[] | undefined = rules?.map((rule, index) => ({\n from: rule.from,\n to: rule.to,\n recurringMonths: rule.months ? new Set(rule.months) : undefined,\n minDate: rule.minDate,\n maxDate: rule.maxDate,\n minRange: rule.minRange,\n maxRange: rule.maxRange,\n sets: precomputeSets(rule),\n hasMinDate: rule.minDate !== undefined,\n hasMaxDate: rule.maxDate !== undefined,\n priority: rule.priority ?? 0,\n originalIndex: index,\n }))\n\n // Fast path: no rules\n if (!precomputedRules || precomputedRules.length === 0) {\n return (date: CalendarDate) => collectReasons(date, minDate, maxDate, globalSets, msgs)\n }\n\n // With rules (highest priority wins)\n return (date: CalendarDate): string[] => {\n const rule = findBestRule(precomputedRules, date)\n\n if (!rule) {\n return collectReasons(date, minDate, maxDate, globalSets, msgs)\n }\n\n const effectiveMinDate = rule.hasMinDate ? rule.minDate : minDate\n const effectiveMaxDate = rule.hasMaxDate ? rule.maxDate : maxDate\n\n const mergedSets: PrecomputedSets = {\n disabledKeys:\n rule.sets.disabledKeys !== undefined ? rule.sets.disabledKeys : globalSets.disabledKeys,\n disabledDays:\n rule.sets.disabledDays !== undefined ? rule.sets.disabledDays : globalSets.disabledDays,\n enabledKeys:\n rule.sets.enabledKeys !== undefined ? rule.sets.enabledKeys : globalSets.enabledKeys,\n enabledDays:\n rule.sets.enabledDays !== undefined ? rule.sets.enabledDays : globalSets.enabledDays,\n disabledMonths:\n rule.sets.disabledMonths !== undefined\n ? rule.sets.disabledMonths\n : globalSets.disabledMonths,\n enabledMonths:\n rule.sets.enabledMonths !== undefined ? rule.sets.enabledMonths : globalSets.enabledMonths,\n disabledYears:\n rule.sets.disabledYears !== undefined ? rule.sets.disabledYears : globalSets.disabledYears,\n enabledYears:\n rule.sets.enabledYears !== undefined ? rule.sets.enabledYears : globalSets.enabledYears,\n }\n\n return collectReasons(date, effectiveMinDate, effectiveMaxDate, mergedSets, msgs)\n }\n}\n","import { CalendarDate, getISOWeekNumber } from './calendar-date'\n\n/** Metadata for a single day cell in the calendar grid. */\nexport interface DayCell {\n date: CalendarDate\n isCurrentMonth: boolean\n isToday: boolean\n isDisabled: boolean\n}\n\n/** A single month grid: always 6 rows × 7 cols. */\nexport interface MonthGrid {\n year: number\n month: number\n rows: DayCell[][]\n /** ISO 8601 week numbers — one per row (6 entries). */\n weekNumbers: number[]\n}\n\n/**\n * Generate a 6×7 calendar grid for a given month.\n *\n * @param year - Full year (e.g. 2025)\n * @param month - Month 1-12\n * @param firstDayOfWeek - 0 = Sunday, 1 = Monday, …, 6 = Saturday\n * @param today - Reference date for \"isToday\" marking (defaults to CalendarDate.today())\n * @param isDisabled - Optional callback to mark dates as disabled\n */\nexport function generateMonth(\n year: number,\n month: number,\n firstDayOfWeek = 0,\n today?: CalendarDate,\n isDisabled?: (date: CalendarDate) => boolean,\n): MonthGrid {\n const todayRef = today ?? CalendarDate.today()\n const disabledFn = isDisabled ?? (() => false)\n\n // First day of the target month\n const firstOfMonth = new CalendarDate(year, month, 1)\n // Day of week for the 1st (0=Sun, 1=Mon, …)\n const firstDow = firstOfMonth.toNativeDate().getDay()\n\n // How many leading days from the previous month?\n // offset = (firstDow - firstDayOfWeek + 7) % 7\n const offset = (firstDow - firstDayOfWeek + 7) % 7\n\n // Start date: go back `offset` days from the 1st\n const gridStart = firstOfMonth.addDays(-offset)\n\n const rows: DayCell[][] = []\n const weekNumbers: number[] = []\n\n for (let row = 0; row < 6; row++) {\n const cells: DayCell[] = []\n for (let col = 0; col < 7; col++) {\n const dayIndex = row * 7 + col\n const date = gridStart.addDays(dayIndex)\n cells.push({\n date,\n isCurrentMonth: date.month === month && date.year === year,\n isToday: date.isSame(todayRef),\n isDisabled: disabledFn(date),\n })\n }\n // Week number from the first date in the row\n const firstCell = cells[0]\n if (firstCell) weekNumbers.push(getISOWeekNumber(firstCell.date))\n rows.push(cells)\n }\n\n return { year, month, rows, weekNumbers }\n}\n\n// ---------------------------------------------------------------------------\n// Month view grid (3×4 of month cells)\n// ---------------------------------------------------------------------------\n\n/** Metadata for a single month cell in the month picker view. */\nexport interface MonthCell {\n /** Month number (1-12). */\n month: number\n /** Year for this cell. */\n year: number\n /** Localized short month label (e.g. \"Jan\"). */\n label: string\n /** Whether this is the current month (today's month and year). */\n isCurrentMonth: boolean\n /** Whether this entire month is outside the selectable range. */\n isDisabled: boolean\n}\n\n/**\n * Generate a 3×4 grid of months for the month picker view.\n *\n * @param year - Year to display\n * @param today - Reference date for \"isCurrentMonth\" marking\n * @param locale - BCP 47 locale for month labels\n * @param isMonthDisabled - Optional callback to check if a month should be disabled\n */\nexport function generateMonthGrid(\n year: number,\n today?: CalendarDate,\n locale?: string,\n isMonthDisabled?: (year: number, month: number) => boolean,\n): MonthCell[][] {\n const todayRef = today ?? CalendarDate.today()\n const disabledFn = isMonthDisabled ?? (() => false)\n\n const rows: MonthCell[][] = []\n for (let row = 0; row < 3; row++) {\n const cells: MonthCell[] = []\n for (let col = 0; col < 4; col++) {\n const month = row * 4 + col + 1\n const d = new CalendarDate(year, month, 1)\n cells.push({\n month,\n year,\n label: d.format({ month: 'short' }, locale),\n isCurrentMonth: todayRef.month === month && todayRef.year === year,\n isDisabled: disabledFn(year, month),\n })\n }\n rows.push(cells)\n }\n\n return rows\n}\n\n// ---------------------------------------------------------------------------\n// Year view grid (3×4 of year cells)\n// ---------------------------------------------------------------------------\n\n/** Metadata for a single year cell in the year picker view. */\nexport interface YearCell {\n /** Full year number (e.g. 2026). */\n year: number\n /** Year as string label. */\n label: string\n /** Whether this is the current year (today's year). */\n isCurrentYear: boolean\n /** Whether this entire year is outside the selectable range. */\n isDisabled: boolean\n}\n\n/**\n * Generate a 3×4 grid of years for the year picker view.\n *\n * Shows 12 consecutive years in a block aligned to multiples of 12.\n * For example, if centerYear is 2026, the grid shows 2016–2027.\n *\n * @param centerYear - Year to determine which 12-year block to display\n * @param today - Reference date for \"isCurrentYear\" marking\n * @param isYearDisabled - Optional callback to check if a year should be disabled\n */\nexport function generateYearGrid(\n centerYear: number,\n today?: CalendarDate,\n isYearDisabled?: (year: number) => boolean,\n): YearCell[][] {\n const todayRef = today ?? CalendarDate.today()\n const disabledFn = isYearDisabled ?? (() => false)\n\n const startYear = Math.floor(centerYear / 12) * 12\n\n const rows: YearCell[][] = []\n for (let row = 0; row < 3; row++) {\n const cells: YearCell[] = []\n for (let col = 0; col < 4; col++) {\n const year = startYear + row * 4 + col\n cells.push({\n year,\n label: String(year),\n isCurrentYear: todayRef.year === year,\n isDisabled: disabledFn(year),\n })\n }\n rows.push(cells)\n }\n\n return rows\n}\n\n// ---------------------------------------------------------------------------\n// Multi-month day view grids\n// ---------------------------------------------------------------------------\n\n/**\n * Generate `count` consecutive month grids starting from year/month.\n *\n * @param year - Starting year\n * @param month - Starting month (1-12)\n * @param count - Number of months to generate (e.g. 1 or 2)\n * @param firstDayOfWeek - 0 = Sunday, 1 = Monday, …\n * @param today - Reference for \"isToday\"\n * @param isDisabled - Optional disabled callback\n */\nexport function generateMonths(\n year: number,\n month: number,\n count: number,\n firstDayOfWeek = 0,\n today?: CalendarDate,\n isDisabled?: (date: CalendarDate) => boolean,\n): MonthGrid[] {\n const grids: MonthGrid[] = []\n\n for (let i = 0; i < count; i++) {\n // Compute the target month, handling year rollover\n let targetMonth = month + i\n let targetYear = year\n while (targetMonth > 12) {\n targetMonth -= 12\n targetYear++\n }\n grids.push(generateMonth(targetYear, targetMonth, firstDayOfWeek, today, isDisabled))\n }\n\n return grids\n}\n","import { CalendarDate } from './calendar-date'\n\n/**\n * Common interface for all selection models.\n *\n * Each model tracks which dates are selected and exposes a uniform API\n * for querying, toggling, clearing, and serializing the selection.\n */\nexport interface Selection {\n /** Check if a specific date is selected. */\n isSelected(date: CalendarDate): boolean\n\n /** Toggle a date's selection state. */\n toggle(date: CalendarDate): void\n\n /** Clear all selected dates. */\n clear(): void\n\n /** Return selected dates as an array (sorted chronologically). */\n toArray(): CalendarDate[]\n\n /** Serialize the selection to a string value (for form inputs). */\n toValue(): string\n}\n\n// ---------------------------------------------------------------------------\n// SingleSelection\n// ---------------------------------------------------------------------------\n\n/** Stores zero or one selected date. */\nexport class SingleSelection implements Selection {\n private selected: CalendarDate | null = null\n\n constructor(initial?: CalendarDate | null) {\n this.selected = initial ?? null\n }\n\n isSelected(date: CalendarDate): boolean {\n return this.selected !== null && this.selected.isSame(date)\n }\n\n /** Toggle: select the date, or deselect if it's already selected. */\n toggle(date: CalendarDate): void {\n if (this.selected !== null && this.selected.isSame(date)) {\n this.selected = null\n } else {\n this.selected = date\n }\n }\n\n clear(): void {\n this.selected = null\n }\n\n toArray(): CalendarDate[] {\n return this.selected !== null ? [this.selected] : []\n }\n\n /** Returns the ISO string of the selected date, or empty string. */\n toValue(): string {\n return this.selected !== null ? this.selected.toISO() : ''\n }\n\n /** Direct access to the current selection. */\n getSelected(): CalendarDate | null {\n return this.selected\n }\n}\n\n// ---------------------------------------------------------------------------\n// MultipleSelection\n// ---------------------------------------------------------------------------\n\n/** Stores zero or more selected dates via a Set of ISO keys. */\nexport class MultipleSelection implements Selection {\n private keys = new Set<string>()\n\n constructor(initial?: CalendarDate[]) {\n if (initial) {\n for (const date of initial) {\n this.keys.add(date.toKey())\n }\n }\n }\n\n isSelected(date: CalendarDate): boolean {\n return this.keys.has(date.toKey())\n }\n\n /** Toggle: add the date if absent, remove if present. */\n toggle(date: CalendarDate): void {\n const key = date.toKey()\n if (this.keys.has(key)) {\n this.keys.delete(key)\n } else {\n this.keys.add(key)\n }\n }\n\n clear(): void {\n this.keys.clear()\n }\n\n /** Returns selected dates sorted chronologically. */\n toArray(): CalendarDate[] {\n return [...this.keys].sort().map((key) => CalendarDate.fromISO(key) as CalendarDate)\n }\n\n /** Returns comma-separated ISO strings, sorted chronologically. */\n toValue(): string {\n return [...this.keys].sort().join(', ')\n }\n\n /** Number of currently selected dates. */\n get count(): number {\n return this.keys.size\n }\n}\n\n// ---------------------------------------------------------------------------\n// RangeSelection\n// ---------------------------------------------------------------------------\n\n/** Stores a date range (start → end), with support for partial state. */\nexport class RangeSelection implements Selection {\n private start: CalendarDate | null = null\n private end: CalendarDate | null = null\n\n constructor(start?: CalendarDate | null, end?: CalendarDate | null) {\n this.start = start ?? null\n this.end = end ?? null\n }\n\n isSelected(date: CalendarDate): boolean {\n if (this.start !== null && this.start.isSame(date)) return true\n if (this.end !== null && this.end.isSame(date)) return true\n return false\n }\n\n /**\n * Toggle behavior for range selection:\n * 1. Nothing selected → set as start\n * 2. Only start selected → set as end (swap if before start)\n * 3. Both selected → clear and set as new start\n */\n toggle(date: CalendarDate): void {\n if (this.start === null) {\n // Step 1: nothing selected — set start\n this.start = date\n } else if (this.end === null) {\n // Step 2: start set, no end — set end (ensure start <= end)\n if (date.isBefore(this.start)) {\n this.end = this.start\n this.start = date\n } else if (date.isSame(this.start)) {\n // Clicking start again → deselect\n this.start = null\n } else {\n this.end = date\n }\n } else {\n // Step 3: both set — start new selection\n this.start = date\n this.end = null\n }\n }\n\n /**\n * Directly set both start and end of the range.\n * Useful for programmatic assignment where `toggle()` semantics are undesirable\n * (e.g., same-day ranges where toggling the same date would deselect).\n */\n setRange(start: CalendarDate, end: CalendarDate): void {\n this.start = start\n this.end = end\n }\n\n clear(): void {\n this.start = null\n this.end = null\n }\n\n /** Returns [start, end] if both set, [start] if partial, or [] if empty. */\n toArray(): CalendarDate[] {\n if (this.start === null) return []\n if (this.end === null) return [this.start]\n return [this.start, this.end]\n }\n\n /** Returns \"start – end\" ISO strings, or just start, or empty string. */\n toValue(): string {\n if (this.start === null) return ''\n if (this.end === null) return this.start.toISO()\n return `${this.start.toISO()} – ${this.end.toISO()}`\n }\n\n /**\n * Check if a date falls within the range (inclusive), with optional\n * hover preview for visual feedback during range building.\n *\n * When only start is selected and the user hovers over a date,\n * pass that date as `hoverDate` to preview the range.\n */\n isInRange(date: CalendarDate, hoverDate?: CalendarDate): boolean {\n // Full range: both endpoints set\n if (this.start !== null && this.end !== null) {\n return date.isBetween(this.start, this.end)\n }\n\n // Hover preview: start set, hovering over a candidate end\n if (this.start !== null && hoverDate !== undefined) {\n const rangeStart = this.start.isBefore(hoverDate) ? this.start : hoverDate\n const rangeEnd = this.start.isBefore(hoverDate) ? hoverDate : this.start\n return date.isBetween(rangeStart, rangeEnd)\n }\n\n return false\n }\n\n /** Direct access to the range endpoints. */\n getStart(): CalendarDate | null {\n return this.start\n }\n\n getEnd(): CalendarDate | null {\n return this.end\n }\n\n /** Whether the range is partially selected (start only, no end). */\n isPartial(): boolean {\n return this.start !== null && this.end === null\n }\n\n /** Whether the range is fully selected (both start and end). */\n isComplete(): boolean {\n return this.start !== null && this.end !== null\n }\n}\n","import type { CalendarDate } from '../core/calendar-date'\n\n/**\n * Date formatting utilities using format token strings.\n *\n * Supported tokens (same as parser):\n * DD - Day of month, zero-padded (01–31)\n * D - Day of month (1–31)\n * MM - Month, zero-padded (01–12)\n * M - Month (1–12)\n * YYYY - Full year (e.g. 2025)\n * YY - Two-digit year (e.g. 25)\n *\n * Supported separators: `/`, `-`, `.`, and any other literal character.\n */\n\n// ---------------------------------------------------------------------------\n// Token replacement\n// ---------------------------------------------------------------------------\n\n/** Map of token names to their formatting functions. */\nconst TOKEN_FORMATTERS: Record<string, (date: CalendarDate) => string> = {\n YYYY: (d) => String(d.year).padStart(4, '0'),\n YY: (d) => String(d.year % 100).padStart(2, '0'),\n MM: (d) => String(d.month).padStart(2, '0'),\n M: (d) => String(d.month),\n DD: (d) => String(d.day).padStart(2, '0'),\n D: (d) => String(d.day),\n}\n\n// Sorted longest-first so YYYY matches before YY, DD before D, MM before M\nconst TOKEN_NAMES = Object.keys(TOKEN_FORMATTERS).sort((a, b) => b.length - a.length)\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Format a CalendarDate according to a format string.\n *\n * Replaces format tokens with the corresponding date values.\n * All non-token characters are passed through as literals.\n *\n * @param date - The CalendarDate to format\n * @param format - The format string (e.g., \"DD/MM/YYYY\")\n * @returns Formatted date string (e.g., \"15/06/2025\")\n */\nexport function formatDate(date: CalendarDate, format: string): string {\n let remaining = format\n let result = ''\n\n while (remaining.length > 0) {\n let matched = false\n for (const token of TOKEN_NAMES) {\n if (remaining.startsWith(token)) {\n const formatter = TOKEN_FORMATTERS[token]\n if (formatter) {\n result += formatter(date)\n remaining = remaining.slice(token.length)\n matched = true\n break\n }\n }\n }\n if (!matched) {\n result += remaining[0] as string\n remaining = remaining.slice(1)\n }\n }\n\n return result\n}\n\n/**\n * Format a date range as a display string.\n *\n * Uses en-dash (–) as the range separator.\n *\n * @param start - The range start date\n * @param end - The range end date\n * @param format - The format string for each date\n * @returns Formatted range string (e.g., \"01/06/2025 – 30/06/2025\")\n */\nexport function formatRange(start: CalendarDate, end: CalendarDate, format: string): string {\n return `${formatDate(start, format)} – ${formatDate(end, format)}`\n}\n\n/**\n * Format multiple dates as a display string.\n *\n * When the number of dates exceeds `maxDisplay`, returns a count string\n * instead of listing all dates (e.g., \"3 dates selected\").\n *\n * @param dates - Array of CalendarDates to format\n * @param format - The format string for each date\n * @param maxDisplay - Maximum number of dates to show before switching to count\n * (default: no limit — always shows all dates)\n * @returns Formatted string: comma-separated dates or count string\n */\nexport function formatMultiple(\n dates: readonly CalendarDate[],\n format: string,\n maxDisplay?: number,\n): string {\n if (dates.length === 0) return ''\n\n if (maxDisplay !== undefined && dates.length > maxDisplay) {\n return `${dates.length} dates selected`\n }\n\n return dates.map((d) => formatDate(d, format)).join(', ')\n}\n","import { CalendarDate, daysInMonth } from '../core/calendar-date'\n\n/**\n * Supported format tokens:\n * DD - Day of month, zero-padded (01–31)\n * D - Day of month (1–31)\n * MM - Month, zero-padded (01–12)\n * M - Month (1–12)\n * YYYY - Full year (e.g. 2025)\n * YY - Two-digit year (e.g. 25 → 2025)\n *\n * Supported separators: `/`, `-`, `.`\n */\n\n/** Map of format tokens to their regex patterns and extraction logic. */\ninterface TokenDef {\n pattern: string\n extract: (match: string) => number\n}\n\nconst TOKENS: Record<string, TokenDef> = {\n YYYY: { pattern: '(\\\\d{4})', extract: (m) => Number(m) },\n YY: { pattern: '(\\\\d{2})', extract: (m) => 2000 + Number(m) },\n MM: { pattern: '(\\\\d{1,2})', extract: (m) => Number(m) },\n M: { pattern: '(\\\\d{1,2})', extract: (m) => Number(m) },\n DD: { pattern: '(\\\\d{1,2})', extract: (m) => Number(m) },\n D: { pattern: '(\\\\d{1,2})', extract: (m) => Number(m) },\n}\n\n// Token names sorted longest-first so YYYY matches before YY, DD before D, MM before M\nconst TOKEN_NAMES = Object.keys(TOKENS).sort((a, b) => b.length - a.length)\n\n/**\n * Build a regex and extraction plan from a format string.\n *\n * Separators (/, -, .) in the format are matched literally.\n * Tokens (DD, MM, YYYY, etc.) become capturing groups.\n */\nfunction compileFormat(format: string): {\n regex: RegExp\n extractors: { token: string; index: number }[]\n} {\n let remaining = format\n let regexStr = '^'\n const extractors: { token: string; index: number }[] = []\n let groupIndex = 1\n\n while (remaining.length > 0) {\n let matched = false\n\n for (const name of TOKEN_NAMES) {\n if (remaining.startsWith(name)) {\n const def = TOKENS[name]\n if (def) {\n regexStr += def.pattern\n extractors.push({ token: name, index: groupIndex })\n groupIndex++\n remaining = remaining.slice(name.length)\n matched = true\n break\n }\n }\n }\n\n if (!matched) {\n // Literal character (separator or other)\n const char = remaining[0] as string\n regexStr += escapeRegex(char)\n remaining = remaining.slice(1)\n }\n }\n\n regexStr += '$'\n return { regex: new RegExp(regexStr), extractors }\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Validate that a year/month/day combination represents a real date.\n */\nfunction isValidDate(year: number, month: number, day: number): boolean {\n if (month < 1 || month > 12) return false\n if (day < 1) return false\n if (day > daysInMonth(year, month)) return false\n if (year < 1) return false\n return true\n}\n\n/**\n * Parse a date string according to the given format.\n *\n * Parsing is lenient: single-digit day/month values are accepted even when\n * the format specifies DD/MM (e.g., `1/3/2025` matches `DD/MM/YYYY`).\n *\n * @param input - The date string to parse (e.g., \"15/06/2025\")\n * @param format - The format string (e.g., \"DD/MM/YYYY\")\n * @returns The parsed CalendarDate, or null if parsing fails or date is invalid\n */\nexport function parseDate(input: string, format: string): CalendarDate | null {\n const trimmed = input.trim()\n if (trimmed === '') return null\n\n const { regex, extractors } = compileFormat(format)\n const match = regex.exec(trimmed)\n if (!match) return null\n\n let year = 0\n let month = 0\n let day = 0\n\n for (const { token, index } of extractors) {\n const value = match[index]\n if (value === undefined) return null\n\n const def = TOKENS[token]\n if (!def) return null\n\n const extracted = def.extract(value)\n\n if (token === 'YYYY' || token === 'YY') {\n year = extracted\n } else if (token === 'MM' || token === 'M') {\n month = extracted\n } else if (token === 'DD' || token === 'D') {\n day = extracted\n }\n }\n\n if (!isValidDate(year, month, day)) return null\n\n return new CalendarDate(year, month, day)\n}\n\n/**\n * Parse a range string into two CalendarDates.\n *\n * Supported separators between the two dates: ` - `, ` – ` (en-dash), ` — ` (em-dash).\n *\n * @param input - The range string (e.g., \"01/01/2025 - 07/01/2025\")\n * @param format - The format for each individual date\n * @returns Tuple of [start, end], or null if parsing fails\n */\nexport function parseDateRange(input: string, format: string): [CalendarDate, CalendarDate] | null {\n const trimmed = input.trim()\n if (trimmed === '') return null\n\n // Try splitting on range separators (with surrounding spaces)\n const separators = [' – ', ' — ', ' - ']\n for (const sep of separators) {\n const idx = trimmed.indexOf(sep)\n if (idx !== -1) {\n const startStr = trimmed.slice(0, idx)\n const endStr = trimmed.slice(idx + sep.length)\n const start = parseDate(startStr, format) ?? CalendarDate.fromISO(startStr.trim())\n const end = parseDate(endStr, format) ?? CalendarDate.fromISO(endStr.trim())\n if (start && end) return [start, end]\n }\n }\n\n return null\n}\n\n/**\n * Parse a comma-separated list of dates.\n *\n * @param input - The comma-separated string (e.g., \"01/06/2025, 15/06/2025, 20/06/2025\")\n * @param format - The format for each individual date\n * @returns Array of parsed CalendarDates (only valid dates included), or empty array\n */\nexport function parseDateMultiple(input: string, format: string): CalendarDate[] {\n const trimmed = input.trim()\n if (trimmed === '') return []\n\n const parts = trimmed.split(',')\n const dates: CalendarDate[] = []\n\n for (const part of parts) {\n const date = parseDate(part, format) ?? CalendarDate.fromISO(part.trim())\n if (date) dates.push(date)\n }\n\n return dates\n}\n","/**\n * Lightweight input mask engine for date format strings.\n *\n * Maps format tokens (DD, MM, YYYY, etc.) to digit slots and\n * auto-inserts separator characters as the user types.\n * No external dependencies.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MaskSlot {\n type: 'digit' | 'literal'\n char: string\n}\n\nexport interface InputMask {\n /** Apply mask to a raw input string, returning the formatted string */\n apply(rawInput: string): string\n /** The mask pattern, e.g. \"99/99/9999\" */\n readonly pattern: string\n /** The format string used to create the mask */\n readonly format: string\n /** Total character length of a fully-filled mask */\n readonly length: number\n /** The slot definitions */\n readonly slots: readonly MaskSlot[]\n /** Maximum number of digit characters the mask accepts */\n readonly maxDigits: number\n}\n\nexport interface MaskEventHandlers {\n onInput: (e: Event) => void\n onKeyDown: (e: KeyboardEvent) => void\n onPaste: (e: ClipboardEvent) => void\n}\n\n// ---------------------------------------------------------------------------\n// Token → digit count mapping\n// ---------------------------------------------------------------------------\n\nconst TOKEN_DIGIT_COUNT: Record<string, number> = {\n YYYY: 4,\n YY: 2,\n MM: 2,\n M: 2,\n DD: 2,\n D: 2,\n}\n\n// Sorted longest-first so YYYY matches before YY, DD before D, MM before M\nconst TOKEN_NAMES = Object.keys(TOKEN_DIGIT_COUNT).sort((a, b) => b.length - a.length)\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction extractDigits(str: string): string {\n return str.replace(/\\D/g, '')\n}\n\nfunction countDigits(str: string): number {\n let count = 0\n for (const ch of str) {\n if (ch >= '0' && ch <= '9') count++\n }\n return count\n}\n\n/**\n * Fill digit slots with provided digits and insert literals.\n * Literals are included after a digit group is filled (auto-insert behavior).\n * Stops when digits run out.\n */\nfunction applyMaskSlots(digits: string, slots: readonly MaskSlot[]): string {\n let result = ''\n let digitIndex = 0\n\n for (const slot of slots) {\n if (slot.type === 'digit') {\n if (digitIndex >= digits.length) break\n result += digits[digitIndex]\n digitIndex++\n } else {\n // Include literal only if at least one digit has been placed\n if (digitIndex > 0) {\n result += slot.char\n } else {\n break\n }\n }\n }\n\n return result\n}\n\n/**\n * Find the cursor position in a masked string that places the cursor\n * after the Nth digit, advancing past any trailing literals.\n */\nfunction cursorAfterNDigits(\n masked: string,\n slots: readonly MaskSlot[],\n digitCount: number,\n): number {\n if (digitCount <= 0) return 0\n\n let seen = 0\n for (let i = 0; i < masked.length && i < slots.length; i++) {\n const slot = slots[i]\n if (slot && slot.type === 'digit') {\n seen++\n if (seen === digitCount) {\n let pos = i + 1\n // Advance past trailing literals (auto-inserted separators)\n while (pos < slots.length && pos < masked.length) {\n const next = slots[pos]\n if (!next || next.type !== 'literal') break\n pos++\n }\n return pos\n }\n }\n }\n\n return masked.length\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a format string into an array of mask slots.\n *\n * Each format token (DD, MM, YYYY, etc.) becomes digit slots,\n * and all other characters become literal slots.\n */\nexport function parseFormatToSlots(format: string): MaskSlot[] {\n const slots: MaskSlot[] = []\n let remaining = format\n\n while (remaining.length > 0) {\n let matched = false\n for (const token of TOKEN_NAMES) {\n if (remaining.startsWith(token)) {\n const count = TOKEN_DIGIT_COUNT[token]\n if (count === undefined) continue\n for (let i = 0; i < count; i++) {\n slots.push({ type: 'digit', char: '9' })\n }\n remaining = remaining.slice(token.length)\n matched = true\n break\n }\n }\n if (!matched) {\n slots.push({ type: 'literal', char: remaining[0] as string })\n remaining = remaining.slice(1)\n }\n }\n\n return slots\n}\n\n/**\n * Create a mask from a date format string.\n *\n * @param format - The date format (e.g., \"DD/MM/YYYY\")\n * @returns An InputMask object with apply() and metadata\n */\nexport function createMask(format: string): InputMask {\n const slots = parseFormatToSlots(format)\n const maxDigits = slots.filter((s) => s.type === 'digit').length\n const pattern = slots.map((s) => (s.type === 'digit' ? '9' : s.char)).join('')\n\n return {\n apply(rawInput: string): string {\n const digits = extractDigits(rawInput).slice(0, maxDigits)\n return applyMaskSlots(digits, slots)\n },\n get pattern() {\n return pattern\n },\n get format() {\n return format\n },\n get length() {\n return slots.length\n },\n get slots() {\n return slots\n },\n get maxDigits() {\n return maxDigits\n },\n }\n}\n\n/**\n * Create event handlers for masking an HTMLInputElement.\n *\n * Handles input, keydown (backspace/delete over separators), and paste.\n *\n * @param mask - The InputMask to use\n * @returns Event handlers to attach to the input element\n */\nexport function createMaskHandlers(mask: InputMask): MaskEventHandlers {\n const { slots, maxDigits } = mask\n\n function onInput(e: Event) {\n const el = e.target as HTMLInputElement\n const rawValue = el.value\n const cursorPos = el.selectionStart ?? rawValue.length\n\n // Count digits before cursor in the raw (browser-modified) value\n const digitsBefore = countDigits(rawValue.slice(0, cursorPos))\n\n // Extract all digits and re-apply mask\n const digits = extractDigits(rawValue).slice(0, maxDigits)\n const masked = applyMaskSlots(digits, slots)\n\n el.value = masked\n\n // Restore cursor position based on digit count\n const newCursor = cursorAfterNDigits(masked, slots, digitsBefore)\n el.setSelectionRange(newCursor, newCursor)\n }\n\n function onKeyDown(e: KeyboardEvent) {\n const el = e.target as HTMLInputElement\n const pos = el.selectionStart ?? 0\n const selEnd = el.selectionEnd ?? pos\n\n // Only handle single-cursor (no selection) for special cases\n if (pos !== selEnd) return\n\n // Backspace over a literal: skip back to the digit before it and delete\n if (e.key === 'Backspace' && pos > 0) {\n const prevSlot = pos <= slots.length ? slots[pos - 1] : undefined\n if (prevSlot && prevSlot.type === 'literal') {\n e.preventDefault()\n // Skip back past consecutive literals\n let targetPos = pos - 1\n while (targetPos > 0) {\n const s = slots[targetPos - 1]\n if (!s || s.type !== 'literal') break\n targetPos--\n }\n if (targetPos > 0) {\n const currentDigits = extractDigits(el.value)\n const digitIndex = countDigits(el.value.slice(0, targetPos))\n if (digitIndex > 0) {\n const newDigits =\n currentDigits.slice(0, digitIndex - 1) + currentDigits.slice(digitIndex)\n const masked = applyMaskSlots(newDigits, slots)\n el.value = masked\n const newCursor = cursorAfterNDigits(masked, slots, digitIndex - 1)\n el.setSelectionRange(newCursor, newCursor)\n }\n }\n }\n }\n\n // Delete over a literal: skip forward to the digit after it and delete\n if (e.key === 'Delete' && pos < el.value.length) {\n const curSlot = pos < slots.length ? slots[pos] : undefined\n if (curSlot && curSlot.type === 'literal') {\n e.preventDefault()\n // Skip forward past consecutive literals\n let targetPos = pos + 1\n while (targetPos < slots.length) {\n const s = slots[targetPos]\n if (!s || s.type !== 'literal') break\n targetPos++\n }\n if (targetPos < el.value.length) {\n const currentDigits = extractDigits(el.value)\n const digitIndex = countDigits(el.value.slice(0, targetPos))\n const newDigits = currentDigits.slice(0, digitIndex) + currentDigits.slice(digitIndex + 1)\n const masked = applyMaskSlots(newDigits, slots)\n el.value = masked\n const newCursor = cursorAfterNDigits(masked, slots, digitIndex)\n el.setSelectionRange(newCursor, newCursor)\n }\n }\n }\n }\n\n function onPaste(e: ClipboardEvent) {\n e.preventDefault()\n const el = e.target as HTMLInputElement\n const pasted = e.clipboardData?.getData('text') ?? ''\n const pastedDigits = extractDigits(pasted)\n if (pastedDigits.length === 0) return\n\n const pos = el.selectionStart ?? 0\n const end = el.selectionEnd ?? pos\n const currentDigits = extractDigits(el.value)\n const digitsBefore = countDigits(el.value.slice(0, pos))\n const digitsInSelection = countDigits(el.value.slice(pos, end))\n\n const newDigits = (\n currentDigits.slice(0, digitsBefore) +\n pastedDigits +\n currentDigits.slice(digitsBefore + digitsInSelection)\n ).slice(0, maxDigits)\n\n const masked = applyMaskSlots(newDigits, slots)\n el.value = masked\n\n const targetDigitCount = Math.min(digitsBefore + pastedDigits.length, maxDigits)\n const newCursor = cursorAfterNDigits(masked, slots, targetDigitCount)\n el.setSelectionRange(newCursor, newCursor)\n }\n\n return { onInput, onKeyDown, onPaste }\n}\n\n/**\n * Attach mask event handlers to an input element.\n * Returns a detach function to remove the handlers.\n *\n * @param input - The HTML input element\n * @param format - The date format string (e.g., \"DD/MM/YYYY\")\n * @returns Detach function to remove event listeners\n */\nexport function attachMask(input: HTMLInputElement, format: string): () => void {\n const mask = createMask(format)\n const handlers = createMaskHandlers(mask)\n\n input.addEventListener('input', handlers.onInput)\n input.addEventListener('keydown', handlers.onKeyDown)\n input.addEventListener('paste', handlers.onPaste as EventListener)\n\n // Apply mask to any existing value\n if (input.value) {\n input.value = mask.apply(input.value)\n }\n\n return () => {\n input.removeEventListener('input', handlers.onInput)\n input.removeEventListener('keydown', handlers.onKeyDown)\n input.removeEventListener('paste', handlers.onPaste as EventListener)\n }\n}\n","// ---------------------------------------------------------------------------\n// Auto-rendering template generator\n// ---------------------------------------------------------------------------\n\nexport interface TemplateOptions {\n display: 'inline' | 'popup'\n isDualMonth: boolean\n isWizard: boolean\n hasName: boolean\n showWeekNumbers: boolean\n hasPresets: boolean\n isScrollable: boolean\n scrollHeight: number\n}\n\n// Close icon SVG (inline, no external deps)\nconst closeSvg = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" aria-hidden=\"true\"><line x1=\"4\" y1=\"4\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"4\" x2=\"4\" y2=\"12\"/></svg>'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** A calendar grid always has 6 rows (weeks). */\nconst GRID_ROWS = 6\n\n// ---------------------------------------------------------------------------\n// Helpers: unrolled day-grid rows\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a layout-only row div for a specific row index.\n * No ARIA role — the row is transparent to the accessibility tree.\n * The parent listbox directly owns the option children through these wrappers.\n */\nfunction dayRow(ri: number, showWeekNumbers: boolean): string {\n const rowClass = showWeekNumbers ? 'rc-row rc-row--week-numbers' : 'rc-row'\n const weekNumCell = showWeekNumbers\n ? `<div class=\"rc-week-number\" x-text=\"mg.weekNumbers[${ri}]\"></div>`\n : ''\n\n return `<div class=\"${rowClass}\" x-show=\"mg.rows.length > ${ri}\">\n ${weekNumCell}<template x-for=\"cell in (mg.rows[${ri}] || [])\" :key=\"cell.date.toISO()\">\n <div :class=\"dayClasses(cell)\" :id=\"'day-' + cell.date.toISO()\" :aria-selected=\"isSelected(cell.date)\" :aria-disabled=\"cell.isDisabled\" :title=\"dayTitle(cell)\" role=\"option\" tabindex=\"-1\" @click=\"!cell.isDisabled && selectDate(cell.date)\" @mouseenter=\"hoverDate = cell.date\" @mouseleave=\"hoverDate = null\" x-text=\"cell.date.day\"></div>\n </template>\n </div>`\n}\n\n/** Generate all 6 unrolled row templates. */\nfunction dayRows(showWeekNumbers: boolean): string {\n return Array.from({ length: GRID_ROWS }, (_, ri) => dayRow(ri, showWeekNumbers)).join('\\n ')\n}\n\n// ---------------------------------------------------------------------------\n// View fragments\n// ---------------------------------------------------------------------------\n\nfunction yearPickerView(): string {\n return `<template x-if=\"view === 'years'\">\n <div class=\"rc-view-enter\">\n <div class=\"rc-header\">\n <button class=\"rc-header__nav\" @click=\"prev()\" :disabled=\"!canGoPrev\" aria-label=\"Previous decade\">&#8249;</button>\n <span class=\"rc-header__label\" x-text=\"decadeLabel\"></span>\n <button class=\"rc-header__nav\" @click=\"next()\" :disabled=\"!canGoNext\" aria-label=\"Next decade\">&#8250;</button>\n </div>\n <div class=\"rc-year-grid\" role=\"group\" :aria-label=\"decadeLabel\">\n <template x-for=\"cell in yearGrid.flat()\" :key=\"cell.year\">\n <div :class=\"yearClasses(cell)\" :aria-disabled=\"cell.isDisabled\" tabindex=\"-1\" @click=\"!cell.isDisabled && selectYear(cell.year)\" x-text=\"cell.label\"></div>\n </template>\n </div>\n </div>\n</template>`\n}\n\nfunction monthPickerView(): string {\n return `<template x-if=\"view === 'months'\">\n <div class=\"rc-view-enter\">\n <div class=\"rc-header\">\n <button class=\"rc-header__nav\" @click=\"prev()\" :disabled=\"!canGoPrev\" aria-label=\"Previous year\">&#8249;</button>\n <button class=\"rc-header__label\" @click=\"setView('years')\" aria-label=\"Change view\" x-text=\"yearLabel\"></button>\n <button class=\"rc-header__nav\" @click=\"next()\" :disabled=\"!canGoNext\" aria-label=\"Next year\">&#8250;</button>\n </div>\n <div class=\"rc-month-grid\" role=\"group\" :aria-label=\"yearLabel\">\n <template x-for=\"cell in monthGrid.flat()\" :key=\"cell.month\">\n <div :class=\"monthClasses(cell)\" :aria-disabled=\"cell.isDisabled\" tabindex=\"-1\" @click=\"!cell.isDisabled && selectMonth(cell.month)\" x-text=\"cell.label\"></div>\n </template>\n </div>\n </div>\n</template>`\n}\n\nfunction dayView(isDual: boolean, showWeekNumbers: boolean): string {\n // For dual-month: hide prev on 2nd month, next on 1st\n const prevStyle = isDual ? ' :style=\"gi > 0 ? \\'visibility:hidden\\' : \\'\\'\"' : ''\n const nextStyle = isDual ? ' :style=\"gi < grid.length - 1 ? \\'visibility:hidden\\' : \\'\\'\"' : ''\n const monthsClass = isDual ? ' :class=\"{ \\'rc-months--dual\\': monthCount === 2 }\"' : ''\n\n const gridClassBinding = `:class=\"{ 'rc-grid--slide-next': _navDirection === 'next', 'rc-grid--slide-prev': _navDirection === 'prev' }\"`\n\n // Weekday headers\n const weekdayBlock = showWeekNumbers\n ? `<div class=\"rc-weekdays rc-weekdays--week-numbers\">\n <span class=\"rc-weekday rc-week-label\"></span>\n <template x-for=\"wd in weekdayHeaders\" :key=\"wd\">\n <span class=\"rc-weekday\" x-text=\"wd\"></span>\n </template>\n </div>`\n : `<div class=\"rc-weekdays\">\n <template x-for=\"wd in weekdayHeaders\" :key=\"wd\">\n <span class=\"rc-weekday\" x-text=\"wd\"></span>\n </template>\n </div>`\n\n const gridClass = showWeekNumbers ? '\"rc-grid rc-grid--week-numbers\"' : '\"rc-grid\"'\n\n // Unrolled rows — each row is a static DOM element with its own x-for\n const rows = dayRows(showWeekNumbers)\n\n return `<template x-if=\"view === 'days'\">\n <div class=\"rc-months${isDual ? '' : ' rc-view-enter'}\"${monthsClass}${isDual ? '' : ''}>\n <template x-for=\"(mg, gi) in grid\" :key=\"mg.year + '-' + mg.month\">\n <div${isDual ? '' : ''}>\n <div class=\"rc-header\">\n <button class=\"rc-header__nav\" @click=\"prev()\" :disabled=\"!canGoPrev\" aria-label=\"Previous month\"${prevStyle}>&#8249;</button>\n <button class=\"rc-header__label\" @click=\"setView('months')\" aria-label=\"Change view\" x-text=\"monthYearLabel(gi)\"></button>\n <button class=\"rc-header__nav\" @click=\"next()\" :disabled=\"!canGoNext\" aria-label=\"Next month\"${nextStyle}>&#8250;</button>\n </div>\n ${weekdayBlock}\n <div class=\"rc-grid-wrapper\">\n <div class=${gridClass} ${gridClassBinding} @animationend=\"_navDirection = ''\" role=\"listbox\" :aria-label=\"monthYearLabel(gi)\">\n ${rows}\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>`\n}\n\nfunction scrollableDayView(showWeekNumbers: boolean, scrollHeight: number): string {\n const weekdayBlock = showWeekNumbers\n ? `<div class=\"rc-weekdays rc-weekdays--week-numbers\">\n <span class=\"rc-weekday rc-week-label\"></span>\n <template x-for=\"wd in weekdayHeaders\" :key=\"wd\">\n <span class=\"rc-weekday\" x-text=\"wd\"></span>\n </template>\n </div>`\n : `<div class=\"rc-weekdays\">\n <template x-for=\"wd in weekdayHeaders\" :key=\"wd\">\n <span class=\"rc-weekday\" x-text=\"wd\"></span>\n </template>\n </div>`\n\n const gridClass = showWeekNumbers ? '\"rc-grid rc-grid--week-numbers\"' : '\"rc-grid\"'\n\n // Unrolled rows\n const rows = dayRows(showWeekNumbers)\n\n return `<template x-if=\"view === 'days'\">\n <div>\n <div class=\"rc-header rc-header--scroll-sticky\">\n <span class=\"rc-header__label rc-header__label--scroll\" x-text=\"scrollHeaderLabel\"></span>\n </div>\n ${weekdayBlock}\n <div class=\"rc-months rc-months--scroll\" style=\"max-height: ${scrollHeight}px\">\n <template x-for=\"(mg, gi) in grid\" :key=\"mg.year + '-' + mg.month\">\n <div :data-month-id=\"'month-' + mg.year + '-' + mg.month\">\n <div class=\"rc-header rc-header--scroll\" x-show=\"gi > 0\">\n <span class=\"rc-header__label rc-header__label--scroll\" x-text=\"monthYearLabel(gi)\"></span>\n </div>\n <div class=${gridClass} role=\"listbox\" :aria-label=\"monthYearLabel(gi)\">\n ${rows}\n </div>\n </div>\n </template>\n </div>\n </div>\n</template>`\n}\n\nfunction wizardChrome(): string {\n return `<div class=\"rc-wizard-steps\">\n <template x-for=\"step in wizardTotalSteps\" :key=\"step\">\n <div class=\"rc-wizard-step\" :class=\"{ 'rc-wizard-step--active': wizardStep === step, 'rc-wizard-step--done': wizardStep > step }\"></div>\n </template>\n</div>\n<div class=\"rc-wizard-label\" x-text=\"wizardStepLabel\"></div>\n<template x-if=\"wizardStep > 1\">\n <button class=\"rc-wizard-back\" @click=\"wizardBack()\" aria-label=\"Go back\">&#8249; Back</button>\n</template>`\n}\n\nfunction wizardSummary(): string {\n return `<div class=\"rc-wizard-summary\" x-show=\"wizardSummary\" x-transition:enter=\"transition ease-out duration-200\" x-transition:enter-start=\"opacity-0 transform translate-y-1\" x-transition:enter-end=\"opacity-100 transform translate-y-0\" x-text=\"wizardSummary\"></div>`\n}\n\nfunction popupWrapper(content: string): string {\n return `<div x-ref=\"popup\" x-show=\"isOpen\" :style=\"popupStyle\" class=\"rc-popup-overlay\" @click.self=\"close()\" role=\"dialog\" aria-modal=\"true\" :aria-label=\"popupAriaLabel\" x-transition:enter=\"transition ease-out duration-150\" x-transition:enter-start=\"opacity-0\" x-transition:enter-end=\"opacity-100\" x-transition:leave=\"transition ease-in duration-100\" x-transition:leave-start=\"opacity-100\" x-transition:leave-end=\"opacity-0\">\n${content}\n</div>`\n}\n\nfunction popupHeader(isWizard: boolean): string {\n const title = isWizard\n ? '<span class=\"rc-popup-header__title\" x-text=\"wizardStepLabel\"></span>'\n : '<span class=\"rc-popup-header__title\">Select Date</span>'\n return `<div class=\"rc-popup-header\">\n ${title}\n <button class=\"rc-popup-header__close\" @click=\"close()\" aria-label=\"Close calendar\">${closeSvg}</button>\n</div>`\n}\n\nfunction presetsBlock(): string {\n return `<div class=\"rc-presets\" role=\"group\" aria-label=\"Quick select\">\n <template x-for=\"(preset, pi) in presets\" :key=\"pi\">\n <button class=\"rc-preset\" @click=\"applyPreset(pi)\" x-text=\"preset.label\"></button>\n </template>\n</div>`\n}\n\nfunction hiddenInputs(): string {\n return `<template x-if=\"inputName\">\n <template x-for=\"val in hiddenInputValues\" :key=\"val\">\n <input type=\"hidden\" :name=\"inputName\" :value=\"val\">\n </template>\n</template>`\n}\n\n// ---------------------------------------------------------------------------\n// Main generator\n// ---------------------------------------------------------------------------\n\nexport function generateCalendarTemplate(options: TemplateOptions): string {\n const { display, isDualMonth, isWizard, hasName, showWeekNumbers, hasPresets, isScrollable, scrollHeight } = options\n const isPopup = display === 'popup'\n\n const calendarClass = isWizard ? 'rc-calendar rc-calendar--wizard' : 'rc-calendar'\n const ariaLabel = isWizard ? 'Birth date wizard' : 'Calendar'\n\n // Build the inner calendar content\n const parts: string[] = []\n\n // Popup header (close button + title)\n if (isPopup) {\n parts.push(popupHeader(isWizard))\n }\n\n // Wizard chrome (step dots, label, back button)\n if (isWizard) {\n parts.push(wizardChrome())\n }\n\n // Views — always include all three (guarded by x-if)\n parts.push(yearPickerView())\n parts.push(monthPickerView())\n if (isScrollable) {\n parts.push(scrollableDayView(showWeekNumbers, scrollHeight))\n } else {\n parts.push(dayView(isDualMonth, showWeekNumbers))\n }\n\n // Range presets (below the calendar grid, above wizard summary)\n if (hasPresets) {\n parts.push(presetsBlock())\n }\n\n // Wizard summary bar\n if (isWizard) {\n parts.push(wizardSummary())\n }\n\n // Hidden form inputs\n if (hasName) {\n parts.push(hiddenInputs())\n }\n\n const calendarInner = parts.join('\\n')\n\n // Wrap in rc-calendar container\n const calendarEl = `<div class=\"${calendarClass}\" @keydown=\"handleKeydown($event)\" tabindex=\"0\" :aria-activedescendant=\"focusedDateISO ? 'day-' + focusedDateISO : null\" role=\"application\" aria-label=\"${ariaLabel}\">\n<div class=\"rc-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" x-text=\"_statusMessage\"></div>\n${calendarInner}\n</div>`\n\n if (isPopup) {\n return popupWrapper(calendarEl)\n }\n\n return calendarEl\n}\n","import { CalendarDate } from '../core/calendar-date'\nimport {\n createDateConstraint,\n createMonthConstraint,\n createYearConstraint,\n createRangeValidator,\n createDisabledReasons,\n} from '../core/constraints'\nimport type { DateConstraintOptions, DateConstraintRule, ConstraintMessages } from '../core/constraints'\nimport { generateMonths, generateMonthGrid, generateYearGrid } from '../core/grid'\nimport type { DayCell, MonthGrid, MonthCell, YearCell } from '../core/grid'\nimport { SingleSelection, MultipleSelection, RangeSelection } from '../core/selection'\nimport type { Selection } from '../core/selection'\nimport { formatDate, formatRange, formatMultiple } from '../input/formatter'\nimport { parseDate, parseDateRange, parseDateMultiple } from '../input/parser'\nimport { attachMask } from '../input/mask'\nimport type { RangePreset } from '../core/presets'\nimport { generateCalendarTemplate } from './template'\n\n// ---------------------------------------------------------------------------\n// Configuration\n// ---------------------------------------------------------------------------\n\n/** Period-specific constraint rule (string-based for Alpine/HTML config). */\nexport interface CalendarConfigRule {\n /** Start of the period (ISO string). Required unless `months` is set. */\n from?: string\n /** End of the period (ISO string). Required unless `months` is set. */\n to?: string\n /** Recurring months this rule applies to (1=Jan, …, 12=Dec). Matches every year. */\n months?: number[]\n /** Priority for conflict resolution. Higher values win. Default: 0. */\n priority?: number\n /** Minimum selectable date within this period (ISO string). */\n minDate?: string\n /** Maximum selectable date within this period (ISO string). */\n maxDate?: string\n /** Specific dates to disable within this period (ISO strings). */\n disabledDates?: string[]\n /** Days of the week to disable within this period (0=Sun, 6=Sat). */\n disabledDaysOfWeek?: number[]\n /** Specific dates to force-enable within this period (ISO strings). */\n enabledDates?: string[]\n /** Days of the week to enable within this period (whitelist, 0=Sun, 6=Sat). */\n enabledDaysOfWeek?: number[]\n /** Specific months to disable within this period (1=Jan, 12=Dec). */\n disabledMonths?: number[]\n /** Months to enable within this period (whitelist, 1=Jan, 12=Dec). */\n enabledMonths?: number[]\n /** Specific years to disable within this period. */\n disabledYears?: number[]\n /** Years to enable within this period (whitelist). */\n enabledYears?: number[]\n /** Minimum range length in days (inclusive) for this period. */\n minRange?: number\n /** Maximum range length in days (inclusive) for this period. */\n maxRange?: number\n}\n\nexport type { RangePreset } from '../core/presets'\n\nexport interface CalendarConfig {\n /** Selection mode. Default: 'single'. */\n mode?: 'single' | 'multiple' | 'range'\n /** Display mode. Default: 'inline'. */\n display?: 'inline' | 'popup'\n /** Date format string (e.g. 'DD/MM/YYYY'). Default: 'DD/MM/YYYY'. */\n format?: string\n /** Number of months to show. 1 = single, 2 = side-by-side dual, 3+ = scrollable. Default: 1. */\n months?: number\n /** Max height of the scrollable container in px (only used when months >= 3). Default: 400. */\n scrollHeight?: number\n /** First day of the week (0=Sun, 1=Mon, …, 6=Sat). Default: 0. */\n firstDay?: number\n /** Minimum selectable date (ISO string). */\n minDate?: string\n /** Maximum selectable date (ISO string). */\n maxDate?: string\n /** Specific dates to disable (ISO strings). */\n disabledDates?: string[]\n /** Days of the week to disable (0=Sun, 6=Sat). */\n disabledDaysOfWeek?: number[]\n /** Specific dates to force-enable (ISO strings). Overrides disabled checks. */\n enabledDates?: string[]\n /** Days of the week to enable (whitelist — all other days disabled). */\n enabledDaysOfWeek?: number[]\n /** Specific months to disable (1=Jan, 12=Dec). */\n disabledMonths?: number[]\n /** Months to enable (whitelist — all other months disabled, 1=Jan, 12=Dec). */\n enabledMonths?: number[]\n /** Specific years to disable. */\n disabledYears?: number[]\n /** Years to enable (whitelist — all other years disabled). */\n enabledYears?: number[]\n /** Minimum range length in days (inclusive). Only used in range mode. */\n minRange?: number\n /** Maximum range length in days (inclusive). Only used in range mode. */\n maxRange?: number\n /** Period-specific constraint rules. Highest priority matching rule wins; ties broken by array order. */\n rules?: CalendarConfigRule[]\n /** Enable birth-date wizard mode. Default: false. Use 'year-month' or 'month-day' for half-wizard. */\n wizard?: boolean | 'year-month' | 'month-day'\n /** Enable input masking. Default: true. */\n mask?: boolean\n /** IANA timezone for \"today\" resolution. */\n timezone?: string\n /** BCP 47 locale string. */\n locale?: string\n /** Initial value (ISO string or formatted string). */\n value?: string\n /** Name attribute for hidden form input(s). */\n name?: string\n /** ID attribute for the popup input element. Allows external `<label for=\"...\">` association. */\n inputId?: string\n /** Alpine x-ref name for the input element. Default: 'rc-input'. */\n inputRef?: string\n /** Show ISO 8601 week numbers on the left side of the day grid. Default: false. */\n showWeekNumbers?: boolean\n /**\n * Predefined date range presets (e.g., \"Today\", \"Last 7 Days\", \"This Month\").\n * Displayed as quick-select buttons alongside the calendar. Only meaningful in range or single mode.\n */\n presets?: RangePreset[]\n /** Close popup after a date is selected. Default: true. */\n closeOnSelect?: boolean\n /**\n * Callback invoked before a date is selected. Return `false` to prevent the selection.\n *\n * Receives the date being selected and context about the current selection state.\n * Called after built-in constraint checks (disabled dates, range validation) pass.\n *\n * Usage:\n * ```js\n * calendar({\n * beforeSelect(date, { mode, selectedDates, action }) {\n * // Prevent selecting more than 5 dates\n * if (mode === 'multiple' && action === 'select' && selectedDates.length >= 5) return false\n * return true\n * }\n * })\n * ```\n */\n beforeSelect?: (\n date: CalendarDate,\n context: {\n /** Current selection mode. */\n mode: 'single' | 'multiple' | 'range'\n /** Currently selected dates (before this action). */\n selectedDates: CalendarDate[]\n /** Whether this click would select or deselect the date. */\n action: 'select' | 'deselect'\n },\n ) => boolean | undefined\n /** Custom messages for disabled-date tooltips. Overrides default English strings. */\n constraintMessages?: ConstraintMessages\n /** Auto-render template when no `.rc-calendar` exists in the container. Default: true. Set false to require manual template. */\n template?: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Alpine magic property accessor\n// ---------------------------------------------------------------------------\n\n/** Alpine injects these properties on the component proxy at runtime. */\ninterface AlpineMagics {\n $dispatch(event: string, detail?: Record<string, unknown>): void\n $watch(property: string, callback: (newValue: unknown) => void): void\n $refs: Record<string, HTMLElement>\n $nextTick(callback: () => void): void\n $el: HTMLElement\n}\n\n/**\n * Type-safe accessor for Alpine magic properties on `this`.\n * Alpine injects $dispatch, $watch, etc. onto the reactive proxy at runtime.\n */\nfunction alpine(self: unknown): AlpineMagics {\n return self as AlpineMagics\n}\n\n// ---------------------------------------------------------------------------\n// Config parsing helpers\n// ---------------------------------------------------------------------------\n\nfunction parseISODate(s: string): CalendarDate | null {\n return CalendarDate.fromISO(s)\n}\n\nfunction parseISODates(arr: string[]): CalendarDate[] {\n return arr.map((s) => CalendarDate.fromISO(s)).filter((d): d is CalendarDate => d !== null)\n}\n\nfunction parseConfigRule(rule: CalendarConfigRule): DateConstraintRule | null {\n const from = rule.from ? parseISODate(rule.from) : null\n const to = rule.to ? parseISODate(rule.to) : null\n\n // A rule must have either a date range (from+to) or recurring months\n const hasDateRange = from !== null && to !== null\n const hasMonths = Array.isArray(rule.months) && rule.months.length > 0\n if (!hasDateRange && !hasMonths) return null\n\n const result: DateConstraintRule = {}\n if (hasDateRange) {\n result.from = from\n result.to = to\n }\n if (hasMonths) {\n result.months = rule.months\n }\n if (rule.priority !== undefined) {\n result.priority = rule.priority\n }\n\n if (rule.minDate) {\n const d = parseISODate(rule.minDate)\n if (d) result.minDate = d\n }\n if (rule.maxDate) {\n const d = parseISODate(rule.maxDate)\n if (d) result.maxDate = d\n }\n if (rule.disabledDates) {\n result.disabledDates = parseISODates(rule.disabledDates)\n }\n if (rule.disabledDaysOfWeek) {\n result.disabledDaysOfWeek = rule.disabledDaysOfWeek\n }\n if (rule.enabledDates) {\n result.enabledDates = parseISODates(rule.enabledDates)\n }\n if (rule.enabledDaysOfWeek) {\n result.enabledDaysOfWeek = rule.enabledDaysOfWeek\n }\n if (rule.disabledMonths) {\n result.disabledMonths = rule.disabledMonths\n }\n if (rule.enabledMonths) {\n result.enabledMonths = rule.enabledMonths\n }\n if (rule.disabledYears) {\n result.disabledYears = rule.disabledYears\n }\n if (rule.enabledYears) {\n result.enabledYears = rule.enabledYears\n }\n if (rule.minRange !== undefined) {\n result.minRange = rule.minRange\n }\n if (rule.maxRange !== undefined) {\n result.maxRange = rule.maxRange\n }\n\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Config validation\n// ---------------------------------------------------------------------------\n\n/**\n * Validate calendar configuration and warn about invalid combinations.\n * Does not throw — the component still initialises with best-effort defaults.\n */\nfunction validateConfig(config: CalendarConfig): void {\n const warn = (msg: string) => console.warn(`[reach-calendar] ${msg}`)\n\n // months must be a positive integer\n if (config.months !== undefined && (config.months < 1 || !Number.isInteger(config.months))) {\n warn(`months must be a positive integer, got: ${config.months}`)\n }\n\n // wizard + scrollable combo\n if (config.wizard && config.months && config.months >= 3) {\n warn('months >= 3 (scrollable) is not compatible with wizard mode; using months: 1')\n }\n\n // firstDay must be 0-6\n if (config.firstDay !== undefined && (config.firstDay < 0 || config.firstDay > 6)) {\n warn(`firstDay must be 0-6, got: ${config.firstDay}`)\n }\n\n // Invalid date strings\n if (config.minDate && !CalendarDate.fromISO(config.minDate)) {\n warn(`invalid minDate: \"${config.minDate}\"`)\n }\n if (config.maxDate && !CalendarDate.fromISO(config.maxDate)) {\n warn(`invalid maxDate: \"${config.maxDate}\"`)\n }\n\n // minDate must be before maxDate\n if (config.minDate && config.maxDate) {\n const min = CalendarDate.fromISO(config.minDate)\n const max = CalendarDate.fromISO(config.maxDate)\n if (min && max && min.isAfter(max)) {\n warn(`minDate \"${config.minDate}\" is after maxDate \"${config.maxDate}\"`)\n }\n }\n\n // minRange <= maxRange\n if (\n config.minRange !== undefined &&\n config.maxRange !== undefined &&\n config.minRange > config.maxRange\n ) {\n warn(`minRange (${config.minRange}) exceeds maxRange (${config.maxRange})`)\n }\n\n // wizard with non-single mode\n if (config.wizard && config.mode && config.mode !== 'single') {\n warn(`wizard mode is designed for single selection; mode \"${config.mode}\" may not work as expected`)\n }\n\n // timezone must be a valid IANA timezone string\n if (config.timezone) {\n try {\n Intl.DateTimeFormat(undefined, { timeZone: config.timezone })\n } catch {\n warn(`invalid timezone: \"${config.timezone}\"`)\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Constraint builder (reusable for initial config + runtime updates)\n// ---------------------------------------------------------------------------\n\ninterface ConstraintFunctions {\n isDisabledDate: (d: CalendarDate) => boolean\n isRangeValid: (start: CalendarDate, end: CalendarDate) => boolean\n isMonthDisabled: (year: number, month: number) => boolean\n isYearDisabled: (year: number) => boolean\n getDisabledReasons: (d: CalendarDate) => string[]\n}\n\n/**\n * Build constraint functions from a CalendarConfig (or partial update).\n * Reused by both initial config parsing and `updateConstraints()`.\n */\nfunction buildConstraints(\n cfg: Partial<CalendarConfig>,\n messages?: ConstraintMessages,\n): ConstraintFunctions {\n const opts: DateConstraintOptions = {}\n\n if (cfg.minDate) {\n const d = CalendarDate.fromISO(cfg.minDate)\n if (d) opts.minDate = d\n }\n if (cfg.maxDate) {\n const d = CalendarDate.fromISO(cfg.maxDate)\n if (d) opts.maxDate = d\n }\n if (cfg.disabledDates) {\n opts.disabledDates = parseISODates(cfg.disabledDates)\n }\n if (cfg.disabledDaysOfWeek) {\n opts.disabledDaysOfWeek = cfg.disabledDaysOfWeek\n }\n if (cfg.enabledDates) {\n opts.enabledDates = parseISODates(cfg.enabledDates)\n }\n if (cfg.enabledDaysOfWeek) {\n opts.enabledDaysOfWeek = cfg.enabledDaysOfWeek\n }\n if (cfg.disabledMonths) {\n opts.disabledMonths = cfg.disabledMonths\n }\n if (cfg.enabledMonths) {\n opts.enabledMonths = cfg.enabledMonths\n }\n if (cfg.disabledYears) {\n opts.disabledYears = cfg.disabledYears\n }\n if (cfg.enabledYears) {\n opts.enabledYears = cfg.enabledYears\n }\n if (cfg.minRange !== undefined) {\n opts.minRange = cfg.minRange\n }\n if (cfg.maxRange !== undefined) {\n opts.maxRange = cfg.maxRange\n }\n if (cfg.rules) {\n const parsedRules = cfg.rules\n .map((r) => parseConfigRule(r))\n .filter((r): r is DateConstraintRule => r !== null)\n if (parsedRules.length > 0) {\n opts.rules = parsedRules\n }\n }\n\n return {\n isDisabledDate: createDateConstraint(opts),\n isRangeValid: createRangeValidator(opts),\n isMonthDisabled: createMonthConstraint(opts),\n isYearDisabled: createYearConstraint(opts),\n getDisabledReasons: createDisabledReasons(opts, messages),\n }\n}\n\n/** Constraint-related keys from CalendarConfig. */\nconst CONSTRAINT_KEYS = [\n 'minDate', 'maxDate', 'disabledDates', 'disabledDaysOfWeek',\n 'enabledDates', 'enabledDaysOfWeek', 'disabledMonths', 'enabledMonths',\n 'disabledYears', 'enabledYears', 'minRange', 'maxRange', 'rules',\n] as const\n\ntype ConstraintConfig = Pick<CalendarConfig, (typeof CONSTRAINT_KEYS)[number]>\n\n/** Extract only the constraint-related properties from a config object. */\nfunction extractConstraintConfig(cfg: Partial<CalendarConfig>): ConstraintConfig {\n const result: Partial<ConstraintConfig> = {}\n for (const key of CONSTRAINT_KEYS) {\n if (cfg[key] !== undefined) {\n ;(result as Record<string, unknown>)[key] = cfg[key]\n }\n }\n return result as ConstraintConfig\n}\n\n// ---------------------------------------------------------------------------\n// Component factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create the Alpine component data object for the calendar.\n *\n * This factory is called by `Alpine.data('calendar', createCalendarData)`.\n * The returned object becomes the reactive component state.\n */\nexport function createCalendarData(config: CalendarConfig = {}, Alpine?: { initTree: (el: HTMLElement) => void }) {\n // --- Validate config ---\n validateConfig(config)\n\n // --- Parse config with defaults ---\n const mode = config.mode ?? 'single'\n const display = config.display ?? 'inline'\n const format = config.format ?? 'DD/MM/YYYY'\n const firstDay = config.firstDay ?? 0\n let timezone = config.timezone\n if (timezone) {\n try {\n Intl.DateTimeFormat(undefined, { timeZone: timezone })\n } catch {\n timezone = undefined\n }\n }\n const wizardConfig = config.wizard ?? false\n const rawMonthCount = config.months ?? 1\n // Force months: 1 when wizard + scrollable\n const monthCount = (wizardConfig && rawMonthCount >= 3) ? 1 : rawMonthCount\n const isScrollable = monthCount >= 3\n const scrollHeight = config.scrollHeight ?? 400\n const wizard = !!wizardConfig\n const wizardMode: 'none' | 'full' | 'year-month' | 'month-day' =\n wizardConfig === true ? 'full'\n : wizardConfig === false ? 'none'\n : wizardConfig\n const wizardTotalSteps = wizardMode === 'none' ? 0 : wizardMode === 'full' ? 3 : 2\n const wizardStartView: 'days' | 'months' | 'years' =\n wizardMode === 'full' || wizardMode === 'year-month' ? 'years'\n : wizardMode === 'month-day' ? 'months'\n : 'days'\n const useMask = config.mask ?? true\n const showWeekNumbers = config.showWeekNumbers ?? false\n const presets: RangePreset[] = config.presets ?? []\n const inputName = config.name ?? ''\n const inputId = config.inputId ?? null\n const inputRef = config.inputRef ?? 'rc-input'\n const locale = config.locale\n const closeOnSelect = config.closeOnSelect ?? true\n const beforeSelectCb = config.beforeSelect ?? null\n\n // --- Build constraint functions ---\n const constraintMessages = config.constraintMessages\n const constraints = buildConstraints(config, constraintMessages)\n\n // --- Create selection model ---\n function buildSelection(): Selection {\n if (mode === 'multiple') return new MultipleSelection()\n if (mode === 'range') return new RangeSelection()\n return new SingleSelection()\n }\n\n const selection = buildSelection()\n\n // --- Parse initial value ---\n if (config.value) {\n if (mode === 'single') {\n const d = parseDate(config.value, format) ?? CalendarDate.fromISO(config.value)\n if (d && !constraints.isDisabledDate(d)) selection.toggle(d)\n } else if (mode === 'range') {\n const range = parseDateRange(config.value, format)\n if (range) {\n let [start, end] = range\n if (end.isBefore(start)) { const tmp = start; start = end; end = tmp }\n if (!constraints.isDisabledDate(start) && !constraints.isDisabledDate(end) && constraints.isRangeValid(start, end)) {\n selection.toggle(start)\n selection.toggle(end)\n }\n }\n } else if (mode === 'multiple') {\n const dates = parseDateMultiple(config.value, format)\n for (const d of dates) {\n if (!constraints.isDisabledDate(d)) selection.toggle(d)\n }\n }\n }\n\n // --- Resolve today ---\n const today = CalendarDate.today(timezone)\n\n // --- Determine initial viewing month/year ---\n const initialDates = selection.toArray()\n const defaultViewDate = (initialDates.length > 0 ? initialDates[0] : today) as CalendarDate\n\n // Wizard: center year picker around ~30 years ago (full & year-month modes)\n const viewDate = (wizardMode === 'full' || wizardMode === 'year-month')\n ? new CalendarDate(today.year - 30, today.month, today.day)\n : defaultViewDate\n\n // --- Compute initial inputValue ---\n function computeFormattedValue(sel: Selection): string {\n const dates = sel.toArray()\n if (dates.length === 0) return ''\n const first = dates[0] as CalendarDate\n if (mode === 'range' && dates.length === 2) {\n return formatRange(first, dates[1] as CalendarDate, format)\n }\n if (mode === 'multiple') {\n return formatMultiple(dates, format)\n }\n return formatDate(first, format)\n }\n\n // ---------------------------------------------------------------------------\n // Return the Alpine data object\n // ---------------------------------------------------------------------------\n\n return {\n // --- Config (exposed to templates) ---\n mode,\n display,\n format,\n monthCount,\n firstDay,\n wizard,\n wizardMode,\n wizardTotalSteps,\n showWeekNumbers,\n presets,\n inputName,\n\n // --- Reactive state ---\n month: viewDate.month,\n year: viewDate.year,\n view: (wizard ? wizardStartView : 'days') as 'days' | 'months' | 'years',\n isOpen: display === 'inline',\n grid: [] as MonthGrid[],\n monthGrid: [] as MonthCell[][],\n yearGrid: [] as YearCell[][],\n inputValue: computeFormattedValue(selection),\n popupStyle: display === 'popup'\n ? 'position:fixed;inset:0;z-index:50;'\n : '',\n focusedDate: null as CalendarDate | null,\n hoverDate: null as CalendarDate | null,\n wizardStep: (wizard ? 1 : 0) as number,\n _wizardYear: null as number | null,\n _wizardMonth: null as number | null,\n _wizardDay: null as number | null,\n\n // --- Internal state ---\n _navDirection: '' as '' | 'next' | 'prev',\n _selection: selection,\n _today: today,\n _constraintConfig: extractConstraintConfig(config),\n _isDisabledDate: constraints.isDisabledDate,\n _isRangeValid: constraints.isRangeValid,\n _isMonthDisabled: constraints.isMonthDisabled,\n _isYearDisabled: constraints.isYearDisabled,\n _getDisabledReasons: constraints.getDisabledReasons,\n _inputEl: null as HTMLInputElement | null,\n _detachInput: null as (() => void) | null,\n _syncing: false,\n _suppressFocusOpen: false,\n _Alpine: (Alpine ?? null) as { initTree: (el: HTMLElement) => void } | null,\n _autoRendered: false,\n\n // Scrollable multi-month state\n isScrollable,\n _scrollHeight: scrollHeight,\n _scrollContainerEl: null as HTMLElement | null,\n _scrollObserver: null as IntersectionObserver | null,\n /** Index into grid[] of the month currently visible at top of scroll viewport. */\n _scrollVisibleIndex: 0,\n /**\n * Reactive counter bumped on selection changes. Read by dayClasses() so Alpine\n * re-evaluates class bindings without needing a full grid rebuild.\n */\n _selectionRev: 0,\n\n // --- Accessibility: live region ---\n _statusMessage: '' as string,\n\n // --- Getters ---\n\n get selectedDates(): CalendarDate[] {\n return this._selection.toArray()\n },\n\n get formattedValue(): string {\n return computeFormattedValue(this._selection)\n },\n\n /** ISO string values for hidden form inputs. */\n get hiddenInputValues(): string[] {\n return this._selection.toArray().map((d: CalendarDate) => d.toISO())\n },\n\n /** ISO string of focused date for aria-activedescendant binding. */\n get focusedDateISO(): string {\n return this.focusedDate ? this.focusedDate.toISO() : ''\n },\n\n /** ID for the popup input element (for external label association). */\n get inputId(): string | null {\n return inputId\n },\n\n /** Accessible label for the popup input element. */\n get inputAriaLabel(): string {\n if (mode === 'range') return 'Select date range'\n if (mode === 'multiple') return 'Select dates'\n if (wizard) return 'Select birth date'\n return 'Select date'\n },\n\n /** Accessible label for the popup dialog. */\n get popupAriaLabel(): string {\n if (wizard) return 'Birth date wizard'\n if (mode === 'range') return 'Date range picker'\n return 'Date picker'\n },\n\n /** Label for the current wizard step (e.g. \"Select Year\"). */\n get wizardStepLabel(): string {\n if (!this.wizard) return ''\n if (wizardMode === 'full') {\n if (this.wizardStep === 1) return 'Select Year'\n if (this.wizardStep === 2) return 'Select Month'\n return 'Select Day'\n }\n if (wizardMode === 'year-month') {\n if (this.wizardStep === 1) return 'Select Year'\n return 'Select Month'\n }\n if (wizardMode === 'month-day') {\n if (this.wizardStep === 1) return 'Select Month'\n return 'Select Day'\n }\n return ''\n },\n\n /** Summary of wizard selections so far (e.g. \"1995 · June · 15\"). */\n get wizardSummary(): string {\n if (!wizard) return ''\n const parts: string[] = []\n if (this._wizardYear !== null) parts.push(String(this._wizardYear))\n if (this._wizardMonth !== null) {\n const d = new CalendarDate(this._wizardYear ?? this.year, this._wizardMonth, 1)\n parts.push(d.format({ month: 'long' }, locale))\n }\n if (this._wizardDay !== null) parts.push(String(this._wizardDay))\n return parts.join(' \\u00b7 ')\n },\n\n /**\n * Localized short weekday headers in the correct order for the current `firstDay`.\n * Returns an array of 7 short names (e.g., [\"Mo\", \"Tu\", \"We\", ...]).\n */\n get weekdayHeaders(): string[] {\n const headers: string[] = []\n // Use a reference Sunday (Jan 4 2026 is a Sunday)\n const refSunday = new Date(2026, 0, 4)\n for (let i = 0; i < 7; i++) {\n const dayIndex = (this.firstDay + i) % 7\n const d = new Date(refSunday)\n d.setDate(refSunday.getDate() + dayIndex)\n headers.push(\n new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(d),\n )\n }\n return headers\n },\n\n // --- Lifecycle ---\n\n init() {\n // Auto-template injection: append calendar template if not already present\n const el = alpine(this).$el\n const hasCalendar = el.querySelector('.rc-calendar') !== null\n if (!hasCalendar && config.template !== false && this._Alpine?.initTree) {\n const fragment = document.createRange().createContextualFragment(\n generateCalendarTemplate({\n display: this.display,\n isDualMonth: this.monthCount === 2,\n isWizard: this.wizardMode !== 'none',\n hasName: !!this.inputName,\n showWeekNumbers: this.showWeekNumbers,\n hasPresets: this.presets.length > 0,\n isScrollable: this.isScrollable,\n scrollHeight: this._scrollHeight,\n }),\n )\n const newElements = Array.from(fragment.children).filter(\n (c): c is HTMLElement => c instanceof HTMLElement,\n )\n el.appendChild(fragment)\n for (const child of newElements) {\n this._Alpine.initTree(child)\n }\n this._autoRendered = true\n }\n\n this._rebuildGrid()\n this._rebuildMonthGrid()\n this._rebuildYearGrid()\n\n // Alpine $watch: rebuild grids and dispatch events on state changes\n alpine(this).$watch('month', () => {\n this._rebuildGrid()\n this._emitNavigate()\n this._announceNavigation()\n if (this.isScrollable) {\n alpine(this).$nextTick(() => { this._rebindScrollObserver() })\n }\n })\n alpine(this).$watch('year', () => {\n this._rebuildGrid()\n this._rebuildMonthGrid()\n this._rebuildYearGrid()\n this._emitNavigate()\n this._announceNavigation()\n if (this.isScrollable) {\n alpine(this).$nextTick(() => { this._rebindScrollObserver() })\n }\n })\n alpine(this).$watch('view', () => {\n this._emitViewChange()\n this._announceViewChange()\n })\n\n // Auto-bind to x-ref input if present\n alpine(this).$nextTick(() => {\n const refs = alpine(this).$refs\n if (refs && refs[inputRef] && refs[inputRef] instanceof HTMLInputElement) {\n this.bindInput(refs[inputRef])\n } else if (this.display === 'popup') {\n console.warn(\n `[reach-calendar] Popup mode requires an <input x-ref=\"${inputRef}\"> inside the component container.`,\n )\n }\n // Init scroll listener for scrollable multi-month\n if (this.isScrollable) {\n this._initScrollListener()\n }\n })\n },\n\n destroy() {\n if (this._scrollObserver) {\n this._scrollObserver.disconnect()\n this._scrollObserver = null\n }\n this._scrollContainerEl = null\n if (this._detachInput) {\n this._detachInput()\n this._detachInput = null\n }\n this._inputEl = null\n if (this._autoRendered) {\n const el = alpine(this).$el\n el.querySelector('.rc-popup-overlay')?.remove()\n el.querySelector('.rc-calendar')?.remove()\n this._autoRendered = false\n }\n },\n\n // --- Grid ---\n\n _rebuildGrid() {\n this.grid = generateMonths(\n this.year,\n this.month,\n this.monthCount,\n this.firstDay,\n this._today,\n this._isDisabledDate,\n )\n },\n\n /** Rebuild the 3×4 month picker grid for the current year. */\n _rebuildMonthGrid() {\n this.monthGrid = generateMonthGrid(this.year, this._today, locale, this._isMonthDisabled)\n },\n\n /** Rebuild the 3×4 year picker grid for the current year's 12-year block. */\n _rebuildYearGrid() {\n this.yearGrid = generateYearGrid(this.year, this._today, this._isYearDisabled)\n },\n\n /**\n * Build a flat array of grid items for template rendering, interleaving week number\n * markers with day cells. Used by the auto-rendered template when `showWeekNumbers` is true.\n */\n dayGridItems(mg: MonthGrid): { isWeekNumber: boolean; weekNumber: number; cell: DayCell; key: string }[] {\n const items: { isWeekNumber: boolean; weekNumber: number; cell: DayCell; key: string }[] = []\n for (let ri = 0; ri < mg.rows.length; ri++) {\n const row = mg.rows[ri]\n if (!row || row.length === 0) continue\n const firstCell = row[0] as DayCell\n items.push({\n isWeekNumber: true,\n weekNumber: mg.weekNumbers[ri] ?? 0,\n // Placeholder cell — template guards prevent access when isWeekNumber is true\n cell: firstCell,\n key: `wn-${ri}`,\n })\n for (const cell of row) {\n items.push({\n isWeekNumber: false,\n weekNumber: 0,\n cell,\n key: cell.date.toISO(),\n })\n }\n }\n return items\n },\n\n /** Year label for the month view header (e.g. \"2026\"). */\n get yearLabel(): string {\n return String(this.year)\n },\n\n /** Decade range label for the year view header (e.g. \"2016 – 2027\"). */\n get decadeLabel(): string {\n const startYear = Math.floor(this.year / 12) * 12\n return `${startYear} – ${startYear + 11}`\n },\n\n /**\n * Whether backward navigation is possible from the current position.\n *\n * - Days view: checks if the previous month has any selectable dates.\n * - Months view: checks if the previous year has any selectable months.\n * - Years view: checks if the previous 12-year block has any selectable years.\n *\n * Usage in Alpine template:\n * ```html\n * <button @click=\"prev()\" :disabled=\"!canGoPrev\">←</button>\n * ```\n */\n get canGoPrev(): boolean {\n if (this.view === 'days') {\n if (this.isScrollable) return false\n const d = new CalendarDate(this.year, this.month, 1).addMonths(-1)\n return !this._isMonthDisabled(d.year, d.month)\n }\n if (this.view === 'months') {\n return !this._isYearDisabled(this.year - 1)\n }\n if (this.view === 'years') {\n const blockStart = Math.floor(this.year / 12) * 12\n // Check if any year in the previous 12-year block is enabled\n for (let y = blockStart - 12; y < blockStart; y++) {\n if (!this._isYearDisabled(y)) return true\n }\n return false\n }\n return true\n },\n\n /**\n * Whether forward navigation is possible from the current position.\n *\n * - Days view: checks if the next month has any selectable dates.\n * - Months view: checks if the next year has any selectable months.\n * - Years view: checks if the next 12-year block has any selectable years.\n *\n * Usage in Alpine template:\n * ```html\n * <button @click=\"next()\" :disabled=\"!canGoNext\">→</button>\n * ```\n */\n get canGoNext(): boolean {\n if (this.view === 'days') {\n if (this.isScrollable) return false\n const d = new CalendarDate(this.year, this.month, 1).addMonths(1)\n return !this._isMonthDisabled(d.year, d.month)\n }\n if (this.view === 'months') {\n return !this._isYearDisabled(this.year + 1)\n }\n if (this.view === 'years') {\n const blockStart = Math.floor(this.year / 12) * 12\n // Check if any year in the next 12-year block is enabled\n for (let y = blockStart + 12; y < blockStart + 24; y++) {\n if (!this._isYearDisabled(y)) return true\n }\n return false\n }\n return true\n },\n\n /**\n * Compute CSS class object for a year cell in the year picker view.\n */\n yearClasses(cell: YearCell): Record<string, boolean> {\n const selected = this.year === cell.year && this.view === 'months'\n return {\n 'rc-year': true,\n 'rc-year--current': cell.isCurrentYear,\n 'rc-year--selected': selected,\n 'rc-year--disabled': cell.isDisabled,\n }\n },\n\n /**\n * Compute CSS class object for a month cell in the month picker view.\n */\n monthClasses(cell: MonthCell): Record<string, boolean> {\n const selected = this.month === cell.month && this.view === 'days'\n return {\n 'rc-month': true,\n 'rc-month--current': cell.isCurrentMonth,\n 'rc-month--selected': selected,\n 'rc-month--disabled': cell.isDisabled,\n }\n },\n\n /**\n * Get a localized \"Month Year\" label for a specific month grid.\n * @param gridIndex - Index into the `grid` array (0 for first month, 1 for second).\n */\n monthYearLabel(gridIndex: number): string {\n const g = this.grid[gridIndex]\n if (!g) return ''\n const d = new CalendarDate(g.year, g.month, 1)\n return d.format({ month: 'long', year: 'numeric' }, locale)\n },\n\n /**\n * Compute CSS class object for a day cell.\n * Returns an object keyed by class name with boolean values, suitable for Alpine `:class`.\n */\n dayClasses(\n cell: { date: CalendarDate; isCurrentMonth: boolean; isToday: boolean; isDisabled: boolean },\n ): Record<string, boolean> {\n // Read _selectionRev to register it as an Alpine dependency.\n // This lets Alpine re-evaluate class bindings when selection changes\n // without needing a full grid rebuild (important for large month counts).\n void this._selectionRev\n const d = cell.date\n const selected = this.isSelected(d)\n const rangeStart = this.isRangeStart(d)\n const rangeEnd = this.isRangeEnd(d)\n const inRange = this.isInRange(d, this.hoverDate ?? undefined)\n const isOtherMonth = !cell.isCurrentMonth\n\n // Hover preview constraint feedback: mark dates that would form an invalid range\n let rangeInvalid = false\n if (\n mode === 'range' &&\n this.hoverDate !== null &&\n !cell.isDisabled &&\n !selected &&\n (this._selection as RangeSelection).isPartial()\n ) {\n rangeInvalid = !this.isDateSelectableForRange(d)\n }\n\n return {\n 'rc-day': true,\n 'rc-day--today': cell.isToday,\n 'rc-day--selected': selected,\n 'rc-day--range-start': rangeStart,\n 'rc-day--range-end': rangeEnd,\n 'rc-day--in-range': inRange && !rangeStart && !rangeEnd,\n 'rc-day--disabled': cell.isDisabled,\n 'rc-day--other-month': isOtherMonth,\n 'rc-day--hidden': isOtherMonth && this.monthCount > 1,\n 'rc-day--focused': this.focusedDate !== null && this.focusedDate.isSame(d),\n 'rc-day--range-invalid': rangeInvalid,\n }\n },\n\n /**\n * Get tooltip text for a day cell explaining why it is disabled.\n * Returns an empty string for enabled dates.\n */\n dayTitle(\n cell: { date: CalendarDate; isDisabled: boolean },\n ): string {\n if (!cell.isDisabled) return ''\n return this._getDisabledReasons(cell.date).join('; ')\n },\n\n // --- Input binding ---\n\n /**\n * Bind an input element to the calendar.\n *\n * Sets up input masking (if enabled), syncs the initial value, and\n * attaches an input listener to keep `inputValue` in sync.\n *\n * Usage:\n * ```html\n * <!-- Alpine component root with calendar() -->\n * <input x-ref=\"rc-input\" type=\"text\">\n * ```\n * The component auto-binds to the ref named by `config.inputRef` (default: `rc-input`) during init().\n * For custom refs, set `inputRef` in config or call `bindInput($refs.myInput)` explicitly.\n */\n bindInput(el: HTMLInputElement) {\n // Clean up previous binding\n if (this._detachInput) {\n this._detachInput()\n this._detachInput = null\n }\n\n this._inputEl = el\n\n // Set initial value\n el.value = this.inputValue\n\n // Attach mask if enabled\n if (useMask) {\n this._detachInput = attachMask(el, format)\n // attachMask reformats the existing value through the mask\n this.inputValue = el.value\n }\n\n // Listen for input changes to keep inputValue in sync\n const syncHandler = () => {\n if (!this._syncing) {\n this.inputValue = el.value\n }\n }\n el.addEventListener('input', syncHandler)\n\n // Attach focus/blur handlers for popup mode\n const focusHandler = () => this.handleFocus()\n const blurHandler = () => this.handleBlur()\n el.addEventListener('focus', focusHandler)\n el.addEventListener('blur', blurHandler)\n\n // Set aria attributes for popup combobox pattern\n if (display === 'popup') {\n el.setAttribute('role', 'combobox')\n el.setAttribute('aria-haspopup', 'dialog')\n el.setAttribute('aria-expanded', String(this.isOpen))\n el.setAttribute('autocomplete', 'off')\n if (inputId && !el.id) {\n el.id = inputId\n }\n if (!el.getAttribute('aria-label')) {\n el.setAttribute('aria-label', this.inputAriaLabel)\n }\n }\n\n // Extend detach to include all listeners and aria attributes\n const prevDetach = this._detachInput\n this._detachInput = () => {\n prevDetach?.()\n el.removeEventListener('input', syncHandler)\n el.removeEventListener('focus', focusHandler)\n el.removeEventListener('blur', blurHandler)\n if (display === 'popup') {\n el.removeAttribute('role')\n el.removeAttribute('aria-haspopup')\n el.removeAttribute('aria-expanded')\n el.removeAttribute('autocomplete')\n }\n }\n\n // Set placeholder if not already set\n if (!el.placeholder) {\n el.placeholder = format.toLowerCase()\n }\n },\n\n /**\n * Handle input event for unbound inputs (using `:value` + `@input`).\n * When using `bindInput()`, this is handled automatically.\n */\n handleInput(e: Event) {\n const el = e.target as HTMLInputElement\n this.inputValue = el.value\n },\n\n /**\n * Handle focus on the input element.\n * Opens the calendar popup in popup display mode.\n */\n handleFocus() {\n if (this._suppressFocusOpen) {\n this._suppressFocusOpen = false\n return\n }\n this.open()\n },\n\n /**\n * Handle blur on the input element.\n * Parses the typed value, updates selection if valid, and reformats the input.\n */\n handleBlur() {\n const value = this._inputEl ? this._inputEl.value : this.inputValue\n\n // Empty input → clear selection\n if (!value.trim()) {\n if (this._selection.toArray().length > 0) {\n this._selection.clear()\n this._selectionRev++\n this._emitChange()\n }\n this._syncInputFromSelection()\n return\n }\n\n // Try to parse and update selection\n let changed = false\n\n if (mode === 'single') {\n const parsed = parseDate(value, format) ?? CalendarDate.fromISO(value)\n if (parsed && !this._isDisabledDate(parsed)) {\n this._selection.clear()\n this._selection.toggle(parsed)\n this.month = parsed.month\n this.year = parsed.year\n changed = true\n }\n } else if (mode === 'range') {\n const range = parseDateRange(value, format)\n if (range) {\n let [start, end] = range\n if (end.isBefore(start)) { const tmp = start; start = end; end = tmp }\n if (\n !this._isDisabledDate(start) &&\n !this._isDisabledDate(end) &&\n this._isRangeValid(start, end)\n ) {\n this._selection.clear()\n this._selection.toggle(start)\n this._selection.toggle(end)\n this.month = start.month\n this.year = start.year\n changed = true\n }\n }\n } else if (mode === 'multiple') {\n const dates = parseDateMultiple(value, format)\n const valid = dates.filter((d) => !this._isDisabledDate(d))\n if (valid.length > 0) {\n this._selection.clear()\n for (const d of valid) {\n this._selection.toggle(d)\n }\n const first = valid[0] as CalendarDate\n this.month = first.month\n this.year = first.year\n changed = true\n }\n }\n\n if (changed) {\n this._selectionRev++\n this._emitChange()\n }\n\n // Always reformat input to canonical display\n this._syncInputFromSelection()\n },\n\n // --- Internal: input sync ---\n\n /** Update inputValue and bound input element from current selection. */\n _syncInputFromSelection() {\n this._syncing = true\n this.inputValue = this.formattedValue\n\n if (this._inputEl) {\n this._inputEl.value = this.inputValue\n }\n\n this._syncing = false\n },\n\n /** Announce a message to screen readers via the aria-live status region. */\n _announce(message: string) {\n this._statusMessage = ''\n alpine(this).$nextTick(() => {\n this._statusMessage = message\n })\n },\n\n /** Announce the current navigation context (month/year/decade) for screen readers. */\n _announceNavigation() {\n if (this.view === 'days') {\n if (this.monthCount > 1 && !this.isScrollable) {\n // Dual-month: announce both months\n const labels: string[] = []\n for (let i = 0; i < this.grid.length; i++) {\n labels.push(this.monthYearLabel(i))\n }\n this._announce(labels.join(' \\u2013 '))\n } else {\n this._announce(this.monthYearLabel(0))\n }\n } else if (this.view === 'months') {\n this._announce('Year: ' + this.year)\n } else if (this.view === 'years') {\n this._announce('Decade: ' + this.decadeLabel)\n }\n },\n\n /** Announce the new view after a view switch for screen readers. */\n _announceViewChange() {\n if (this.view === 'days') {\n this._announce(this.monthYearLabel(0))\n } else if (this.view === 'months') {\n this._announce('Select month, ' + this.year)\n } else if (this.view === 'years') {\n this._announce('Select year, ' + this.decadeLabel)\n }\n },\n\n /** Dispatch calendar:change event with current selection state. */\n _emitChange() {\n alpine(this).$dispatch('calendar:change', {\n value: this._selection.toValue(),\n dates: this._selection.toArray().map((d: CalendarDate) => d.toISO()),\n formatted: this.formattedValue,\n })\n },\n\n /** Dispatch calendar:navigate event on month/year change. */\n _emitNavigate() {\n alpine(this).$dispatch('calendar:navigate', {\n year: this.year,\n month: this.month,\n view: this.view,\n })\n },\n\n /** Dispatch calendar:view-change event on view switch. */\n _emitViewChange() {\n alpine(this).$dispatch('calendar:view-change', {\n view: this.view,\n year: this.year,\n month: this.month,\n })\n },\n\n // --- Navigation ---\n\n prev() {\n this._navDirection = 'prev'\n if (this.view === 'days') {\n if (this.isScrollable) return\n const d = new CalendarDate(this.year, this.month, 1).addMonths(-1)\n this.month = d.month\n this.year = d.year\n } else if (this.view === 'months') {\n this.year--\n } else if (this.view === 'years') {\n this.year -= 12\n }\n },\n\n next() {\n this._navDirection = 'next'\n if (this.view === 'days') {\n if (this.isScrollable) return\n const d = new CalendarDate(this.year, this.month, 1).addMonths(1)\n this.month = d.month\n this.year = d.year\n } else if (this.view === 'months') {\n this.year++\n } else if (this.view === 'years') {\n this.year += 12\n }\n },\n\n goToToday() {\n this.month = this._today.month\n this.year = this._today.year\n this.view = 'days'\n },\n\n // --- Selection ---\n\n selectDate(dateOrISO: CalendarDate | string) {\n const date = typeof dateOrISO === 'string' ? CalendarDate.fromISO(dateOrISO) : dateOrISO\n if (!date) return\n if (this._isDisabledDate(date)) return\n\n // Range validation: when about to complete a range, check min/max range\n if (mode === 'range') {\n const range = this._selection as RangeSelection\n const rangeStart = range.getStart()\n if (range.isPartial() && rangeStart && !date.isSame(rangeStart)) {\n // Determine actual start/end after potential swap\n let start: CalendarDate = rangeStart\n let end: CalendarDate = date\n if (end.isBefore(start)) {\n const tmp = start\n start = end\n end = tmp\n }\n if (!this._isRangeValid(start, end)) return\n }\n }\n\n // beforeSelect callback: allow consumers to prevent selection\n if (beforeSelectCb) {\n const action = this._selection.isSelected(date) ? 'deselect' : 'select'\n const result = beforeSelectCb(date, {\n mode,\n selectedDates: this._selection.toArray(),\n action,\n })\n if (result === false) return\n }\n\n // Capture pre-toggle state for announcements\n const wasSelected = this._selection.isSelected(date)\n const wasPartialRange = mode === 'range' && (this._selection as RangeSelection).isPartial()\n\n this._selection.toggle(date)\n if (wizard) this._wizardDay = date.day\n // Bump reactive counter so Alpine re-evaluates dayClasses() bindings.\n // No grid rebuild needed — grid structure doesn't change on selection.\n this._selectionRev++\n this._emitChange()\n this._syncInputFromSelection()\n\n // Announce selection to screen readers\n const dateLabel = date.format({ weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }, locale)\n if (mode === 'single') {\n this._announce(dateLabel + ' selected')\n } else if (mode === 'multiple') {\n const count = this._selection.toArray().length\n if (wasSelected) {\n this._announce(dateLabel + ' deselected. ' + count + ' dates selected')\n } else {\n this._announce(dateLabel + ' selected. ' + count + ' dates selected')\n }\n } else if (mode === 'range') {\n const range = this._selection as RangeSelection\n if (range.isPartial()) {\n this._announce('Range start: ' + dateLabel + '. Select end date')\n } else if (wasPartialRange) {\n const dates = range.toArray()\n if (dates.length === 2) {\n const startLabel = (dates[0] as CalendarDate).format({ weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }, locale)\n const endLabel = (dates[1] as CalendarDate).format({ weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }, locale)\n this._announce('Range: ' + startLabel + ' to ' + endLabel)\n }\n }\n }\n\n // Auto-close popup after selection is complete\n if (closeOnSelect && display === 'popup' && this.isOpen) {\n const isComplete =\n mode === 'single' ||\n (mode === 'range' && !(this._selection as RangeSelection).isPartial()) ||\n mode === 'multiple'\n if (isComplete) this.close()\n }\n },\n\n isSelected(date: CalendarDate): boolean {\n return this._selection.isSelected(date)\n },\n\n isInRange(date: CalendarDate, hoverDate?: CalendarDate): boolean {\n if (mode !== 'range') return false\n return (this._selection as RangeSelection).isInRange(date, hoverDate)\n },\n\n isRangeStart(date: CalendarDate): boolean {\n if (mode !== 'range') return false\n const start = (this._selection as RangeSelection).getStart()\n return start !== null && date.isSame(start)\n },\n\n isRangeEnd(date: CalendarDate): boolean {\n if (mode !== 'range') return false\n const end = (this._selection as RangeSelection).getEnd()\n return end !== null && date.isSame(end)\n },\n\n /**\n * Check whether selecting `date` as a range endpoint would produce a valid range.\n *\n * Returns `true` when:\n * - The date is not disabled AND\n * - Either no range start is selected yet (any non-disabled date can start), OR\n * - Completing the range with this date would satisfy minRange/maxRange constraints.\n *\n * Returns `false` for non-range modes.\n *\n * Useful for dimming dates in the UI that would result in an invalid range.\n */\n isDateSelectableForRange(date: CalendarDate): boolean {\n if (mode !== 'range') return false\n if (this._isDisabledDate(date)) return false\n\n const range = this._selection as RangeSelection\n\n // No start selected yet, or range is already complete (next click restarts)\n if (!range.isPartial()) return true\n\n const rangeStart = range.getStart()\n if (!rangeStart) return true\n\n // Clicking the same date as start deselects — always allowed\n if (date.isSame(rangeStart)) return true\n\n // Determine actual start/end after potential swap\n let start = rangeStart\n let end = date\n if (end.isBefore(start)) {\n const tmp = start\n start = end\n end = tmp\n }\n\n return this._isRangeValid(start, end)\n },\n\n /**\n * Get human-readable reasons why a date is disabled.\n * Returns an empty array for enabled dates.\n * Accepts a CalendarDate or ISO string.\n */\n getDisabledReason(date: CalendarDate | string): string[] {\n const d = typeof date === 'string' ? CalendarDate.fromISO(date) : date\n if (!d) return []\n return this._getDisabledReasons(d)\n },\n\n clearSelection() {\n this._selection.clear()\n this._selectionRev++\n this._emitChange()\n this._syncInputFromSelection()\n this._announce('Selection cleared')\n },\n\n // --- Programmatic control ---\n\n /**\n * Set the calendar selection programmatically.\n *\n * Accepts a single ISO date string, an array of ISO strings, or CalendarDate(s).\n * The calendar navigates to show the first selected date.\n *\n * Usage:\n * ```js\n * // Single mode\n * $data.setValue('2025-06-15')\n *\n * // Multiple mode\n * $data.setValue(['2025-06-15', '2025-06-20'])\n *\n * // Range mode\n * $data.setValue(['2025-06-15', '2025-06-20'])\n *\n * // With CalendarDate\n * $data.setValue(new CalendarDate(2025, 6, 15))\n * ```\n */\n setValue(value: string | string[] | CalendarDate | CalendarDate[]) {\n this._selection.clear()\n\n const dates: CalendarDate[] = []\n\n if (typeof value === 'string') {\n // Single ISO string\n const d = CalendarDate.fromISO(value) ?? parseDate(value, format)\n if (d && !this._isDisabledDate(d)) {\n dates.push(d)\n }\n } else if (Array.isArray(value)) {\n for (const v of value) {\n const d = typeof v === 'string' ? (CalendarDate.fromISO(v) ?? parseDate(v, format)) : v\n if (d && !this._isDisabledDate(d)) {\n dates.push(d)\n }\n }\n } else if (value instanceof CalendarDate) {\n if (!this._isDisabledDate(value)) {\n dates.push(value)\n }\n }\n\n // Range validation\n if (mode === 'range' && dates.length === 2) {\n let [start, end] = dates as [CalendarDate, CalendarDate]\n if (end.isBefore(start)) {\n const tmp = start\n start = end\n end = tmp\n }\n if (!this._isRangeValid(start, end)) {\n // Invalid range — don't set anything\n this._selectionRev++\n this._emitChange()\n this._syncInputFromSelection()\n return\n }\n // Use setRange() for direct assignment — avoids toggle() deselecting same-day ranges\n ;(this._selection as RangeSelection).setRange(start, end)\n } else {\n for (const d of dates) {\n this._selection.toggle(d)\n }\n }\n\n // Navigate to the first selected date\n const selected = this._selection.toArray()\n if (selected.length > 0) {\n const first = selected[0] as CalendarDate\n this.month = first.month\n this.year = first.year\n }\n\n this._selectionRev++\n this._emitChange()\n this._syncInputFromSelection()\n },\n\n /**\n * Clear the current selection. Alias for `clearSelection()`.\n */\n clear() {\n this.clearSelection()\n },\n\n /**\n * Navigate the calendar to a specific year and month without changing selection.\n *\n * Usage:\n * ```js\n * $data.goTo(2025, 6) // Navigate to June 2025\n * $data.goTo(2030) // Navigate to the current month in 2030\n * ```\n */\n goTo(year: number, month?: number) {\n this.year = year\n if (month !== undefined) {\n this.month = month\n }\n this.view = 'days'\n if (this.isScrollable) {\n this._rebuildGrid()\n alpine(this).$nextTick(() => {\n this._rebindScrollObserver()\n this._scrollToMonth(year, month ?? this.month)\n })\n }\n },\n\n /**\n * Get the current selection as an array of CalendarDate objects.\n *\n * Returns a new array each time (safe to mutate).\n *\n * Usage:\n * ```js\n * const dates = $data.getSelection()\n * console.log(dates.map(d => d.toISO()))\n * ```\n */\n getSelection(): CalendarDate[] {\n return [...this._selection.toArray()]\n },\n\n /**\n * Apply a predefined range preset by index.\n *\n * Evaluates the preset's `value()` function, sets the selection to the\n * returned `[start, end]` range, navigates to the start date, and\n * emits a change event. In popup mode with `closeOnSelect`, the popup closes.\n *\n * Usage in Alpine template:\n * ```html\n * <template x-for=\"(preset, pi) in presets\" :key=\"pi\">\n * <button @click=\"applyPreset(pi)\" x-text=\"preset.label\"></button>\n * </template>\n * ```\n */\n applyPreset(index: number) {\n const preset = this.presets[index]\n if (!preset) return\n\n const [start, end] = preset.value()\n\n // In single mode, only use the start date — presets return [start, end] pairs\n // but single mode should not receive an array (avoids toggle-on/toggle-off bug)\n if (mode === 'single') {\n this.setValue(start)\n } else {\n this.setValue([start, end])\n }\n\n // Close popup if configured\n if (this.display === 'popup' && closeOnSelect) {\n this.close()\n }\n },\n\n // --- Runtime config ---\n\n /**\n * Update constraint-related configuration at runtime.\n *\n * Rebuilds all constraint functions and refreshes grids. Accepts the same\n * constraint properties as `CalendarConfig` (minDate, maxDate, disabledDates,\n * disabledDaysOfWeek, enabledDates, enabledDaysOfWeek, disabledMonths,\n * enabledMonths, disabledYears, enabledYears, minRange, maxRange, rules).\n *\n * Updates are **merged** with the existing constraint config. To remove a\n * previously set constraint, pass `undefined` explicitly (e.g.\n * `{ disabledDaysOfWeek: undefined }`).\n *\n * Usage:\n * ```js\n * $data.updateConstraints({ minDate: '2025-06-01', disabledDaysOfWeek: [0, 6] })\n * ```\n */\n updateConstraints(updates: Partial<CalendarConfig>) {\n // Merge: explicit undefined removes a key, otherwise overlay on existing\n const merged = { ...this._constraintConfig }\n for (const key of CONSTRAINT_KEYS) {\n if (key in updates) {\n ;(merged as Record<string, unknown>)[key] = (updates as Record<string, unknown>)[key]\n }\n }\n this._constraintConfig = merged\n const c = buildConstraints(merged, constraintMessages)\n this._isDisabledDate = c.isDisabledDate\n this._isRangeValid = c.isRangeValid\n this._isMonthDisabled = c.isMonthDisabled\n this._isYearDisabled = c.isYearDisabled\n this._getDisabledReasons = c.getDisabledReasons\n this._rebuildGrid()\n this._rebuildMonthGrid()\n this._rebuildYearGrid()\n if (this.isScrollable) {\n alpine(this).$nextTick(() => { this._rebindScrollObserver() })\n }\n },\n\n // --- View switching ---\n\n setView(newView: 'days' | 'months' | 'years') {\n this.view = newView\n },\n\n selectMonth(targetMonth: number) {\n if (this._isMonthDisabled(this.year, targetMonth)) return\n this.month = targetMonth\n this._wizardMonth = targetMonth\n\n if (wizardMode === 'year-month') {\n // Auto-select 1st of month → emit → close\n this.wizardStep = wizardTotalSteps\n this.selectDate(new CalendarDate(this.year, targetMonth, 1))\n return\n }\n\n this.view = 'days'\n if (wizard) {\n this.wizardStep = wizardMode === 'month-day' ? 2 : 3\n }\n },\n\n selectYear(targetYear: number) {\n if (this._isYearDisabled(targetYear)) return\n this.year = targetYear\n this._wizardYear = targetYear\n this.view = 'months'\n if (this.wizard) this.wizardStep = 2\n },\n\n /** Navigate the wizard back one step. No-op if not in wizard mode. */\n wizardBack() {\n if (!this.wizard) return\n if (wizardMode === 'full') {\n if (this.wizardStep === 3) {\n this.wizardStep = 2\n this.view = 'months'\n this._wizardMonth = null\n this._wizardDay = null\n } else if (this.wizardStep === 2) {\n this.wizardStep = 1\n this.view = 'years'\n this._wizardYear = null\n this._wizardMonth = null\n }\n } else if (wizardMode === 'year-month') {\n if (this.wizardStep === 2) {\n this.wizardStep = 1\n this.view = 'years'\n this._wizardYear = null\n this._wizardMonth = null\n }\n } else if (wizardMode === 'month-day') {\n if (this.wizardStep === 2) {\n this.wizardStep = 1\n this.view = 'months'\n this._wizardMonth = null\n }\n }\n },\n\n // --- Popup ---\n\n open() {\n if (this.display !== 'popup') return\n\n // Reset wizard to first step on reopen\n if (wizard) {\n this.wizardStep = 1\n this.view = wizardStartView\n this._wizardYear = null\n this._wizardMonth = null\n this._wizardDay = null\n if (wizardMode !== 'month-day') {\n this.year = this._today.year - 30\n this._rebuildYearGrid()\n }\n }\n\n this.isOpen = true\n this._inputEl?.setAttribute('aria-expanded', 'true')\n alpine(this).$dispatch('calendar:open')\n\n // CSS handles centered modal layout via `.rc-popup-overlay`\n alpine(this).$nextTick(() => {\n // Focus management after popup renders\n })\n },\n\n close() {\n if (this.display !== 'popup') return\n this.isOpen = false\n this._inputEl?.setAttribute('aria-expanded', 'false')\n alpine(this).$dispatch('calendar:close')\n },\n\n toggle() {\n if (this.isOpen) {\n this.close()\n } else {\n this.open()\n }\n },\n\n /**\n * Handle keydown events on the calendar container.\n *\n * Supports full keyboard navigation per ARIA grid pattern:\n * - Arrow keys: move focus between days (±1 day / ±7 days)\n * - Enter/Space: select the focused day\n * - PageUp/PageDown: navigate prev/next month (+ Shift: prev/next year)\n * - Home/End: jump to first/last day of current month\n * - Escape: return to day view from month/year picker, or close popup\n * - Tab: natural tab order (exits calendar)\n *\n * Uses `aria-activedescendant` pattern: the calendar grid container holds\n * focus (`tabindex=\"0\"`), and `focusedDate` drives which cell is visually\n * highlighted. Day cells should have `id=\"day-{ISO}\"` in the template.\n *\n * Usage in Alpine template:\n * ```html\n * <div @keydown=\"handleKeydown($event)\" tabindex=\"0\"\n * :aria-activedescendant=\"focusedDateISO ? 'day-' + focusedDateISO : null\">\n * ```\n */\n handleKeydown(e: KeyboardEvent) {\n // --- Escape: wizard back → view fallback → close popup → do nothing ---\n if (e.key === 'Escape') {\n e.preventDefault()\n e.stopPropagation()\n // Wizard mode: go back one step instead of jumping to days\n if (this.wizard && this.wizardStep > 1) {\n this.wizardBack()\n return\n }\n // If in month or year picker, return to days view\n if (this.view === 'months' || this.view === 'years') {\n this.view = 'days'\n return\n }\n // If popup is open, close it and return focus to input\n if (display === 'popup' && this.isOpen) {\n this.close()\n if (this._inputEl) {\n this._suppressFocusOpen = true\n this._inputEl.focus()\n }\n }\n return\n }\n\n // --- Day view keyboard navigation ---\n if (this.view === 'days') {\n switch (e.key) {\n // Navigation keys: auto-initialize focusedDate if not set\n case 'ArrowRight':\n case 'ArrowLeft':\n case 'ArrowDown':\n case 'ArrowUp':\n case 'PageDown':\n case 'PageUp':\n case 'Home':\n case 'End': {\n e.preventDefault()\n // Auto-init focusedDate on first navigation keypress\n if (!this.focusedDate) {\n const selected = this._selection.toArray()\n if (selected.length > 0) {\n this.focusedDate = selected[0] as CalendarDate\n } else {\n this.focusedDate = new CalendarDate(this.year, this.month, 1)\n }\n }\n // Now dispatch to the specific navigation action\n if (e.key === 'ArrowRight') this._moveFocus(1)\n else if (e.key === 'ArrowLeft') this._moveFocus(-1)\n else if (e.key === 'ArrowDown') this._moveFocus(7)\n else if (e.key === 'ArrowUp') this._moveFocus(-7)\n else if (e.key === 'PageDown') this._moveFocusByMonths(e.shiftKey ? 12 : 1)\n else if (e.key === 'PageUp') this._moveFocusByMonths(e.shiftKey ? -12 : -1)\n else if (e.key === 'Home')\n this._setFocusedDate(new CalendarDate(this.year, this.month, 1))\n else if (e.key === 'End')\n this._setFocusedDate(new CalendarDate(this.year, this.month, 1).endOfMonth())\n return\n }\n // Selection keys: only act when focus is already established\n case 'Enter':\n case ' ':\n if (this.focusedDate) {\n e.preventDefault()\n this.selectDate(this.focusedDate)\n }\n return\n }\n }\n },\n\n // --- Internal: keyboard focus management ---\n\n /**\n * Move focusedDate by a number of days, navigating months as needed.\n * Skips disabled dates in the direction of movement (up to 31 attempts).\n */\n _moveFocus(deltaDays: number) {\n if (!this.focusedDate) return\n let candidate = this.focusedDate.addDays(deltaDays)\n\n // Skip disabled dates (up to 31 attempts to avoid infinite loops)\n let attempts = 0\n while (this._isDisabledDate(candidate) && attempts < 31) {\n candidate = candidate.addDays(deltaDays > 0 ? 1 : -1)\n attempts++\n }\n\n // If all candidates were disabled, don't move\n if (this._isDisabledDate(candidate)) return\n\n this._setFocusedDate(candidate)\n },\n\n /**\n * Move focusedDate by a number of months, clamping the day to valid range.\n */\n _moveFocusByMonths(deltaMonths: number) {\n if (!this.focusedDate) return\n const candidate = this.focusedDate.addMonths(deltaMonths)\n this._setFocusedDate(candidate)\n },\n\n /**\n * Set focusedDate and navigate the calendar view if needed.\n */\n _setFocusedDate(date: CalendarDate) {\n this.focusedDate = date\n if (this.isScrollable) {\n // Scroll the focused date's month into view\n alpine(this).$nextTick(() => {\n this._scrollToMonth(date.year, date.month)\n })\n return\n }\n // Navigate the calendar view to show the focused date's month\n if (date.month !== this.month || date.year !== this.year) {\n this.month = date.month\n this.year = date.year\n }\n },\n\n // --- Internal: scrollable multi-month ---\n\n /** Label for the sticky header in scrollable mode — tracks the topmost visible month. */\n get scrollHeaderLabel(): string {\n if (!this.isScrollable) return ''\n const mg = this.grid[this._scrollVisibleIndex]\n if (!mg) return ''\n const d = new CalendarDate(mg.year, mg.month, 1)\n return d.format({ month: 'long', year: 'numeric' }, locale)\n },\n\n /** Attach an IntersectionObserver that updates the sticky header as the user scrolls. */\n _initScrollListener() {\n if (typeof IntersectionObserver === 'undefined') return\n const el = alpine(this).$el\n const container = el.querySelector('.rc-months--scroll') as HTMLElement | null\n if (!container) return\n this._scrollContainerEl = container\n\n const monthEls = container.querySelectorAll('[data-month-id]')\n if (monthEls.length === 0) return\n\n const indexMap = new Map<Element, number>()\n monthEls.forEach((el, i) => indexMap.set(el, i))\n\n const visible = new Set<number>()\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n const idx = indexMap.get(entry.target)\n if (idx === undefined) continue\n if (entry.isIntersecting) {\n visible.add(idx)\n } else {\n visible.delete(idx)\n }\n }\n if (visible.size > 0) {\n const minIdx = Math.min(...visible)\n if (this._scrollVisibleIndex !== minIdx) {\n this._scrollVisibleIndex = minIdx\n }\n }\n },\n { root: container, rootMargin: '0px 0px -90% 0px', threshold: 0 },\n )\n\n monthEls.forEach((el) => observer.observe(el))\n this._scrollObserver = observer\n },\n\n /** Disconnect and re-initialize the scroll observer after DOM rebuild. */\n _rebindScrollObserver() {\n if (this._scrollObserver) {\n this._scrollObserver.disconnect()\n this._scrollObserver = null\n }\n this._initScrollListener()\n },\n\n /** Smooth scroll a specific month into view inside the scroll container. */\n _scrollToMonth(year: number, month: number) {\n if (!this._scrollContainerEl) return\n const el = this._scrollContainerEl.querySelector(\n `[data-month-id=\"month-${year}-${month}\"]`,\n ) as HTMLElement | null\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' })\n },\n\n }\n}\n","import { CalendarDate, daysInMonth } from './calendar-date'\n\n/**\n * A predefined date range shortcut (e.g., \"Today\", \"Last 7 Days\").\n *\n * Re-exported from the component module for convenience — this is the\n * canonical definition of the interface used by both core and plugin.\n */\nexport interface RangePreset {\n /** Display label for the preset button. */\n label: string\n /**\n * Function that returns a `[start, end]` date pair.\n * Called at click time so \"Today\", \"Last 7 Days\", etc. stay current.\n */\n value: () => [CalendarDate, CalendarDate]\n}\n\n// ---------------------------------------------------------------------------\n// Built-in preset factories\n// ---------------------------------------------------------------------------\n\n/**\n * Create a \"Today\" preset — selects today as a single-day range.\n *\n * @param label - Custom label (default: \"Today\")\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetToday(label = 'Today', timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const today = CalendarDate.today(timezone)\n return [today, today]\n },\n }\n}\n\n/**\n * Create a \"Yesterday\" preset — selects yesterday as a single-day range.\n *\n * @param label - Custom label (default: \"Yesterday\")\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetYesterday(label = 'Yesterday', timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const yesterday = CalendarDate.today(timezone).addDays(-1)\n return [yesterday, yesterday]\n },\n }\n}\n\n/**\n * Create a \"Last N Days\" preset — selects from (today - N + 1) to today.\n *\n * @param days - Number of days (inclusive)\n * @param label - Custom label (default: \"Last {days} Days\")\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetLastNDays(days: number, label?: string, timezone?: string): RangePreset {\n return {\n label: label ?? `Last ${days} Days`,\n value: () => {\n const today = CalendarDate.today(timezone)\n return [today.addDays(-(days - 1)), today]\n },\n }\n}\n\n/**\n * Create a \"This Week\" preset — selects from the start of the current week to today.\n * Weeks start on the given `firstDay` (0=Sun, 1=Mon, default: 1).\n *\n * @param label - Custom label (default: \"This Week\")\n * @param firstDay - First day of the week (0=Sun, 1=Mon; default: 1)\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetThisWeek(label = 'This Week', firstDay = 1, timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const today = CalendarDate.today(timezone)\n const dow = today.toNativeDate().getDay()\n const diff = (dow - firstDay + 7) % 7\n const weekStart = today.addDays(-diff)\n return [weekStart, today]\n },\n }\n}\n\n/**\n * Create a \"Last Week\" preset — selects the full 7-day week before the current week.\n * Weeks start on the given `firstDay` (0=Sun, 1=Mon, default: 1).\n *\n * @param label - Custom label (default: \"Last Week\")\n * @param firstDay - First day of the week (0=Sun, 1=Mon; default: 1)\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetLastWeek(label = 'Last Week', firstDay = 1, timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const today = CalendarDate.today(timezone)\n const dow = today.toNativeDate().getDay()\n const diff = (dow - firstDay + 7) % 7\n const thisWeekStart = today.addDays(-diff)\n const lastWeekStart = thisWeekStart.addDays(-7)\n const lastWeekEnd = thisWeekStart.addDays(-1)\n return [lastWeekStart, lastWeekEnd]\n },\n }\n}\n\n/**\n * Create a \"This Month\" preset — selects from the 1st of the current month to today.\n *\n * @param label - Custom label (default: \"This Month\")\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetThisMonth(label = 'This Month', timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const today = CalendarDate.today(timezone)\n return [today.startOfMonth(), today]\n },\n }\n}\n\n/**\n * Create a \"Last Month\" preset — selects the full previous month.\n *\n * @param label - Custom label (default: \"Last Month\")\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetLastMonth(label = 'Last Month', timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const today = CalendarDate.today(timezone)\n const prevMonth = today.addMonths(-1)\n return [\n prevMonth.startOfMonth(),\n new CalendarDate(prevMonth.year, prevMonth.month, daysInMonth(prevMonth.year, prevMonth.month)),\n ]\n },\n }\n}\n\n/**\n * Create a \"This Year\" preset — selects from January 1st of the current year to today.\n *\n * @param label - Custom label (default: \"This Year\")\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetThisYear(label = 'This Year', timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const today = CalendarDate.today(timezone)\n return [new CalendarDate(today.year, 1, 1), today]\n },\n }\n}\n\n/**\n * Create a \"Last Year\" preset — selects the full previous year (Jan 1 – Dec 31).\n *\n * @param label - Custom label (default: \"Last Year\")\n * @param timezone - IANA timezone for resolving today\n */\nexport function presetLastYear(label = 'Last Year', timezone?: string): RangePreset {\n return {\n label,\n value: () => {\n const today = CalendarDate.today(timezone)\n const prevYear = today.year - 1\n return [new CalendarDate(prevYear, 1, 1), new CalendarDate(prevYear, 12, 31)]\n },\n }\n}\n","/**\n * Lightweight popup positioning engine.\n *\n * Calculates fixed-position coordinates for a floating element relative to\n * a reference element. Supports automatic flipping when the popup would\n * overflow the viewport.\n *\n * No external dependencies — replaces Floating UI for simple use cases.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type Placement = 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end'\n\nexport interface PositionOptions {\n /** Preferred placement. Default: 'bottom-start'. */\n placement?: Placement\n /** Offset in pixels between reference and floating element. Default: 4. */\n offset?: number\n /** Whether to flip to the opposite side when there's not enough space. Default: true. */\n flip?: boolean\n}\n\nexport interface PositionResult {\n /** X coordinate (CSS `left`) for `position: fixed`. */\n x: number\n /** Y coordinate (CSS `top`) for `position: fixed`. */\n y: number\n /** Actual placement after potential flip. */\n placement: Placement\n}\n\n// ---------------------------------------------------------------------------\n// Core positioning\n// ---------------------------------------------------------------------------\n\n/**\n * Compute fixed-position coordinates for a floating element.\n *\n * Uses `getBoundingClientRect()` on both the reference and floating elements\n * to calculate position. The floating element must be in the DOM (but can\n * be hidden with `visibility: hidden`) so its dimensions are measurable.\n *\n * @param reference - The trigger/anchor element\n * @param floating - The popup element to position\n * @param options - Positioning options\n * @returns Position coordinates and resolved placement\n */\nexport function computePosition(\n reference: Element,\n floating: Element,\n options: PositionOptions = {},\n): PositionResult {\n const placement = options.placement ?? 'bottom-start'\n const offset = options.offset ?? 4\n const flip = options.flip ?? true\n\n const refRect = reference.getBoundingClientRect()\n const floatRect = floating.getBoundingClientRect()\n const viewportHeight = window.innerHeight\n const viewportWidth = window.innerWidth\n\n // Calculate x (horizontal alignment)\n let x: number\n const side = placement.includes('start') ? 'start' : 'end'\n if (side === 'start') {\n x = refRect.left\n } else {\n x = refRect.right - floatRect.width\n }\n\n // Clamp x to viewport\n x = clamp(x, 0, Math.max(0, viewportWidth - floatRect.width))\n\n // Calculate y based on vertical side\n const isBottom = placement.startsWith('bottom')\n let resolvedPlacement = placement\n\n if (isBottom) {\n const yBelow = refRect.bottom + offset\n const fitsBelow = yBelow + floatRect.height <= viewportHeight\n\n if (!fitsBelow && flip) {\n const yAbove = refRect.top - offset - floatRect.height\n const fitsAbove = yAbove >= 0\n\n if (fitsAbove) {\n resolvedPlacement = placement.replace('bottom', 'top') as Placement\n return { x, y: yAbove, placement: resolvedPlacement }\n }\n }\n\n return { x, y: yBelow, placement: resolvedPlacement }\n }\n\n // top placement\n const yAbove = refRect.top - offset - floatRect.height\n\n if (yAbove < 0 && flip) {\n const yBelow = refRect.bottom + offset\n const fitsBelow = yBelow + floatRect.height <= viewportHeight\n\n if (fitsBelow) {\n resolvedPlacement = placement.replace('top', 'bottom') as Placement\n return { x, y: yBelow, placement: resolvedPlacement }\n }\n }\n\n return { x, y: Math.max(0, yAbove), placement: resolvedPlacement }\n}\n\n// ---------------------------------------------------------------------------\n// Auto-update (scroll/resize listener)\n// ---------------------------------------------------------------------------\n\n/**\n * Subscribe to scroll and resize events that could affect popup position.\n *\n * Calls `update()` whenever the reference element's position may have\n * changed due to scrolling or window resize. Uses passive event listeners\n * and throttles callbacks for performance.\n *\n * @param reference - The trigger/anchor element\n * @param update - Callback to recalculate position\n * @param throttleMs - Throttle interval in ms. Default: 16 (~60fps)\n * @returns Cleanup function to remove all listeners\n */\nexport function autoUpdate(reference: Element, update: () => void, throttleMs = 16): () => void {\n let ticking = false\n let rafId = 0\n let timerId = 0\n\n const onEvent = () => {\n if (ticking) return\n ticking = true\n\n if (throttleMs <= 16) {\n // Use rAF for frame-rate throttling\n rafId = requestAnimationFrame(() => {\n update()\n ticking = false\n })\n } else {\n timerId = window.setTimeout(() => {\n update()\n ticking = false\n }, throttleMs)\n }\n }\n\n // Listen on window for resize\n window.addEventListener('resize', onEvent, { passive: true })\n\n // Listen on all scrollable ancestors\n const scrollParents = getScrollParents(reference)\n for (const parent of scrollParents) {\n parent.addEventListener('scroll', onEvent, { passive: true })\n }\n\n return () => {\n cancelAnimationFrame(rafId)\n clearTimeout(timerId)\n window.removeEventListener('resize', onEvent)\n for (const parent of scrollParents) {\n parent.removeEventListener('scroll', onEvent)\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value))\n}\n\n/**\n * Walk up the DOM tree and collect all scrollable ancestors.\n * Includes the document for top-level scroll.\n */\nfunction getScrollParents(element: Element): EventTarget[] {\n const parents: EventTarget[] = []\n let current = element.parentElement\n\n while (current) {\n const style = getComputedStyle(current)\n const overflow = style.overflow + style.overflowX + style.overflowY\n\n if (/auto|scroll|overlay/.test(overflow)) {\n parents.push(current)\n }\n\n current = current.parentElement\n }\n\n // Always listen on document (handles body scroll)\n parents.push(document)\n\n return parents\n}\n","import type { Alpine as AlpineType } from 'alpinejs'\nimport '../styles/calendar.css'\nimport { createCalendarData } from './plugin/calendar-component'\nimport type { CalendarConfig } from './plugin/calendar-component'\n\n// ---------------------------------------------------------------------------\n// Global defaults\n// ---------------------------------------------------------------------------\n\nlet globalDefaults: Partial<CalendarConfig> = {}\n\n// ---------------------------------------------------------------------------\n// Plugin\n// ---------------------------------------------------------------------------\n\n/**\n * Alpine.js plugin that registers the `calendar` component.\n *\n * Usage:\n * ```ts\n * import Alpine from 'alpinejs'\n * import { calendarPlugin } from '@reachgr/alpine-calendar'\n *\n * Alpine.plugin(calendarPlugin)\n * Alpine.start()\n * ```\n */\nexport function calendarPlugin(Alpine: AlpineType) {\n Alpine.data('calendar', (config: CalendarConfig = {}) =>\n createCalendarData({ ...globalDefaults, ...config }, Alpine),\n )\n}\n\n/**\n * Set global defaults that apply to every calendar instance.\n * Instance-level config overrides global defaults.\n *\n * Usage:\n * ```ts\n * import { calendarPlugin } from '@reachgr/alpine-calendar'\n *\n * calendarPlugin.defaults({ firstDay: 1, locale: 'el' })\n * Alpine.plugin(calendarPlugin)\n * ```\n */\ncalendarPlugin.defaults = (config: Partial<CalendarConfig>) => {\n globalDefaults = { ...globalDefaults, ...config }\n}\n\n/**\n * Get the current global defaults (useful for testing/debugging).\n */\ncalendarPlugin.getDefaults = (): Partial<CalendarConfig> => ({ ...globalDefaults })\n\n/**\n * Reset global defaults to empty (useful for testing).\n */\ncalendarPlugin.resetDefaults = () => {\n globalDefaults = {}\n}\n\nexport default calendarPlugin\n\n// Re-export types and utilities for bundler consumers\nexport { createCalendarData } from './plugin/calendar-component'\nexport type { CalendarConfig } from './plugin/calendar-component'\nexport { CalendarDate, daysInMonth, getISOWeekNumber } from './core/calendar-date'\nexport { generateMonth, generateMonths, generateMonthGrid, generateYearGrid } from './core/grid'\nexport type { DayCell, MonthGrid, MonthCell, YearCell } from './core/grid'\nexport { SingleSelection, MultipleSelection, RangeSelection } from './core/selection'\nexport type { Selection } from './core/selection'\nexport {\n createDateConstraint,\n createRangeValidator,\n createDisabledReasons,\n isDateDisabled,\n} from './core/constraints'\nexport type {\n DateConstraintOptions,\n DateConstraintProperties,\n DateConstraintRule,\n ConstraintMessages,\n} from './core/constraints'\nexport type { CalendarConfigRule, RangePreset } from './plugin/calendar-component'\nexport {\n presetToday,\n presetYesterday,\n presetLastNDays,\n presetThisWeek,\n presetLastWeek,\n presetThisMonth,\n presetLastMonth,\n presetThisYear,\n presetLastYear,\n} from './core/presets'\nexport { parseDate, parseDateRange, parseDateMultiple } from './input/parser'\nexport { formatDate, formatRange, formatMultiple } from './input/formatter'\nexport { createMask, createMaskHandlers, attachMask, parseFormatToSlots } from './input/mask'\nexport type { InputMask, MaskEventHandlers, MaskSlot } from './input/mask'\nexport { computePosition, autoUpdate } from './positioning/popup'\nexport type { Placement, PositionOptions, PositionResult } from './positioning/popup'\n"],"names":["TOKEN_NAMES","el","yAbove"],"mappings":"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"}