ngwr 13.0.1 → 14.0.0

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.
Files changed (167) hide show
  1. package/README.md +13 -6
  2. package/color-picker/styles/_index.scss +43 -5
  3. package/fesm2022/ngwr-alert.mjs +5 -5
  4. package/fesm2022/ngwr-alert.mjs.map +1 -1
  5. package/fesm2022/ngwr-back-top.mjs +11 -1
  6. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  7. package/fesm2022/ngwr-blur-text.mjs +13 -2
  8. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  9. package/fesm2022/ngwr-button.mjs +4 -4
  10. package/fesm2022/ngwr-button.mjs.map +1 -1
  11. package/fesm2022/ngwr-calendar-testing.mjs +15 -0
  12. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  13. package/fesm2022/ngwr-calendar.mjs +51 -5
  14. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  15. package/fesm2022/ngwr-circular-text.mjs +20 -1
  16. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  17. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  18. package/fesm2022/ngwr-color-picker-testing.mjs +23 -7
  19. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  20. package/fesm2022/ngwr-color-picker.mjs +89 -10
  21. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  22. package/fesm2022/ngwr-command-palette.mjs +27 -3
  23. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  24. package/fesm2022/ngwr-context-menu.mjs +7 -1
  25. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  26. package/fesm2022/ngwr-date-adapters-fns.mjs +101 -33
  27. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  28. package/fesm2022/ngwr-date-picker-testing.mjs +10 -2
  29. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  30. package/fesm2022/ngwr-date-picker.mjs +103 -13
  31. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  32. package/fesm2022/ngwr-date.mjs +480 -79
  33. package/fesm2022/ngwr-date.mjs.map +1 -1
  34. package/fesm2022/ngwr-drag-drop.mjs +30 -2
  35. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  36. package/fesm2022/ngwr-dropdown.mjs +2 -1
  37. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  38. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  39. package/fesm2022/ngwr-event-calendar.mjs +1 -1
  40. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  41. package/fesm2022/ngwr-file-upload.mjs +52 -12
  42. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  43. package/fesm2022/ngwr-i18n-en.mjs +63 -1
  44. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  45. package/fesm2022/ngwr-i18n-ru.mjs +28 -1
  46. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  47. package/fesm2022/ngwr-i18n.mjs +150 -22
  48. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  49. package/fesm2022/ngwr-input-number.mjs +3 -3
  50. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  51. package/fesm2022/ngwr-input-otp.mjs +21 -3
  52. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  53. package/fesm2022/ngwr-input.mjs +14 -7
  54. package/fesm2022/ngwr-input.mjs.map +1 -1
  55. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  56. package/fesm2022/ngwr-knob.mjs +20 -2
  57. package/fesm2022/ngwr-knob.mjs.map +1 -1
  58. package/fesm2022/ngwr-loading-bar-router.mjs +73 -0
  59. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -0
  60. package/fesm2022/ngwr-loading-bar.mjs +21 -32
  61. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  62. package/fesm2022/ngwr-mention.mjs +104 -14
  63. package/fesm2022/ngwr-mention.mjs.map +1 -1
  64. package/fesm2022/ngwr-pagination-testing.mjs +11 -10
  65. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  66. package/fesm2022/ngwr-pagination.mjs +65 -30
  67. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  68. package/fesm2022/ngwr-popconfirm.mjs +3 -2
  69. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  70. package/fesm2022/ngwr-popover.mjs +2 -1
  71. package/fesm2022/ngwr-popover.mjs.map +1 -1
  72. package/fesm2022/ngwr-select.mjs +93 -34
  73. package/fesm2022/ngwr-select.mjs.map +1 -1
  74. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  75. package/fesm2022/ngwr-squircle.mjs +2 -1
  76. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  77. package/fesm2022/ngwr-statistic.mjs +35 -4
  78. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  79. package/fesm2022/ngwr-table.mjs +35 -12
  80. package/fesm2022/ngwr-table.mjs.map +1 -1
  81. package/fesm2022/ngwr-tabs-router.mjs +158 -0
  82. package/fesm2022/ngwr-tabs-router.mjs.map +1 -0
  83. package/fesm2022/ngwr-tabs-testing.mjs +13 -11
  84. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  85. package/fesm2022/ngwr-tabs.mjs +98 -10
  86. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  87. package/fesm2022/ngwr-textarea.mjs +20 -1
  88. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  89. package/fesm2022/ngwr-tour.mjs +1 -1
  90. package/fesm2022/ngwr-tour.mjs.map +1 -1
  91. package/fesm2022/ngwr-transfer.mjs +2 -2
  92. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  93. package/fesm2022/ngwr-tree.mjs +18 -2
  94. package/fesm2022/ngwr-tree.mjs.map +1 -1
  95. package/fesm2022/ngwr-utils.mjs +37 -1
  96. package/fesm2022/ngwr-utils.mjs.map +1 -1
  97. package/fesm2022/ngwr-version.mjs +1 -1
  98. package/fesm2022/ngwr-version.mjs.map +1 -1
  99. package/fesm2022/ngwr-window-testing.mjs +10 -2
  100. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  101. package/fesm2022/ngwr-window.mjs +4 -4
  102. package/fesm2022/ngwr-window.mjs.map +1 -1
  103. package/i18n/en.json +33 -6
  104. package/i18n/ru.json +33 -6
  105. package/llms-full.txt +20 -11
  106. package/llms.txt +47 -16
  107. package/mcp/catalog.js +3 -3
  108. package/mcp/providers.js +11 -0
  109. package/package.json +9 -1
  110. package/schematics/migrations/v13/index.js +101 -0
  111. package/schematics/migrations/v14/index.js +422 -0
  112. package/schematics/migrations.json +10 -0
  113. package/schematics/page/templates.js +1 -1
  114. package/schematics/use/symbol-map.json +1 -0
  115. package/skills/ngwr/SKILL.md +4 -1
  116. package/skills/ngwr/references/catalog.md +2 -0
  117. package/skills/ngwr/references/setup.md +4 -0
  118. package/stepper/styles/_index.scss +19 -1
  119. package/textarea/styles/_index.scss +14 -6
  120. package/toast/styles/_index.scss +12 -4
  121. package/types/ngwr-alert.d.ts +3 -3
  122. package/types/ngwr-blur-text.d.ts +8 -0
  123. package/types/ngwr-button.d.ts +2 -2
  124. package/types/ngwr-calendar-testing.d.ts +21 -4
  125. package/types/ngwr-calendar.d.ts +37 -0
  126. package/types/ngwr-circular-text.d.ts +9 -0
  127. package/types/ngwr-collapse.d.ts +19 -15
  128. package/types/ngwr-color-picker-testing.d.ts +10 -4
  129. package/types/ngwr-color-picker.d.ts +70 -2
  130. package/types/ngwr-command-palette.d.ts +14 -0
  131. package/types/ngwr-context-menu.d.ts +1 -1
  132. package/types/ngwr-date-adapters-fns.d.ts +71 -29
  133. package/types/ngwr-date-picker-testing.d.ts +206 -185
  134. package/types/ngwr-date-picker.d.ts +7 -0
  135. package/types/ngwr-date.d.ts +143 -13
  136. package/types/ngwr-drag-drop.d.ts +19 -0
  137. package/types/ngwr-dropdown.d.ts +1 -1
  138. package/types/ngwr-event-calendar-testing.d.ts +12 -9
  139. package/types/ngwr-file-upload.d.ts +31 -3
  140. package/types/ngwr-i18n.d.ts +89 -7
  141. package/types/ngwr-input-number.d.ts +1 -1
  142. package/types/ngwr-input-otp.d.ts +3 -0
  143. package/types/ngwr-input.d.ts +11 -4
  144. package/types/ngwr-knob-testing.d.ts +8 -4
  145. package/types/ngwr-knob.d.ts +18 -0
  146. package/types/ngwr-loading-bar-router.d.ts +35 -0
  147. package/types/ngwr-loading-bar.d.ts +19 -9
  148. package/types/ngwr-mention.d.ts +13 -0
  149. package/types/ngwr-pagination-testing.d.ts +11 -10
  150. package/types/ngwr-pagination.d.ts +39 -10
  151. package/types/ngwr-popconfirm.d.ts +1 -1
  152. package/types/ngwr-popover.d.ts +1 -1
  153. package/types/ngwr-select.d.ts +65 -10
  154. package/types/ngwr-splitter-testing.d.ts +9 -4
  155. package/types/ngwr-squircle.d.ts +1 -1
  156. package/types/ngwr-statistic.d.ts +22 -2
  157. package/types/ngwr-table.d.ts +24 -5
  158. package/types/ngwr-tabs-router.d.ts +67 -0
  159. package/types/ngwr-tabs-testing.d.ts +12 -10
  160. package/types/ngwr-tabs.d.ts +103 -6
  161. package/types/ngwr-textarea.d.ts +9 -0
  162. package/types/ngwr-tree.d.ts +7 -0
  163. package/types/ngwr-utils.d.ts +33 -1
  164. package/types/ngwr-version.d.ts +1 -1
  165. package/types/ngwr-window-testing.d.ts +11 -3
  166. package/types/ngwr-window.d.ts +11 -4
  167. package/window/styles/_index.scss +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-calendar-testing.mjs","sources":["../../../projects/lib/calendar/testing/wr-calendar-day-harness.ts","../../../projects/lib/calendar/testing/wr-calendar-harness.ts","../../../projects/lib/calendar/testing/ngwr-calendar-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrCalendarDayHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one day cell of a `<wr-calendar>` grid.\n *\n * The cell belongs to the calendar, and a date-picker's popup is a calendar in an\n * overlay — so this is the harness for both, re-exported from\n * `ngwr/date-picker/testing` under the name it shipped as\n * (`WrDatePickerDayHarness`). Reach it through `WrCalendarHarness.getDays()`, or\n * through `WrDatePickerHarness.getDay()` / `getDays()`, which scope it to ONE\n * picker's panel — those cells are in the shared overlay container, so a bare query\n * would answer with whichever picker opened first.\n *\n * State is read the way a screen reader reads it (`role`, `aria-selected`,\n * `aria-disabled`) with the `.wr-calendar__day--*` modifiers filling in what\n * ARIA has no word for: today, the spill days of the neighbouring months, and\n * the interior of a picked range.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarDayHarness extends ComponentHarness {\n static hostSelector = '.wr-calendar__day';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCalendarDayHarnessFilters = {}): HarnessPredicate<WrCalendarDayHarness> {\n return new HarnessPredicate(WrCalendarDayHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('selected', options.selected, async (harness, selected) => (await harness.isSelected()) === selected)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('inRange', options.inRange, async (harness, inRange) => (await harness.isInRange()) === inRange);\n }\n\n /** The day number as rendered. */\n async getText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** The day number as a number, for mapping a list of cells to dates. */\n async getDayOfMonth(): Promise<number> {\n return Number(await this.getText());\n }\n\n /** `'gridcell'` — the cell is a button, and the grid semantics are what a spec should assert. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** Whether this day is (one end of) the current selection. */\n async isSelected(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-selected')) === 'true';\n }\n\n /**\n * Whether the day refuses selection — `min` / `max` or `dateFilter` ruled it\n * out, or the whole calendar is disabled.\n */\n async isDisabled(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the cell is today's date. */\n async isToday(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--today');\n }\n\n /**\n * Whether the cell belongs to a neighbouring month. The grid is always 6x7, so\n * every month is padded with days that are selectable but not \"in\" the month —\n * which is why `WrDatePickerHarness.getDay` and {@link WrCalendarHarness.getDay} skip them.\n */\n async isOutOfMonth(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--out-of-month');\n }\n\n /** Whether the day lies strictly between the two ends of a picked range. */\n async isInRange(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--in-range');\n }\n\n /**\n * Whether this is the roving cell — the grid's single tab stop, and where the\n * arrow keys move from.\n *\n * At most ONE cell answers `true`, and it is not always one: the calendar's\n * roving date does not follow `next()` / `previous()`, so a grid navigated away\n * from that month has no active cell (and, deliberately or not, no tab stop)\n * until a cell is clicked or the arrows move it.\n */\n async isActive(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--focused');\n }\n\n /** Click the cell. A disabled cell swallows the click — assert, do not assume. */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate, TestKey, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrCalendarMode } from 'ngwr/calendar';\n\nimport type {\n WrCalendarChip,\n WrCalendarDayHarnessFilters,\n WrCalendarHarnessFilters,\n WrCalendarView,\n} from './interfaces';\nimport { WrCalendarDayHarness } from './wr-calendar-day-harness';\n\n/** The arrow keys, by the direction a user would say out loud. */\ntype Arrow = 'left' | 'right' | 'up' | 'down';\n\nconst ARROWS: Record<Arrow, TestKey> = {\n left: TestKey.LEFT_ARROW,\n right: TestKey.RIGHT_ARROW,\n up: TestKey.UP_ARROW,\n down: TestKey.DOWN_ARROW,\n};\n\n/**\n * Test harness for `<wr-calendar>` — the standalone month grid, and the one\n * `<wr-date-picker>` puts in an overlay.\n *\n * **It is three views behind one header.** Clicking the header label walks\n * `day → month → year`, and each view renders something different: a\n * `role=\"grid\"` of day cells, or a `role=\"listbox\"` of chips. Every day method\n * throws off the day view rather than answering `[]`, which would read as \"this\n * month has no days\".\n *\n * **The roving cell is not the selection.** The grid has one tab stop and the\n * arrows move it; it starts on the selected date, or on today when nothing is\n * picked. And it does NOT follow {@link next} / {@link previous} — a grid paged\n * away from the roving month has no active cell at all, and so no tab stop, until\n * a key or a click puts one back. That is the component's behaviour, and\n * {@link getActiveDayNumber} is how a spec sees it.\n *\n * **Keys go to the host, not to a cell.** The component listens on its own element,\n * so {@link pressArrow} works whether or not jsdom managed to put real focus\n * anywhere — which it often does not, since the calendar moves focus in an\n * `afterNextRender` and a disabled cell cannot take it.\n *\n * @example\n * ```ts\n * const calendar = await loader.getHarness(WrCalendarHarness);\n *\n * expect(await calendar.getHeaderLabel()).toBe('March 2026');\n * await (await calendar.getDay(14)).click();\n * expect(await calendar.getSelectedDayNumbers()).toEqual([14]);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarHarness extends ComponentHarness {\n static hostSelector = 'wr-calendar';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCalendarHarnessFilters = {}): HarnessPredicate<WrCalendarHarness> {\n return new HarnessPredicate(WrCalendarHarness, options)\n .addOption('headerLabel', options.headerLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getHeaderLabel(), label)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);\n }\n\n private readonly header = this.locatorFor('.wr-calendar__label');\n private readonly prevButton = this.locatorFor('.wr-calendar__nav--prev');\n private readonly nextButton = this.locatorFor('.wr-calendar__nav--next');\n\n /** Which sub-view is showing. */\n async getView(): Promise<WrCalendarView> {\n if ((await this.locatorForOptional('.wr-calendar__months')()) !== null) return 'month';\n if ((await this.locatorForOptional('.wr-calendar__years')()) !== null) return 'year';\n return 'day';\n }\n\n /** Single- or range-selection, from the host modifier. */\n async getMode(): Promise<WrCalendarMode> {\n return (await (await this.host()).hasClass('wr-calendar--range')) ? 'range' : 'single';\n }\n\n /** Whether the whole calendar refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar--disabled');\n }\n\n /** The header text — `March 2026`, `2026`, or `2016 – 2027` depending on the view. */\n async getHeaderLabel(): Promise<string> {\n return (await this.header()).text();\n }\n\n /**\n * Click the header — stepping `day → month → year`.\n *\n * The year view is the end of the walk: the header is disabled there, so this\n * throws rather than clicking a button the DOM would ignore.\n */\n async clickHeader(): Promise<void> {\n const header = await this.header();\n if (await header.getProperty<boolean>('disabled')) {\n throw new Error(\n `WrCalendarHarness.clickHeader(): the header is disabled — the calendar is on the ` +\n `${await this.getView()} view, which is where the walk stops (or the whole calendar is disabled).`\n );\n }\n await header.click();\n }\n\n /**\n * Step back — a month, a year or twelve years, depending on the view.\n *\n * The roving day cell does NOT come along: paging is a view change, not a\n * navigation, and the tab stop stays on the month it was in.\n */\n async previous(): Promise<void> {\n await (await this.prevButton()).click();\n }\n\n /** Step forward — a month, a year or twelve years, depending on the view. */\n async next(): Promise<void> {\n await (await this.nextButton()).click();\n }\n\n /**\n * The back arrow's accessible name, which changes with the view — the arrows are\n * icon-only, so this is the only name they have.\n */\n async getPreviousLabel(): Promise<string | null> {\n return (await this.prevButton()).getAttribute('aria-label');\n }\n\n /** The forward arrow's accessible name. */\n async getNextLabel(): Promise<string | null> {\n return (await this.nextButton()).getAttribute('aria-label');\n }\n\n /** The weekday column headers, in the order the adapter's first day of week puts them. */\n async getWeekdayNames(): Promise<string[]> {\n await this.requireView('day', 'getWeekdayNames');\n const names = await this.locatorForAll('.wr-calendar__weekday')();\n return Promise.all(names.map(name => name.text()));\n }\n\n /**\n * Every day cell, in DOM order — 42 of them, since the grid is always six weeks.\n *\n * That includes the spill days of the neighbouring months, which are selectable\n * and not \"in\" the month; {@link getDay} skips them, and\n * `WrCalendarDayHarness.isOutOfMonth()` tells them apart.\n */\n async getDays(filters: WrCalendarDayHarnessFilters = {}): Promise<WrCalendarDayHarness[]> {\n await this.requireView('day', 'getDays');\n return this.locatorForAll(WrCalendarDayHarness.with(filters))();\n }\n\n /**\n * The cell for a day of THIS month.\n *\n * The number alone is ambiguous — a 42-cell grid shows most numbers twice — so\n * the spill days are skipped rather than matched, which is what \"the 3rd\" means\n * to someone reading the calendar.\n */\n async getDay(dayOfMonth: number): Promise<WrCalendarDayHarness> {\n for (const day of await this.getDays({ text: String(dayOfMonth) })) {\n if (!(await day.isOutOfMonth())) return day;\n }\n throw new Error(\n `WrCalendarHarness.getDay(${dayOfMonth}): no such day in ${await this.getHeaderLabel()}. Only cells of ` +\n 'the displayed month count — the grid spills into its neighbours, and those are skipped.'\n );\n }\n\n /** The day numbers currently selected — one in single mode, both ends in range mode. */\n async getSelectedDayNumbers(): Promise<number[]> {\n const selected = await this.getDays({ selected: true });\n return Promise.all(selected.map(day => day.getDayOfMonth()));\n }\n\n /** The day numbers strictly inside a picked range — never the ends. */\n async getInRangeDayNumbers(): Promise<number[]> {\n const inRange = await this.getDays({ inRange: true });\n return Promise.all(inRange.map(day => day.getDayOfMonth()));\n }\n\n /**\n * The day number holding the roving tab stop, or `null` when the grid has none.\n *\n * `null` is a real answer, not a failure: paging with {@link next} leaves the\n * roving date behind in another month, and the grid then has no `tabindex=\"0\"`\n * at all until a key or a click puts one back.\n */\n async getActiveDayNumber(): Promise<number | null> {\n for (const day of await this.getDays()) {\n if (await day.isActive()) return day.getDayOfMonth();\n }\n return null;\n }\n\n /** The month chips, with their state. Throws off the month view. */\n async getMonths(): Promise<WrCalendarChip[]> {\n await this.requireView('month', 'getMonths');\n return this.readChips();\n }\n\n /** The year chips, with their state. Throws off the year view. */\n async getYears(): Promise<WrCalendarChip[]> {\n await this.requireView('year', 'getYears');\n return this.readChips();\n }\n\n /**\n * Click a month or year chip by its printed label — which drops the calendar back\n * one view, the way clicking the header climbed up.\n *\n * Throws on the day view, where there are no chips, and on a label the view does\n * not offer, naming what it does.\n */\n async selectChip(label: string): Promise<void> {\n const view = await this.getView();\n if (view === 'day') {\n throw new Error(\n 'WrCalendarHarness.selectChip(): the calendar is on the day view, which has no chips. Click the ' +\n 'header first — it walks day → month → year.'\n );\n }\n\n for (const chip of await this.locatorForAll('.wr-calendar__chip')()) {\n if ((await chip.text()) === label) {\n await chip.click();\n return;\n }\n }\n\n const offered = (await this.readChips()).map(chip => chip.label);\n throw new Error(`WrCalendarHarness.selectChip(\"${label}\"): the ${view} view offers: ${offered.join(', ')}.`);\n }\n\n /**\n * Press an arrow key — one day left or right, one WEEK up or down.\n *\n * Sent to the host, where the component listens, so this does not depend on jsdom\n * having managed to focus a cell. Under `dir=\"rtl\"` the horizontal pair mirrors:\n * ArrowRight goes back a day, because the grid itself is mirrored.\n */\n async pressArrow(arrow: Arrow): Promise<void> {\n await (await this.host()).sendKeys(ARROWS[arrow]);\n }\n\n /** Press Home — the first day of the roving cell's week, not of the month. */\n async pressHome(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.HOME);\n }\n\n /** Press End — the last day of the roving cell's week. */\n async pressEnd(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.END);\n }\n\n /** Press PageUp — a month back, or a YEAR back with `shift`. */\n async pressPageUp(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_UP) : host.sendKeys(TestKey.PAGE_UP));\n }\n\n /** Press PageDown — a month on, or a YEAR on with `shift`. */\n async pressPageDown(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_DOWN) : host.sendKeys(TestKey.PAGE_DOWN));\n }\n\n /** Press Enter — picking the roving day, exactly as clicking it would. */\n async pressEnter(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.ENTER);\n }\n\n /**\n * The role of the element that owns the day rows.\n *\n * Worth asserting rather than assuming: the grid is NOT the host. The host also\n * holds the nav header, and a `role=\"grid\"` may only own rows — so the role sits\n * on the body, and the weekday strip is a row inside it rather than a sibling.\n */\n async getGridRole(): Promise<string | null> {\n const body = await this.locatorForOptional('.wr-calendar__body')();\n return body ? body.getAttribute('role') : null;\n }\n\n /** How many week rows the grid renders — always six, which is what keeps it from reflowing. */\n async getWeekCount(): Promise<number> {\n await this.requireView('day', 'getWeekCount');\n return (await this.locatorForAll('.wr-calendar__week')()).length;\n }\n\n private async readChips(): Promise<WrCalendarChip[]> {\n const chips = await this.locatorForAll('.wr-calendar__chip')();\n\n return Promise.all(\n chips.map(async (chip: TestElement) => ({\n label: await chip.text(),\n selected: (await chip.getAttribute('aria-selected')) === 'true',\n current: await chip.hasClass('wr-calendar__chip--current'),\n disabled: (await chip.getAttribute('aria-disabled')) === 'true',\n }))\n );\n }\n\n private async requireView(view: WrCalendarView, method: string): Promise<void> {\n const current = await this.getView();\n if (current === view) return;\n\n throw new Error(\n `WrCalendarHarness.${method}(): the calendar is showing the ${current} view, not the ${view} one — those ` +\n 'elements are not rendered at all. The header walks day → month → year; clicking a chip walks back down.'\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-calendar-testing.mjs","sources":["../../../projects/lib/calendar/testing/wr-calendar-day-harness.ts","../../../projects/lib/calendar/testing/wr-calendar-harness.ts","../../../projects/lib/calendar/testing/ngwr-calendar-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrCalendarDayHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one day cell of a `<wr-calendar>` grid.\n *\n * The cell belongs to the calendar, and a date-picker's popup is a calendar in an\n * overlay — so this is the harness for both, re-exported from\n * `ngwr/date-picker/testing` under the name it shipped as\n * (`WrDatePickerDayHarness`). Reach it through `WrCalendarHarness.getDays()`, or\n * through `WrDatePickerHarness.getDay()` / `getDays()`, which scope it to ONE\n * picker's panel — those cells are in the shared overlay container, so a bare query\n * would answer with whichever picker opened first.\n *\n * State is read the way a screen reader reads it (`role`, `aria-selected`,\n * `aria-disabled`) with the `.wr-calendar__day--*` modifiers filling in what\n * ARIA has no word for: today, the spill days of the neighbouring months, and\n * the interior of a picked range.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarDayHarness extends ComponentHarness {\n static hostSelector = '.wr-calendar__day';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCalendarDayHarnessFilters = {}): HarnessPredicate<WrCalendarDayHarness> {\n return new HarnessPredicate(WrCalendarDayHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('selected', options.selected, async (harness, selected) => (await harness.isSelected()) === selected)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('inRange', options.inRange, async (harness, inRange) => (await harness.isInRange()) === inRange);\n }\n\n /** The day number as rendered. */\n async getText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** The day number as a number, for mapping a list of cells to dates. */\n async getDayOfMonth(): Promise<number> {\n return Number(await this.getText());\n }\n\n /**\n * What a screen reader announces for this cell — \"Thursday, January 15, 2026\".\n *\n * A SECOND question from {@link getText}, and the reason this method exists:\n * until v14 the cell had no name at all, so the two answers were \"15\" and\n * nothing. A spec that reads only the drawn number passes on a grid that\n * announces bare integers with no month, year or weekday anywhere in it.\n *\n * The string is `calendar.dayLabel` interpolated with the adapter's\n * `longDate`, so it moves with the locale AND with the adapter — assert\n * against the pair your spec provides, not against an English literal.\n */\n async getAccessibleName(): Promise<string | null> {\n return (await this.host()).getAttribute('aria-label');\n }\n\n /** `'gridcell'` — the cell is a button, and the grid semantics are what a spec should assert. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** Whether this day is (one end of) the current selection. */\n async isSelected(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-selected')) === 'true';\n }\n\n /**\n * Whether the day refuses selection — `min` / `max` or `dateFilter` ruled it\n * out, or the whole calendar is disabled.\n */\n async isDisabled(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the cell is today's date. */\n async isToday(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--today');\n }\n\n /**\n * Whether the cell belongs to a neighbouring month. The grid is always 6x7, so\n * every month is padded with days that are selectable but not \"in\" the month —\n * which is why `WrDatePickerHarness.getDay` and {@link WrCalendarHarness.getDay} skip them.\n */\n async isOutOfMonth(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--out-of-month');\n }\n\n /** Whether the day lies strictly between the two ends of a picked range. */\n async isInRange(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--in-range');\n }\n\n /**\n * Whether this is the roving cell — the grid's single tab stop, and where the\n * arrow keys move from.\n *\n * At most ONE cell answers `true`, and it is not always one: the calendar's\n * roving date does not follow `next()` / `previous()`, so a grid navigated away\n * from that month has no active cell (and, deliberately or not, no tab stop)\n * until a cell is clicked or the arrows move it.\n */\n async isActive(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--focused');\n }\n\n /** Click the cell. A disabled cell swallows the click — assert, do not assume. */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate, TestKey, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrCalendarMode } from 'ngwr/calendar';\n\nimport type {\n WrCalendarArrowKey,\n WrCalendarChip,\n WrCalendarDayHarnessFilters,\n WrCalendarHarnessFilters,\n WrCalendarView,\n} from './interfaces';\nimport { WrCalendarDayHarness } from './wr-calendar-day-harness';\n\nconst ARROWS: Record<WrCalendarArrowKey, TestKey> = {\n left: TestKey.LEFT_ARROW,\n right: TestKey.RIGHT_ARROW,\n up: TestKey.UP_ARROW,\n down: TestKey.DOWN_ARROW,\n};\n\n/**\n * Test harness for `<wr-calendar>` — the standalone month grid, and the one\n * `<wr-date-picker>` puts in an overlay.\n *\n * **It is three views behind one header.** Clicking the header label walks\n * `day → month → year`, and each view renders something different: a\n * `role=\"grid\"` of day cells, or a `role=\"listbox\"` of chips. Every day method\n * throws off the day view rather than answering `[]`, which would read as \"this\n * month has no days\".\n *\n * **The roving cell is not the selection.** The grid has one tab stop and the\n * arrows move it; it starts on the selected date, or on today when nothing is\n * picked. And it does NOT follow {@link next} / {@link previous} — a grid paged\n * away from the roving month has no active cell at all, and so no tab stop, until\n * a key or a click puts one back. That is the component's behaviour, and\n * {@link getActiveDayNumber} is how a spec sees it.\n *\n * **Keys go to the host, not to a cell.** The component listens on its own element,\n * so {@link pressArrow} works whether or not jsdom managed to put real focus\n * anywhere — which it often does not, since the calendar moves focus in an\n * `afterNextRender` and a disabled cell cannot take it.\n *\n * @example\n * ```ts\n * const calendar = await loader.getHarness(WrCalendarHarness);\n *\n * expect(await calendar.getHeaderLabel()).toBe('March 2026');\n * await (await calendar.getDay(14)).click();\n * expect(await calendar.getSelectedDayNumbers()).toEqual([14]);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarHarness extends ComponentHarness {\n static hostSelector = 'wr-calendar';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCalendarHarnessFilters = {}): HarnessPredicate<WrCalendarHarness> {\n return new HarnessPredicate(WrCalendarHarness, options)\n .addOption('headerLabel', options.headerLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getHeaderLabel(), label)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);\n }\n\n private readonly header = this.locatorFor('.wr-calendar__label');\n private readonly prevButton = this.locatorFor('.wr-calendar__nav--prev');\n private readonly nextButton = this.locatorFor('.wr-calendar__nav--next');\n\n /** Which sub-view is showing. */\n async getView(): Promise<WrCalendarView> {\n if ((await this.locatorForOptional('.wr-calendar__months')()) !== null) return 'month';\n if ((await this.locatorForOptional('.wr-calendar__years')()) !== null) return 'year';\n return 'day';\n }\n\n /** Single- or range-selection, from the host modifier. */\n async getMode(): Promise<WrCalendarMode> {\n return (await (await this.host()).hasClass('wr-calendar--range')) ? 'range' : 'single';\n }\n\n /** Whether the whole calendar refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar--disabled');\n }\n\n /** The header text — `March 2026`, `2026`, or `2016 – 2027` depending on the view. */\n async getHeaderLabel(): Promise<string> {\n return (await this.header()).text();\n }\n\n /**\n * Click the header — stepping `day → month → year`.\n *\n * The year view is the end of the walk: the header is disabled there, so this\n * throws rather than clicking a button the DOM would ignore.\n */\n async clickHeader(): Promise<void> {\n const header = await this.header();\n if (await header.getProperty<boolean>('disabled')) {\n throw new Error(\n `WrCalendarHarness.clickHeader(): the header is disabled — the calendar is on the ` +\n `${await this.getView()} view, which is where the walk stops (or the whole calendar is disabled).`\n );\n }\n await header.click();\n }\n\n /**\n * Step back — a month, a year or twelve years, depending on the view.\n *\n * The roving day cell does NOT come along: paging is a view change, not a\n * navigation, and the tab stop stays on the month it was in.\n */\n async previous(): Promise<void> {\n await (await this.prevButton()).click();\n }\n\n /** Step forward — a month, a year or twelve years, depending on the view. */\n async next(): Promise<void> {\n await (await this.nextButton()).click();\n }\n\n /**\n * The back arrow's accessible name, which changes with the view — the arrows are\n * icon-only, so this is the only name they have.\n */\n async getPreviousLabel(): Promise<string | null> {\n return (await this.prevButton()).getAttribute('aria-label');\n }\n\n /** The forward arrow's accessible name. */\n async getNextLabel(): Promise<string | null> {\n return (await this.nextButton()).getAttribute('aria-label');\n }\n\n /** The weekday column headers, in the order the adapter's first day of week puts them. */\n async getWeekdayNames(): Promise<string[]> {\n await this.requireView('day', 'getWeekdayNames');\n const names = await this.locatorForAll('.wr-calendar__weekday')();\n return Promise.all(names.map(name => name.text()));\n }\n\n /**\n * Every day cell, in DOM order — 42 of them, since the grid is always six weeks.\n *\n * That includes the spill days of the neighbouring months, which are selectable\n * and not \"in\" the month; {@link getDay} skips them, and\n * `WrCalendarDayHarness.isOutOfMonth()` tells them apart.\n */\n async getDays(filters: WrCalendarDayHarnessFilters = {}): Promise<WrCalendarDayHarness[]> {\n await this.requireView('day', 'getDays');\n return this.locatorForAll(WrCalendarDayHarness.with(filters))();\n }\n\n /**\n * The cell for a day of THIS month.\n *\n * The number alone is ambiguous — a 42-cell grid shows most numbers twice — so\n * the spill days are skipped rather than matched, which is what \"the 3rd\" means\n * to someone reading the calendar.\n */\n async getDay(dayOfMonth: number): Promise<WrCalendarDayHarness> {\n for (const day of await this.getDays({ text: String(dayOfMonth) })) {\n if (!(await day.isOutOfMonth())) return day;\n }\n throw new Error(\n `WrCalendarHarness.getDay(${dayOfMonth}): no such day in ${await this.getHeaderLabel()}. Only cells of ` +\n 'the displayed month count — the grid spills into its neighbours, and those are skipped.'\n );\n }\n\n /** The day numbers currently selected — one in single mode, both ends in range mode. */\n async getSelectedDayNumbers(): Promise<number[]> {\n const selected = await this.getDays({ selected: true });\n return Promise.all(selected.map(day => day.getDayOfMonth()));\n }\n\n /** The day numbers strictly inside a picked range — never the ends. */\n async getInRangeDayNumbers(): Promise<number[]> {\n const inRange = await this.getDays({ inRange: true });\n return Promise.all(inRange.map(day => day.getDayOfMonth()));\n }\n\n /**\n * The day number holding the roving tab stop, or `null` when the grid has none.\n *\n * `null` is a real answer, not a failure: paging with {@link next} leaves the\n * roving date behind in another month, and the grid then has no `tabindex=\"0\"`\n * at all until a key or a click puts one back.\n */\n async getActiveDayNumber(): Promise<number | null> {\n for (const day of await this.getDays()) {\n if (await day.isActive()) return day.getDayOfMonth();\n }\n return null;\n }\n\n /** The month chips, with their state. Throws off the month view. */\n async getMonths(): Promise<WrCalendarChip[]> {\n await this.requireView('month', 'getMonths');\n return this.readChips();\n }\n\n /** The year chips, with their state. Throws off the year view. */\n async getYears(): Promise<WrCalendarChip[]> {\n await this.requireView('year', 'getYears');\n return this.readChips();\n }\n\n /**\n * Click a month or year chip by its printed label — which drops the calendar back\n * one view, the way clicking the header climbed up.\n *\n * Throws on the day view, where there are no chips, and on a label the view does\n * not offer, naming what it does.\n */\n async selectChip(label: string): Promise<void> {\n const view = await this.getView();\n if (view === 'day') {\n throw new Error(\n 'WrCalendarHarness.selectChip(): the calendar is on the day view, which has no chips. Click the ' +\n 'header first — it walks day → month → year.'\n );\n }\n\n for (const chip of await this.locatorForAll('.wr-calendar__chip')()) {\n if ((await chip.text()) === label) {\n await chip.click();\n return;\n }\n }\n\n const offered = (await this.readChips()).map(chip => chip.label);\n throw new Error(`WrCalendarHarness.selectChip(\"${label}\"): the ${view} view offers: ${offered.join(', ')}.`);\n }\n\n /**\n * Press an arrow key — one day left or right, one WEEK up or down.\n *\n * Sent to the host, where the component listens, so this does not depend on jsdom\n * having managed to focus a cell. Under `dir=\"rtl\"` the horizontal pair mirrors:\n * ArrowRight goes back a day, because the grid itself is mirrored.\n */\n async pressArrow(arrow: WrCalendarArrowKey): Promise<void> {\n await (await this.host()).sendKeys(ARROWS[arrow]);\n }\n\n /** Press Home — the first day of the roving cell's week, not of the month. */\n async pressHome(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.HOME);\n }\n\n /** Press End — the last day of the roving cell's week. */\n async pressEnd(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.END);\n }\n\n /** Press PageUp — a month back, or a YEAR back with `shift`. */\n async pressPageUp(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_UP) : host.sendKeys(TestKey.PAGE_UP));\n }\n\n /** Press PageDown — a month on, or a YEAR on with `shift`. */\n async pressPageDown(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_DOWN) : host.sendKeys(TestKey.PAGE_DOWN));\n }\n\n /** Press Enter — picking the roving day, exactly as clicking it would. */\n async pressEnter(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.ENTER);\n }\n\n /**\n * The role of the element that owns the day rows.\n *\n * Worth asserting rather than assuming: the grid is NOT the host. The host also\n * holds the nav header, and a `role=\"grid\"` may only own rows — so the role sits\n * on the body, and the weekday strip is a row inside it rather than a sibling.\n */\n async getGridRole(): Promise<string | null> {\n const body = await this.locatorForOptional('.wr-calendar__body')();\n return body ? body.getAttribute('role') : null;\n }\n\n /** How many week rows the grid renders — always six, which is what keeps it from reflowing. */\n async getWeekCount(): Promise<number> {\n await this.requireView('day', 'getWeekCount');\n return (await this.locatorForAll('.wr-calendar__week')()).length;\n }\n\n private async readChips(): Promise<WrCalendarChip[]> {\n const chips = await this.locatorForAll('.wr-calendar__chip')();\n\n return Promise.all(\n chips.map(async (chip: TestElement) => ({\n label: await chip.text(),\n selected: (await chip.getAttribute('aria-selected')) === 'true',\n current: await chip.hasClass('wr-calendar__chip--current'),\n disabled: (await chip.getAttribute('aria-disabled')) === 'true',\n }))\n );\n }\n\n private async requireView(view: WrCalendarView, method: string): Promise<void> {\n const current = await this.getView();\n if (current === view) return;\n\n throw new Error(\n `WrCalendarHarness.${method}(): the calendar is showing the ${current} view, not the ${view} one — those ` +\n 'elements are not rendered at all. The header walks day → month → year; clicking a chip walks back down.'\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;;AAiBG;AACG,MAAO,oBAAqB,SAAQ,gBAAgB,CAAA;AACxD,IAAA,OAAO,YAAY,GAAG,mBAAmB;;AAGzC,IAAA,OAAO,IAAI,CAAC,OAAA,GAAuC,EAAE,EAAA;AACnD,QAAA,OAAO,IAAI,gBAAgB,CAAC,oBAAoB,EAAE,OAAO;aACtD,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC;aAC1G,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,QAAQ;aAC9G,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,QAAQ;aAC9G,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC,MAAM,OAAO,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAC/G;;AAGA,IAAA,MAAM,OAAO,GAAA;QACX,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE;IACnC;;AAGA,IAAA,MAAM,aAAa,GAAA;QACjB,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACrC;AAEA;;;;;;;;;;;AAWG;AACH,IAAA,MAAM,iBAAiB,GAAA;AACrB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC;IACvD;;AAGA,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC;IACjD;;AAGA,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,eAAe,CAAC,MAAM,MAAM;IAC7E;AAEA;;;AAGG;AACH,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,YAAY,CAAC,eAAe,CAAC,MAAM,MAAM;IAC7E;;AAGA,IAAA,MAAM,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,yBAAyB,CAAC;IAChE;AAEA;;;;AAIG;AACH,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,gCAAgC,CAAC;IACvE;;AAGA,IAAA,MAAM,SAAS,GAAA;AACb,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,4BAA4B,CAAC;IACnE;AAEA;;;;;;;;AAQG;AACH,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,2BAA2B,CAAC;IAClE;;AAGA,IAAA,MAAM,KAAK,GAAA;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE;IACpC;;;ACxHF;;;;;AAKG;AAeH,MAAM,MAAM,GAAwC;IAClD,IAAI,EAAE,OAAO,CAAC,UAAU;IACxB,KAAK,EAAE,OAAO,CAAC,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAC,QAAQ;IACpB,IAAI,EAAE,OAAO,CAAC,UAAU;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCG;AACG,MAAO,iBAAkB,SAAQ,gBAAgB,CAAA;AACrD,IAAA,OAAO,YAAY,GAAG,aAAa;;AAGnC,IAAA,OAAO,IAAI,CAAC,OAAA,GAAoC,EAAE,EAAA;AAChD,QAAA,OAAO,IAAI,gBAAgB,CAAC,iBAAiB,EAAE,OAAO;aACnD,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,KAC5D,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,KAAK,CAAC;aAEhE,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI;aAC3F,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,QAAQ,CAAC;IACpH;AAEiB,IAAA,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC;AAC/C,IAAA,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC;AACvD,IAAA,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC;;AAGxE,IAAA,MAAM,OAAO,GAAA;QACX,IAAI,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,sBAAsB,CAAC,EAAE,MAAM,IAAI;AAAE,YAAA,OAAO,OAAO;QACtF,IAAI,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,EAAE,MAAM,IAAI;AAAE,YAAA,OAAO,MAAM;AACpF,QAAA,OAAO,KAAK;IACd;;AAGA,IAAA,MAAM,OAAO,GAAA;QACX,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,oBAAoB,CAAC,IAAI,OAAO,GAAG,QAAQ;IACxF;;AAGA,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,uBAAuB,CAAC;IAC9D;;AAGA,IAAA,MAAM,cAAc,GAAA;QAClB,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE;IACrC;AAEA;;;;;AAKG;AACH,IAAA,MAAM,WAAW,GAAA;AACf,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE;QAClC,IAAI,MAAM,MAAM,CAAC,WAAW,CAAU,UAAU,CAAC,EAAE;YACjD,MAAM,IAAI,KAAK,CACb,CAAA,iFAAA,CAAmF;AACjF,gBAAA,CAAA,EAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA,yEAAA,CAA2E,CACrG;QACH;AACA,QAAA,MAAM,MAAM,CAAC,KAAK,EAAE;IACtB;AAEA;;;;;AAKG;AACH,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE;IACzC;;AAGA,IAAA,MAAM,IAAI,GAAA;QACR,MAAM,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE;IACzC;AAEA;;;AAGG;AACH,IAAA,MAAM,gBAAgB,GAAA;AACpB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC;IAC7D;;AAGA,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC;IAC7D;;AAGA,IAAA,MAAM,eAAe,GAAA;QACnB,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,iBAAiB,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC,EAAE;AACjE,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,OAAO,CAAC,OAAA,GAAuC,EAAE,EAAA;QACrD,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC;AACxC,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE;IACjE;AAEA;;;;;;AAMG;IACH,MAAM,MAAM,CAAC,UAAkB,EAAA;AAC7B,QAAA,KAAK,MAAM,GAAG,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE;AAClE,YAAA,IAAI,EAAE,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;AAAE,gBAAA,OAAO,GAAG;QAC7C;QACA,MAAM,IAAI,KAAK,CACb,CAAA,yBAAA,EAA4B,UAAU,CAAA,kBAAA,EAAqB,MAAM,IAAI,CAAC,cAAc,EAAE,CAAA,gBAAA,CAAkB;AACtG,YAAA,yFAAyF,CAC5F;IACH;;AAGA,IAAA,MAAM,qBAAqB,GAAA;AACzB,QAAA,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACvD,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;IAC9D;;AAGA,IAAA,MAAM,oBAAoB,GAAA;AACxB,QAAA,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACrD,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;IAC7D;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,kBAAkB,GAAA;QACtB,KAAK,MAAM,GAAG,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE;AACtC,YAAA,IAAI,MAAM,GAAG,CAAC,QAAQ,EAAE;AAAE,gBAAA,OAAO,GAAG,CAAC,aAAa,EAAE;QACtD;AACA,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,MAAM,SAAS,GAAA;QACb,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC;AAC5C,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE;IACzB;;AAGA,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC;AAC1C,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE;IACzB;AAEA;;;;;;AAMG;IACH,MAAM,UAAU,CAAC,KAAa,EAAA;AAC5B,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;AACjC,QAAA,IAAI,IAAI,KAAK,KAAK,EAAE;YAClB,MAAM,IAAI,KAAK,CACb,iGAAiG;AAC/F,gBAAA,6CAA6C,CAChD;QACH;AAEA,QAAA,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE,EAAE;YACnE,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,EAAE;AACjC,gBAAA,MAAM,IAAI,CAAC,KAAK,EAAE;gBAClB;YACF;QACF;QAEA,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC;AAChE,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,8BAAA,EAAiC,KAAK,WAAW,IAAI,CAAA,cAAA,EAAiB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAA,CAAG,CAAC;IAC9G;AAEA;;;;;;AAMG;IACH,MAAM,UAAU,CAAC,KAAyB,EAAA;AACxC,QAAA,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnD;;AAGA,IAAA,MAAM,SAAS,GAAA;AACb,QAAA,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;IAClD;;AAGA,IAAA,MAAM,QAAQ,GAAA;AACZ,QAAA,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;IACjD;;AAGA,IAAA,MAAM,WAAW,CAAC,OAAA,GAA+B,EAAE,EAAA;AACjD,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE;AAC9B,QAAA,OAAO,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1G;;AAGA,IAAA,MAAM,aAAa,CAAC,OAAA,GAA+B,EAAE,EAAA;AACnD,QAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE;AAC9B,QAAA,OAAO,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9G;;AAGA,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;IACnD;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,WAAW,GAAA;QACf,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,EAAE;AAClE,QAAA,OAAO,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI;IAChD;;AAGA,IAAA,MAAM,YAAY,GAAA;QAChB,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC;AAC7C,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM;IAClE;AAEQ,IAAA,MAAM,SAAS,GAAA;QACrB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE;AAE9D,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,OAAO,IAAiB,MAAM;AACtC,YAAA,KAAK,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE;YACxB,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,MAAM;AAC/D,YAAA,OAAO,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC1D,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,MAAM;SAChE,CAAC,CAAC,CACJ;IACH;AAEQ,IAAA,MAAM,WAAW,CAAC,IAAoB,EAAE,MAAc,EAAA;AAC5D,QAAA,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE;QACpC,IAAI,OAAO,KAAK,IAAI;YAAE;QAEtB,MAAM,IAAI,KAAK,CACb,CAAA,kBAAA,EAAqB,MAAM,CAAA,gCAAA,EAAmC,OAAO,CAAA,eAAA,EAAkB,IAAI,CAAA,aAAA,CAAe;AACxG,YAAA,yGAAyG,CAC5G;IACH;;;AClUF;;AAEG;;;;"}
@@ -3,7 +3,7 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
3
3
  import * as i0 from '@angular/core';
4
4
  import { signal, input, model, inject, ElementRef, Injector, computed, afterNextRender, effect, untracked, ViewEncapsulation, Component } from '@angular/core';
5
5
  import { WrDateAdapter } from 'ngwr/date';
6
- import { useI18nText } from 'ngwr/i18n';
6
+ import { useI18nText, useI18nFormatter } from 'ngwr/i18n';
7
7
 
8
8
  /**
9
9
  * @license
@@ -147,22 +147,68 @@ class WrCalendar {
147
147
  return Array.from({ length: 12 }, (_, i) => start + i);
148
148
  }, /* @ts-ignore */
149
149
  ...(ngDevMode ? [{ debugName: "yearsView" }] : /* istanbul ignore next */ []));
150
+ /**
151
+ * The header above the grid.
152
+ *
153
+ * Both templated strings used to be assembled here: `${month} ${year}` and
154
+ * `${first} – ${last}`. That is English word order with an English separator
155
+ * baked into TypeScript, and no catalog could move either — ja-JP writes
156
+ * 2026年3月, which is not a translation of any word in `March 2026` but a
157
+ * different arrangement of the same two values. So the arrangement is the
158
+ * translatable unit, and `calendar.header` / `calendar.yearRange` are it.
159
+ */
150
160
  headerLabel = computed(() => {
151
161
  const v = this.viewDate();
152
162
  switch (this.viewMode()) {
153
163
  case 'day': {
154
164
  const monthNames = this.adapter.getMonthNames('long');
155
- return `${monthNames[this.adapter.getMonth(v)]} ${this.adapter.getYear(v)}`;
165
+ return this.headerText({
166
+ month: monthNames[this.adapter.getMonth(v)],
167
+ year: this.adapter.getYear(v),
168
+ });
156
169
  }
157
170
  case 'month':
158
171
  return `${this.adapter.getYear(v)}`;
159
172
  case 'year': {
160
173
  const years = this.yearsView();
161
- return `${years[0]} – ${years[years.length - 1]}`;
174
+ return this.yearRangeText({ from: years[0], to: years[years.length - 1] });
162
175
  }
163
176
  }
164
177
  }, /* @ts-ignore */
165
178
  ...(ngDevMode ? [{ debugName: "headerLabel" }] : /* istanbul ignore next */ []));
179
+ headerText = useI18nFormatter('calendar.header', '{{month}} {{year}}');
180
+ yearRangeText = useI18nFormatter('calendar.yearRange', '{{from}} – {{to}}');
181
+ dayLabelText = useI18nFormatter('calendar.dayLabel', '{{weekday}}, {{date}}');
182
+ /**
183
+ * Long weekday names for the cell names.
184
+ *
185
+ * `getDayOfWeekNames` returns them in COLUMN order — index 0 is
186
+ * `getFirstDayOfWeek()`, not Sunday — which is what the header strip wants and
187
+ * what a `getDayOfWeek()` result (0 = Sunday) must be rotated into. Indexing
188
+ * it directly reads Monday's name for a Sunday in every locale that starts its
189
+ * week on Monday, which is most of them.
190
+ */
191
+ longWeekdays = computed(() => this.adapter.getDayOfWeekNames('long'), /* @ts-ignore */
192
+ ...(ngDevMode ? [{ debugName: "longWeekdays" }] : /* istanbul ignore next */ []));
193
+ /**
194
+ * A day cell's accessible name — "Sunday, March 15, 2026".
195
+ *
196
+ * The cell had none. Its only content is the day NUMBER, and `role="gridcell"`
197
+ * does not inherit a name from the grid's header or from the column header
198
+ * above it, so every date in the month announced as a bare number: the month,
199
+ * the year and the weekday were all on screen and none of them reachable.
200
+ *
201
+ * `{{date}}` is the adapter's `longDate`, so its field order, its separators
202
+ * and its digits are `Intl`'s — the catalog decides only where the weekday
203
+ * goes. Building it from `getMonthNames('long')` instead would have hard-coded
204
+ * the nominative month, which Russian and Finnish inflect inside a date.
205
+ */
206
+ dayLabel(date) {
207
+ return this.dayLabelText({
208
+ weekday: this.longWeekdays()[(this.adapter.getDayOfWeek(date) - this.adapter.getFirstDayOfWeek() + 7) % 7],
209
+ date: this.adapter.format(date, 'longDate'),
210
+ });
211
+ }
166
212
  /** 6×7 day grid covering the current month plus spillover. */
167
213
  weeks = computed(() => {
168
214
  const view = this.viewDate();
@@ -700,7 +746,7 @@ class WrCalendar {
700
746
  return key;
701
747
  }
702
748
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
703
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: WrCalendar, isStandalone: true, selector: "wr-calendar", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, dateFilter: { classPropertyName: "dateFilter", publicName: "dateFilter", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { date: "dateChange", range: "rangeChange" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model \u2014 arrow to a month, Tab\n out of the list \u2014 that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n", encapsulation: i0.ViewEncapsulation.None });
749
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: WrCalendar, isStandalone: true, selector: "wr-calendar", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, dateFilter: { classPropertyName: "dateFilter", publicName: "dateFilter", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { date: "dateChange", range: "rangeChange" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model \u2014 arrow to a month, Tab\n out of the list \u2014 that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n", encapsulation: i0.ViewEncapsulation.None });
704
750
  }
705
751
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrCalendar, decorators: [{
706
752
  type: Component,
@@ -710,7 +756,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
710
756
  // only own rows. The role sits on `.wr-calendar__body`, which is the day
711
757
  // matrix and nothing else.
712
758
  '(keydown)': 'onKeyDown($event)',
713
- }, template: "<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model \u2014 arrow to a month, Tab\n out of the list \u2014 that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n" }]
759
+ }, template: "<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model \u2014 arrow to a month, Tab\n out of the list \u2014 that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n" }]
714
760
  }], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }, { type: i0.Output, args: ["dateChange"] }], range: [{ type: i0.Input, args: [{ isSignal: true, alias: "range", required: false }] }, { type: i0.Output, args: ["rangeChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], dateFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFilter", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
715
761
 
716
762
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-calendar.mjs","sources":["../../../projects/lib/calendar/calendar.ts","../../../projects/lib/calendar/calendar.html","../../../projects/lib/calendar/ngwr-calendar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { WrDateAdapter } from 'ngwr/date';\nimport { useI18nText } from 'ngwr/i18n';\n\nimport type { WrCalendarMode, WrCalendarRange } from './interfaces';\n\n/**\n * Stands in for the consumer input `useI18nText` expects, for labels the calendar\n * exposes no input for. Constant and read-only, so one instance is safe to share.\n */\nconst NO_OVERRIDE = signal<string | null>(null).asReadonly();\n\nconst ROWS = 6;\nconst COLS = 7;\n\n/**\n * Chips per row in the month and year views — the vertical arrows step by one\n * of these, so they have to agree with `grid-template-columns` in\n * `styles/_index.scss`. Two numbers because the two grids differ: twelve months\n * read as four rows of three, twelve years as three rows of four.\n */\nconst MONTH_COLS = 3;\nconst YEAR_COLS = 4;\n\n/**\n * Month-view calendar. Supports single-date selection (`mode=\"single\"`) or\n * date-range selection (`mode=\"range\"`). Reusable on its own; consumed by\n * `<wr-date-picker>` inside an overlay.\n *\n * Uses {@link WrDateAdapter} for all date math and formatting — register\n * one via {@link provideWrDateAdapter} at bootstrap.\n *\n * @example\n * ```html\n * <wr-calendar [(date)]=\"picked\" [min]=\"minDate\" />\n *\n * <wr-calendar mode=\"range\" [(range)]=\"[start, end]\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar\n */\n@Component({\n selector: 'wr-calendar',\n templateUrl: './calendar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // No `role=\"grid\"` here: the host also wraps the nav header, and a grid may\n // only own rows. The role sits on `.wr-calendar__body`, which is the day\n // matrix and nothing else.\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class WrCalendar {\n /** Selection mode. @default 'single' */\n readonly mode = input<WrCalendarMode>('single');\n\n /** Two-way bindable single value (used when `mode === 'single'`). */\n readonly date = model<Date | null>(null);\n\n /** Two-way bindable `[start, end]` (used when `mode === 'range'`). */\n readonly range = model<WrCalendarRange>([null, null]);\n\n /** Min selectable date (inclusive). */\n readonly min = input<Date | null>(null);\n\n /** Max selectable date (inclusive). */\n readonly max = input<Date | null>(null);\n\n /** Predicate — return `false` to disable specific dates (e.g. weekends only). */\n readonly dateFilter = input<((date: Date) => boolean) | null>(null);\n\n /**\n * Move real focus onto the roving cell as soon as the grid is on screen.\n *\n * Off by default: a standalone `<wr-calendar>` sitting in a page must not\n * steal focus on load. `wr-date-picker` turns it on for the popup it opens\n * from its trigger, where the user asked to be taken to the calendar.\n * @default false\n */\n readonly autoFocus = input(false, { transform: coerceBooleanProperty });\n\n /** Disable interaction entirely. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n private readonly adapter = inject<WrDateAdapter<Date>>(WrDateAdapter);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n /** Currently displayed month (any date inside it). */\n protected readonly viewDate = signal(this.adapter.today());\n\n /** Date currently focused by keyboard (single roving tabindex). */\n protected readonly focusedDate = signal(this.adapter.today());\n\n /** Hovered date during range-mode end-pick — drives the preview highlight. */\n protected readonly hoverDate = signal<Date | null>(null);\n\n /** Which sub-view is currently shown. Cycles `day → month → year` on header click. */\n protected readonly viewMode = signal<'day' | 'month' | 'year'>('day');\n\n /**\n * Chip the month / year listbox has moved its ring to, as an index into\n * `monthsView()` / `yearsView()`. `null` means \"nobody has pressed an arrow\n * yet\", which resolves to the month or year on screen — see {@link activeChip}.\n *\n * Reset on every view change rather than remembered: coming back to the month\n * list should ring the month you are looking at, not the one an earlier visit\n * happened to leave the ring on.\n */\n private readonly rovedChip = signal<number | null>(null);\n\n // The four month/year strings have been in both catalogs since they were written\n // and nothing read them: the template hard-coded the same English beside them, so a\n // localized app announced its calendar's arrows in English. `nullSignal()` is the\n // shim for exactly this — a label with no consumer input to forward.\n private readonly prevMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.prevMonth', 'Previous month');\n private readonly nextMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.nextMonth', 'Next month');\n private readonly prevYearLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYear', 'Previous year');\n private readonly nextYearLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYear', 'Next year');\n private readonly prevYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYears', 'Previous 12 years');\n private readonly nextYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYears', 'Next 12 years');\n\n /** What the ← button does from here — a month, a year, or a 12-year page. */\n protected readonly prevLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.prevYearsLabel();\n case 'month':\n return this.prevYearLabel();\n default:\n return this.prevMonthLabel();\n }\n });\n\n /** What the → button does from here. */\n protected readonly nextLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.nextYearsLabel();\n case 'month':\n return this.nextYearLabel();\n default:\n return this.nextMonthLabel();\n }\n });\n\n protected readonly today = computed(() => this.adapter.today());\n\n protected readonly weekdayNames = computed(() => this.adapter.getDayOfWeekNames('short'));\n\n protected readonly monthsView = computed(() => this.adapter.getMonthNames('short'));\n\n /** 12-year window centered on the floor-aligned decade containing `viewDate`. */\n protected readonly yearsView = computed<readonly number[]>(() => {\n const y = this.adapter.getYear(this.viewDate());\n const start = Math.floor(y / 12) * 12;\n return Array.from({ length: 12 }, (_, i) => start + i);\n });\n\n protected readonly headerLabel = computed(() => {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day': {\n const monthNames = this.adapter.getMonthNames('long');\n return `${monthNames[this.adapter.getMonth(v)]} ${this.adapter.getYear(v)}`;\n }\n case 'month':\n return `${this.adapter.getYear(v)}`;\n case 'year': {\n const years = this.yearsView();\n return `${years[0]} – ${years[years.length - 1]}`;\n }\n }\n });\n\n /** 6×7 day grid covering the current month plus spillover. */\n protected readonly weeks = computed<readonly (readonly Date[])[]>(() => {\n const view = this.viewDate();\n const year = this.adapter.getYear(view);\n const month = this.adapter.getMonth(view);\n const firstOfMonth = this.adapter.createDate(year, month, 1);\n const firstWeekday = this.adapter.getDayOfWeek(firstOfMonth);\n const firstDayOfWeek = this.adapter.getFirstDayOfWeek();\n const lead = (firstWeekday - firstDayOfWeek + 7) % 7;\n const gridStart = this.adapter.addDays(firstOfMonth, -lead);\n\n const out: Date[][] = [];\n for (let w = 0; w < ROWS; w++) {\n const row: Date[] = [];\n for (let d = 0; d < COLS; d++) {\n row.push(this.adapter.addDays(gridStart, w * COLS + d));\n }\n out.push(row);\n }\n return out;\n });\n\n /**\n * The chip carrying the listbox's only `tabindex=\"0\"` — where the ring is, and\n * where Tab lands.\n *\n * A listbox owns its arrows, and these two did not: twelve months were twelve\n * tab stops, so the role promised an interaction model the component never\n * implemented. One tab stop plus arrow keys is the roving-tabindex half of the\n * pattern the day grid already uses.\n *\n * Routed through {@link nearestEnabledChip} on BOTH paths — the seed and every\n * arrow — for the reason the grid learned first: `.focus()` on a\n * `<button disabled>` is a no-op, so parking the sole tab stop on a month a\n * `[min]` has closed off leaves the whole view unreachable by keyboard.\n * `-1` on the day view, where there are no chips at all.\n */\n protected readonly activeChip = computed(() => {\n if (this.viewMode() === 'day') return -1;\n return this.nearestEnabledChip(this.rovedChip() ?? this.currentChip());\n });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-calendar', `wr-calendar--${this.mode()}`];\n if (this.disabled()) parts.push('wr-calendar--disabled');\n return parts.join(' ');\n });\n\n constructor() {\n // Initial focus: selected date if any, else today. Also snap viewDate to\n // that month.\n //\n // Stepped onto an ENABLED day, because the roving tabindex puts the grid's\n // only `tabindex=\"0\"` on this cell: seed it on a disabled one — which is\n // exactly what a `min` in the future does to \"today\" — and the sole tab\n // stop is an unfocusable button, leaving the grid unreachable by keyboard.\n afterNextRender(() => {\n const initial = this.nearestEnabled(this.date() ?? this.range()[0] ?? this.adapter.today());\n this.focusedDate.set(initial);\n this.viewDate.set(initial);\n\n // A second, NESTED hook: the lines above only SET the signals, which\n // schedules another change-detection pass — the `--focused` class and the\n // `tabindex` are not in the DOM until that one has run.\n if (this.autoFocus()) {\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n });\n\n // Keep viewDate in sync when date / range changes externally to a\n // different month. The viewDate read must stay untracked — otherwise\n // the effect re-runs on every internal navigation (month stepping,\n // year picking) and snaps the view back to the selected month.\n effect(() => {\n const candidate = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!candidate) return;\n untracked(() => {\n if (!this.adapter.isSameMonth(candidate, this.viewDate())) {\n this.viewDate.set(candidate);\n }\n });\n });\n }\n\n // Navigation\n\n /** Header `‹` button — steps by month / year / decade based on the active view. */\n protected prev(): void {\n this.viewDate.set(this.stepViewDate(-1));\n }\n\n /** Header `›` button — steps by month / year / decade based on the active view. */\n protected next(): void {\n this.viewDate.set(this.stepViewDate(1));\n }\n\n /** Header label click — zooms out (`day → month → year`). No-op at year view. */\n protected onLabelClick(): void {\n if (this.disabled()) return;\n if (this.viewMode() === 'day') {\n this.setViewMode('month');\n } else if (this.viewMode() === 'month') {\n this.setViewMode('year');\n }\n }\n\n protected onMonthSelect(monthIdx: number): void {\n if (this.isMonthDisabled(monthIdx)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(this.adapter.getYear(v), monthIdx, 1));\n this.setViewMode('day');\n }\n\n protected onYearSelect(year: number): void {\n if (this.isYearDisabled(year)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(year, this.adapter.getMonth(v), 1));\n this.setViewMode('month');\n }\n\n /**\n * Switch views and drop the chip ring with them.\n *\n * Every view change is the only thing that changes what the chips MEAN, so it\n * is the one place the ring has to forget where it was — otherwise a year\n * picked at index 7 rings the eighth MONTH on the way back down.\n */\n private setViewMode(view: 'day' | 'month' | 'year'): void {\n this.rovedChip.set(null);\n this.viewMode.set(view);\n }\n\n private stepViewDate(direction: -1 | 1): Date {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day':\n return this.adapter.addMonths(v, direction);\n case 'month':\n return this.adapter.addYears(v, direction);\n case 'year':\n return this.adapter.addYears(v, direction * 12);\n }\n }\n\n // Cell state predicates (used by template)\n\n protected isToday(date: Date): boolean {\n return this.adapter.isSameDay(date, this.today());\n }\n\n protected isOutOfMonth(date: Date): boolean {\n return !this.adapter.isSameMonth(date, this.viewDate());\n }\n\n protected isSelected(date: Date): boolean {\n if (this.mode() === 'single') {\n const v = this.date();\n return v ? this.adapter.isSameDay(date, v) : false;\n }\n const [start, end] = this.range();\n if (start && this.adapter.isSameDay(date, start)) return true;\n if (end && this.adapter.isSameDay(date, end)) return true;\n return false;\n }\n\n protected isInRange(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n if (!start || !end) return false;\n return this.adapter.compareDate(date, start) > 0 && this.adapter.compareDate(date, end) < 0;\n }\n\n protected isInRangePreview(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n const hover = this.hoverDate();\n if (!start || end || !hover) return false;\n const before = this.adapter.compareDate(start, hover) <= 0;\n const lo = before ? start : hover;\n const hi = before ? hover : start;\n return this.adapter.compareDate(date, lo) > 0 && this.adapter.compareDate(date, hi) < 0;\n }\n\n protected isFocused(date: Date): boolean {\n return this.adapter.isSameDay(date, this.focusedDate());\n }\n\n protected isDisabled(date: Date): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && this.adapter.compareDate(date, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(date, max) > 0) return true;\n const filter = this.dateFilter();\n if (filter && !filter(date)) return true;\n return false;\n }\n\n // Month / year view predicates\n\n protected isMonthCurrent(monthIdx: number): boolean {\n return this.adapter.getMonth(this.viewDate()) === monthIdx;\n }\n\n protected isMonthSelected(monthIdx: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!v) return false;\n return this.adapter.getYear(v) === this.adapter.getYear(this.viewDate()) && this.adapter.getMonth(v) === monthIdx;\n }\n\n protected isMonthDisabled(monthIdx: number): boolean {\n if (this.disabled()) return true;\n const year = this.adapter.getYear(this.viewDate());\n const monthStart = this.adapter.createDate(year, monthIdx, 1);\n const monthEnd = this.adapter.createDate(year, monthIdx, this.adapter.getDaysInMonth(monthStart));\n const min = this.min();\n if (min && this.adapter.compareDate(monthEnd, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(monthStart, max) > 0) return true;\n return false;\n }\n\n protected isYearCurrent(year: number): boolean {\n return this.adapter.getYear(this.viewDate()) === year;\n }\n\n protected isYearSelected(year: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n return v ? this.adapter.getYear(v) === year : false;\n }\n\n protected isYearDisabled(year: number): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && year < this.adapter.getYear(min)) return true;\n const max = this.max();\n if (max && year > this.adapter.getYear(max)) return true;\n return false;\n }\n\n // Interaction\n\n protected onCellClick(date: Date): void {\n if (this.isDisabled(date)) return;\n if (this.mode() === 'single') {\n this.date.set(this.adapter.clone(date));\n } else {\n this.applyRangeClick(date);\n }\n this.focusedDate.set(date);\n if (!this.adapter.isSameMonth(date, this.viewDate())) {\n this.viewDate.set(date);\n }\n }\n\n protected onCellEnter(date: Date): void {\n if (this.mode() === 'range') this.hoverDate.set(date);\n }\n\n protected onCellLeave(): void {\n if (this.mode() === 'range') this.hoverDate.set(null);\n }\n\n private applyRangeClick(date: Date): void {\n const [start, end] = this.range();\n if (!start || (start && end)) {\n this.range.set([this.adapter.clone(date), null]);\n return;\n }\n if (this.adapter.compareDate(date, start) < 0) {\n this.range.set([this.adapter.clone(date), start]);\n } else {\n this.range.set([start, this.adapter.clone(date)]);\n }\n this.hoverDate.set(null);\n }\n\n // Keyboard\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n\n // The listener sits on the HOST, which also wraps the nav header — so\n // without this every key aimed at a `‹` button drove the day grid instead,\n // and the `preventDefault()` below cancelled the button's own activation:\n // Enter on `‹` picked a day the user never touched, ArrowDown on the header\n // yanked real focus into the grid. The host element itself is deliberately\n // let through: `WrCalendarHarness` sends its keys to `<wr-calendar>` rather\n // than to a cell, because the calendar moves focus in an `afterNextRender`\n // and jsdom often has focus nowhere at all.\n const target = event.target as Element | null;\n if (target !== this.host.nativeElement && target?.closest('.wr-calendar__header')) return;\n\n // The month and year views are listboxes, and the arrows belong to them\n // while they are up — there is no day grid on screen to drive. Their chips\n // are real `<button>`s, so Enter and Space fall through to the browser's own\n // activation and must not be swallowed here.\n if (this.viewMode() !== 'day') {\n this.onChipKeyDown(event);\n return;\n }\n\n const current = this.focusedDate();\n let next: Date | null = null;\n // Which way the key travels, so a landing on a closed-off day can keep\n // going instead of stopping on it. See `nearestEnabledToward`.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = this.adapter.addDays(current, -1);\n dir = -1;\n break;\n case 'ArrowRight':\n next = this.adapter.addDays(current, 1);\n break;\n case 'ArrowUp':\n next = this.adapter.addDays(current, -7);\n dir = -1;\n break;\n case 'ArrowDown':\n next = this.adapter.addDays(current, 7);\n break;\n case 'Home': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, -((dow - first + 7) % 7));\n dir = -1;\n break;\n }\n case 'End': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, 6 - ((dow - first + 7) % 7));\n break;\n }\n case 'PageUp':\n next = event.shiftKey ? this.adapter.addYears(current, -1) : this.adapter.addMonths(current, -1);\n dir = -1;\n break;\n case 'PageDown':\n next = event.shiftKey ? this.adapter.addYears(current, 1) : this.adapter.addMonths(current, 1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.onCellClick(current);\n return;\n }\n\n if (!next) return;\n event.preventDefault();\n\n // The seed is routed through `nearestEnabled` for a reason, and navigation\n // needs the same care: a cell renders `disabled` AND carries the grid's only\n // `tabindex=\"0\"`, so parking the ring on a closed-off day leaves zero\n // tabbable cells — the user tabs out of the calendar and can never tab back\n // in. Real focus splits from the ring too, because `.focus()` on a disabled\n // button is a no-op. Reached by nothing more exotic than `[minDate]`.\n const landing = this.nearestEnabledToward(next, dir);\n if (!landing) return;\n next = landing;\n\n this.focusedDate.set(next);\n if (!this.adapter.isSameMonth(next, this.viewDate())) {\n this.viewDate.set(next);\n }\n // `afterNextRender`, NOT `queueMicrotask`. Under zoneless CD the scheduler\n // runs change detection in a macrotask, so a microtask fires FIRST — the\n // `--focused` class is still on the cell we just left, and this focuses\n // that one. The ring moved and real focus did not, permanently: a screen\n // reader kept announcing the previous day.\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /**\n * Arrow / Home / End inside the month or year listbox — the roving half of the\n * pattern their `role` has always claimed.\n *\n * Steps by one along the row and by a full row vertically, and the inline pair\n * mirrors under `dir=\"rtl\"` for the same reason the grid's does: those two keys\n * name a side of the screen. The page does NOT wrap or spill into the next\n * one — a month list is twelve fixed cells, and the header's `‹` / `›` are what\n * change which twelve. Anything else (Enter, Space, Tab, Escape) is left to the\n * button and to whatever owns the calendar.\n */\n private onChipKeyDown(event: KeyboardEvent): void {\n const cols = this.viewMode() === 'month' ? MONTH_COLS : YEAR_COLS;\n const count = this.chipCount();\n const current = this.activeChip();\n // Assigned on every branch that does not return, so it needs no placeholder.\n let next: number;\n // Which way to keep looking when the landing chip is closed off, exactly as\n // `nearestEnabledToward` does for days.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = current - 1;\n dir = -1;\n break;\n case 'ArrowRight':\n next = current + 1;\n break;\n case 'ArrowUp':\n next = current - cols;\n dir = -1;\n break;\n case 'ArrowDown':\n next = current + cols;\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = count - 1;\n dir = -1;\n break;\n default:\n return;\n }\n\n const landing = this.enabledChipToward(next, dir);\n if (landing === null) return;\n\n event.preventDefault();\n this.rovedChip.set(landing);\n // `afterNextRender`, not `queueMicrotask` — same trap as the grid: under\n // zoneless CD the microtask runs before the new `tabindex` is in the DOM, so\n // the focus call would land on the chip the ring just left.\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /** How many chips the current view renders — twelve either way, read rather than assumed. */\n private chipCount(): number {\n return this.viewMode() === 'month' ? this.monthsView().length : this.yearsView().length;\n }\n\n /** Whether the chip at `index` refuses selection in the current view. */\n private isChipDisabled(index: number): boolean {\n if (this.viewMode() === 'month') return this.isMonthDisabled(index);\n const year = this.yearsView()[index];\n return year === undefined || this.isYearDisabled(year);\n }\n\n /** The chip the view itself points at: the month or year currently on screen. */\n private currentChip(): number {\n if (this.viewMode() === 'month') return this.adapter.getMonth(this.viewDate());\n const index = this.yearsView().indexOf(this.adapter.getYear(this.viewDate()));\n return index === -1 ? 0 : index;\n }\n\n /**\n * The first selectable chip at or after `from`, else the first before it, else\n * `from` unchanged when the whole page is closed off — the chip version of\n * {@link nearestEnabled}, and it exists for the same reason: the ring carries\n * the only `tabindex=\"0\"`, and a disabled button cannot hold it.\n */\n private nearestEnabledChip(from: number): number {\n const count = this.chipCount();\n const start = Math.min(Math.max(from, 0), count - 1);\n if (!this.isChipDisabled(start)) return start;\n\n for (const step of [1, -1] as const) {\n const found = this.enabledChipToward(start + step, step);\n if (found !== null) return found;\n }\n return start;\n }\n\n /**\n * The first selectable chip at `from` or beyond it in `step`'s direction, else\n * null when that whole direction is closed off — which is the answer for an\n * ArrowLeft on the first chip: stay put.\n */\n private enabledChipToward(from: number, step: 1 | -1): number | null {\n for (let i = from; i >= 0 && i < this.chipCount(); i += step) {\n if (!this.isChipDisabled(i)) return i;\n }\n return null;\n }\n\n private focusActiveChip(): void {\n // By the tab stop, not by index: it is the same element the ring is on, and\n // asking for it this way cannot drift out of step with the template.\n this.host.nativeElement.querySelector<HTMLElement>('.wr-calendar__chip[tabindex=\"0\"]')?.focus();\n }\n\n /**\n * The first selectable day at or after `candidate`, else the first before it,\n * else `candidate` unchanged when everything nearby is closed off. Bounded at\n * a year each way so a pathological `dateFilter` cannot spin.\n */\n private nearestEnabled(candidate: Date): Date {\n if (!this.isDisabled(candidate)) return candidate;\n\n for (const step of [1, -1] as const) {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n probe = this.adapter.addDays(probe, step);\n if (!this.isDisabled(probe)) return probe;\n }\n }\n return candidate;\n }\n\n /**\n * The first selectable day at `candidate` or beyond it in `step`'s direction,\n * else null when that whole direction is closed off — which is the answer for\n * an ArrowLeft that would cross `min`: stay put.\n *\n * Direction matters. Reusing `nearestEnabled`, which probes forward first,\n * would send an ArrowLeft over a disabled weekend straight back to the day it\n * started from, so the ring could never cross the hole.\n */\n private nearestEnabledToward(candidate: Date, step: 1 | -1): Date | null {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n if (!this.isDisabled(probe)) return probe;\n probe = this.adapter.addDays(probe, step);\n }\n return null;\n }\n\n private focusActiveCell(): void {\n const el = this.host.nativeElement.querySelector('.wr-calendar__day--focused');\n (el as HTMLElement | null)?.focus();\n }\n\n /** Used by the template's `track` expression. */\n protected trackByTime(_: number, date: Date): number {\n return date.getTime();\n }\n\n /**\n * The key as the GRID sees it.\n *\n * Arrow keys follow visual order, and a calendar grid mirrors under\n * `dir=\"rtl\"`: the day to the visual right of today is yesterday. Only the\n * inline pair swaps — Up/Down step a week either way, and PageUp/PageDown and\n * Home/End are semantic rather than physical.\n */\n private inlineKey(key: string): string {\n if (this.dir?.value !== 'rtl') return key;\n if (key === 'ArrowRight') return 'ArrowLeft';\n if (key === 'ArrowLeft') return 'ArrowRight';\n return key;\n }\n}\n","<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model — arrow to a month, Tab\n out of the list — that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-calendar.mjs","sources":["../../../projects/lib/calendar/calendar.ts","../../../projects/lib/calendar/calendar.html","../../../projects/lib/calendar/ngwr-calendar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n signal,\n untracked,\n} from '@angular/core';\n\nimport { WrDateAdapter } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrCalendarMode, WrCalendarRange } from './interfaces';\n\n/**\n * Stands in for the consumer input `useI18nText` expects, for labels the calendar\n * exposes no input for. Constant and read-only, so one instance is safe to share.\n */\nconst NO_OVERRIDE = signal<string | null>(null).asReadonly();\n\nconst ROWS = 6;\nconst COLS = 7;\n\n/**\n * Chips per row in the month and year views — the vertical arrows step by one\n * of these, so they have to agree with `grid-template-columns` in\n * `styles/_index.scss`. Two numbers because the two grids differ: twelve months\n * read as four rows of three, twelve years as three rows of four.\n */\nconst MONTH_COLS = 3;\nconst YEAR_COLS = 4;\n\n/**\n * Month-view calendar. Supports single-date selection (`mode=\"single\"`) or\n * date-range selection (`mode=\"range\"`). Reusable on its own; consumed by\n * `<wr-date-picker>` inside an overlay.\n *\n * Uses {@link WrDateAdapter} for all date math and formatting — register\n * one via {@link provideWrDateAdapter} at bootstrap.\n *\n * @example\n * ```html\n * <wr-calendar [(date)]=\"picked\" [min]=\"minDate\" />\n *\n * <wr-calendar mode=\"range\" [(range)]=\"[start, end]\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar\n */\n@Component({\n selector: 'wr-calendar',\n templateUrl: './calendar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // No `role=\"grid\"` here: the host also wraps the nav header, and a grid may\n // only own rows. The role sits on `.wr-calendar__body`, which is the day\n // matrix and nothing else.\n '(keydown)': 'onKeyDown($event)',\n },\n})\nexport class WrCalendar {\n /** Selection mode. @default 'single' */\n readonly mode = input<WrCalendarMode>('single');\n\n /** Two-way bindable single value (used when `mode === 'single'`). */\n readonly date = model<Date | null>(null);\n\n /** Two-way bindable `[start, end]` (used when `mode === 'range'`). */\n readonly range = model<WrCalendarRange>([null, null]);\n\n /** Min selectable date (inclusive). */\n readonly min = input<Date | null>(null);\n\n /** Max selectable date (inclusive). */\n readonly max = input<Date | null>(null);\n\n /** Predicate — return `false` to disable specific dates (e.g. weekends only). */\n readonly dateFilter = input<((date: Date) => boolean) | null>(null);\n\n /**\n * Move real focus onto the roving cell as soon as the grid is on screen.\n *\n * Off by default: a standalone `<wr-calendar>` sitting in a page must not\n * steal focus on load. `wr-date-picker` turns it on for the popup it opens\n * from its trigger, where the user asked to be taken to the calendar.\n * @default false\n */\n readonly autoFocus = input(false, { transform: coerceBooleanProperty });\n\n /** Disable interaction entirely. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n private readonly adapter = inject<WrDateAdapter<Date>>(WrDateAdapter);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n /** Currently displayed month (any date inside it). */\n protected readonly viewDate = signal(this.adapter.today());\n\n /** Date currently focused by keyboard (single roving tabindex). */\n protected readonly focusedDate = signal(this.adapter.today());\n\n /** Hovered date during range-mode end-pick — drives the preview highlight. */\n protected readonly hoverDate = signal<Date | null>(null);\n\n /** Which sub-view is currently shown. Cycles `day → month → year` on header click. */\n protected readonly viewMode = signal<'day' | 'month' | 'year'>('day');\n\n /**\n * Chip the month / year listbox has moved its ring to, as an index into\n * `monthsView()` / `yearsView()`. `null` means \"nobody has pressed an arrow\n * yet\", which resolves to the month or year on screen — see {@link activeChip}.\n *\n * Reset on every view change rather than remembered: coming back to the month\n * list should ring the month you are looking at, not the one an earlier visit\n * happened to leave the ring on.\n */\n private readonly rovedChip = signal<number | null>(null);\n\n // The four month/year strings have been in both catalogs since they were written\n // and nothing read them: the template hard-coded the same English beside them, so a\n // localized app announced its calendar's arrows in English. `nullSignal()` is the\n // shim for exactly this — a label with no consumer input to forward.\n private readonly prevMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.prevMonth', 'Previous month');\n private readonly nextMonthLabel = useI18nText(NO_OVERRIDE, 'calendar.nextMonth', 'Next month');\n private readonly prevYearLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYear', 'Previous year');\n private readonly nextYearLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYear', 'Next year');\n private readonly prevYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.prevYears', 'Previous 12 years');\n private readonly nextYearsLabel = useI18nText(NO_OVERRIDE, 'calendar.nextYears', 'Next 12 years');\n\n /** What the ← button does from here — a month, a year, or a 12-year page. */\n protected readonly prevLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.prevYearsLabel();\n case 'month':\n return this.prevYearLabel();\n default:\n return this.prevMonthLabel();\n }\n });\n\n /** What the → button does from here. */\n protected readonly nextLabel = computed(() => {\n switch (this.viewMode()) {\n case 'year':\n return this.nextYearsLabel();\n case 'month':\n return this.nextYearLabel();\n default:\n return this.nextMonthLabel();\n }\n });\n\n protected readonly today = computed(() => this.adapter.today());\n\n protected readonly weekdayNames = computed(() => this.adapter.getDayOfWeekNames('short'));\n\n protected readonly monthsView = computed(() => this.adapter.getMonthNames('short'));\n\n /** 12-year window centered on the floor-aligned decade containing `viewDate`. */\n protected readonly yearsView = computed<readonly number[]>(() => {\n const y = this.adapter.getYear(this.viewDate());\n const start = Math.floor(y / 12) * 12;\n return Array.from({ length: 12 }, (_, i) => start + i);\n });\n\n /**\n * The header above the grid.\n *\n * Both templated strings used to be assembled here: `${month} ${year}` and\n * `${first} – ${last}`. That is English word order with an English separator\n * baked into TypeScript, and no catalog could move either — ja-JP writes\n * 2026年3月, which is not a translation of any word in `March 2026` but a\n * different arrangement of the same two values. So the arrangement is the\n * translatable unit, and `calendar.header` / `calendar.yearRange` are it.\n */\n protected readonly headerLabel = computed(() => {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day': {\n const monthNames = this.adapter.getMonthNames('long');\n return this.headerText({\n month: monthNames[this.adapter.getMonth(v)],\n year: this.adapter.getYear(v),\n });\n }\n case 'month':\n return `${this.adapter.getYear(v)}`;\n case 'year': {\n const years = this.yearsView();\n return this.yearRangeText({ from: years[0], to: years[years.length - 1] });\n }\n }\n });\n\n private readonly headerText = useI18nFormatter('calendar.header', '{{month}} {{year}}');\n private readonly yearRangeText = useI18nFormatter('calendar.yearRange', '{{from}} – {{to}}');\n private readonly dayLabelText = useI18nFormatter('calendar.dayLabel', '{{weekday}}, {{date}}');\n\n /**\n * Long weekday names for the cell names.\n *\n * `getDayOfWeekNames` returns them in COLUMN order — index 0 is\n * `getFirstDayOfWeek()`, not Sunday — which is what the header strip wants and\n * what a `getDayOfWeek()` result (0 = Sunday) must be rotated into. Indexing\n * it directly reads Monday's name for a Sunday in every locale that starts its\n * week on Monday, which is most of them.\n */\n private readonly longWeekdays = computed(() => this.adapter.getDayOfWeekNames('long'));\n\n /**\n * A day cell's accessible name — \"Sunday, March 15, 2026\".\n *\n * The cell had none. Its only content is the day NUMBER, and `role=\"gridcell\"`\n * does not inherit a name from the grid's header or from the column header\n * above it, so every date in the month announced as a bare number: the month,\n * the year and the weekday were all on screen and none of them reachable.\n *\n * `{{date}}` is the adapter's `longDate`, so its field order, its separators\n * and its digits are `Intl`'s — the catalog decides only where the weekday\n * goes. Building it from `getMonthNames('long')` instead would have hard-coded\n * the nominative month, which Russian and Finnish inflect inside a date.\n */\n protected dayLabel(date: Date): string {\n return this.dayLabelText({\n weekday: this.longWeekdays()[(this.adapter.getDayOfWeek(date) - this.adapter.getFirstDayOfWeek() + 7) % 7],\n date: this.adapter.format(date, 'longDate'),\n });\n }\n\n /** 6×7 day grid covering the current month plus spillover. */\n protected readonly weeks = computed<readonly (readonly Date[])[]>(() => {\n const view = this.viewDate();\n const year = this.adapter.getYear(view);\n const month = this.adapter.getMonth(view);\n const firstOfMonth = this.adapter.createDate(year, month, 1);\n const firstWeekday = this.adapter.getDayOfWeek(firstOfMonth);\n const firstDayOfWeek = this.adapter.getFirstDayOfWeek();\n const lead = (firstWeekday - firstDayOfWeek + 7) % 7;\n const gridStart = this.adapter.addDays(firstOfMonth, -lead);\n\n const out: Date[][] = [];\n for (let w = 0; w < ROWS; w++) {\n const row: Date[] = [];\n for (let d = 0; d < COLS; d++) {\n row.push(this.adapter.addDays(gridStart, w * COLS + d));\n }\n out.push(row);\n }\n return out;\n });\n\n /**\n * The chip carrying the listbox's only `tabindex=\"0\"` — where the ring is, and\n * where Tab lands.\n *\n * A listbox owns its arrows, and these two did not: twelve months were twelve\n * tab stops, so the role promised an interaction model the component never\n * implemented. One tab stop plus arrow keys is the roving-tabindex half of the\n * pattern the day grid already uses.\n *\n * Routed through {@link nearestEnabledChip} on BOTH paths — the seed and every\n * arrow — for the reason the grid learned first: `.focus()` on a\n * `<button disabled>` is a no-op, so parking the sole tab stop on a month a\n * `[min]` has closed off leaves the whole view unreachable by keyboard.\n * `-1` on the day view, where there are no chips at all.\n */\n protected readonly activeChip = computed(() => {\n if (this.viewMode() === 'day') return -1;\n return this.nearestEnabledChip(this.rovedChip() ?? this.currentChip());\n });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-calendar', `wr-calendar--${this.mode()}`];\n if (this.disabled()) parts.push('wr-calendar--disabled');\n return parts.join(' ');\n });\n\n constructor() {\n // Initial focus: selected date if any, else today. Also snap viewDate to\n // that month.\n //\n // Stepped onto an ENABLED day, because the roving tabindex puts the grid's\n // only `tabindex=\"0\"` on this cell: seed it on a disabled one — which is\n // exactly what a `min` in the future does to \"today\" — and the sole tab\n // stop is an unfocusable button, leaving the grid unreachable by keyboard.\n afterNextRender(() => {\n const initial = this.nearestEnabled(this.date() ?? this.range()[0] ?? this.adapter.today());\n this.focusedDate.set(initial);\n this.viewDate.set(initial);\n\n // A second, NESTED hook: the lines above only SET the signals, which\n // schedules another change-detection pass — the `--focused` class and the\n // `tabindex` are not in the DOM until that one has run.\n if (this.autoFocus()) {\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n });\n\n // Keep viewDate in sync when date / range changes externally to a\n // different month. The viewDate read must stay untracked — otherwise\n // the effect re-runs on every internal navigation (month stepping,\n // year picking) and snaps the view back to the selected month.\n effect(() => {\n const candidate = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!candidate) return;\n untracked(() => {\n if (!this.adapter.isSameMonth(candidate, this.viewDate())) {\n this.viewDate.set(candidate);\n }\n });\n });\n }\n\n // Navigation\n\n /** Header `‹` button — steps by month / year / decade based on the active view. */\n protected prev(): void {\n this.viewDate.set(this.stepViewDate(-1));\n }\n\n /** Header `›` button — steps by month / year / decade based on the active view. */\n protected next(): void {\n this.viewDate.set(this.stepViewDate(1));\n }\n\n /** Header label click — zooms out (`day → month → year`). No-op at year view. */\n protected onLabelClick(): void {\n if (this.disabled()) return;\n if (this.viewMode() === 'day') {\n this.setViewMode('month');\n } else if (this.viewMode() === 'month') {\n this.setViewMode('year');\n }\n }\n\n protected onMonthSelect(monthIdx: number): void {\n if (this.isMonthDisabled(monthIdx)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(this.adapter.getYear(v), monthIdx, 1));\n this.setViewMode('day');\n }\n\n protected onYearSelect(year: number): void {\n if (this.isYearDisabled(year)) return;\n const v = this.viewDate();\n this.viewDate.set(this.adapter.createDate(year, this.adapter.getMonth(v), 1));\n this.setViewMode('month');\n }\n\n /**\n * Switch views and drop the chip ring with them.\n *\n * Every view change is the only thing that changes what the chips MEAN, so it\n * is the one place the ring has to forget where it was — otherwise a year\n * picked at index 7 rings the eighth MONTH on the way back down.\n */\n private setViewMode(view: 'day' | 'month' | 'year'): void {\n this.rovedChip.set(null);\n this.viewMode.set(view);\n }\n\n private stepViewDate(direction: -1 | 1): Date {\n const v = this.viewDate();\n switch (this.viewMode()) {\n case 'day':\n return this.adapter.addMonths(v, direction);\n case 'month':\n return this.adapter.addYears(v, direction);\n case 'year':\n return this.adapter.addYears(v, direction * 12);\n }\n }\n\n // Cell state predicates (used by template)\n\n protected isToday(date: Date): boolean {\n return this.adapter.isSameDay(date, this.today());\n }\n\n protected isOutOfMonth(date: Date): boolean {\n return !this.adapter.isSameMonth(date, this.viewDate());\n }\n\n protected isSelected(date: Date): boolean {\n if (this.mode() === 'single') {\n const v = this.date();\n return v ? this.adapter.isSameDay(date, v) : false;\n }\n const [start, end] = this.range();\n if (start && this.adapter.isSameDay(date, start)) return true;\n if (end && this.adapter.isSameDay(date, end)) return true;\n return false;\n }\n\n protected isInRange(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n if (!start || !end) return false;\n return this.adapter.compareDate(date, start) > 0 && this.adapter.compareDate(date, end) < 0;\n }\n\n protected isInRangePreview(date: Date): boolean {\n if (this.mode() !== 'range') return false;\n const [start, end] = this.range();\n const hover = this.hoverDate();\n if (!start || end || !hover) return false;\n const before = this.adapter.compareDate(start, hover) <= 0;\n const lo = before ? start : hover;\n const hi = before ? hover : start;\n return this.adapter.compareDate(date, lo) > 0 && this.adapter.compareDate(date, hi) < 0;\n }\n\n protected isFocused(date: Date): boolean {\n return this.adapter.isSameDay(date, this.focusedDate());\n }\n\n protected isDisabled(date: Date): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && this.adapter.compareDate(date, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(date, max) > 0) return true;\n const filter = this.dateFilter();\n if (filter && !filter(date)) return true;\n return false;\n }\n\n // Month / year view predicates\n\n protected isMonthCurrent(monthIdx: number): boolean {\n return this.adapter.getMonth(this.viewDate()) === monthIdx;\n }\n\n protected isMonthSelected(monthIdx: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n if (!v) return false;\n return this.adapter.getYear(v) === this.adapter.getYear(this.viewDate()) && this.adapter.getMonth(v) === monthIdx;\n }\n\n protected isMonthDisabled(monthIdx: number): boolean {\n if (this.disabled()) return true;\n const year = this.adapter.getYear(this.viewDate());\n const monthStart = this.adapter.createDate(year, monthIdx, 1);\n const monthEnd = this.adapter.createDate(year, monthIdx, this.adapter.getDaysInMonth(monthStart));\n const min = this.min();\n if (min && this.adapter.compareDate(monthEnd, min) < 0) return true;\n const max = this.max();\n if (max && this.adapter.compareDate(monthStart, max) > 0) return true;\n return false;\n }\n\n protected isYearCurrent(year: number): boolean {\n return this.adapter.getYear(this.viewDate()) === year;\n }\n\n protected isYearSelected(year: number): boolean {\n const v = this.mode() === 'single' ? this.date() : this.range()[0];\n return v ? this.adapter.getYear(v) === year : false;\n }\n\n protected isYearDisabled(year: number): boolean {\n if (this.disabled()) return true;\n const min = this.min();\n if (min && year < this.adapter.getYear(min)) return true;\n const max = this.max();\n if (max && year > this.adapter.getYear(max)) return true;\n return false;\n }\n\n // Interaction\n\n protected onCellClick(date: Date): void {\n if (this.isDisabled(date)) return;\n if (this.mode() === 'single') {\n this.date.set(this.adapter.clone(date));\n } else {\n this.applyRangeClick(date);\n }\n this.focusedDate.set(date);\n if (!this.adapter.isSameMonth(date, this.viewDate())) {\n this.viewDate.set(date);\n }\n }\n\n protected onCellEnter(date: Date): void {\n if (this.mode() === 'range') this.hoverDate.set(date);\n }\n\n protected onCellLeave(): void {\n if (this.mode() === 'range') this.hoverDate.set(null);\n }\n\n private applyRangeClick(date: Date): void {\n const [start, end] = this.range();\n if (!start || (start && end)) {\n this.range.set([this.adapter.clone(date), null]);\n return;\n }\n if (this.adapter.compareDate(date, start) < 0) {\n this.range.set([this.adapter.clone(date), start]);\n } else {\n this.range.set([start, this.adapter.clone(date)]);\n }\n this.hoverDate.set(null);\n }\n\n // Keyboard\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.disabled()) return;\n\n // The listener sits on the HOST, which also wraps the nav header — so\n // without this every key aimed at a `‹` button drove the day grid instead,\n // and the `preventDefault()` below cancelled the button's own activation:\n // Enter on `‹` picked a day the user never touched, ArrowDown on the header\n // yanked real focus into the grid. The host element itself is deliberately\n // let through: `WrCalendarHarness` sends its keys to `<wr-calendar>` rather\n // than to a cell, because the calendar moves focus in an `afterNextRender`\n // and jsdom often has focus nowhere at all.\n const target = event.target as Element | null;\n if (target !== this.host.nativeElement && target?.closest('.wr-calendar__header')) return;\n\n // The month and year views are listboxes, and the arrows belong to them\n // while they are up — there is no day grid on screen to drive. Their chips\n // are real `<button>`s, so Enter and Space fall through to the browser's own\n // activation and must not be swallowed here.\n if (this.viewMode() !== 'day') {\n this.onChipKeyDown(event);\n return;\n }\n\n const current = this.focusedDate();\n let next: Date | null = null;\n // Which way the key travels, so a landing on a closed-off day can keep\n // going instead of stopping on it. See `nearestEnabledToward`.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = this.adapter.addDays(current, -1);\n dir = -1;\n break;\n case 'ArrowRight':\n next = this.adapter.addDays(current, 1);\n break;\n case 'ArrowUp':\n next = this.adapter.addDays(current, -7);\n dir = -1;\n break;\n case 'ArrowDown':\n next = this.adapter.addDays(current, 7);\n break;\n case 'Home': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, -((dow - first + 7) % 7));\n dir = -1;\n break;\n }\n case 'End': {\n const dow = this.adapter.getDayOfWeek(current);\n const first = this.adapter.getFirstDayOfWeek();\n next = this.adapter.addDays(current, 6 - ((dow - first + 7) % 7));\n break;\n }\n case 'PageUp':\n next = event.shiftKey ? this.adapter.addYears(current, -1) : this.adapter.addMonths(current, -1);\n dir = -1;\n break;\n case 'PageDown':\n next = event.shiftKey ? this.adapter.addYears(current, 1) : this.adapter.addMonths(current, 1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.onCellClick(current);\n return;\n }\n\n if (!next) return;\n event.preventDefault();\n\n // The seed is routed through `nearestEnabled` for a reason, and navigation\n // needs the same care: a cell renders `disabled` AND carries the grid's only\n // `tabindex=\"0\"`, so parking the ring on a closed-off day leaves zero\n // tabbable cells — the user tabs out of the calendar and can never tab back\n // in. Real focus splits from the ring too, because `.focus()` on a disabled\n // button is a no-op. Reached by nothing more exotic than `[minDate]`.\n const landing = this.nearestEnabledToward(next, dir);\n if (!landing) return;\n next = landing;\n\n this.focusedDate.set(next);\n if (!this.adapter.isSameMonth(next, this.viewDate())) {\n this.viewDate.set(next);\n }\n // `afterNextRender`, NOT `queueMicrotask`. Under zoneless CD the scheduler\n // runs change detection in a macrotask, so a microtask fires FIRST — the\n // `--focused` class is still on the cell we just left, and this focuses\n // that one. The ring moved and real focus did not, permanently: a screen\n // reader kept announcing the previous day.\n afterNextRender(() => this.focusActiveCell(), { injector: this.injector });\n }\n\n /**\n * Arrow / Home / End inside the month or year listbox — the roving half of the\n * pattern their `role` has always claimed.\n *\n * Steps by one along the row and by a full row vertically, and the inline pair\n * mirrors under `dir=\"rtl\"` for the same reason the grid's does: those two keys\n * name a side of the screen. The page does NOT wrap or spill into the next\n * one — a month list is twelve fixed cells, and the header's `‹` / `›` are what\n * change which twelve. Anything else (Enter, Space, Tab, Escape) is left to the\n * button and to whatever owns the calendar.\n */\n private onChipKeyDown(event: KeyboardEvent): void {\n const cols = this.viewMode() === 'month' ? MONTH_COLS : YEAR_COLS;\n const count = this.chipCount();\n const current = this.activeChip();\n // Assigned on every branch that does not return, so it needs no placeholder.\n let next: number;\n // Which way to keep looking when the landing chip is closed off, exactly as\n // `nearestEnabledToward` does for days.\n let dir: 1 | -1 = 1;\n\n switch (this.inlineKey(event.key)) {\n case 'ArrowLeft':\n next = current - 1;\n dir = -1;\n break;\n case 'ArrowRight':\n next = current + 1;\n break;\n case 'ArrowUp':\n next = current - cols;\n dir = -1;\n break;\n case 'ArrowDown':\n next = current + cols;\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = count - 1;\n dir = -1;\n break;\n default:\n return;\n }\n\n const landing = this.enabledChipToward(next, dir);\n if (landing === null) return;\n\n event.preventDefault();\n this.rovedChip.set(landing);\n // `afterNextRender`, not `queueMicrotask` — same trap as the grid: under\n // zoneless CD the microtask runs before the new `tabindex` is in the DOM, so\n // the focus call would land on the chip the ring just left.\n afterNextRender(() => this.focusActiveChip(), { injector: this.injector });\n }\n\n /** How many chips the current view renders — twelve either way, read rather than assumed. */\n private chipCount(): number {\n return this.viewMode() === 'month' ? this.monthsView().length : this.yearsView().length;\n }\n\n /** Whether the chip at `index` refuses selection in the current view. */\n private isChipDisabled(index: number): boolean {\n if (this.viewMode() === 'month') return this.isMonthDisabled(index);\n const year = this.yearsView()[index];\n return year === undefined || this.isYearDisabled(year);\n }\n\n /** The chip the view itself points at: the month or year currently on screen. */\n private currentChip(): number {\n if (this.viewMode() === 'month') return this.adapter.getMonth(this.viewDate());\n const index = this.yearsView().indexOf(this.adapter.getYear(this.viewDate()));\n return index === -1 ? 0 : index;\n }\n\n /**\n * The first selectable chip at or after `from`, else the first before it, else\n * `from` unchanged when the whole page is closed off — the chip version of\n * {@link nearestEnabled}, and it exists for the same reason: the ring carries\n * the only `tabindex=\"0\"`, and a disabled button cannot hold it.\n */\n private nearestEnabledChip(from: number): number {\n const count = this.chipCount();\n const start = Math.min(Math.max(from, 0), count - 1);\n if (!this.isChipDisabled(start)) return start;\n\n for (const step of [1, -1] as const) {\n const found = this.enabledChipToward(start + step, step);\n if (found !== null) return found;\n }\n return start;\n }\n\n /**\n * The first selectable chip at `from` or beyond it in `step`'s direction, else\n * null when that whole direction is closed off — which is the answer for an\n * ArrowLeft on the first chip: stay put.\n */\n private enabledChipToward(from: number, step: 1 | -1): number | null {\n for (let i = from; i >= 0 && i < this.chipCount(); i += step) {\n if (!this.isChipDisabled(i)) return i;\n }\n return null;\n }\n\n private focusActiveChip(): void {\n // By the tab stop, not by index: it is the same element the ring is on, and\n // asking for it this way cannot drift out of step with the template.\n this.host.nativeElement.querySelector<HTMLElement>('.wr-calendar__chip[tabindex=\"0\"]')?.focus();\n }\n\n /**\n * The first selectable day at or after `candidate`, else the first before it,\n * else `candidate` unchanged when everything nearby is closed off. Bounded at\n * a year each way so a pathological `dateFilter` cannot spin.\n */\n private nearestEnabled(candidate: Date): Date {\n if (!this.isDisabled(candidate)) return candidate;\n\n for (const step of [1, -1] as const) {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n probe = this.adapter.addDays(probe, step);\n if (!this.isDisabled(probe)) return probe;\n }\n }\n return candidate;\n }\n\n /**\n * The first selectable day at `candidate` or beyond it in `step`'s direction,\n * else null when that whole direction is closed off — which is the answer for\n * an ArrowLeft that would cross `min`: stay put.\n *\n * Direction matters. Reusing `nearestEnabled`, which probes forward first,\n * would send an ArrowLeft over a disabled weekend straight back to the day it\n * started from, so the ring could never cross the hole.\n */\n private nearestEnabledToward(candidate: Date, step: 1 | -1): Date | null {\n let probe = candidate;\n for (let i = 0; i < 366; i++) {\n if (!this.isDisabled(probe)) return probe;\n probe = this.adapter.addDays(probe, step);\n }\n return null;\n }\n\n private focusActiveCell(): void {\n const el = this.host.nativeElement.querySelector('.wr-calendar__day--focused');\n (el as HTMLElement | null)?.focus();\n }\n\n /** Used by the template's `track` expression. */\n protected trackByTime(_: number, date: Date): number {\n return date.getTime();\n }\n\n /**\n * The key as the GRID sees it.\n *\n * Arrow keys follow visual order, and a calendar grid mirrors under\n * `dir=\"rtl\"`: the day to the visual right of today is yesterday. Only the\n * inline pair swaps — Up/Down step a week either way, and PageUp/PageDown and\n * Home/End are semantic rather than physical.\n */\n private inlineKey(key: string): string {\n if (this.dir?.value !== 'rtl') return key;\n if (key === 'ArrowRight') return 'ArrowLeft';\n if (key === 'ArrowLeft') return 'ArrowRight';\n return key;\n }\n}\n","<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model — arrow to a month, Tab\n out of the list — that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}