ngwr 13.0.0 → 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 (200) 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-border-glow.mjs +12 -3
  10. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  11. package/fesm2022/ngwr-breadcrumbs.mjs +14 -3
  12. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  13. package/fesm2022/ngwr-button.mjs +4 -4
  14. package/fesm2022/ngwr-button.mjs.map +1 -1
  15. package/fesm2022/ngwr-calendar-testing.mjs +15 -0
  16. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  17. package/fesm2022/ngwr-calendar.mjs +51 -5
  18. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  19. package/fesm2022/ngwr-circular-text.mjs +20 -1
  20. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  21. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  22. package/fesm2022/ngwr-color-picker-testing.mjs +23 -7
  23. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  24. package/fesm2022/ngwr-color-picker.mjs +89 -10
  25. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  26. package/fesm2022/ngwr-command-palette.mjs +27 -3
  27. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  28. package/fesm2022/ngwr-context-menu.mjs +13 -3
  29. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  30. package/fesm2022/ngwr-date-adapters-fns.mjs +101 -33
  31. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  32. package/fesm2022/ngwr-date-picker-testing.mjs +10 -2
  33. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  34. package/fesm2022/ngwr-date-picker.mjs +103 -13
  35. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  36. package/fesm2022/ngwr-date.mjs +480 -79
  37. package/fesm2022/ngwr-date.mjs.map +1 -1
  38. package/fesm2022/ngwr-dialog.mjs +22 -16
  39. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  40. package/fesm2022/ngwr-directives.mjs +5 -2
  41. package/fesm2022/ngwr-directives.mjs.map +1 -1
  42. package/fesm2022/ngwr-drag-drop.mjs +30 -2
  43. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  44. package/fesm2022/ngwr-drawer.mjs +24 -18
  45. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  46. package/fesm2022/ngwr-dropdown.mjs +8 -3
  47. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  48. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  49. package/fesm2022/ngwr-event-calendar.mjs +1 -1
  50. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  51. package/fesm2022/ngwr-file-upload.mjs +52 -12
  52. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  53. package/fesm2022/ngwr-fuzzy-text.mjs +21 -4
  54. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  55. package/fesm2022/ngwr-gradient-text.mjs +9 -2
  56. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  57. package/fesm2022/ngwr-i18n-en.mjs +63 -1
  58. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  59. package/fesm2022/ngwr-i18n-ru.mjs +28 -1
  60. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  61. package/fesm2022/ngwr-i18n.mjs +150 -22
  62. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  63. package/fesm2022/ngwr-icon-adapters-feather.mjs +11 -0
  64. package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
  65. package/fesm2022/ngwr-icon-adapters-lucide.mjs +22 -2
  66. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  67. package/fesm2022/ngwr-icon.mjs +474 -37
  68. package/fesm2022/ngwr-icon.mjs.map +1 -1
  69. package/fesm2022/ngwr-input-number.mjs +3 -3
  70. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  71. package/fesm2022/ngwr-input-otp.mjs +21 -3
  72. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  73. package/fesm2022/ngwr-input.mjs +14 -7
  74. package/fesm2022/ngwr-input.mjs.map +1 -1
  75. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  76. package/fesm2022/ngwr-knob.mjs +20 -2
  77. package/fesm2022/ngwr-knob.mjs.map +1 -1
  78. package/fesm2022/ngwr-loading-bar-router.mjs +73 -0
  79. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -0
  80. package/fesm2022/ngwr-loading-bar.mjs +21 -32
  81. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  82. package/fesm2022/ngwr-markdown.mjs +63 -11
  83. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  84. package/fesm2022/ngwr-mention.mjs +104 -14
  85. package/fesm2022/ngwr-mention.mjs.map +1 -1
  86. package/fesm2022/ngwr-overlay.mjs +36 -7
  87. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  88. package/fesm2022/ngwr-pagination-testing.mjs +11 -10
  89. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  90. package/fesm2022/ngwr-pagination.mjs +65 -30
  91. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  92. package/fesm2022/ngwr-popconfirm.mjs +3 -2
  93. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  94. package/fesm2022/ngwr-popover.mjs +2 -1
  95. package/fesm2022/ngwr-popover.mjs.map +1 -1
  96. package/fesm2022/ngwr-qr.mjs +38 -1
  97. package/fesm2022/ngwr-qr.mjs.map +1 -1
  98. package/fesm2022/ngwr-select.mjs +93 -34
  99. package/fesm2022/ngwr-select.mjs.map +1 -1
  100. package/fesm2022/ngwr-shiny-text.mjs +10 -3
  101. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  102. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  103. package/fesm2022/ngwr-squircle.mjs +2 -1
  104. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  105. package/fesm2022/ngwr-statistic.mjs +35 -4
  106. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  107. package/fesm2022/ngwr-table.mjs +35 -12
  108. package/fesm2022/ngwr-table.mjs.map +1 -1
  109. package/fesm2022/ngwr-tabs-router.mjs +158 -0
  110. package/fesm2022/ngwr-tabs-router.mjs.map +1 -0
  111. package/fesm2022/ngwr-tabs-testing.mjs +13 -11
  112. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  113. package/fesm2022/ngwr-tabs.mjs +104 -12
  114. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  115. package/fesm2022/ngwr-textarea.mjs +20 -1
  116. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  117. package/fesm2022/ngwr-tour.mjs +1 -1
  118. package/fesm2022/ngwr-tour.mjs.map +1 -1
  119. package/fesm2022/ngwr-transfer.mjs +2 -2
  120. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  121. package/fesm2022/ngwr-tree.mjs +18 -2
  122. package/fesm2022/ngwr-tree.mjs.map +1 -1
  123. package/fesm2022/ngwr-utils.mjs +143 -1
  124. package/fesm2022/ngwr-utils.mjs.map +1 -1
  125. package/fesm2022/ngwr-version.mjs +1 -1
  126. package/fesm2022/ngwr-version.mjs.map +1 -1
  127. package/fesm2022/ngwr-window-testing.mjs +10 -2
  128. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  129. package/fesm2022/ngwr-window.mjs +4 -4
  130. package/fesm2022/ngwr-window.mjs.map +1 -1
  131. package/i18n/en.json +33 -6
  132. package/i18n/ru.json +33 -6
  133. package/llms-full.txt +20 -11
  134. package/llms.txt +47 -16
  135. package/mcp/catalog.js +3 -3
  136. package/mcp/providers.js +11 -0
  137. package/package.json +11 -3
  138. package/schematics/migrations/v13/index.js +101 -0
  139. package/schematics/migrations/v14/index.js +422 -0
  140. package/schematics/migrations.json +10 -0
  141. package/schematics/page/templates.js +1 -1
  142. package/schematics/use/symbol-map.json +1 -0
  143. package/skills/ngwr/SKILL.md +4 -1
  144. package/skills/ngwr/references/catalog.md +2 -0
  145. package/skills/ngwr/references/setup.md +4 -0
  146. package/stepper/styles/_index.scss +19 -1
  147. package/textarea/styles/_index.scss +14 -6
  148. package/toast/styles/_index.scss +12 -4
  149. package/types/ngwr-alert.d.ts +3 -3
  150. package/types/ngwr-blur-text.d.ts +8 -0
  151. package/types/ngwr-breadcrumbs.d.ts +1 -0
  152. package/types/ngwr-button.d.ts +2 -2
  153. package/types/ngwr-calendar-testing.d.ts +21 -4
  154. package/types/ngwr-calendar.d.ts +37 -0
  155. package/types/ngwr-circular-text.d.ts +9 -0
  156. package/types/ngwr-collapse.d.ts +19 -15
  157. package/types/ngwr-color-picker-testing.d.ts +10 -4
  158. package/types/ngwr-color-picker.d.ts +70 -2
  159. package/types/ngwr-command-palette.d.ts +14 -0
  160. package/types/ngwr-context-menu.d.ts +1 -1
  161. package/types/ngwr-date-adapters-fns.d.ts +71 -29
  162. package/types/ngwr-date-picker-testing.d.ts +206 -185
  163. package/types/ngwr-date-picker.d.ts +7 -0
  164. package/types/ngwr-date.d.ts +143 -13
  165. package/types/ngwr-drag-drop.d.ts +19 -0
  166. package/types/ngwr-dropdown.d.ts +1 -1
  167. package/types/ngwr-event-calendar-testing.d.ts +12 -9
  168. package/types/ngwr-file-upload.d.ts +31 -3
  169. package/types/ngwr-fuzzy-text.d.ts +5 -0
  170. package/types/ngwr-i18n.d.ts +89 -7
  171. package/types/ngwr-icon-adapters-feather.d.ts +11 -0
  172. package/types/ngwr-icon.d.ts +42 -1
  173. package/types/ngwr-input-number.d.ts +1 -1
  174. package/types/ngwr-input-otp.d.ts +3 -0
  175. package/types/ngwr-input.d.ts +11 -4
  176. package/types/ngwr-knob-testing.d.ts +8 -4
  177. package/types/ngwr-knob.d.ts +18 -0
  178. package/types/ngwr-loading-bar-router.d.ts +35 -0
  179. package/types/ngwr-loading-bar.d.ts +19 -9
  180. package/types/ngwr-mention.d.ts +13 -0
  181. package/types/ngwr-pagination-testing.d.ts +11 -10
  182. package/types/ngwr-pagination.d.ts +39 -10
  183. package/types/ngwr-popconfirm.d.ts +1 -1
  184. package/types/ngwr-popover.d.ts +1 -1
  185. package/types/ngwr-select.d.ts +65 -10
  186. package/types/ngwr-shiny-text.d.ts +1 -0
  187. package/types/ngwr-splitter-testing.d.ts +9 -4
  188. package/types/ngwr-squircle.d.ts +1 -1
  189. package/types/ngwr-statistic.d.ts +22 -2
  190. package/types/ngwr-table.d.ts +24 -5
  191. package/types/ngwr-tabs-router.d.ts +67 -0
  192. package/types/ngwr-tabs-testing.d.ts +12 -10
  193. package/types/ngwr-tabs.d.ts +103 -6
  194. package/types/ngwr-textarea.d.ts +9 -0
  195. package/types/ngwr-tree.d.ts +7 -0
  196. package/types/ngwr-utils.d.ts +79 -1
  197. package/types/ngwr-version.d.ts +1 -1
  198. package/types/ngwr-window-testing.d.ts +11 -3
  199. package/types/ngwr-window.d.ts +11 -4
  200. package/window/styles/_index.scss +1 -1
