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
@@ -8,7 +8,9 @@ import { TemplateRef, InjectionToken, Signal, ElementRef } from '@angular/core';
8
8
  * panel when this tab is active.
9
9
  * - **Router tab** — set `routerLink` and the tab becomes a link; the
10
10
  * parent skips its content panel and the consumer drops a
11
- * `<router-outlet>` below the tab strip.
11
+ * `<router-outlet>` below the tab strip. Router mode needs the
12
+ * `WrTabsRouting` directive from `ngwr/tabs/router` in the same
13
+ * `imports: []`; without it a strip carrying a `routerLink` throws.
12
14
  */
13
15
  declare class WrTab {
14
16
  /** Visible label on the tab strip. */
@@ -26,7 +28,30 @@ declare class WrTab {
26
28
  readonly contentTpl: _angular_core.Signal<TemplateRef<any>>;
27
29
  private readonly parent;
28
30
  private readonly destroyRef;
31
+ /**
32
+ * The routing adapter published by `WrTabsRouting` on the parent `<wr-tabs>`
33
+ * element. A `<wr-tab>` is DECLARED inside `<wr-tabs>` in the consumer's
34
+ * template — content projection moves where it renders, not where it injects
35
+ * — so the parent's element injector is this one's, the same walk that
36
+ * resolves `WR_TABS` above.
37
+ */
38
+ private readonly routing;
29
39
  protected readonly isRouter: _angular_core.Signal<boolean>;
40
+ /**
41
+ * Resolved href for a router tab — `null` for a content tab, and for a
42
+ * disabled one, which is how the anchor stops navigating at all.
43
+ * @internal
44
+ */
45
+ readonly routerHref: _angular_core.Signal<string | null>;
46
+ /**
47
+ * Whether the current route selects this tab. The strip publishes it as BOTH
48
+ * `aria-selected` and the `--active` class, off this one read, so the
49
+ * announced selection and the painted one cannot drift apart.
50
+ * @internal
51
+ */
52
+ readonly routerActive: _angular_core.Signal<boolean>;
53
+ /** Hand a click on this tab's anchor to the routing adapter. @internal */
54
+ navigate(event: MouseEvent): void;
30
55
  constructor();
31
56
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrTab, never>;
32
57
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrTab, "wr-tab", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "key": { "alias": "key"; "required": false; "isSignal": true; }; "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
@@ -65,6 +90,54 @@ interface WrTabsContext {
65
90
  */
66
91
  declare const WR_TABS: InjectionToken<WrTabsContext>;
67
92
 
93
+ /**
94
+ * @license
95
+ *
96
+ * Use of this source code is governed by an MIT-style license that can be
97
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
98
+ */
99
+
100
+ /**
101
+ * What a `<wr-tabs>` needs from a router in order to render a router tab, and
102
+ * nothing more. Three questions — the href to put on the anchor, whether the
103
+ * current URL selects it, and what a click should do.
104
+ *
105
+ * It exists so that `ngwr/tabs` can name the capability without naming
106
+ * `@angular/router`: a directive listed in `imports: []` lands in the compiled
107
+ * component's `dependencies` whether or not its branch of the template ever
108
+ * runs, so `RouterLink` + `RouterLinkActive` on the strip charged every content
109
+ * tab strip the whole router — 73.9 kB of a 144.8 kB component. The
110
+ * implementation lives at `ngwr/tabs/router`, which a consumer imports only
111
+ * when they use router tabs.
112
+ *
113
+ * `href` and `isActive` are read from computeds and must both be reactive to
114
+ * navigation: a RELATIVE `routerLink` resolves against the active route, so its
115
+ * href changes when the route does, exactly as `RouterLink` recomputes its own.
116
+ */
117
+ interface WrTabsRoutingAdapter {
118
+ /**
119
+ * Serialized href for a tab's `routerLink`, or `null` when the adapter cannot
120
+ * build one.
121
+ */
122
+ href(commands: string | readonly string[]): string | null;
123
+ /**
124
+ * Whether the current URL selects this tab. Matched the way `routerLinkActive`
125
+ * matches without `[routerLinkActiveOptions]`: a path prefix, not an exact URL.
126
+ */
127
+ isActive(commands: string | readonly string[]): boolean;
128
+ /**
129
+ * Handle a click on a tab anchor. A modified or non-primary click is left to
130
+ * the browser, so ctrl/cmd-click still opens the tab in a new window.
131
+ */
132
+ navigate(commands: string | readonly string[], event: MouseEvent): void;
133
+ }
134
+ /**
135
+ * Token a `<wr-tabs>` reads to find out whether router tabs are usable. Provided
136
+ * by the `WrTabsRouting` directive from `ngwr/tabs/router`; absent by default,
137
+ * which is what keeps `@angular/router` out of a content-only strip.
138
+ */
139
+ declare const WR_TABS_ROUTING: InjectionToken<WrTabsRoutingAdapter>;
140
+
68
141
  /**
69
142
  * Tabbed container. Two modes depending on the child `<wr-tab>`
70
143
  * definitions:
@@ -73,7 +146,10 @@ declare const WR_TABS: InjectionToken<WrTabsContext>;
73
146
  * active-tab panel automatically.
74
147
  * - **Router** — any child with `routerLink` switches the whole strip
75
148
  * into router mode; the parent skips its panel so the consumer can
76
- * drop a `<router-outlet>` after it.
149
+ * drop a `<router-outlet>` after it. That mode needs the `WrTabsRouting`
150
+ * directive from `ngwr/tabs/router` alongside `WrTabs` in `imports: []`
151
+ * — the strip itself names no `@angular/router` symbol, which is what
152
+ * keeps a content-only strip free of the router.
77
153
  *
78
154
  * @example
79
155
  * ```html
@@ -83,7 +159,7 @@ declare const WR_TABS: InjectionToken<WrTabsContext>;
83
159
  * <wr-tab key="two" title="Two">Second panel</wr-tab>
84
160
  * </wr-tabs>
85
161
  *
86
- * <!-- router tabs -->
162
+ * <!-- router tabs: imports: [WrTabs, WrTab, WrTabsRouting] -->
87
163
  * <wr-tabs>
88
164
  * <wr-tab title="Overview" routerLink="overview" />
89
165
  * <wr-tab title="Details" routerLink="details" />
@@ -108,7 +184,22 @@ declare class WrTabs implements WrTabsContext {
108
184
  * directive, which writes `valueSignal`, so the read stays reactive.
109
185
  */
110
186
  private readonly isRtl;
111
- /** When any child has a routerLink, the whole strip switches to router mode. */
187
+ /**
188
+ * The routing adapter, when `WrTabsRouting` from `ngwr/tabs/router` is in the
189
+ * consumer's `imports`. `null` is the default and the whole point: the strip
190
+ * has no `@angular/router` import of its own, so a content-only tab strip
191
+ * costs no router bytes.
192
+ */
193
+ private readonly routing;
194
+ /**
195
+ * When any child has a routerLink, the whole strip switches to router mode.
196
+ *
197
+ * Throws rather than degrading when the adapter is missing. Falling back to
198
+ * content mode would render the tabs as `<button>`s that navigate nowhere and
199
+ * open an empty panel — a strip that looks right and does nothing, with the
200
+ * one missing import unnamed. The route is what selects a tab here, so there
201
+ * is no half of this that still works.
202
+ */
112
203
  protected readonly isRouter: _angular_core.Signal<boolean>;
113
204
  /** Content-mode: the tab whose key matches `active()` (or the first tab if none yet). */
114
205
  protected readonly activeTab: _angular_core.Signal<WrTab | null>;
@@ -123,6 +214,12 @@ declare class WrTabs implements WrTabsContext {
123
214
  /** Recompute which edges can scroll, from the strip's scroll metrics. @internal */
124
215
  protected updateFades(): void;
125
216
  protected onTabClick(tab: WrTab): void;
217
+ /**
218
+ * Click on a router tab's anchor. The anchor carries a real `href`, so a
219
+ * modified or middle click is left alone and the browser opens it the way it
220
+ * opens any link; only a plain left click is turned into a navigation.
221
+ */
222
+ protected onRouterTabClick(tab: WrTab, event: MouseEvent): void;
126
223
  /** Per-instance prefix, so keys only have to be unique within one group. */
127
224
  private readonly uid;
128
225
  /** Header id for `aria-labelledby` on the panel. @internal */
@@ -135,5 +232,5 @@ declare class WrTabs implements WrTabsContext {
135
232
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrTabs, "wr-tabs", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "active": "activeChange"; }, ["tabs"], never, true, never>;
136
233
  }
137
234
 
138
- export { WR_TABS, WrTab, WrTabs };
139
- export type { WrTabsContext };
235
+ export { WR_TABS, WR_TABS_ROUTING, WrTab, WrTabs };
236
+ export type { WrTabsContext, WrTabsRoutingAdapter };
@@ -77,6 +77,15 @@ declare class WrTextarea implements FormValueControl<string> {
77
77
  private readonly platformId;
78
78
  private readonly isBrowser;
79
79
  private readonly hostEl;
80
+ /**
81
+ * Ambient reading direction, read by the horizontal half of the resize drag.
82
+ *
83
+ * Optional so a bare `TestBed` — or any consumer that never set a direction —
84
+ * needs no provider; `Directionality` is root-provided, so `null` only ever
85
+ * means "nobody asked", which is LTR. Read inside the handler rather than
86
+ * cached, so a runtime flip needs no subscription to `Directionality.change`.
87
+ */
88
+ private readonly dir;
80
89
  private resizing;
81
90
  private resizeStartY;
82
91
  private resizeStartX;
@@ -205,6 +205,13 @@ declare class WrTree<TId = string> implements FormValueControl<unknown> {
205
205
  protected readonly expandLabel: _angular_core.Signal<string>;
206
206
  protected readonly collapseLabel: _angular_core.Signal<string>;
207
207
  protected readonly chipRemoveLabel: (params?: ngwr_i18n.WrI18nParams) => string;
208
+ /**
209
+ * The overflow chip past `maxTagCount`. It was the literal `+{{ extra }} more`
210
+ * in the template while `wr-select` — the same chip, the same string — read
211
+ * `select.more` from the catalog, so a Russian tree rendered
212
+ * `["Черновик", "+2 more"]`.
213
+ */
214
+ protected readonly chipMoreLabel: (params?: ngwr_i18n.WrI18nParams) => string;
208
215
  /** Flattened list of currently visible nodes — what the template renders. */
209
216
  protected readonly flat: _angular_core.Signal<readonly FlatNode<TId>[]>;
210
217
  protected readonly selectedSet: _angular_core.Signal<Set<TId>>;
@@ -158,6 +158,52 @@ declare function round(value: number, decimals?: number): number;
158
158
  */
159
159
  declare const numAttr: (fallback: number) => (value: unknown) => number;
160
160
 
161
+ /**
162
+ * @license
163
+ *
164
+ * Use of this source code is governed by an MIT-style license that can be
165
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
166
+ */
167
+ /**
168
+ * Answers whether a value can be composed **into** a larger CSS expression
169
+ * without escaping the slot it was given — a colour inside a `linear-gradient()`
170
+ * the component builds, an entry the component joins into a custom property a
171
+ * stylesheet then substitutes.
172
+ *
173
+ * It is a containment check, not a colour parser. It says the value cannot
174
+ * terminate the construct the library wrapped around it; it says nothing about
175
+ * whether the value is a colour a browser will accept, and a rejected value
176
+ * should fall back to the component's own default rather than be repaired.
177
+ *
178
+ * **A value bound straight to `[style.background]` needs none of this.** There
179
+ * is nothing to break out of there, and Angular applies style values through
180
+ * CSSOM by design — validating those would amount to refusing style values in a
181
+ * style binding.
182
+ *
183
+ * Rejected, and each one is a way out of the slot:
184
+ *
185
+ * - a `)` the value never opened — `red), url(…), linear-gradient(red` is the
186
+ * shape that turns a colour into an extra background layer the browser fetches;
187
+ * - a top-level `,` — a `<color>` is one value, so a comma at depth 0 means the
188
+ * payload has reached the slot next to the one it was handed;
189
+ * - `;` `{` `}` a quote, a backslash, `!`, or a CSS comment delimiter;
190
+ * - any function outside {@link ALLOWED_FUNCTIONS} — `url()` above all.
191
+ *
192
+ * Top-level whitespace is allowed: `red 20%` is a legitimate gradient stop, and
193
+ * without a comma or a bare `)` it cannot reach anything.
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * isSafeCssValue('var(--wr-color-primary)'); // true
198
+ * isSafeCssValue('color-mix(in srgb, red 50%, blue)'); // true
199
+ * isSafeCssValue('red), url("https://x.test/beacon"), linear-gradient(red'); // false
200
+ * ```
201
+ *
202
+ * @param value Raw value handed to the component.
203
+ * @returns `true` when the value stays inside its slot.
204
+ */
205
+ declare function isSafeCssValue(value: string): boolean;
206
+
161
207
  /**
162
208
  * @license
163
209
  *
@@ -419,6 +465,38 @@ declare function hasModifier(event: KeyboardEvent): boolean;
419
465
  * keys like `Backspace` or `Tab`.
420
466
  */
421
467
  declare function isPrintableKey(event: KeyboardEvent): boolean;
468
+ /**
469
+ * True while an input method is composing — the key belongs to the IME, not to
470
+ * your handler. **Return early on it in every `keydown` handler that reads
471
+ * Enter, Escape or an arrow on, or above, a field that accepts typed text.**
472
+ *
473
+ * A Japanese or Chinese user reaches every character through a conversion. From
474
+ * `compositionstart` until `compositionend` a candidate window is open, and
475
+ * those keys are how it is driven: Enter accepts the candidate, Escape cancels
476
+ * the conversion back to kana, the arrows walk the candidate list. A component
477
+ * that acts on them anyway takes the key away from the IME mid-word — the
478
+ * overlay closes instead of the candidate window, and the half-composed reading
479
+ * the user was still choosing between is gone with it.
480
+ *
481
+ * Both halves of the test are needed. `isComposing` is the standard flag, but
482
+ * Safari fires `compositionend` *before* the `keydown` of the Enter that commits
483
+ * a candidate, so that one arrives with `isComposing === false` and only the
484
+ * legacy `keyCode` of `229` — the sentinel every engine sets on a key it handed
485
+ * to the input method — to say where it came from.
486
+ *
487
+ * `keydown` is the whole scope. It does NOT answer "is a composition in
488
+ * progress" for an `input` or `blur` handler: on the committing keystroke the
489
+ * two disagree by design. A component that needs the state *between* events
490
+ * tracks it with the `compositionstart` / `compositionend` pair instead.
491
+ *
492
+ * ```ts
493
+ * protected onKeydown(event: KeyboardEvent): void {
494
+ * if (isComposing(event)) return;
495
+ * // …
496
+ * }
497
+ * ```
498
+ */
499
+ declare function isComposing(event: KeyboardEvent): boolean;
422
500
 
423
501
  /**
424
502
  * @license
@@ -446,5 +524,5 @@ declare function isPrintableKey(event: KeyboardEvent): boolean;
446
524
  */
447
525
  declare function badgeLog(badgeText: string, color: string, message: unknown): void;
448
526
 
449
- export { KEYS, badgeLog, clamp, debounce, getFocusableElements, getRootFontSize, hasModifier, isDefined, isNonEmptyArray, isObservable, isPrintableKey, noop, numAttr, randomId, resolveCssSize, round, throttle, trapFocus };
527
+ export { KEYS, badgeLog, clamp, debounce, getFocusableElements, getRootFontSize, hasModifier, isComposing, isDefined, isNonEmptyArray, isObservable, isPrintableKey, isSafeCssValue, noop, numAttr, randomId, resolveCssSize, round, throttle, trapFocus };
450
528
  export type { Maybe, ResolveCssSizeOptions, ResolvedCssSize, SafeAny, WrDebouncedFn, WrKey, WrThrottledFn };
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
16
16
  * Distinct from `Version` exported by `@angular/core`, which reports the
17
17
  * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.
18
18
  */
19
- declare const NGWR_VERSION = "13.0.0";
19
+ declare const NGWR_VERSION = "14.0.0";
20
20
 
21
21
  /**
22
22
  * @license
@@ -1,5 +1,5 @@
1
1
  import { BaseHarnessFilters, ContentContainerComponentHarness, HarnessPredicate, ComponentHarness } from '@angular/cdk/testing';
2
- import { WrWindowState } from 'ngwr/window';
2
+ import { WrWindowState, WrWindowChromeSize } from 'ngwr/window';
3
3
 
4
4
  /**
5
5
  * @license
@@ -101,8 +101,16 @@ declare class WrWindowHarness extends ContentContainerComponentHarness {
101
101
  * invariant — see {@link hasMinimizeButton}.
102
102
  */
103
103
  getOs(): Promise<string>;
104
- /** The title-bar density — `normal` or `compact`. */
105
- getChromeSize(): Promise<string>;
104
+ /**
105
+ * The title-bar density — `sm` or `md`.
106
+ *
107
+ * Typed as the union rather than `string`, so a value added to
108
+ * `WrWindowChromeSize` fails this method's compile instead of quietly
109
+ * answering `md` for it. Only `sm` carries a modifier class: `md` is the
110
+ * default and paints from the base block, so its answer is the absence of
111
+ * the other one.
112
+ */
113
+ getChromeSize(): Promise<WrWindowChromeSize>;
106
114
  /**
107
115
  * Where the window is and how big, in CSS pixels.
108
116
  *
@@ -14,11 +14,18 @@ import * as ngwr_i18n from 'ngwr/i18n';
14
14
  /**
15
15
  * Chrome bar density.
16
16
  *
17
- * - `normal` (default) — 2.25rem bar, regular title font.
18
- * - `compact` — 1.625rem bar, smaller title + tighter action dots; useful
19
- * for utility / docked panels where vertical space is precious.
17
+ * - `md` (default) — 2.25rem bar, regular title font.
18
+ * - `sm` — 1.625rem bar, smaller title + tighter action dots; useful for
19
+ * utility / docked panels where vertical space is precious.
20
+ *
21
+ * Spelled `sm` / `md` rather than `compact` / `normal` because this is a
22
+ * density, and v8 renamed every density value in the library to the `sm` /
23
+ * `md` / `lg` scale. This union was missed by that migration and kept the
24
+ * retired vocabulary for three majors; `migration-v14` finishes the job.
25
+ * `WrWindowState`'s own `'normal'` is NOT this word — a window state is not a
26
+ * size — and stays as it is.
20
27
  */
21
- type WrWindowChromeSize = 'compact' | 'normal';
28
+ type WrWindowChromeSize = 'sm' | 'md';
22
29
 
23
30
  /**
24
31
  * @license
@@ -69,7 +69,7 @@
69
69
 
70
70
  // Compact title bar — useful for utility / docked panels where every
71
71
  // pixel of vertical space matters.
72
- &--chrome-compact {
72
+ &--chrome-sm {
73
73
  --wr-window-chrome-height: 1.625rem;
74
74
  --wr-window-title-size: var(--wr-text-xs);
75
75
  --wr-window-action-size: 1.125rem;