ngwr 13.0.1 → 14.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/README.md +69 -13
  2. package/aurora/aurora.scss +1 -1
  3. package/aurora/styles/_dark.scss +21 -0
  4. package/aurora/styles/_index.scss +11 -30
  5. package/aurora/styles/_rules.scss +25 -0
  6. package/border-glow/styles/_dark.scss +46 -0
  7. package/border-glow/styles/_index.scss +5 -0
  8. package/border-glow/styles/_rules.scss +0 -31
  9. package/button/styles/_index.scss +16 -0
  10. package/color-picker/styles/_index.scss +43 -5
  11. package/event-calendar/styles/_index.scss +15 -0
  12. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  13. package/fesm2022/ngwr-affix.mjs +3 -3
  14. package/fesm2022/ngwr-alert.mjs +7 -7
  15. package/fesm2022/ngwr-alert.mjs.map +1 -1
  16. package/fesm2022/ngwr-anchor.mjs +3 -3
  17. package/fesm2022/ngwr-aurora.mjs +4 -4
  18. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  19. package/fesm2022/ngwr-avatar.mjs +3 -3
  20. package/fesm2022/ngwr-back-top.mjs +14 -4
  21. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  22. package/fesm2022/ngwr-badge.mjs +6 -6
  23. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  24. package/fesm2022/ngwr-blur-text.mjs +16 -5
  25. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  26. package/fesm2022/ngwr-border-glow.mjs +4 -4
  27. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  28. package/fesm2022/ngwr-breadcrumbs.mjs +7 -7
  29. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  30. package/fesm2022/ngwr-burger.mjs +3 -3
  31. package/fesm2022/ngwr-button.mjs +88 -10
  32. package/fesm2022/ngwr-button.mjs.map +1 -1
  33. package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
  34. package/fesm2022/ngwr-calendar-testing.mjs +15 -0
  35. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  36. package/fesm2022/ngwr-calendar.mjs +53 -7
  37. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  38. package/fesm2022/ngwr-card.mjs +9 -9
  39. package/fesm2022/ngwr-carousel.mjs +6 -6
  40. package/fesm2022/ngwr-cascader.mjs +4 -4
  41. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  42. package/fesm2022/ngwr-checkbox.mjs +6 -6
  43. package/fesm2022/ngwr-circular-text.mjs +23 -4
  44. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  45. package/fesm2022/ngwr-click-spark.mjs +3 -3
  46. package/fesm2022/ngwr-clipboard.mjs +3 -3
  47. package/fesm2022/ngwr-collapse.mjs +9 -9
  48. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  49. package/fesm2022/ngwr-color-picker-testing.mjs +23 -7
  50. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  51. package/fesm2022/ngwr-color-picker.mjs +93 -14
  52. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  53. package/fesm2022/ngwr-command-palette.mjs +29 -5
  54. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  55. package/fesm2022/ngwr-compare.mjs +3 -3
  56. package/fesm2022/ngwr-confetti.mjs +3 -3
  57. package/fesm2022/ngwr-context-menu.mjs +18 -12
  58. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  59. package/fesm2022/ngwr-cookie.mjs +3 -3
  60. package/fesm2022/ngwr-counter.mjs +6 -6
  61. package/fesm2022/ngwr-date-adapters-fns.mjs +104 -36
  62. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  63. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  64. package/fesm2022/ngwr-date-picker-testing.mjs +10 -2
  65. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  66. package/fesm2022/ngwr-date-picker.mjs +118 -28
  67. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  68. package/fesm2022/ngwr-date.mjs +483 -82
  69. package/fesm2022/ngwr-date.mjs.map +1 -1
  70. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  71. package/fesm2022/ngwr-density.mjs +6 -6
  72. package/fesm2022/ngwr-descriptions.mjs +6 -6
  73. package/fesm2022/ngwr-dialog.mjs +15 -15
  74. package/fesm2022/ngwr-directives.mjs +12 -12
  75. package/fesm2022/ngwr-divider.mjs +3 -3
  76. package/fesm2022/ngwr-donut-chart.mjs +3 -3
  77. package/fesm2022/ngwr-drag-drop.mjs +37 -9
  78. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  79. package/fesm2022/ngwr-drawer.mjs +18 -18
  80. package/fesm2022/ngwr-dropdown.mjs +29 -12
  81. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  82. package/fesm2022/ngwr-empty.mjs +3 -3
  83. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  84. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  85. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  86. package/fesm2022/ngwr-falling-text.mjs +3 -3
  87. package/fesm2022/ngwr-file-upload.mjs +55 -15
  88. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  89. package/fesm2022/ngwr-form-testing.mjs +13 -7
  90. package/fesm2022/ngwr-form-testing.mjs.map +1 -1
  91. package/fesm2022/ngwr-form.mjs +44 -25
  92. package/fesm2022/ngwr-form.mjs.map +1 -1
  93. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  94. package/fesm2022/ngwr-gauge.mjs +3 -3
  95. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  96. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  97. package/fesm2022/ngwr-hotkey.mjs +6 -6
  98. package/fesm2022/ngwr-i18n-en.mjs +63 -1
  99. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  100. package/fesm2022/ngwr-i18n-ru.mjs +28 -1
  101. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  102. package/fesm2022/ngwr-i18n.mjs +159 -31
  103. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  104. package/fesm2022/ngwr-icon.mjs +6 -6
  105. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  106. package/fesm2022/ngwr-input-number.mjs +5 -5
  107. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  108. package/fesm2022/ngwr-input-otp.mjs +23 -5
  109. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  110. package/fesm2022/ngwr-input.mjs +37 -26
  111. package/fesm2022/ngwr-input.mjs.map +1 -1
  112. package/fesm2022/ngwr-keyboard.mjs +3 -3
  113. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  114. package/fesm2022/ngwr-knob.mjs +22 -4
  115. package/fesm2022/ngwr-knob.mjs.map +1 -1
  116. package/fesm2022/ngwr-layout.mjs +15 -15
  117. package/fesm2022/ngwr-lightbox.mjs +4 -4
  118. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  119. package/fesm2022/ngwr-line-chart.mjs +3 -3
  120. package/fesm2022/ngwr-list.mjs +7 -7
  121. package/fesm2022/ngwr-list.mjs.map +1 -1
  122. package/fesm2022/ngwr-loading-bar-router.mjs +73 -0
  123. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -0
  124. package/fesm2022/ngwr-loading-bar.mjs +27 -38
  125. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  126. package/fesm2022/ngwr-markdown.mjs +6 -6
  127. package/fesm2022/ngwr-marquee.mjs +3 -3
  128. package/fesm2022/ngwr-media.mjs +3 -3
  129. package/fesm2022/ngwr-mention.mjs +109 -19
  130. package/fesm2022/ngwr-mention.mjs.map +1 -1
  131. package/fesm2022/ngwr-meta.mjs +6 -6
  132. package/fesm2022/ngwr-meter-group.mjs +3 -3
  133. package/fesm2022/ngwr-overlay.mjs +6 -6
  134. package/fesm2022/ngwr-page-header.mjs +3 -3
  135. package/fesm2022/ngwr-pagination-testing.mjs +11 -10
  136. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  137. package/fesm2022/ngwr-pagination.mjs +67 -32
  138. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  139. package/fesm2022/ngwr-pipes.mjs +21 -21
  140. package/fesm2022/ngwr-platform.mjs +9 -9
  141. package/fesm2022/ngwr-popconfirm.mjs +7 -6
  142. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  143. package/fesm2022/ngwr-popover.mjs +7 -6
  144. package/fesm2022/ngwr-popover.mjs.map +1 -1
  145. package/fesm2022/ngwr-progress.mjs +3 -3
  146. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  147. package/fesm2022/ngwr-qr.mjs +3 -3
  148. package/fesm2022/ngwr-radio.mjs +6 -6
  149. package/fesm2022/ngwr-rating.mjs +48 -22
  150. package/fesm2022/ngwr-rating.mjs.map +1 -1
  151. package/fesm2022/ngwr-result.mjs +12 -12
  152. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  153. package/fesm2022/ngwr-scroll.mjs +3 -3
  154. package/fesm2022/ngwr-segmented.mjs +12 -8
  155. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  156. package/fesm2022/ngwr-select.mjs +217 -59
  157. package/fesm2022/ngwr-select.mjs.map +1 -1
  158. package/fesm2022/ngwr-shiny-text.mjs +7 -7
  159. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  160. package/fesm2022/ngwr-sidebar.mjs +3 -3
  161. package/fesm2022/ngwr-skeleton.mjs +3 -3
  162. package/fesm2022/ngwr-slider.mjs +12 -8
  163. package/fesm2022/ngwr-slider.mjs.map +1 -1
  164. package/fesm2022/ngwr-sparkline.mjs +3 -3
  165. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  166. package/fesm2022/ngwr-spinner.mjs +3 -3
  167. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  168. package/fesm2022/ngwr-split-text.mjs +3 -3
  169. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  170. package/fesm2022/ngwr-splitter.mjs +3 -3
  171. package/fesm2022/ngwr-spotlight-card.mjs +7 -7
  172. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  173. package/fesm2022/ngwr-squircle.mjs +7 -6
  174. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  175. package/fesm2022/ngwr-star-border.mjs +4 -4
  176. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  177. package/fesm2022/ngwr-statistic.mjs +44 -13
  178. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  179. package/fesm2022/ngwr-stepper.mjs +6 -6
  180. package/fesm2022/ngwr-storage.mjs +11 -3
  181. package/fesm2022/ngwr-storage.mjs.map +1 -1
  182. package/fesm2022/ngwr-switch.mjs +3 -3
  183. package/fesm2022/ngwr-table.mjs +51 -28
  184. package/fesm2022/ngwr-table.mjs.map +1 -1
  185. package/fesm2022/ngwr-tabs-router.mjs +158 -0
  186. package/fesm2022/ngwr-tabs-router.mjs.map +1 -0
  187. package/fesm2022/ngwr-tabs-testing.mjs +13 -11
  188. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  189. package/fesm2022/ngwr-tabs.mjs +104 -16
  190. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  191. package/fesm2022/ngwr-textarea.mjs +46 -6
  192. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  193. package/fesm2022/ngwr-theme.mjs +90 -4
  194. package/fesm2022/ngwr-theme.mjs.map +1 -1
  195. package/fesm2022/ngwr-tilt-card.mjs +7 -7
  196. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  197. package/fesm2022/ngwr-timeline.mjs +6 -6
  198. package/fesm2022/ngwr-toast.mjs +116 -11
  199. package/fesm2022/ngwr-toast.mjs.map +1 -1
  200. package/fesm2022/ngwr-toolbar.mjs +3 -3
  201. package/fesm2022/ngwr-tour.mjs +6 -6
  202. package/fesm2022/ngwr-tour.mjs.map +1 -1
  203. package/fesm2022/ngwr-transfer.mjs +4 -4
  204. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  205. package/fesm2022/ngwr-tree.mjs +35 -12
  206. package/fesm2022/ngwr-tree.mjs.map +1 -1
  207. package/fesm2022/ngwr-typewriter.mjs +3 -3
  208. package/fesm2022/ngwr-typography.mjs +3 -3
  209. package/fesm2022/ngwr-utils.mjs +37 -1
  210. package/fesm2022/ngwr-utils.mjs.map +1 -1
  211. package/fesm2022/ngwr-version.mjs +1 -1
  212. package/fesm2022/ngwr-version.mjs.map +1 -1
  213. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  214. package/fesm2022/ngwr-waves.mjs +4 -4
  215. package/fesm2022/ngwr-waves.mjs.map +1 -1
  216. package/fesm2022/ngwr-window-testing.mjs +10 -2
  217. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  218. package/fesm2022/ngwr-window.mjs +15 -15
  219. package/fesm2022/ngwr-window.mjs.map +1 -1
  220. package/i18n/en.json +33 -6
  221. package/i18n/ru.json +33 -6
  222. package/llms-full.txt +29 -20
  223. package/llms.txt +127 -25
  224. package/mcp/catalog.js +3 -3
  225. package/mcp/providers.js +11 -0
  226. package/package.json +9 -1
  227. package/schematics/migrations/v13/index.js +101 -0
  228. package/schematics/migrations/v14/index.js +422 -0
  229. package/schematics/migrations.json +10 -0
  230. package/schematics/page/templates.js +1 -1
  231. package/schematics/use/symbol-map.json +1 -0
  232. package/shiny-text/styles/_dark.scss +20 -0
  233. package/shiny-text/styles/_index.scss +5 -0
  234. package/shiny-text/styles/_rules.scss +0 -4
  235. package/skills/ngwr/SKILL.md +4 -1
  236. package/skills/ngwr/references/catalog.md +2 -0
  237. package/skills/ngwr/references/setup.md +4 -0
  238. package/spotlight-card/styles/_dark.scss +21 -0
  239. package/spotlight-card/styles/_index.scss +5 -0
  240. package/spotlight-card/styles/_rules.scss +0 -6
  241. package/star-border/styles/_dark.scss +21 -0
  242. package/star-border/styles/_index.scss +5 -0
  243. package/star-border/styles/_rules.scss +0 -5
  244. package/stepper/styles/_index.scss +19 -1
  245. package/textarea/styles/_index.scss +14 -6
  246. package/theme/styles/_colors.scss +102 -0
  247. package/theme/styles/_focus.scss +31 -1
  248. package/tilt-card/styles/_dark.scss +21 -0
  249. package/tilt-card/styles/_index.scss +5 -0
  250. package/tilt-card/styles/_rules.scss +0 -5
  251. package/toast/styles/_index.scss +12 -4
  252. package/types/ngwr-alert.d.ts +3 -3
  253. package/types/ngwr-blur-text.d.ts +8 -0
  254. package/types/ngwr-button.d.ts +45 -2
  255. package/types/ngwr-calendar-testing.d.ts +21 -4
  256. package/types/ngwr-calendar.d.ts +37 -0
  257. package/types/ngwr-circular-text.d.ts +9 -0
  258. package/types/ngwr-collapse.d.ts +19 -15
  259. package/types/ngwr-color-picker-testing.d.ts +10 -4
  260. package/types/ngwr-color-picker.d.ts +70 -2
  261. package/types/ngwr-command-palette.d.ts +14 -0
  262. package/types/ngwr-context-menu.d.ts +1 -1
  263. package/types/ngwr-date-adapters-fns.d.ts +71 -29
  264. package/types/ngwr-date-picker-testing.d.ts +206 -185
  265. package/types/ngwr-date-picker.d.ts +7 -0
  266. package/types/ngwr-date.d.ts +143 -13
  267. package/types/ngwr-drag-drop.d.ts +19 -0
  268. package/types/ngwr-dropdown.d.ts +18 -2
  269. package/types/ngwr-event-calendar-testing.d.ts +12 -9
  270. package/types/ngwr-file-upload.d.ts +31 -3
  271. package/types/ngwr-form-testing.d.ts +13 -7
  272. package/types/ngwr-form.d.ts +47 -12
  273. package/types/ngwr-i18n.d.ts +89 -7
  274. package/types/ngwr-input-number.d.ts +1 -1
  275. package/types/ngwr-input-otp.d.ts +3 -0
  276. package/types/ngwr-input.d.ts +13 -5
  277. package/types/ngwr-knob-testing.d.ts +8 -4
  278. package/types/ngwr-knob.d.ts +18 -0
  279. package/types/ngwr-loading-bar-router.d.ts +35 -0
  280. package/types/ngwr-loading-bar.d.ts +19 -9
  281. package/types/ngwr-mention.d.ts +13 -0
  282. package/types/ngwr-pagination-testing.d.ts +11 -10
  283. package/types/ngwr-pagination.d.ts +39 -10
  284. package/types/ngwr-popconfirm.d.ts +1 -1
  285. package/types/ngwr-popover.d.ts +1 -1
  286. package/types/ngwr-rating.d.ts +25 -4
  287. package/types/ngwr-segmented.d.ts +1 -0
  288. package/types/ngwr-select.d.ts +110 -19
  289. package/types/ngwr-slider.d.ts +1 -0
  290. package/types/ngwr-splitter-testing.d.ts +9 -4
  291. package/types/ngwr-squircle.d.ts +1 -1
  292. package/types/ngwr-statistic.d.ts +22 -2
  293. package/types/ngwr-storage.d.ts +39 -1
  294. package/types/ngwr-table.d.ts +24 -5
  295. package/types/ngwr-tabs-router.d.ts +67 -0
  296. package/types/ngwr-tabs-testing.d.ts +12 -10
  297. package/types/ngwr-tabs.d.ts +103 -6
  298. package/types/ngwr-textarea.d.ts +29 -0
  299. package/types/ngwr-theme.d.ts +92 -2
  300. package/types/ngwr-toast.d.ts +53 -0
  301. package/types/ngwr-tree.d.ts +10 -2
  302. package/types/ngwr-utils.d.ts +33 -1
  303. package/types/ngwr-version.d.ts +1 -1
  304. package/types/ngwr-window-testing.d.ts +11 -3
  305. package/types/ngwr-window.d.ts +11 -4
  306. package/waves/styles/_dark.scss +19 -0
  307. package/waves/styles/_index.scss +5 -0
  308. package/waves/styles/_rules.scss +0 -3
  309. package/window/styles/_index.scss +1 -1
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ /**
10
+ * v12 to v13 migration. It REPORTS and rewrites nothing, and both halves of
11
+ * that are deliberate.
12
+ *
13
+ * v13 has exactly one breaking change that reaches consumer code: `[id]` on
14
+ * `<wr-checkbox>`, `<wr-radio>` and `<wr-switch>` no longer lands on the HOST
15
+ * element. It only ever lived there by accident — a static `id="x"` was written
16
+ * to the host as a plain attribute AS WELL as fed to the inner `<input>`, so two
17
+ * elements carried the same id, `<label for>` resolved through
18
+ * `getElementById` to the host (not a labelable element, so `input.labels` went
19
+ * from 1 to 0) and `document.getElementById(id)` returned the wrong node. The
20
+ * host binding is `[attr.id]: null` now and the id lands only where it was
21
+ * documented to.
22
+ *
23
+ * **Why this reports instead of rewriting.** The change is not a rename. What a
24
+ * consumer has to do depends on what they wrote and on what they meant by it: a
25
+ * `wr-checkbox#agree { … }` rule may want to become `#agree` (the inner input,
26
+ * which is what most of them were reaching for), or `wr-checkbox:has(#agree)`,
27
+ * or a class — and only the author knows which. Rewriting the selector to
28
+ * `#agree` moves the declarations onto an `<input>` whose box is the 16px tick,
29
+ * not the row, so a codemod confident enough to edit it would silently restyle
30
+ * the wrong element. Naming the files is the honest amount of help.
31
+ *
32
+ * **Why it exists at all**, when v10 and v11 ship nothing. Those two broke
33
+ * painted COLOUR, and an empty codemod would have told people their visual
34
+ * regressions were handled. This one has something true to say: a selector that
35
+ * stops matching is silent in every language it can be written in — CSS has no
36
+ * error for it, `querySelector` returns `null`, and a Playwright or Cypress
37
+ * locator times out somewhere unrelated. It is exactly the shape that needs a
38
+ * file list, and until now nothing produced one: `ng update ngwr@14` from a v12
39
+ * app runs `migration-v14` and never mentions v13 at all, because the semver
40
+ * range `>12.x <=14.0.0` has nothing in it between the two.
41
+ *
42
+ * **What is deliberately NOT reported.** A `<label for="x">` pointing at one of
43
+ * these components got BETTER, not worse — it used to resolve to the
44
+ * unlabelable host and now finds the real input — so there is nothing to tell
45
+ * anyone. And `<wr-checkbox-group>` / `<wr-radio-group>` keep their host `id`;
46
+ * they never had the double-write, and the `#` immediately after the tag name
47
+ * in every pattern here is what keeps `wr-checkbox-group#filters` out of the
48
+ * warning.
49
+ *
50
+ * The other thing v13 shipped — `readonly` and `invalid` reaching every control
51
+ * — is additive, and needs no entry.
52
+ */
53
+ const IGNORE_DIRS = new Set(['node_modules', 'dist', '.git', '.cache', '.angular', 'coverage', '.next', '.nuxt']);
54
+ /**
55
+ * An id selector anchored to one of the three tags, in a stylesheet, a
56
+ * `querySelector` string or a test locator alike — the substring is the same in
57
+ * all of them.
58
+ *
59
+ * The `#` is doing the anchoring work a negative lookahead does elsewhere in
60
+ * these migrations: `wr-checkbox-group#filters` cannot match `wr-checkbox#`,
61
+ * because the character after `wr-checkbox` is a hyphen. That is worth stating
62
+ * rather than relying on, since the group DOES keep its host id and reporting
63
+ * it would be a false alarm on working code.
64
+ */
65
+ const HOST_ID_SELECTOR = /\bwr-(?:checkbox|radio|switch)#[\w-]+/g;
66
+ function ngUpdateV13() {
67
+ return (tree, context) => {
68
+ const hits = [];
69
+ visit(tree, '/', filePath => {
70
+ const lower = filePath.toLowerCase();
71
+ if (!/\.(ts|html|scss|css)$/.test(lower))
72
+ return;
73
+ const found = [...new Set(tree.readText(filePath).match(HOST_ID_SELECTOR) ?? [])];
74
+ if (found.length > 0)
75
+ hits.push({ file: filePath, selectors: found });
76
+ });
77
+ if (hits.length === 0) {
78
+ context.logger.info('ngwr v13 migration: nothing to do — no host-id selector on a checkbox, radio or switch.');
79
+ return tree;
80
+ }
81
+ context.logger.warn(`ngwr v13: a host-id selector found in ${hits.length} file(s). \`[id]\` on <wr-checkbox>, <wr-radio> and ` +
82
+ '<wr-switch> no longer lands on the host element — it goes to the inner <input>, which is where the input ' +
83
+ 'was always documented to put it. Nothing throws: the selector simply stops matching, and CSS has no error ' +
84
+ 'for that. Point it at the inner input (`#agree`), at the host by another hook (`wr-checkbox:has(#agree)`, ' +
85
+ 'or a class), depending on which box you meant to style — the row or the 16px tick.');
86
+ for (const { file, selectors } of hits)
87
+ context.logger.warn(` ${file} — ${selectors.join(', ')}`);
88
+ return tree;
89
+ };
90
+ }
91
+ function visit(tree, path, visitor) {
92
+ const dir = tree.getDir(path);
93
+ for (const file of dir.subfiles)
94
+ visitor(`${path === '/' ? '' : path}/${file}`);
95
+ for (const sub of dir.subdirs) {
96
+ if (IGNORE_DIRS.has(sub))
97
+ continue;
98
+ visit(tree, `${path === '/' ? '' : path}/${sub}`, visitor);
99
+ }
100
+ }
101
+ exports.default = ngUpdateV13;
@@ -0,0 +1,422 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ /**
10
+ * v13 to v14 migration. Two halves, and the split is deliberate.
11
+ *
12
+ * **It REWRITES the five renames**: on `<wr-alert>` from `closeable` to
13
+ * `closable`, on `<wr-table>` from `[totalItems]` to `[total]`, on
14
+ * `<wr-pagination>` from `[(currentPage)]` to `[(page)]`, from
15
+ * `isDisabledWhenLoading` to `disabledWhenLoading`, and the window
16
+ * `chromeSize` scale from `'compact' | 'normal'` to `'sm' | 'md'`. A rename is
17
+ * exactly what a codemod does well: the new name means what the old one meant,
18
+ * on the same element, and nothing about the app has to be understood to move it.
19
+ *
20
+ * **It REPORTS everything else.** Those need a decision a codemod cannot make
21
+ * correctly, and v10/v11 already establish the rule here — a migration that
22
+ * pretends to have handled something it has not is worse than none, because the
23
+ * silence reads as "nothing to do".
24
+ *
25
+ * **`wr-loading-bar`** no longer subscribes to the router on its own. Add
26
+ * `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router` to your
27
+ * application providers. Without it the bar still works for manual
28
+ * `start()` / `complete()` and simply never moves for navigation — which is the
29
+ * dangerous shape, because nothing throws: this project's own site shipped a
30
+ * permanently-empty bar for the length of a release by missing exactly this.
31
+ * Not auto-fixed because the provider belongs in a bootstrap file this schematic
32
+ * cannot identify: `app.config.ts`, a `main.ts` calling `bootstrapApplication`,
33
+ * or a route-level `providers` array are all legitimate, and guessing wrong puts
34
+ * the subscription in the wrong injector.
35
+ *
36
+ * **`<wr-tab routerLink>`** needs `wrTabsRouting` on the strip and
37
+ * `WrTabsRouting` in the component's `imports`. This one at least fails loudly —
38
+ * the strip throws when a tab carries a `routerLink` and no adapter is present.
39
+ * Not auto-fixed because adding the attribute is only half of it: the class has
40
+ * to reach an `imports` array in a `.ts` file that this rule would have to match
41
+ * to the template by convention, and a template can be inline, external, or
42
+ * shared between components.
43
+ *
44
+ * **The locale sources were collapsed into one precedence**, and two defaults
45
+ * moved with it. `WR_DATE_LOCALE` used to default to `navigator.language`; it
46
+ * now defaults to Angular's `LOCALE_ID`, so `provideWrDateAdapter()` with no
47
+ * `locale` follows the application rather than the browser. `WrI18n`'s own
48
+ * default locale used to be the literal `'en'`; it is now `LOCALE_ID` as well,
49
+ * and `availableLocales` defaults to `[defaultLocale]` instead of `['en']`.
50
+ * Reported rather than rewritten for the usual reason: the fix, where one is
51
+ * wanted at all, is a value only the app knows — an app that really did want the
52
+ * browser's tag writes `provideWrDateAdapter({ locale: navigator.language })`,
53
+ * and one that really did want `'en'` writes it. A codemod cannot tell those
54
+ * from the majority for whom the new default is the answer they meant.
55
+ *
56
+ * **`<wr-pagination ofLabel>`** is gone. The "1–10 of 235" line is now ONE
57
+ * catalog template, `pagination.range`, with `{{from}}` / `{{to}}` /
58
+ * `{{total}}` placeholders — because an input for the word in the middle
59
+ * localised only the middle: the ASCII hyphen between the bounds and the
60
+ * operand order were both frozen in TypeScript, and several languages put the
61
+ * total first. Reported rather than rewritten for the reason the others are —
62
+ * the text moves out of a template into a catalog file this schematic cannot
63
+ * identify, and the sentence it becomes is a translation decision. A bound
64
+ * `[ofLabel]` fails the template type-check, so it cannot ship unnoticed; a
65
+ * static `ofLabel="…"` is the shape worth naming.
66
+ *
67
+ * Two more v14 changes are visible without being breaking API, and are called
68
+ * out here because a snapshot or a text assertion will catch them: the
69
+ * pagination range separates its bounds with an EN DASH and groups its three
70
+ * numbers per `LOCALE_ID` (`1–10 of 1,234`), and `<wr-statistic>` formats its
71
+ * delta through `Intl.NumberFormat` rather than interpolating the raw number,
72
+ * so a non-English locale sees its own digits, sign and decimal separator
73
+ * there — matching the value printed above it, which always did.
74
+ *
75
+ * **The five renames**, and why each one moved. `wr-alert` spelled its dismiss
76
+ * toggle `closeable` while `wr-drawer`, `WrDrawerOptions` and `WrDialogOptions`
77
+ * all spelled the same idea `closable` — and a bare attribute that matches no
78
+ * input raises no template error, so `<wr-alert closable>` and
79
+ * `<wr-drawer closeable>` both compiled to nothing at all. `wr-table` and
80
+ * `wr-pagination` disagreed about the two concepts they share: `totalItems` /
81
+ * `page` against `total` / `currentPage`, two components designed to sit on the
82
+ * same screen. `isDisabledWhenLoading` was the only `is`-prefixed input in the
83
+ * library, against thirty-nine plainly-named `disabled` inputs and no
84
+ * `isDisabled` anywhere; dropping the prefix leaves none at all. And
85
+ * `WrWindowChromeSize` was still `'compact' | 'normal'` — the exact vocabulary
86
+ * v8's density migration exists to retire, three majors after it landed.
87
+ *
88
+ * What the rename rules will NOT catch, because no regex can: a component class
89
+ * reading one of these off a `viewChild()` reference. Those are type errors on
90
+ * upgrade, which is the loud failure and needs no help. One quiet case is worth
91
+ * naming: `WrWindowHarness.getChromeSize()` now answers `'sm'` / `'md'`, so a
92
+ * test asserting `'compact'` fails as a wrong value rather than as a wrong type.
93
+ *
94
+ * Why the split happened at all: the subscription and the link directives are
95
+ * what pull `@angular/router` into the bundle. Measured on 13.0.0, in an app
96
+ * declaring no routes, `ngwr/loading-bar` cost 100.1 kB of which 67.9 kB was the
97
+ * router, against 2.4 kB of its own code; `ngwr/tabs` carried 75.6 kB of router.
98
+ * Both are now zero for an app that does not opt in.
99
+ */
100
+ const IGNORE_DIRS = new Set(['node_modules', 'dist', '.git', '.cache', '.angular', 'coverage', '.next', '.nuxt']);
101
+ /**
102
+ * An open tag, up to and including the whitespace before some attribute.
103
+ * `[^>]*?` cannot cross a `>`, so a rename can never escape the element it is
104
+ * scoped to, however the tag wraps across lines.
105
+ *
106
+ * The anchor is `(?![-\w])` and NOT `\b`: a word boundary still matches at the
107
+ * front of a longer element name, which is how a v9-shaped rule would have
108
+ * renamed an attribute on `<wr-table-filter>` while claiming to touch only
109
+ * `<wr-table>`. Every one of these four has such a neighbour — `wr-table-filter`
110
+ * and `wr-table-sort`, `wr-window-container` and `wr-window-taskbar` — or would
111
+ * acquire one the moment the catalog grows.
112
+ *
113
+ * Quoted values are stepped over rather than excluded, and that is the half a
114
+ * plain `[^>]*?` gets wrong: a `>` inside a binding expression looks like the end
115
+ * of the tag, so `<wr-alert [type]="n > 0 ? 'a' : 'b'" closeable>` left
116
+ * `closeable` behind while the same attributes in the other order moved. The
117
+ * leftover is SILENT — a static `closeable` / `totalItems="42"` that matches no
118
+ * input is an ordinary DOM attribute and `strictTemplates` says nothing, so the
119
+ * alert quietly loses its dismiss button. (Bracketed forms are loud: NG8002.)
120
+ * `migration-v9` carries the same anchoring and the same hole.
121
+ */
122
+ const openTag = (name) => String.raw `<${name}(?![-\w])(?:"[^"]*"|'[^']*'|[^>])*?\s`;
123
+ const ALERT = openTag('wr-alert');
124
+ const TABLE = openTag('wr-table');
125
+ const PAGER = openTag('wr-pagination');
126
+ const WINDOW = openTag('wr-window');
127
+ /**
128
+ * Template renames. Run over `.html` AND `.ts`, because an inline template is
129
+ * a string in a component file and is otherwise invisible to this.
130
+ */
131
+ const HTML_TRANSFORMS = [
132
+ // <wr-alert closeable>, to closable. The bracketed form first: after it runs
133
+ // the bare rule cannot see what it rewrote, and the bare rule's lookahead
134
+ // (`[\s/>=]`) is what keeps it from matching the inside of a longer word.
135
+ { pattern: new RegExp(`(${ALERT})\\[closeable\\]`, 'g'), replacement: '$1[closable]' },
136
+ { pattern: new RegExp(`(${ALERT})closeable(?=[\\s/>=])`, 'g'), replacement: '$1closable' },
137
+ // `[wrInput]`'s size input drops its prefix. Anchored on the DIRECTIVE, not on
138
+ // an element, because it sits on a native `<input>` / `<textarea>` — and the
139
+ // anchor matters more here than anywhere else in this table: `size` is a legal
140
+ // native attribute, so rewriting one that was never ngwr's silently rebinds a
141
+ // character-width hint. The two orders are both real markup, hence two rules.
142
+ {
143
+ pattern: /(<(?:input|textarea)(?![-\w])(?:"[^"]*"|'[^']*'|[^>])*?\swrInput(?:"[^"]*"|'[^']*'|[^>])*?\s)\[wrSize\]/g,
144
+ replacement: '$1[size]',
145
+ },
146
+ {
147
+ pattern: /(<(?:input|textarea)(?![-\w])(?:"[^"]*"|'[^']*'|[^>])*?\swrInput(?:"[^"]*"|'[^']*'|[^>])*?\s)wrSize=/g,
148
+ replacement: '$1size=',
149
+ },
150
+ {
151
+ pattern: /(<(?:input|textarea)(?![-\w])(?:"[^"]*"|'[^']*'|[^>])*?\s)\[wrSize\]((?:"[^"]*"|'[^']*'|[^>])*?\swrInput)/g,
152
+ replacement: '$1[size]$2',
153
+ },
154
+ {
155
+ pattern: /(<(?:input|textarea)(?![-\w])(?:"[^"]*"|'[^']*'|[^>])*?\s)wrSize=((?:"[^"]*"|'[^']*'|[^>])*?\swrInput)/g,
156
+ replacement: '$1size=$2',
157
+ },
158
+ // <wr-table>, from [totalItems] to [total]
159
+ { pattern: new RegExp(`(${TABLE})\\[totalItems\\]`, 'g'), replacement: '$1[total]' },
160
+ { pattern: new RegExp(`(${TABLE})totalItems=`, 'g'), replacement: '$1total=' },
161
+ // <wr-pagination>, from [(currentPage)] to [(page)], and the one-way pair with it.
162
+ { pattern: new RegExp(`(${PAGER})\\[\\(currentPage\\)\\]`, 'g'), replacement: '$1[(page)]' },
163
+ { pattern: new RegExp(`(${PAGER})\\(currentPageChange\\)`, 'g'), replacement: '$1(pageChange)' },
164
+ { pattern: new RegExp(`(${PAGER})\\[currentPage\\]`, 'g'), replacement: '$1[page]' },
165
+ { pattern: new RegExp(`(${PAGER})currentPage=`, 'g'), replacement: '$1page=' },
166
+ // <wr-window>, from chromeSize="compact" to "sm", bound literal included.
167
+ { pattern: new RegExp(`(${WINDOW}chromeSize=")compact(")`, 'g'), replacement: '$1sm$2' },
168
+ { pattern: new RegExp(`(${WINDOW}chromeSize=")normal(")`, 'g'), replacement: '$1md$2' },
169
+ { pattern: new RegExp(`(${WINDOW}\\[chromeSize\\]=")'compact'(")`, 'g'), replacement: "$1'sm'$2" },
170
+ { pattern: new RegExp(`(${WINDOW}\\[chromeSize\\]=")'normal'(")`, 'g'), replacement: "$1'md'$2" },
171
+ ];
172
+ /** `.ts` only — object keys and a harness filter, neither of which is markup. */
173
+ const TS_TRANSFORMS = [
174
+ // WrWindowManager.open(Cmp, { chromeSize: 'compact' }) — the primary form,
175
+ // since a window is always a service call. Keyed on the property name rather
176
+ // than the element: there is no element in a `.ts` object literal to scope to,
177
+ // and `chromeSize` carrying one of exactly these two values is not a shape
178
+ // another library hands you by accident.
179
+ { pattern: /(\bchromeSize\s*:\s*['"])compact(['"])/g, replacement: '$1sm$2' },
180
+ { pattern: /(\bchromeSize\s*:\s*['"])normal(['"])/g, replacement: '$1md$2' },
181
+ // WrPaginationHarness.with({ currentPage: 3 }), to { page: 3 }. The filter is
182
+ // named after the input, so it moved with it. Scoped to the `with(` call —
183
+ // `currentPage` is far too ordinary a property name to rename on sight.
184
+ { pattern: /(WrPaginationHarness\.with\(\s*\{[^}]*?\b)currentPage(\s*:)/g, replacement: '$1page$2' },
185
+ ];
186
+ /**
187
+ * Renames safe ANYWHERE, in markup, TypeScript and stylesheets alike, because
188
+ * the string itself is unambiguous. `isDisabledWhenLoading` was the library's
189
+ * only `is`-prefixed input and appears nowhere else; `wr-window--chrome-compact`
190
+ * is a BEM class, which is public API here, so a consumer stylesheet overriding
191
+ * it has to move with the component.
192
+ */
193
+ const GLOBAL_TRANSFORMS = [
194
+ { pattern: /\bisDisabledWhenLoading\b/g, replacement: 'disabledWhenLoading' },
195
+ { pattern: /\bwr-window--chrome-compact\b/g, replacement: 'wr-window--chrome-sm' },
196
+ // `--chrome-normal` too, even though the library never styled it: the class is
197
+ // emitted as `wr-window--chrome-${chromeSize()}`, so every default window in
198
+ // v13 carried it, BEM classes are public API here, and a consumer override
199
+ // keyed on it stops matching with no error — CSS does not have one.
200
+ { pattern: /\bwr-window--chrome-normal\b/g, replacement: 'wr-window--chrome-md' },
201
+ ];
202
+ /** `<wr-tab …>` carrying a `routerLink`, however the tag is wrapped across lines. */
203
+ const ROUTER_TAB = /<wr-tab\b[^>]*\brouterLink\b/;
204
+ const LOADING_BAR = /<wr-loading-bar\b/;
205
+ /** `provideWrDateAdapter(` with no `locale:` before the call closes. */
206
+ // `locale` as a key OR as shorthand, and the scan for it runs to the call's own
207
+ // closing brace rather than to the first `)`. The first version demanded a colon
208
+ // and could not cross a nested call, so it reported
209
+ // `provideWrDateAdapter({ locale })` — which the audit's own stand writes — and
210
+ // `provideWrDateAdapter({ adapter: mk(), locale: 'ru' })` as having no locale.
211
+ // Over-reporting is the gentler failure, but a warning that fires on the
212
+ // idiomatic form is a warning people learn to skip.
213
+ const DATE_ADAPTER_NO_LOCALE = /\bprovideWrDateAdapter\(\s*(?:\)|\{(?![\s\S]*?\blocale\s*[,:}]))/;
214
+ /** `provideWrI18n(` with no `defaultLocale:` before the call closes. */
215
+ const I18N_NO_DEFAULT_LOCALE = /\bprovideWrI18n\(\s*(?:\)|\{(?![^})]*\bdefaultLocale\s*:))/;
216
+ const DEFAULT_CONFIG = /\bDEFAULT_WR_I18N_CONFIG\b/;
217
+ /** `ofLabel` on a pagination tag, bound (`[ofLabel]`) or static. */
218
+ const OF_LABEL = /<wr-pagination\b[^>]*\[?ofLabel\]?\s*=/;
219
+ // The half `OF_LABEL` cannot see. Apps that never bound the input still
220
+ // translated the key, and `pagination.of` is gone: the range is one
221
+ // `pagination.range` template now, so a catalog that defines the old key loses
222
+ // its translation with nothing said. Markup detection misses every one of them,
223
+ // which is why this looks at the catalog instead.
224
+ const REMOVED_KEY = /['"`]?\bof['"`]?\s*:\s*['"`]/;
225
+ const PAGINATION_SCOPE = /\bpagination\s*:\s*\{/g;
226
+ /**
227
+ * Every `pagination: { … }` object literal in a file, brace-matched and
228
+ * QUOTE-AWARE — and it has to be both, because the first version was neither.
229
+ *
230
+ * It sliced to `content.indexOf('}')`, and the shipped catalog carries
231
+ * `perPage: '{{size}} / page'` two lines ABOVE `of`, so the slice ended inside
232
+ * `{{size` and the scan never reached the key it exists to find. The detector
233
+ * therefore answered "clean" for the one shape that actually occurs — a
234
+ * consumer catalog copied from ngwr's own — and green for the toy literal in
235
+ * its spec, `pagination: { of: 'von' }`, where `of` comes first and no
236
+ * placeholder precedes it. A warning that only fires on a shape nobody writes
237
+ * is the silent half of a silent change.
238
+ *
239
+ * All of them rather than the first, since one file commonly holds several
240
+ * locales.
241
+ */
242
+ function paginationBlocks(content) {
243
+ const blocks = [];
244
+ PAGINATION_SCOPE.lastIndex = 0;
245
+ for (let scope = PAGINATION_SCOPE.exec(content); scope; scope = PAGINATION_SCOPE.exec(content)) {
246
+ // The `{` the match ends on.
247
+ const start = scope.index + scope[0].length - 1;
248
+ let depth = 0;
249
+ let quote = null;
250
+ for (let i = start; i < content.length; i += 1) {
251
+ const char = content[i];
252
+ if (quote !== null) {
253
+ if (char === '\\')
254
+ i += 1;
255
+ else if (char === quote)
256
+ quote = null;
257
+ continue;
258
+ }
259
+ if (char === "'" || char === '"' || char === '`') {
260
+ quote = char;
261
+ }
262
+ else if (char === '{') {
263
+ depth += 1;
264
+ }
265
+ else if (char === '}') {
266
+ depth -= 1;
267
+ if (depth === 0) {
268
+ blocks.push(content.slice(start, i + 1));
269
+ break;
270
+ }
271
+ }
272
+ }
273
+ }
274
+ return blocks;
275
+ }
276
+ function ngUpdateV14() {
277
+ return (tree, context) => {
278
+ const routerTabs = [];
279
+ const loadingBars = [];
280
+ const dateAdapters = [];
281
+ const i18nProviders = [];
282
+ const defaultConfigs = [];
283
+ const ofLabels = [];
284
+ const staleCatalogs = [];
285
+ let rewritten = 0;
286
+ visit(tree, '/', filePath => {
287
+ const lower = filePath.toLowerCase();
288
+ const isTs = lower.endsWith('.ts');
289
+ const isHtml = lower.endsWith('.html');
290
+ const isStyle = lower.endsWith('.scss') || lower.endsWith('.css');
291
+ // Inline templates live in `.ts`, external ones in `.html`; the renames
292
+ // reach stylesheets too, because one of them is a BEM class.
293
+ if (!isTs && !isHtml && !isStyle && !lower.endsWith('.json'))
294
+ return;
295
+ // Read ONCE. Every detector below then answers about the file the user
296
+ // wrote, not about the file a transform left behind — none of the five
297
+ // renames touches a reported token today, and relying on that is exactly
298
+ // the coupling that breaks the next time one is added.
299
+ const content = tree.readText(filePath);
300
+ if (isTs || isHtml || isStyle) {
301
+ const next = apply(content, [
302
+ ...(isTs || isHtml ? HTML_TRANSFORMS : []),
303
+ ...(isTs ? TS_TRANSFORMS : []),
304
+ ...GLOBAL_TRANSFORMS,
305
+ ]);
306
+ if (next !== content) {
307
+ tree.overwrite(filePath, next);
308
+ rewritten += 1;
309
+ }
310
+ }
311
+ if (ROUTER_TAB.test(content))
312
+ routerTabs.push(filePath);
313
+ if (LOADING_BAR.test(content))
314
+ loadingBars.push(filePath);
315
+ if (DATE_ADAPTER_NO_LOCALE.test(content))
316
+ dateAdapters.push(filePath);
317
+ if (I18N_NO_DEFAULT_LOCALE.test(content))
318
+ i18nProviders.push(filePath);
319
+ if (DEFAULT_CONFIG.test(content))
320
+ defaultConfigs.push(filePath);
321
+ if (OF_LABEL.test(content))
322
+ ofLabels.push(filePath);
323
+ // Scoped to the `pagination:` block so a `common: { of: '…' }` — a key that
324
+ // is still shipped and still unread — does not drag every catalog in.
325
+ if (paginationBlocks(content).some(block => REMOVED_KEY.test(block))) {
326
+ staleCatalogs.push(filePath);
327
+ }
328
+ });
329
+ if (rewritten > 0) {
330
+ context.logger.info(`ngwr v14 migration: rewrote ${rewritten} file(s) for the renames: on <wr-alert> from ` +
331
+ 'closeable to closable, on <wr-table> from totalItems to total, on <wr-pagination> from ' +
332
+ 'currentPage to page (and from currentPageChange to pageChange), from isDisabledWhenLoading ' +
333
+ 'to disabledWhenLoading, and the window chromeSize scale from compact/normal to sm/md ' +
334
+ '(class .wr-window--chrome-compact to --chrome-sm).');
335
+ context.logger.info('Verify the result with `git diff` — a few edge cases may need manual touch-up.');
336
+ }
337
+ if (staleCatalogs.length > 0) {
338
+ context.logger.warn(`ngwr v14: a translated \`pagination.of\` found in ${staleCatalogs.length} file(s). The range is ` +
339
+ 'one template now — replace it with `pagination.range` ("{{from}}–{{to}} of {{total}}") and ' +
340
+ '`pagination.compact`. Nothing throws: the old key is simply never read again, so a catalog ' +
341
+ 'that keeps it silently reverts that line to English.');
342
+ for (const file of staleCatalogs)
343
+ context.logger.warn(` ${file}`);
344
+ }
345
+ if (loadingBars.length > 0) {
346
+ context.logger.warn(`ngwr v14: <wr-loading-bar> found in ${loadingBars.length} file(s). Router navigations no ` +
347
+ 'longer drive it by default — add `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router` ' +
348
+ 'to your application providers. Nothing throws without it; the bar simply stays at 0%.');
349
+ for (const file of loadingBars)
350
+ context.logger.warn(` ${file}`);
351
+ }
352
+ if (routerTabs.length > 0) {
353
+ context.logger.warn(`ngwr v14: <wr-tab routerLink> found in ${routerTabs.length} file(s). Add \`wrTabsRouting\` to the ` +
354
+ "`<wr-tabs>` element and `WrTabsRouting` (from `ngwr/tabs/router`) to the component's imports. " +
355
+ 'The strip throws at runtime until you do, so this one cannot ship unnoticed.');
356
+ for (const file of routerTabs)
357
+ context.logger.warn(` ${file}`);
358
+ }
359
+ if (dateAdapters.length > 0) {
360
+ context.logger.warn(`ngwr v14: provideWrDateAdapter() with no \`locale\` found in ${dateAdapters.length} file(s). It now ` +
361
+ "takes Angular's LOCALE_ID instead of navigator.language, so a prerendered page and its hydrated " +
362
+ 'self finally agree and an app that set LOCALE_ID stops rendering an English calendar inside ' +
363
+ "itself. If you genuinely wanted the browser's tag, say so: " +
364
+ 'provideWrDateAdapter({ locale: navigator.language }).');
365
+ for (const file of dateAdapters)
366
+ context.logger.warn(` ${file}`);
367
+ }
368
+ if (i18nProviders.length > 0) {
369
+ context.logger.warn(`ngwr v14: provideWrI18n() with no \`defaultLocale\` found in ${i18nProviders.length} file(s). The ` +
370
+ "default is now LOCALE_ID rather than the literal 'en', and `availableLocales` defaults to " +
371
+ "[defaultLocale] rather than ['en']. Catalog lookups also fall back from a region to its language, " +
372
+ 'so a `ru` catalog answers an app running `ru-RU`. Pass `defaultLocale` explicitly to pin the old ' +
373
+ 'behaviour.');
374
+ for (const file of i18nProviders)
375
+ context.logger.warn(` ${file}`);
376
+ }
377
+ if (defaultConfigs.length > 0) {
378
+ context.logger.warn(`ngwr v14: DEFAULT_WR_I18N_CONFIG referenced in ${defaultConfigs.length} file(s). It no longer ` +
379
+ 'carries `defaultLocale` or `availableLocales` — those cannot be constants now that they resolve ' +
380
+ 'from LOCALE_ID — so spreading it no longer produces a complete WrI18nConfigResolved.');
381
+ for (const file of defaultConfigs)
382
+ context.logger.warn(` ${file}`);
383
+ }
384
+ if (ofLabels.length > 0) {
385
+ context.logger.warn(`ngwr v14: <wr-pagination ofLabel> found in ${ofLabels.length} file(s). The input is gone — the ` +
386
+ 'whole "1–10 of 235" line is now the `pagination.range` catalog entry, with `{{from}}`, ' +
387
+ '`{{to}}` and `{{total}}` placeholders, so a translation owns the operand order and the ' +
388
+ 'punctuation as well as the word between them. Move your text there and drop the binding.');
389
+ for (const file of ofLabels)
390
+ context.logger.warn(` ${file}`);
391
+ }
392
+ if (rewritten === 0 &&
393
+ loadingBars.length === 0 &&
394
+ routerTabs.length === 0 &&
395
+ dateAdapters.length === 0 &&
396
+ i18nProviders.length === 0 &&
397
+ defaultConfigs.length === 0 &&
398
+ ofLabels.length === 0 &&
399
+ staleCatalogs.length === 0) {
400
+ context.logger.info('ngwr v14 migration: nothing to do — no affected usage found.');
401
+ }
402
+ return tree;
403
+ };
404
+ }
405
+ function apply(content, transforms) {
406
+ let next = content;
407
+ for (const { pattern, replacement } of transforms) {
408
+ next = next.replace(pattern, replacement);
409
+ }
410
+ return next;
411
+ }
412
+ function visit(tree, path, visitor) {
413
+ const dir = tree.getDir(path);
414
+ for (const file of dir.subfiles)
415
+ visitor(`${path === '/' ? '' : path}/${file}`);
416
+ for (const sub of dir.subdirs) {
417
+ if (IGNORE_DIRS.has(sub))
418
+ continue;
419
+ visit(tree, `${path === '/' ? '' : path}/${sub}`, visitor);
420
+ }
421
+ }
422
+ exports.default = ngUpdateV14;
@@ -20,6 +20,16 @@
20
20
  "version": "12.0.0",
21
21
  "description": "Move the date entry points under one namespace: ngwr/date-adapter \u2192 ngwr/date, ngwr/date-adapter-fns \u2192 ngwr/date/adapters/fns, ngwr/date-adapter-luxon \u2192 ngwr/date/adapters/luxon. Import paths only \u2014 every exported symbol keeps its name. Touches .ts, .html and .json files.",
22
22
  "factory": "./migrations/v12/index#default"
23
+ },
24
+ "migration-v13": {
25
+ "version": "13.0.0",
26
+ "description": "Reports every host-id selector on <wr-checkbox>, <wr-radio> and <wr-switch>: `[id]` no longer lands on the host element, it goes to the inner <input> where the input was always documented to put it. Rewrites nothing — whether `wr-checkbox#agree` should become `#agree` (the tick), `wr-checkbox:has(#agree)` (the row) or a class is a decision only the author can make, and a selector that stops matching is silent in CSS, in querySelector and in a test locator alike. Reads .ts, .html, .scss and .css files.",
27
+ "factory": "./migrations/v13/index#default"
28
+ },
29
+ "migration-v14": {
30
+ "version": "14.0.0",
31
+ "description": "Rewrites five renames: on <wr-alert> from closeable to closable; on <wr-table> from totalItems to total; on <wr-pagination> from currentPage to page (and from currentPageChange to pageChange); from isDisabledWhenLoading to disabledWhenLoading; and the window chromeSize scale from compact/normal to sm/md, including the .wr-window--chrome-compact class. Reports what a codemod cannot decide: router integration is now opt-in (<wr-loading-bar> needs provideWrLoadingBarRouter() from ngwr/loading-bar/router, <wr-tab routerLink> needs wrTabsRouting on the strip plus WrTabsRouting in imports), the locale defaults now follow LOCALE_ID, and <wr-pagination ofLabel> is gone. Touches .ts, .html, .scss and .css files.",
32
+ "factory": "./migrations/v14/index#default"
23
33
  }
24
34
  }
25
35
  }
@@ -120,7 +120,7 @@ export default class ${pascalName} {
120
120
  <wr-table [columns]="columns" [items]="rows()" />
121
121
 
122
122
  <wr-pagination
123
- [(currentPage)]="page"
123
+ [(page)]="page"
124
124
  [(pageSize)]="pageSize"
125
125
  [total]="total()"
126
126
  />
@@ -193,6 +193,7 @@
193
193
  "WrTableFilter": "ngwr/table",
194
194
  "WrTabs": "ngwr/tabs",
195
195
  "WrTab": "ngwr/tabs",
196
+ "WrTabsRouting": "ngwr/tabs/router",
196
197
  "WrTextarea": "ngwr/textarea",
197
198
  "WrTheme": "ngwr/theme",
198
199
  "WrTiltCard": "ngwr/tilt-card",
@@ -0,0 +1,20 @@
1
+ // Dark theme.
2
+ //
3
+ // Keyed on `theme.dark-selector()`, never on a literal `[data-theme='dark']`.
4
+ // The attribute is renameable — `@use 'ngwr' with ($theme-attribute: '…')`
5
+ // alongside `provideWrTheme({ attribute: '…' })` — and a hand-written literal
6
+ // misses the rename in both directions: this block stops firing under the
7
+ // configured name, and it keeps firing under `data-theme`, which is the
8
+ // attribute a foreign design system owns and the rename exists to escape.
9
+ //
10
+ // It lives outside the `styleUrl` closure for the same reason. A component
11
+ // stylesheet is compiled when the LIBRARY is built, where `$theme-attribute` can
12
+ // only ever be the default, and Angular appends that copy after the app's linked
13
+ // sheet — so an inlined literal would not merely be dead, it would outrank the
14
+ // correctly-named rule beside it.
15
+ @use '../../theme/styles' as theme;
16
+
17
+ #{theme.dark-selector()} .wr-shiny-text {
18
+ --wr-shiny-text-base: #b5b5b5;
19
+ --wr-shiny-text-shine: #ffffff;
20
+ }
@@ -11,5 +11,10 @@
11
11
  // box-sizing reset into the compiled component styles, which ng-packagr then
12
12
  // embeds in the FESM bundle as a string. `shiny-text.scss` forwards `_rules`
13
13
  // instead, so it carries this component's own CSS and nothing else.
14
+ //
15
+ // `_dark` is loaded from HERE for a second reason: its selector is built out of
16
+ // `$theme-attribute`, which only a stylesheet compiled by the consuming app can
17
+ // configure, so a copy inside the bundle could only ever carry the default name.
14
18
  @use '../../theme/styles';
15
19
  @forward 'rules';
20
+ @forward 'dark';
@@ -95,7 +95,3 @@
95
95
  }
96
96
  }
97
97
 
98
- [data-theme='dark'] .wr-shiny-text {
99
- --wr-shiny-text-base: #b5b5b5;
100
- --wr-shiny-text-shine: #ffffff;
101
- }
@@ -5,7 +5,7 @@ description: Build Angular UIs with the ngwr component library (standalone, sign
5
5
 
6
6
  # ngwr
7
7
 
8
- An Angular 22 UI library: 202 tree-shakable entry points, 110 of them shipping a selector.
8
+ An Angular 22 UI library: 204 tree-shakable entry points, 111 of them shipping a selector.
9
9
  Standalone, signals-first, zoneless, `ViewEncapsulation.None`. One runtime
10
10
  dependency (`tslib`).
11
11
 
@@ -92,6 +92,9 @@ cause.
92
92
  - `provideWrDateFnsAdapter() // from 'ngwr/date/adapters/fns'`
93
93
  — every date mode goes through an adapter; there is no built-in default
94
94
  — needed by: `WrDatePicker`, `WrCalendar`, `WrEventCalendar`
95
+ - `provideWrLoadingBarRouter() // from 'ngwr/loading-bar/router'`
96
+ — without it the bar never responds to navigation; it only moves for manual start() / complete()
97
+ — needed by: `WrLoadingBar`
95
98
  - `provideWrI18n() + provideWrI18nStaticLoader({ en: wrEn }) // from 'ngwr/i18n' + 'ngwr/i18n/en'`
96
99
  — the pipe and directive read from a catalog you provide
97
100
  — needed by: `WrTPipe`, `WrTDirective`, `WrI18n`
@@ -114,6 +114,7 @@ root barrel for components.
114
114
  | `ngwr/line-chart/testing` | `import { WrLineChartHarness } from 'ngwr/line-chart/testing'` | — |
115
115
  | `ngwr/list` | `import { WrList } from 'ngwr/list'` | `wr-list-item` `wr-list` |
116
116
  | `ngwr/loading-bar` | `import { WrLoadingBar } from 'ngwr/loading-bar'` | `wr-loading-bar` |
117
+ | `ngwr/loading-bar/router` | `import { provideWrLoadingBarRouter } from 'ngwr/loading-bar/router'` | — |
117
118
  | `ngwr/markdown` | `import { WrMarkdown } from 'ngwr/markdown'` | `wr-markdown` |
118
119
  | `ngwr/markdown/testing` | `import { WrMarkdownCodeBlockHarness } from 'ngwr/markdown/testing'` | — |
119
120
  | `ngwr/marquee` | `import { WrMarquee } from 'ngwr/marquee'` | `wr-marquee` |
@@ -180,6 +181,7 @@ root barrel for components.
180
181
  | `ngwr/table` | `import { WrTable } from 'ngwr/table'` | `[wrTableCell]` `ng-template[wrTableExpand]` `wr-table-filter` `ng-template[wrTableGroupHeader]` `wr-table-sort` `wr-table` |
181
182
  | `ngwr/table/testing` | `import { WrTableCellHarness } from 'ngwr/table/testing'` | — |
182
183
  | `ngwr/tabs` | `import { WrTabs } from 'ngwr/tabs'` | `wr-tab` `wr-tabs` |
184
+ | `ngwr/tabs/router` | `import { WrTabsRouting } from 'ngwr/tabs/router'` | `[wrTabsRouting]` |
183
185
  | `ngwr/tabs/testing` | `import { WrTabHarness } from 'ngwr/tabs/testing'` | — |
184
186
  | `ngwr/textarea` | `import { WrTextarea } from 'ngwr/textarea'` | `wr-textarea` |
185
187
  | `ngwr/textarea/testing` | `import { WrTextareaHarness } from 'ngwr/textarea/testing'` | — |
@@ -56,6 +56,10 @@ Icons resolve by name from a registry you populate. Needed by `WrIcon`.
56
56
 
57
57
  Every date mode goes through an adapter; there is no built-in default. Needed by `WrDatePicker`, `WrCalendar`, `WrEventCalendar`.
58
58
 
59
+ ### `provideWrLoadingBarRouter() // from 'ngwr/loading-bar/router'`
60
+
61
+ Without it the bar never responds to navigation; it only moves for manual start() / complete(). Needed by `WrLoadingBar`.
62
+
59
63
  ### `provideWrI18n() + provideWrI18nStaticLoader({ en: wrEn }) // from 'ngwr/i18n' + 'ngwr/i18n/en'`
60
64
 
61
65
  The pipe and directive read from a catalog you provide. Needed by `WrTPipe`, `WrTDirective`, `WrI18n`.