@@ -67,6 +67,14 @@ declare class WrBlurText {
67
67
  * watching the same host and all of them able to fire `animate()`.
68
68
  */
69
69
  private observer;
70
+ /**
71
+ * The effect below reaches `startObserver()` through a `queueMicrotask`, so
72
+ * the component can be destroyed between the two. The destroy hook runs first
73
+ * and disconnects whatever exists at that moment — then the continuation
74
+ * builds a FRESH observer on a host Angular has already detached, and nothing
75
+ * is left to disconnect it. Same hazard, and same flag, as `wr-split-text`.
76
+ */
77
+ private destroyed;
70
78
  constructor();
71
79
  private startObserver;
72
80
  private animate;
@@ -29,6 +29,7 @@ declare class WrBreadcrumbs {
29
29
  */
30
30
  readonly ariaLabel: _angular_core.InputSignal<string | null>;
31
31
  protected readonly resolvedAriaLabel: _angular_core.Signal<string>;
32
+ protected readonly separatorValue: _angular_core.Signal<string>;
32
33
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrBreadcrumbs, never>;
33
34
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrBreadcrumbs, "wr-breadcrumbs", never, { "separator": { "alias": "separator"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
34
35
  }
@@ -117,7 +117,7 @@ declare class WrButton {
117
117
  *
118
118
  * @default true
119
119
  */
120
- readonly isDisabledWhenLoading: _angular_core.InputSignalWithTransform<boolean, any>;
120
+ readonly disabledWhenLoading: _angular_core.InputSignalWithTransform<boolean, any>;
121
121
  private readonly group;
122
122
  /** The size, or the app-wide default, or `md`. @see useConfigValue */
123
123
  protected readonly resolvedSize: _angular_core.Signal<WrButtonSize>;
@@ -164,7 +164,7 @@ declare class WrButton {
164
164
  protected onHostKeydown(event: KeyboardEvent): void;
165
165
  protected readonly classes: _angular_core.Signal<string>;
166
166
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrButton, never>;
167
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrButton, "wr-btn, button[wr-btn], a[wr-btn]", never, { "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "outlined": { "alias": "outlined"; "required": false; "isSignal": true; }; "block": { "alias": "block"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "isDisabledWhenLoading": { "alias": "isDisabledWhenLoading"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
167
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrButton, "wr-btn, button[wr-btn], a[wr-btn]", never, { "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "outlined": { "alias": "outlined"; "required": false; "isSignal": true; }; "block": { "alias": "block"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "disabledWhenLoading": { "alias": "disabledWhenLoading"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
168
168
  }
169
169
 
170
170
  /**
@@ -8,6 +8,12 @@ import { WrCalendarMode } from 'ngwr/calendar';
8
8
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
9
9
  */
10
10
 
11
+ /**
12
+ * An arrow key, by the direction a user would say out loud — the parameter type
13
+ * of `WrCalendarHarness.pressArrow`, exported so a consumer's own test helper can
14
+ * name what it forwards.
15
+ */
16
+ type WrCalendarArrowKey = 'left' | 'right' | 'up' | 'down';
11
17
  /** Which of the three sub-views the calendar is showing. */
12
18
  type WrCalendarView = 'day' | 'month' | 'year';
13
19
  /** One month or year chip, as the picker views render them. */
@@ -82,6 +88,19 @@ declare class WrCalendarDayHarness extends ComponentHarness {
82
88
  getText(): Promise<string>;
83
89
  /** The day number as a number, for mapping a list of cells to dates. */
84
90
  getDayOfMonth(): Promise<number>;
91
+ /**
92
+ * What a screen reader announces for this cell — "Thursday, January 15, 2026".
93
+ *
94
+ * A SECOND question from {@link getText}, and the reason this method exists:
95
+ * until v14 the cell had no name at all, so the two answers were "15" and
96
+ * nothing. A spec that reads only the drawn number passes on a grid that
97
+ * announces bare integers with no month, year or weekday anywhere in it.
98
+ *
99
+ * The string is `calendar.dayLabel` interpolated with the adapter's
100
+ * `longDate`, so it moves with the locale AND with the adapter — assert
101
+ * against the pair your spec provides, not against an English literal.
102
+ */
103
+ getAccessibleName(): Promise<string | null>;
85
104
  /** `'gridcell'` — the cell is a button, and the grid semantics are what a spec should assert. */
86
105
  getRole(): Promise<string | null>;
87
106
  /** Whether this day is (one end of) the current selection. */
@@ -122,8 +141,6 @@ declare class WrCalendarDayHarness extends ComponentHarness {
122
141
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
123
142
  */
124
143
 
125
- /** The arrow keys, by the direction a user would say out loud. */
126
- type Arrow = 'left' | 'right' | 'up' | 'down';
127
144
  /**
128
145
  * Test harness for `<wr-calendar>` — the standalone month grid, and the one
129
146
  * `<wr-date-picker>` puts in an overlay.
@@ -244,7 +261,7 @@ declare class WrCalendarHarness extends ComponentHarness {
244
261
  * having managed to focus a cell. Under `dir="rtl"` the horizontal pair mirrors:
245
262
  * ArrowRight goes back a day, because the grid itself is mirrored.
246
263
  */
247
- pressArrow(arrow: Arrow): Promise<void>;
264
+ pressArrow(arrow: WrCalendarArrowKey): Promise<void>;
248
265
  /** Press Home — the first day of the roving cell's week, not of the month. */
249
266
  pressHome(): Promise<void>;
250
267
  /** Press End — the last day of the roving cell's week. */
@@ -274,4 +291,4 @@ declare class WrCalendarHarness extends ComponentHarness {
274
291
  }
275
292
 
276
293
  export { WrCalendarDayHarness, WrCalendarHarness };
277
- export type { WrCalendarChip, WrCalendarDayHarnessFilters, WrCalendarHarnessFilters, WrCalendarView };
294
+ export type { WrCalendarArrowKey, WrCalendarChip, WrCalendarDayHarnessFilters, WrCalendarHarnessFilters, WrCalendarView };
@@ -104,7 +104,44 @@ declare class WrCalendar {
104
104
  protected readonly monthsView: _angular_core.Signal<readonly string[]>;
105
105
  /** 12-year window centered on the floor-aligned decade containing `viewDate`. */
106
106
  protected readonly yearsView: _angular_core.Signal<readonly number[]>;
107
+ /**
108
+ * The header above the grid.
109
+ *
110
+ * Both templated strings used to be assembled here: `${month} ${year}` and
111
+ * `${first} – ${last}`. That is English word order with an English separator
112
+ * baked into TypeScript, and no catalog could move either — ja-JP writes
113
+ * 2026年3月, which is not a translation of any word in `March 2026` but a
114
+ * different arrangement of the same two values. So the arrangement is the
115
+ * translatable unit, and `calendar.header` / `calendar.yearRange` are it.
116
+ */
107
117
  protected readonly headerLabel: _angular_core.Signal<string>;
118
+ private readonly headerText;
119
+ private readonly yearRangeText;
120
+ private readonly dayLabelText;
121
+ /**
122
+ * Long weekday names for the cell names.
123
+ *
124
+ * `getDayOfWeekNames` returns them in COLUMN order — index 0 is
125
+ * `getFirstDayOfWeek()`, not Sunday — which is what the header strip wants and
126
+ * what a `getDayOfWeek()` result (0 = Sunday) must be rotated into. Indexing
127
+ * it directly reads Monday's name for a Sunday in every locale that starts its
128
+ * week on Monday, which is most of them.
129
+ */
130
+ private readonly longWeekdays;
131
+ /**
132
+ * A day cell's accessible name — "Sunday, March 15, 2026".
133
+ *
134
+ * The cell had none. Its only content is the day NUMBER, and `role="gridcell"`
135
+ * does not inherit a name from the grid's header or from the column header
136
+ * above it, so every date in the month announced as a bare number: the month,
137
+ * the year and the weekday were all on screen and none of them reachable.
138
+ *
139
+ * `{{date}}` is the adapter's `longDate`, so its field order, its separators
140
+ * and its digits are `Intl`'s — the catalog decides only where the weekday
141
+ * goes. Building it from `getMonthNames('long')` instead would have hard-coded
142
+ * the nominative month, which Russian and Finnish inflect inside a date.
143
+ */
144
+ protected dayLabel(date: Date): string;
108
145
  /** 6×7 day grid covering the current month plus spillover. */
109
146
  protected readonly weeks: _angular_core.Signal<readonly (readonly Date[])[]>;
110
147
  /**
@@ -33,6 +33,15 @@ declare class WrCircularText {
33
33
  private readonly platform;
34
34
  private rotation;
35
35
  private hovered;
36
+ /**
37
+ * The effect below reaches `startOrSwap()` through a `queueMicrotask`, so the
38
+ * ring can be destroyed between the two. Without this flag the continuation
39
+ * then starts an infinite Web Animation on a host Angular has already
40
+ * detached — and an animation keeps its target alive, so the whole `#spin`
41
+ * subtree is retained for the life of the page. Same hazard, and same flag, as
42
+ * `wr-split-text` and `wr-fuzzy-text`.
43
+ */
44
+ private destroyed;
36
45
  /** Active spin duration in seconds — base, or hover-modified. */
37
46
  private effectiveDuration;
38
47
  constructor();
@@ -54,6 +54,21 @@ declare class WrCollapse {
54
54
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
55
55
  */
56
56
 
57
+ /**
58
+ * What a `<wr-collapse>` hands its parent group when it registers.
59
+ *
60
+ * A named export rather than the structural type it used to be spelled as. Both
61
+ * group components declared their OWN local `interface Member`, so d.ts
62
+ * flattening had two of one name to resolve and published the second as
63
+ * `Member$1` — a bundler-assigned identifier in the signature of a public method,
64
+ * which no consumer could import and nobody had authored.
65
+ */
66
+ interface WrCollapseGroupMember {
67
+ /** Close this collapse — the group calls it on siblings in accordion mode. */
68
+ close(): void;
69
+ /** Identity of the registering collapse, used as the map key and by `notifyOpened`. */
70
+ readonly id: object;
71
+ }
57
72
  /**
58
73
  * Contract a collapse uses to talk to its parent `<wr-collapse-group>`.
59
74
  *
@@ -65,10 +80,7 @@ interface WrCollapseGroupContext {
65
80
  /** Called by a child when it opens — closes siblings in accordion mode. */
66
81
  notifyOpened(opener: object): void;
67
82
  /** Register a child so the group can call `closeAll()` etc. */
68
- register(member: {
69
- close(): void;
70
- readonly id: object;
71
- }): void;
83
+ register(member: WrCollapseGroupMember): void;
72
84
  /** Unregister on destroy. */
73
85
  unregister(memberId: object): void;
74
86
  }
@@ -81,10 +93,6 @@ interface WrCollapseGroupContext {
81
93
  */
82
94
  declare const WR_COLLAPSE_GROUP: InjectionToken<WrCollapseGroupContext>;
83
95
 
84
- interface Member$1 {
85
- close(): void;
86
- readonly id: object;
87
- }
88
96
  /**
89
97
  * Visual + behavioral grouping of `<wr-collapse>` children. When
90
98
  * `accordion` is true, opening one child closes the others.
@@ -95,17 +103,13 @@ declare class WrCollapseGroup implements WrCollapseGroupContext {
95
103
  /** When true, only one child may be open at a time. @default false */
96
104
  readonly accordion: _angular_core.InputSignalWithTransform<boolean, any>;
97
105
  private readonly members;
98
- register(member: Member$1): void;
106
+ register(member: WrCollapseGroupMember): void;
99
107
  unregister(memberId: object): void;
100
108
  notifyOpened(opener: object): void;
101
109
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrCollapseGroup, never>;
102
110
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrCollapseGroup, "wr-collapse-group", never, { "accordion": { "alias": "accordion"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
103
111
  }
104
112
 
105
- interface Member {
106
- close(): void;
107
- readonly id: object;
108
- }
109
113
  /**
110
114
  * Accordion — a `<wr-collapse>` container that enforces single-open
111
115
  * behavior: opening a child closes its siblings.
@@ -128,7 +132,7 @@ declare class WrAccordion implements WrCollapseGroupContext {
128
132
  /** Always behaves as an accordion. Provided for context-interface symmetry. */
129
133
  readonly accordion: _angular_core.Signal<boolean>;
130
134
  private readonly members;
131
- register(member: Member): void;
135
+ register(member: WrCollapseGroupMember): void;
132
136
  unregister(memberId: object): void;
133
137
  notifyOpened(opener: object): void;
134
138
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrAccordion, never>;
@@ -136,4 +140,4 @@ declare class WrAccordion implements WrCollapseGroupContext {
136
140
  }
137
141
 
138
142
  export { WR_COLLAPSE_GROUP, WrAccordion, WrCollapse, WrCollapseGroup };
139
- export type { WrCollapseGroupContext };
143
+ export type { WrCollapseGroupContext, WrCollapseGroupMember };
@@ -193,10 +193,16 @@ declare class WrColorPickerHarness extends ComponentHarness {
193
193
  /**
194
194
  * Where the three thumbs sit, in percent along their surfaces.
195
195
  *
196
- * The component writes these as inline `left` / `top` percentages, so they are
197
- * readable with no layout at all — which makes them the only evidence a spec has
198
- * that the surfaces followed a colour set through the fields. A measured position
199
- * would be zero for all three.
196
+ * The component writes these as inline percentages, so they are readable with no
197
+ * layout at all — which makes them the only evidence a spec has that the surfaces
198
+ * followed a colour set through the fields. A measured position would be zero for
199
+ * all three.
200
+ *
201
+ * The number is always "along the surface from its own start", so it is direction
202
+ * free: the SV canvas reports a physical `left` because it does not mirror, and
203
+ * the two tracks report `inset-inline-start` because they do. An RTL spec reads
204
+ * the same value as an LTR one, which is the point — what mirrors is where that
205
+ * fraction lands on screen, not the fraction.
200
206
  *
201
207
  * Read off the `style` ATTRIBUTE rather than through `getCssValue()`, and the
202
208
  * difference is not cosmetic: `getCssValue()` is `getComputedStyle()`, and `left` /
@@ -239,6 +239,18 @@ declare class WrColorPicker implements FormValueControl<string> {
239
239
  protected readonly hueCss: _angular_core.Signal<string>;
240
240
  /** RGB string used for the alpha-slider gradient. */
241
241
  protected readonly rgbCss: _angular_core.Signal<string>;
242
+ /**
243
+ * Ambient reading direction, for the two SLIDERS only — see `updateFromEvent`
244
+ * for why the SV canvas is not in that set.
245
+ *
246
+ * Optional so a bare `TestBed` — or any consumer that never set a direction —
247
+ * needs no provider; `Directionality` is root-provided, so `null` only ever
248
+ * means "nobody asked", which is LTR. Read inside the handlers rather than
249
+ * cached: the thumbs are placed with `inset-inline-start`, so the tracks mirror
250
+ * from CSS alone and a runtime flip needs no subscription to
251
+ * `Directionality.change`.
252
+ */
253
+ private readonly dir;
242
254
  /** Thumb positions in % for each surface. */
243
255
  protected readonly svThumbX: _angular_core.Signal<number>;
244
256
  protected readonly svThumbY: _angular_core.Signal<number>;
@@ -259,7 +271,33 @@ declare class WrColorPicker implements FormValueControl<string> {
259
271
  protected readonly resolvedAreaLabel: _angular_core.Signal<string>;
260
272
  protected readonly resolvedHueLabel: _angular_core.Signal<string>;
261
273
  protected readonly resolvedAlphaLabel: _angular_core.Signal<string>;
262
- protected readonly tabOptions: readonly WrSegmentedOption<Tab>[];
274
+ /**
275
+ * Every visible word in this component that is not a slider name.
276
+ *
277
+ * The format strip and the nine channel captions were literals — three in
278
+ * TypeScript, the rest in the template — beside a `colorPicker` catalog
279
+ * section that already existed and held the slider names. So the section was
280
+ * there and these had simply not been put in it, which is why a fully Russian
281
+ * picker still read `HEX RGB HSL` over `R G B`. Each caption is one string
282
+ * INCLUDING its `%`, because a locale that spaces the sign differently has to
283
+ * move the letter and the sign together.
284
+ *
285
+ * Signals, not strings: they follow a locale switch, and a catalog that lands
286
+ * a microtask after the first change-detection pass.
287
+ */
288
+ protected readonly channelHexLabel: _angular_core.Signal<string>;
289
+ protected readonly channelRedLabel: _angular_core.Signal<string>;
290
+ protected readonly channelGreenLabel: _angular_core.Signal<string>;
291
+ protected readonly channelBlueLabel: _angular_core.Signal<string>;
292
+ protected readonly channelHueLabel: _angular_core.Signal<string>;
293
+ protected readonly channelSaturationLabel: _angular_core.Signal<string>;
294
+ protected readonly channelLightnessLabel: _angular_core.Signal<string>;
295
+ protected readonly channelAlphaLabel: _angular_core.Signal<string>;
296
+ private readonly formatHexLabel;
297
+ private readonly formatRgbLabel;
298
+ private readonly formatHslLabel;
299
+ /** A `computed`, because `WrSegmentedOption.label` is a plain string. */
300
+ protected readonly tabOptions: _angular_core.Signal<readonly WrSegmentedOption<Tab>[]>;
263
301
  protected readonly classes: _angular_core.Signal<string>;
264
302
  /**
265
303
  * The one write we just made, held only until the sync effect has seen it.
@@ -278,16 +316,46 @@ declare class WrColorPicker implements FormValueControl<string> {
278
316
  /**
279
317
  * Hue and alpha are real one-value sliders, so they take the APG slider keys —
280
318
  * the same set `wr-knob` and `wr-slider` implement, including Home / End.
319
+ *
320
+ * The horizontal arrows name a SIDE of the track and so follow the reading
321
+ * direction, exactly as `wr-slider`'s do; the vertical pair names a value's
322
+ * direction and never mirrors.
281
323
  */
282
324
  protected onSliderKeydown(event: KeyboardEvent, surface: 'hue' | 'alpha'): void;
283
325
  /**
284
326
  * The SV canvas is two axes at once, so the keys follow the picture: left and
285
327
  * right run along saturation, up and down along brightness — the directions
286
328
  * the thumb visibly moves. Shift takes ten percent at a time.
329
+ *
330
+ * Not mirrored under `dir="rtl"`, unlike the two sliders above, and for the
331
+ * reason given on `fraction()`: the canvas is a picture rather than a track, so
332
+ * its gradient does not flip and neither may the keys that walk it.
287
333
  */
288
334
  protected onAreaKeydown(event: KeyboardEvent): void;
289
335
  /** Leaving a surface is what "touched" means, the same as leaving the hex field. */
290
336
  protected onSurfaceBlur(): void;
337
+ /**
338
+ * The pointer's position along a surface, as a 0–1 fraction.
339
+ *
340
+ * Measured from whichever edge the surface STARTS at, and the two surfaces do
341
+ * not agree on what that means — deliberately.
342
+ *
343
+ * The hue and alpha bars are one-value tracks with `role="slider"`, the same
344
+ * widget `wr-slider` is, so they mirror: their thumbs are placed with
345
+ * `inset-inline-start` and their gradients are flipped by a `[dir='rtl']` rule,
346
+ * which makes the reader's start the physical right edge under `dir="rtl"`.
347
+ * Opacity 100% used to sit at the physical right in both directions, i.e. at
348
+ * the reader's START in RTL, while the format strip in the same panel mirrored
349
+ * correctly.
350
+ *
351
+ * The SV canvas does NOT mirror, and stays measured from `rect.left`. It is a
352
+ * two-axis colour FIELD, not a track — the component says so itself by giving
353
+ * it `role="group"` rather than `role="slider"`, because it carries two values
354
+ * and a slider has one. A picture with no start and no end has nothing to
355
+ * mirror, and flipping it would only move white to the other side of an image
356
+ * every colour picker in the world draws the same way.
357
+ */
358
+ private fraction;
291
359
  private updateFromEvent;
292
360
  protected onHexInput(event: Event): void;
293
361
  protected onHexBlur(): void;
@@ -360,7 +428,7 @@ declare class WrColorPickerTrigger {
360
428
  close(): void;
361
429
  private dispose;
362
430
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrColorPickerTrigger, never>;
363
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<WrColorPickerTrigger, "[wrColorPickerTrigger]", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "alpha": { "alias": "alpha"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "swatches": { "alias": "swatches"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "opened": "opened"; "closed": "closed"; }, never, never, true, never>;
431
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<WrColorPickerTrigger, "[wrColorPickerTrigger]", ["wrColorPickerTrigger"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "alpha": { "alias": "alpha"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "swatches": { "alias": "swatches"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "opened": "opened"; "closed": "closed"; }, never, never, true, never>;
364
432
  }
365
433
 
366
434
  export { WrColorPicker, WrColorPickerTrigger, hslToRgb, hsvToRgb, parseHex, rgbToHsl, rgbToHsv, toHex };
@@ -71,6 +71,12 @@ declare class WrCommandPalette {
71
71
  readonly emptyText: _angular_core.InputSignal<string | null>;
72
72
  protected readonly resolvedPlaceholder: _angular_core.Signal<string>;
73
73
  protected readonly resolvedEmpty: _angular_core.Signal<string>;
74
+ /**
75
+ * The key-cap chip beside the search field. It was the literal `esc` in the
76
+ * template — the one string on this component no catalog could reach, so a
77
+ * fully Russian palette still hinted in English.
78
+ */
79
+ protected readonly resolvedEscHint: _angular_core.Signal<string>;
74
80
  /** Auto-close on `(picked)`. Set false to keep open. @default true */
75
81
  readonly closeOnPick: _angular_core.InputSignalWithTransform<boolean, any>;
76
82
  /**
@@ -110,6 +116,14 @@ declare class WrCommandPalette {
110
116
  private bindingHandle;
111
117
  private focusTrap;
112
118
  private previouslyFocused;
119
+ /**
120
+ * The open branch below builds the trap inside a `queueMicrotask`, so a
121
+ * palette destroyed while open — in the same task that opened it — runs its
122
+ * destroy hook first and then constructs a fresh trap nothing will ever
123
+ * destroy. A `ConfigurableFocusTrap` plants two anchor elements in the panel
124
+ * and holds it, so that is retained DOM, not just a stray object.
125
+ */
126
+ private destroyed;
113
127
  /** Grouped view — what the template renders. */
114
128
  protected readonly buckets: _angular_core.Signal<readonly Bucket[]>;
115
129
  /**
@@ -182,7 +182,7 @@ declare class WrContextMenu {
182
182
  private cancelLeaveTimer;
183
183
  private scheduleLeave;
184
184
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrContextMenu, never>;
185
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<WrContextMenu, "[wrContextMenu]", never, { "menu": { "alias": "wrContextMenu"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
185
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<WrContextMenu, "[wrContextMenu]", ["wrContextMenuTrigger"], { "menu": { "alias": "wrContextMenu"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
186
186
  }
187
187
 
188
188
  /**
@@ -1,6 +1,7 @@
1
1
  import { WrDateAdapter, WrDateFormat } from 'ngwr/date';
2
2
  import * as i0 from '@angular/core';
3
- import { EnvironmentProviders } from '@angular/core';
3
+ import { EnvironmentProviders, InjectionToken } from '@angular/core';
4
+ import { Locale } from 'date-fns';
4
5
 
5
6
  /**
6
7
  * {@link WrDateAdapter} backed by `date-fns`. Same `Date` value type as the
@@ -8,32 +9,28 @@ import { EnvironmentProviders } from '@angular/core';
8
9
  * pick this when you want its long patterns (`P`, `PP`, `PPP`, `p`) without
9
10
  * writing them by hand.
10
11
  *
11
- * **{@link WR_DATE_LOCALE} does not reach `format` or `parse`, and that is not
12
- * an oversight.** date-fns resolves those patterns against a date-fns `Locale`
13
- * OBJECT rather than a BCP 47 tag, and the objects are separate modules —
14
- * mapping a tag onto one would mean importing all of them, which defeats the
15
- * tree-shaking that is the reason this is an opt-in entry point. So the named
16
- * formats render AND read in en-US whatever the tag says, while
17
- * `getFirstDayOfWeek`, `getDayOfWeekNames` and `getMonthNames` go through `Intl`
18
- * and do honour it: a calendar heads its columns `пн вт ср` beside a trigger
19
- * reading `08/11/2025`. Reading is the sharper edge — `11/08/2025` typed by a
20
- * user in a dd/MM locale parses as 8 November, valid and wrong.
21
- *
22
- * The lever is date-fns's own module default, and the adapter passing no locale
23
- * is precisely what keeps it working. Set it once at bootstrap, or take
24
- * `provideWrLuxonAdapter()`, which forwards the tag itself:
12
+ * **Localising it takes TWO settings, and that is a property of date-fns rather
13
+ * than a wart here.** `WR_DATE_LOCALE` is a BCP 47 tag; date-fns resolves its
14
+ * patterns against a `Locale` OBJECT, and the objects are separate modules, so
15
+ * mapping a tag onto one would mean importing all of them and defeating the
16
+ * tree-shaking that is the reason this is an opt-in entry point. Pass the object
17
+ * as `dateFnsLocale` and it reaches `format` and `parse`; leave it out and they
18
+ * stay on date-fns's own module default, which is what keeps
19
+ * `setDefaultOptions({ locale })` working for apps that already use it.
25
20
  *
26
- * ```ts
27
- * import { setDefaultOptions } from 'date-fns';
28
- * import { ru } from 'date-fns/locale';
29
- *
30
- * setDefaultOptions({ locale: ru });
31
- * ```
21
+ * Half-localising is the failure mode this is designed to make loud: with only a
22
+ * tag, `getFirstDayOfWeek`, `getDayOfWeekNames` and `getMonthNames` go through
23
+ * `Intl` and answer in the locale while the trigger beside them reads
24
+ * `08/11/2025`, and READING is the sharper edge — `11/08/2025` typed by a user in
25
+ * a dd/MM locale parses as 8 November, valid and wrong. A non-English tag with no
26
+ * object warns once in dev mode for exactly that reason.
32
27
  *
33
28
  * @example
34
29
  * ```ts
30
+ * import { ru } from 'date-fns/locale/ru';
31
+ *
35
32
  * bootstrapApplication(AppComponent, {
36
- * providers: [provideWrDateFnsAdapter()],
33
+ * providers: [provideWrDateFnsAdapter({ locale: 'ru-RU', dateFnsLocale: ru })],
37
34
  * });
38
35
  * ```
39
36
  *
@@ -41,6 +38,10 @@ import { EnvironmentProviders } from '@angular/core';
41
38
  */
42
39
  declare class WrDateFnsAdapter extends WrDateAdapter<Date> {
43
40
  private readonly locale;
41
+ private readonly dateFnsLocale;
42
+ constructor();
43
+ /** What date-fns is handed. `{}` leaves its module default in charge. */
44
+ private get options();
44
45
  today(): Date;
45
46
  clone(date: Date): Date;
46
47
  createDate(year: number, month: number, day: number): Date;
@@ -80,21 +81,62 @@ declare class WrDateFnsAdapter extends WrDateAdapter<Date> {
80
81
  * Register the {@link WrDateFnsAdapter} so date-pickers / calendars in this
81
82
  * app use `date-fns` for all math and formatting.
82
83
  *
83
- * `locale` sets {@link WR_DATE_LOCALE}, which this adapter reads for the first
84
- * day of the week and nothing else — its `format` and `parse` do not pass a
85
- * locale to date-fns. For localized month names and patterns, set date-fns's own
86
- * module default with `setDefaultOptions`, or use the luxon adapter, which does
87
- * thread the tag through everything.
84
+ * Two locale settings, because date-fns needs a `Locale` OBJECT where the rest of the
85
+ * library needs a BCP 47 TAG:
86
+ *
87
+ * - `dateFnsLocale` — the imported object. It reaches `format` and `parse`, which is
88
+ * where the field's own text comes from, and it also decides the first day of the
89
+ * week. Leave it out and date-fns stays on its module default, so an existing
90
+ * `setDefaultOptions({ locale })` keeps working.
91
+ * - `locale` — the tag {@link WR_DATE_LOCALE} carries, read through `Intl` for the month
92
+ * and weekday NAMES. Omit it and the object's own `code` supplies it, so one import is
93
+ * enough for a fully localized picker.
94
+ *
95
+ * Passing only `locale` localizes the calendar headings and not the field, which is the
96
+ * shape of a real defect rather than a preference — the adapter warns about it once in
97
+ * dev mode.
88
98
  *
89
99
  * @example
90
100
  * ```ts
101
+ * import { ru } from 'date-fns/locale/ru';
102
+ *
91
103
  * bootstrapApplication(AppComponent, {
92
- * providers: [provideWrDateFnsAdapter()],
104
+ * providers: [provideWrDateFnsAdapter({ dateFnsLocale: ru })],
93
105
  * });
94
106
  * ```
95
107
  */
96
108
  declare function provideWrDateFnsAdapter(options?: {
97
109
  readonly locale?: string;
110
+ readonly dateFnsLocale?: Locale;
98
111
  }): EnvironmentProviders;
99
112
 
100
- export { WrDateFnsAdapter, provideWrDateFnsAdapter };
113
+ /**
114
+ * @license
115
+ *
116
+ * Use of this source code is governed by an MIT-style license that can be
117
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
118
+ */
119
+
120
+ /**
121
+ * The date-fns `Locale` OBJECT {@link WrDateFnsAdapter} formats and parses with.
122
+ *
123
+ * `WR_DATE_LOCALE` is a BCP 47 TAG, and date-fns cannot resolve a tag: its locales are
124
+ * separate modules, so mapping `'ru-RU'` onto one would mean importing all of them and
125
+ * defeating the tree-shaking that makes this an opt-in entry point. The consumer imports
126
+ * the one they need and hands it over — which is what
127
+ * {@link provideWrDateFnsAdapter}'s `dateFnsLocale` option sets.
128
+ *
129
+ * `null` (the default) passes nothing to date-fns, which leaves that library's own
130
+ * module-level default in charge — so `setDefaultOptions({ locale })` keeps working for
131
+ * apps that already use it.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * import { ru } from 'date-fns/locale/ru';
136
+ *
137
+ * provideWrDateFnsAdapter({ locale: 'ru-RU', dateFnsLocale: ru });
138
+ * ```
139
+ */
140
+ declare const WR_DATE_FNS_LOCALE: InjectionToken<Locale | null>;
141
+
142
+ export { WR_DATE_FNS_LOCALE, WrDateFnsAdapter, provideWrDateFnsAdapter };