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
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-list.mjs","sources":["../../../projects/lib/list/list.ts","../../../projects/lib/list/list-item.ts","../../../projects/lib/list/list-item.html","../../../projects/lib/list/ngwr-list.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Generic list container. Renders `<ul role=\"list\">` with optional\n * borders, dividers between items, and dense (compact) padding. Project\n * `<wr-list-item>` children — they pick up the container's settings\n * through CSS cascade, no DI needed.\n *\n * @example\n * ```html\n * <wr-list bordered dividers>\n * <wr-list-item>\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * <wr-list-item interactive (click)=\"open(item)\">\n * Click anywhere on this row\n * </wr-list-item>\n * </wr-list>\n * ```\n *\n * @see https://ngwr.dev/reference/components/list\n */\n@Component({\n selector: 'wr-list',\n template: '<ul class=\"wr-list__items\" role=\"list\"><ng-content /></ul>',\n styleUrl: './list.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-label]': 'ariaLabel() || null',\n },\n})\nexport class WrList {\n /** Wrap the list in a card-style border + radius. @default false */\n readonly bordered = input(false, { transform: coerceBooleanProperty });\n\n /** Draw a thin divider between items. @default false */\n readonly dividers = input(false, { transform: coerceBooleanProperty });\n\n /** Use compact padding on every item. @default false */\n readonly dense = input(false, { transform: coerceBooleanProperty });\n\n /** Optional accessible label for the list. */\n readonly ariaLabel = input<string>('');\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list'];\n if (this.bordered()) parts.push('wr-list--bordered');\n if (this.dividers()) parts.push('wr-list--dividers');\n if (this.dense()) parts.push('wr-list--dense');\n return parts.join(' ');\n });\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Row inside `<wr-list>`. Three projection slots:\n *\n * - `[wrListItemLeading]` — icon, avatar, status dot, etc.\n * - default — main label / body\n * - `[wrListItemTrailing]` — meta value, action button, chevron\n *\n * Set `interactive` to get hover and cursor styles, a tab stop, and Enter /\n * Space activation. The role stays `listitem`: the row lives inside a\n * `<ul role=\"list\">`, where a `button` or `option` child role would break the\n * structure the container promises. That means an interactive row ANNOUNCES as\n * a list item rather than as a control — deliberate, but worth knowing when the\n * whole row is the only way to reach an action. Where the action needs to be\n * announced as one, project a real button into `[wrListItemTrailing]`.\n *\n * @example\n * ```html\n * <wr-list-item>Plain row</wr-list-item>\n *\n * <wr-list-item interactive (click)=\"onPick(item)\">\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * ```\n */\n@Component({\n selector: 'wr-list-item',\n templateUrl: './list-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n role: 'listitem',\n '[attr.tabindex]': 'interactive() ? \"0\" : null',\n '[attr.aria-disabled]': 'disabled() || null',\n '(keydown.enter)': 'onActivate($event)',\n '(keydown.space)': 'onActivate($event)',\n },\n})\nexport class WrListItem {\n /** Adds hover / cursor styles + keyboard activation. @default false */\n readonly interactive = input(false, { transform: coerceBooleanProperty });\n\n /** Visual disabled state. Suppresses hover + keyboard activation. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list__item'];\n if (this.interactive()) parts.push('wr-list__item--interactive');\n if (this.disabled()) parts.push('wr-list__item--disabled');\n return parts.join(' ');\n });\n\n protected onActivate(event: Event): void {\n if (!this.interactive() || this.disabled()) return;\n event.preventDefault();\n (event.currentTarget as HTMLElement).click();\n }\n}\n","<span class=\"wr-list__leading\"><ng-content select=\"[wrListItemLeading]\" /></span>\n<span class=\"wr-list__body\"><ng-content /></span>\n<span class=\"wr-list__trailing\"><ng-content select=\"[wrListItemTrailing]\" /></span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-list.mjs","sources":["../../../projects/lib/list/list.ts","../../../projects/lib/list/list-item.ts","../../../projects/lib/list/list-item.html","../../../projects/lib/list/ngwr-list.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Generic list container. Renders `<ul role=\"list\">` with optional\n * borders, dividers between items, and dense (compact) padding. Project\n * `<wr-list-item>` children — they pick up the container's settings\n * through CSS cascade, no DI needed.\n *\n * @example\n * ```html\n * <wr-list bordered dividers>\n * <wr-list-item>\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * <wr-list-item interactive (click)=\"open(item)\">\n * Click anywhere on this row\n * </wr-list-item>\n * </wr-list>\n * ```\n *\n * @see https://ngwr.dev/reference/components/list\n */\n@Component({\n selector: 'wr-list',\n template: '<ul class=\"wr-list__items\" role=\"list\"><ng-content /></ul>',\n styleUrl: './list.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[attr.aria-label]': 'ariaLabel() || null',\n },\n})\nexport class WrList {\n /** Wrap the list in a card-style border + radius. @default false */\n readonly bordered = input(false, { transform: coerceBooleanProperty });\n\n /** Draw a thin divider between items. @default false */\n readonly dividers = input(false, { transform: coerceBooleanProperty });\n\n /** Use compact padding on every item. @default false */\n readonly dense = input(false, { transform: coerceBooleanProperty });\n\n /** Optional accessible label for the list. */\n readonly ariaLabel = input<string>('');\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list'];\n if (this.bordered()) parts.push('wr-list--bordered');\n if (this.dividers()) parts.push('wr-list--dividers');\n if (this.dense()) parts.push('wr-list--dense');\n return parts.join(' ');\n });\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Row inside `<wr-list>`. Three projection slots:\n *\n * - `[wrListItemLeading]` — icon, avatar, status dot, etc.\n * - default — main label / body\n * - `[wrListItemTrailing]` — meta value, action button, chevron\n *\n * Set `interactive` to get hover and cursor styles, a tab stop, and Enter /\n * Space activation. The role stays `listitem`: the row lives inside a\n * `<ul role=\"list\">`, where a `button` or `option` child role would break the\n * structure the container promises. That means an interactive row ANNOUNCES as\n * a list item rather than as a control — deliberate, but worth knowing when the\n * whole row is the only way to reach an action. Where the action needs to be\n * announced as one, project a real button into `[wrListItemTrailing]`.\n *\n * @example\n * ```html\n * <wr-list-item>Plain row</wr-list-item>\n *\n * <wr-list-item interactive (click)=\"onPick(item)\">\n * <wr-icon ngProjectAs=\"[wrListItemLeading]\" name=\"folder\" />\n * Reports\n * <span ngProjectAs=\"[wrListItemTrailing]\">12</span>\n * </wr-list-item>\n * ```\n */\n@Component({\n selector: 'wr-list-item',\n templateUrl: './list-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n role: 'listitem',\n '[attr.tabindex]': 'interactive() ? \"0\" : null',\n '[attr.aria-disabled]': 'disabled() || null',\n '(keydown.enter)': 'onActivate($event)',\n '(keydown.space)': 'onActivate($event)',\n },\n})\nexport class WrListItem {\n /** Adds hover / cursor styles + keyboard activation. @default false */\n readonly interactive = input(false, { transform: coerceBooleanProperty });\n\n /** Visual disabled state. Suppresses hover + keyboard activation. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-list__item'];\n if (this.interactive()) parts.push('wr-list__item--interactive');\n if (this.disabled()) parts.push('wr-list__item--disabled');\n return parts.join(' ');\n });\n\n protected onActivate(event: Event): void {\n if (!this.interactive() || this.disabled()) return;\n event.preventDefault();\n (event.currentTarget as HTMLElement).click();\n }\n}\n","<span class=\"wr-list__leading\"><ng-content select=\"[wrListItemLeading]\" /></span>\n<span class=\"wr-list__body\"><ng-content /></span>\n<span class=\"wr-list__trailing\"><ng-content select=\"[wrListItemTrailing]\" /></span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { isPlatformBrowser } from '@angular/common';
2
+ import { makeEnvironmentProviders, provideEnvironmentInitializer, inject, PLATFORM_ID, DestroyRef } from '@angular/core';
3
+ import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
4
+ import { WrLoadingBar } from 'ngwr/loading-bar';
5
+
6
+ /**
7
+ * @license
8
+ *
9
+ * Use of this source code is governed by an MIT-style license that can be
10
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
11
+ */
12
+ /**
13
+ * Drive {@link WrLoadingBar} from router navigations: `NavigationStart` takes a
14
+ * slot, and each of `NavigationEnd` / `NavigationCancel` / `NavigationError`
15
+ * releases one.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { provideWrLoadingBarRouter } from 'ngwr/loading-bar/router';
20
+ *
21
+ * bootstrapApplication(App, {
22
+ * providers: [provideRouter(routes), provideWrLoadingBarRouter()],
23
+ * });
24
+ * ```
25
+ *
26
+ * **Why this is a call and not the default.** `WrLoadingBar` used to inject
27
+ * `Router` itself, so navigations drove the bar with no configuration — and
28
+ * every app that rendered `<wr-loading-bar>` paid 66.3 kB of `@angular/router`
29
+ * for it, two thirds of the entry point's total cost, whether or not it had
30
+ * routes. `{ optional: true }` does not help: an optional inject still names the
31
+ * class as the token, and it measured byte-for-byte identical to a required one.
32
+ * An automatic integration and a router-free bundle cannot both exist in a
33
+ * statically linked app, so the automatic half moved here.
34
+ */
35
+ function provideWrLoadingBarRouter() {
36
+ return makeEnvironmentProviders([
37
+ provideEnvironmentInitializer(() => {
38
+ // Browser only. During prerender the initial navigation runs the whole
39
+ // cycle in the Node worker — including the bar's 150 ms interval — and
40
+ // leaves `progress` at 1, because the reset that clears it is deferred and
41
+ // the HTML is serialized first: every prerendered page then ships a
42
+ // full-width bar across the top until hydration.
43
+ if (!isPlatformBrowser(inject(PLATFORM_ID)))
44
+ return;
45
+ const bar = inject(WrLoadingBar);
46
+ const destroyRef = inject(DestroyRef);
47
+ const sub = inject(Router).events.subscribe(event => {
48
+ if (event instanceof NavigationStart)
49
+ bar.start();
50
+ else if (event instanceof NavigationEnd ||
51
+ event instanceof NavigationCancel ||
52
+ event instanceof NavigationError) {
53
+ bar.complete();
54
+ }
55
+ });
56
+ destroyRef.onDestroy(() => sub.unsubscribe());
57
+ }),
58
+ ]);
59
+ }
60
+
61
+ /**
62
+ * @license
63
+ *
64
+ * Use of this source code is governed by an MIT-style license that can be
65
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
66
+ */
67
+
68
+ /**
69
+ * Generated bundle index. Do not edit.
70
+ */
71
+
72
+ export { provideWrLoadingBarRouter };
73
+ //# sourceMappingURL=ngwr-loading-bar-router.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngwr-loading-bar-router.mjs","sources":["../../../projects/lib/loading-bar/router/provide-wr-loading-bar-router.ts","../../../projects/lib/loading-bar/router/public-api.ts","../../../projects/lib/loading-bar/router/ngwr-loading-bar-router.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n DestroyRef,\n type EnvironmentProviders,\n PLATFORM_ID,\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\nimport { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';\n\nimport { WrLoadingBar } from 'ngwr/loading-bar';\n\n/**\n * Drive {@link WrLoadingBar} from router navigations: `NavigationStart` takes a\n * slot, and each of `NavigationEnd` / `NavigationCancel` / `NavigationError`\n * releases one.\n *\n * @example\n * ```ts\n * import { provideWrLoadingBarRouter } from 'ngwr/loading-bar/router';\n *\n * bootstrapApplication(App, {\n * providers: [provideRouter(routes), provideWrLoadingBarRouter()],\n * });\n * ```\n *\n * **Why this is a call and not the default.** `WrLoadingBar` used to inject\n * `Router` itself, so navigations drove the bar with no configuration — and\n * every app that rendered `<wr-loading-bar>` paid 66.3 kB of `@angular/router`\n * for it, two thirds of the entry point's total cost, whether or not it had\n * routes. `{ optional: true }` does not help: an optional inject still names the\n * class as the token, and it measured byte-for-byte identical to a required one.\n * An automatic integration and a router-free bundle cannot both exist in a\n * statically linked app, so the automatic half moved here.\n */\nexport function provideWrLoadingBarRouter(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => {\n // Browser only. During prerender the initial navigation runs the whole\n // cycle in the Node worker — including the bar's 150 ms interval — and\n // leaves `progress` at 1, because the reset that clears it is deferred and\n // the HTML is serialized first: every prerendered page then ships a\n // full-width bar across the top until hydration.\n if (!isPlatformBrowser(inject(PLATFORM_ID))) return;\n\n const bar = inject(WrLoadingBar);\n const destroyRef = inject(DestroyRef);\n const sub = inject(Router).events.subscribe(event => {\n if (event instanceof NavigationStart) bar.start();\n else if (\n event instanceof NavigationEnd ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError\n ) {\n bar.complete();\n }\n });\n destroyRef.onDestroy(() => sub.unsubscribe());\n }),\n ]);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nexport { provideWrLoadingBarRouter } from './provide-wr-loading-bar-router';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;;;;AAKG;AAeH;;;;;;;;;;;;;;;;;;;;;;AAsBG;SACa,yBAAyB,GAAA;AACvC,IAAA,OAAO,wBAAwB,CAAC;QAC9B,6BAA6B,CAAC,MAAK;;;;;;AAMjC,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAAE;AAE7C,YAAA,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC;AAChC,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACrC,YAAA,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,IAAG;gBAClD,IAAI,KAAK,YAAY,eAAe;oBAAE,GAAG,CAAC,KAAK,EAAE;qBAC5C,IACH,KAAK,YAAY,aAAa;AAC9B,oBAAA,KAAK,YAAY,gBAAgB;oBACjC,KAAK,YAAY,eAAe,EAChC;oBACA,GAAG,CAAC,QAAQ,EAAE;gBAChB;AACF,YAAA,CAAC,CAAC;YACF,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;AAC/C,QAAA,CAAC,CAAC;AACH,KAAA,CAAC;AACJ;;ACpEA;;;;;AAKG;;ACLH;;AAEG;;;;"}
@@ -1,7 +1,6 @@
1
1
  import { isPlatformBrowser } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, DestroyRef, PLATFORM_ID, signal, computed, Service, input, ViewEncapsulation, Component } from '@angular/core';
4
- import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
3
+ import { inject, PLATFORM_ID, signal, computed, Service, input, ViewEncapsulation, Component } from '@angular/core';
5
4
 
6
5
  /**
7
6
  * @license
@@ -10,12 +9,19 @@ import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationErr
10
9
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
11
10
  */
12
11
  /**
13
- * Singleton state machine for a top-of-page progress indicator. Driven
14
- * by router events out of the box, plus a manual `start()` / `complete()`
15
- * API for HTTP-interceptor-style usage.
12
+ * Singleton state machine for a top-of-page progress indicator: a counter of
13
+ * in-flight tasks and a tween between 0 and 1, driven through `start()` /
14
+ * `complete()`.
16
15
  *
17
16
  * Pair with `<wr-loading-bar>` to render the bar at the top of your shell.
18
17
  *
18
+ * It knows nothing about the router on purpose. Naming `Router` here — even
19
+ * `{ optional: true }`, which is byte-for-byte identical to a required inject —
20
+ * put 66.3 kB of `@angular/router` into every app that rendered the bar,
21
+ * two thirds of what `ngwr/loading-bar` cost and 27× the component's own code.
22
+ * Call `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router` to have
23
+ * navigations drive it.
24
+ *
19
25
  * @example
20
26
  * ```ts
21
27
  * // From an HttpInterceptor:
@@ -27,8 +33,6 @@ import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationErr
27
33
  * @see https://ngwr.dev/reference/services/loading-bar
28
34
  */
29
35
  class WrLoadingBar {
30
- router = inject(Router, { optional: true });
31
- destroyRef = inject(DestroyRef);
32
36
  isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
33
37
  /** Live count of pending "tasks" (manual + router). */
34
38
  count = signal(0, /* @ts-ignore */
@@ -45,27 +49,6 @@ class WrLoadingBar {
45
49
  ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
46
50
  timer = null;
47
51
  holdTimer = null;
48
- constructor() {
49
- // Router-driven only in the browser. During prerender the initial
50
- // navigation ran the whole cycle in the Node worker — including a 150 ms
51
- // `setInterval` — and left `progress` at 1, because the reset that clears
52
- // it is deferred and the HTML is serialized first. Every prerendered page
53
- // shipped a full-width bar across the top until hydration.
54
- if (!this.router || !this.isBrowser)
55
- return;
56
- // Mirror router events: any in-flight navigation starts the bar,
57
- // each terminal event releases one slot.
58
- const sub = this.router.events.subscribe(event => {
59
- if (event instanceof NavigationStart)
60
- this.start();
61
- else if (event instanceof NavigationEnd ||
62
- event instanceof NavigationCancel ||
63
- event instanceof NavigationError) {
64
- this.complete();
65
- }
66
- });
67
- this.destroyRef.onDestroy(() => sub.unsubscribe());
68
- }
69
52
  /** Reserve a slot. The bar starts trickling as long as `count > 0`. */
70
53
  start() {
71
54
  if (this.count() === 0)
@@ -148,12 +131,12 @@ class WrLoadingBar {
148
131
  this._progress.set(0);
149
132
  }, 220);
150
133
  }
151
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrLoadingBar, deps: [], target: i0.ɵɵFactoryTarget.Service });
152
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.4", ngImport: i0, type: WrLoadingBar });
134
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrLoadingBar, deps: [], target: i0.ɵɵFactoryTarget.Service });
135
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrLoadingBar });
153
136
  }
154
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrLoadingBar, decorators: [{
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrLoadingBar, decorators: [{
155
138
  type: Service
156
- }], ctorParameters: () => [] });
139
+ }] });
157
140
 
158
141
  /**
159
142
  * @license
@@ -164,9 +147,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
164
147
  /**
165
148
  * Thin progress bar fixed to the top of the viewport.
166
149
  *
167
- * Drop one at the root of your shell. Reads the singleton {@link WrLoadingBar}
168
- * — every router navigation drives it automatically; HTTP interceptors
169
- * can call `start()` / `complete()` to add their own slots.
150
+ * Drop one at the root of your shell. Reads the singleton {@link WrLoadingBar},
151
+ * which is driven manually by `start()` / `complete()` — an HTTP interceptor, a
152
+ * long save, anything with a beginning and an end.
153
+ *
154
+ * Router navigations drive it too, but only once you add
155
+ * `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router`. That is an opt-in
156
+ * because the subscription is what pulls `@angular/router` into the bundle: this
157
+ * component is 2.4 kB of its own code and used to carry 66 kB of router into
158
+ * apps that never routed.
170
159
  *
171
160
  * @example
172
161
  * ```html
@@ -184,10 +173,10 @@ class WrLoadingBarComponent {
184
173
  bar = inject(WrLoadingBar);
185
174
  active = computed(() => this.bar.state() !== 'idle', /* @ts-ignore */
186
175
  ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
187
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrLoadingBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
188
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: WrLoadingBarComponent, isStandalone: true, selector: "wr-loading-bar", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-loading-bar" }, ngImport: i0, template: "<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n", styles: [".wr-loading-bar{position:fixed;top:0;inset-inline:0;z-index:var(--wr-z-top, 9999);pointer-events:none}.wr-loading-bar__track{width:100%;overflow:hidden;opacity:0;transition:opacity .2s ease}.wr-loading-bar--active{opacity:1}.wr-loading-bar__fill{width:0;height:2px;background:var(--wr-color-primary);box-shadow:0 0 8px rgb(var(--wr-color-primary-rgb)/60%);transition:width .15s ease-out,opacity .2s ease}\n"], encapsulation: i0.ViewEncapsulation.None });
176
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrLoadingBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
177
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrLoadingBarComponent, isStandalone: true, selector: "wr-loading-bar", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-loading-bar" }, ngImport: i0, template: "<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n", styles: [".wr-loading-bar{position:fixed;top:0;inset-inline:0;z-index:var(--wr-z-top, 9999);pointer-events:none}.wr-loading-bar__track{width:100%;overflow:hidden;opacity:0;transition:opacity .2s ease}.wr-loading-bar--active{opacity:1}.wr-loading-bar__fill{width:0;height:2px;background:var(--wr-color-primary);box-shadow:0 0 8px rgb(var(--wr-color-primary-rgb)/60%);transition:width .15s ease-out,opacity .2s ease}\n"], encapsulation: i0.ViewEncapsulation.None });
189
178
  }
190
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrLoadingBarComponent, decorators: [{
179
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrLoadingBarComponent, decorators: [{
191
180
  type: Component,
192
181
  args: [{ selector: 'wr-loading-bar', encapsulation: ViewEncapsulation.None, host: { class: 'wr-loading-bar' }, template: "<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n", styles: [".wr-loading-bar{position:fixed;top:0;inset-inline:0;z-index:var(--wr-z-top, 9999);pointer-events:none}.wr-loading-bar__track{width:100%;overflow:hidden;opacity:0;transition:opacity .2s ease}.wr-loading-bar--active{opacity:1}.wr-loading-bar__fill{width:0;height:2px;background:var(--wr-color-primary);box-shadow:0 0 8px rgb(var(--wr-color-primary-rgb)/60%);transition:width .15s ease-out,opacity .2s ease}\n"] }]
193
182
  }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-loading-bar.mjs","sources":["../../../projects/lib/loading-bar/services/loading-bar.ts","../../../projects/lib/loading-bar/loading-bar.component.ts","../../../projects/lib/loading-bar/loading-bar.component.html","../../../projects/lib/loading-bar/ngwr-loading-bar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport { DestroyRef, Service, PLATFORM_ID, type Signal, computed, inject, signal } from '@angular/core';\nimport { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';\n\nimport type { WrLoadingState } from '../interfaces';\n\n/**\n * Singleton state machine for a top-of-page progress indicator. Driven\n * by router events out of the box, plus a manual `start()` / `complete()`\n * API for HTTP-interceptor-style usage.\n *\n * Pair with `<wr-loading-bar>` to render the bar at the top of your shell.\n *\n * @example\n * ```ts\n * // From an HttpInterceptor:\n * const bar = inject(WrLoadingBar);\n * bar.start();\n * return next(req).pipe(finalize(() => bar.complete()));\n * ```\n *\n * @see https://ngwr.dev/reference/services/loading-bar\n */\n@Service()\nexport class WrLoadingBar {\n private readonly router = inject(Router, { optional: true });\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Live count of pending \"tasks\" (manual + router). */\n private readonly count = signal(0);\n\n /** Tween value `[0, 1]` — the bar's actual width. */\n private readonly _progress = signal(0);\n readonly progress: Signal<number> = this._progress.asReadonly();\n\n readonly state: Signal<WrLoadingState> = computed(() => {\n if (this.count() > 0) return 'running';\n return this._progress() > 0 ? 'completing' : 'idle';\n });\n\n private timer: ReturnType<typeof setInterval> | null = null;\n private holdTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n // Router-driven only in the browser. During prerender the initial\n // navigation ran the whole cycle in the Node worker — including a 150 ms\n // `setInterval` — and left `progress` at 1, because the reset that clears\n // it is deferred and the HTML is serialized first. Every prerendered page\n // shipped a full-width bar across the top until hydration.\n if (!this.router || !this.isBrowser) return;\n\n // Mirror router events: any in-flight navigation starts the bar,\n // each terminal event releases one slot.\n const sub = this.router.events.subscribe(event => {\n if (event instanceof NavigationStart) this.start();\n else if (\n event instanceof NavigationEnd ||\n event instanceof NavigationCancel ||\n event instanceof NavigationError\n ) {\n this.complete();\n }\n });\n this.destroyRef.onDestroy(() => sub.unsubscribe());\n }\n\n /** Reserve a slot. The bar starts trickling as long as `count > 0`. */\n start(): void {\n if (this.count() === 0) this.beginTrickle();\n this.count.update(v => v + 1);\n }\n\n /** Release a slot. When the last one closes, the bar fast-forwards to 100% then resets. */\n complete(): void {\n // Only a call that actually RELEASED something may finish. `Math.max` turns\n // a stray `complete()` into a no-op on the count, but the old code still\n // read the resulting zero as \"the last task just ended\" and flashed the bar\n // to 100% — reachable from a `finalize` that runs twice, or any\n // `complete()` after a `reset()`.\n if (this.count() === 0) return;\n this.count.update(v => v - 1);\n if (this.count() === 0) this.finish();\n }\n\n /** Cancel without animating the bar to 100%. Resets immediately. */\n reset(): void {\n this.count.set(0);\n this.stopTrickle();\n this.clearHold();\n this._progress.set(0);\n }\n\n // Internals\n\n private beginTrickle(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing paints during prerender, so there is nothing to animate. The\n // count still moves — a task really is in flight — but no 150 ms interval\n // is left spinning inside the render worker, and the serialized bar stays\n // at zero width whether or not the task finishes before serialization.\n if (!this.isBrowser) return;\n\n // Unconditionally, not `if (progress === 0)`. A task that starts inside the\n // 220 ms hold found progress at 1, kept it, and then trickled the WRONG WAY:\n // `p + (0.9 - p) * 0.08` approaches 0.9 from above, so the bar sat at ~99%\n // and crept backwards for the whole task. A redirecting route guard hits\n // that window on every navigation.\n this._progress.set(0.08);\n this.timer = setInterval(() => {\n const p = this._progress();\n // Approach 90% asymptotically — we want the user-visible final jump\n // to clearly indicate completion.\n const next = p + (0.9 - p) * 0.08;\n this._progress.set(next);\n }, 150);\n }\n\n private stopTrickle(): void {\n if (this.timer === null) return;\n clearInterval(this.timer);\n this.timer = null;\n }\n\n private clearHold(): void {\n if (this.holdTimer === null) return;\n clearTimeout(this.holdTimer);\n this.holdTimer = null;\n }\n\n private finish(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing animates during prerender and nothing will run the reset before\n // the HTML is serialized, so there is no 100% worth holding — go straight\n // to rest and leave the markup clean.\n if (!this.isBrowser) {\n this._progress.set(0);\n return;\n }\n\n this._progress.set(1);\n // Give the bar a moment to render the final 100% width before resetting.\n // The handle is kept so a later cycle's hold is not cut short by this\n // one's leftover timer.\n this.holdTimer = setTimeout(() => {\n this.holdTimer = null;\n if (this.count() === 0) this._progress.set(0);\n }, 220);\n }\n}\n\nexport type { WrLoadingState } from '../interfaces';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WrLoadingBar } from './services/loading-bar';\n\n/**\n * Thin progress bar fixed to the top of the viewport.\n *\n * Drop one at the root of your shell. Reads the singleton {@link WrLoadingBar}\n * — every router navigation drives it automatically; HTTP interceptors\n * can call `start()` / `complete()` to add their own slots.\n *\n * @example\n * ```html\n * <wr-loading-bar /> <!-- top, primary color -->\n * <wr-loading-bar color=\"#9b51e0\" height=\"3px\" />\n * ```\n */\n@Component({\n selector: 'wr-loading-bar',\n templateUrl: './loading-bar.component.html',\n styleUrl: './loading-bar.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-loading-bar' },\n})\nexport class WrLoadingBarComponent {\n /** Bar colour. Defaults to the primary brand colour. */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Bar height. */\n readonly height = input<string>('2px');\n\n protected readonly bar = inject(WrLoadingBar);\n\n protected readonly active = computed(() => this.bar.state() !== 'idle');\n}\n","<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-loading-bar.mjs","sources":["../../../projects/lib/loading-bar/services/loading-bar.ts","../../../projects/lib/loading-bar/loading-bar.component.ts","../../../projects/lib/loading-bar/loading-bar.component.html","../../../projects/lib/loading-bar/ngwr-loading-bar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport { Service, PLATFORM_ID, type Signal, computed, inject, signal } from '@angular/core';\n\nimport type { WrLoadingState } from '../interfaces';\n\n/**\n * Singleton state machine for a top-of-page progress indicator: a counter of\n * in-flight tasks and a tween between 0 and 1, driven through `start()` /\n * `complete()`.\n *\n * Pair with `<wr-loading-bar>` to render the bar at the top of your shell.\n *\n * It knows nothing about the router on purpose. Naming `Router` here — even\n * `{ optional: true }`, which is byte-for-byte identical to a required inject —\n * put 66.3 kB of `@angular/router` into every app that rendered the bar,\n * two thirds of what `ngwr/loading-bar` cost and 27× the component's own code.\n * Call `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router` to have\n * navigations drive it.\n *\n * @example\n * ```ts\n * // From an HttpInterceptor:\n * const bar = inject(WrLoadingBar);\n * bar.start();\n * return next(req).pipe(finalize(() => bar.complete()));\n * ```\n *\n * @see https://ngwr.dev/reference/services/loading-bar\n */\n@Service()\nexport class WrLoadingBar {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Live count of pending \"tasks\" (manual + router). */\n private readonly count = signal(0);\n\n /** Tween value `[0, 1]` — the bar's actual width. */\n private readonly _progress = signal(0);\n readonly progress: Signal<number> = this._progress.asReadonly();\n\n readonly state: Signal<WrLoadingState> = computed(() => {\n if (this.count() > 0) return 'running';\n return this._progress() > 0 ? 'completing' : 'idle';\n });\n\n private timer: ReturnType<typeof setInterval> | null = null;\n private holdTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** Reserve a slot. The bar starts trickling as long as `count > 0`. */\n start(): void {\n if (this.count() === 0) this.beginTrickle();\n this.count.update(v => v + 1);\n }\n\n /** Release a slot. When the last one closes, the bar fast-forwards to 100% then resets. */\n complete(): void {\n // Only a call that actually RELEASED something may finish. `Math.max` turns\n // a stray `complete()` into a no-op on the count, but the old code still\n // read the resulting zero as \"the last task just ended\" and flashed the bar\n // to 100% — reachable from a `finalize` that runs twice, or any\n // `complete()` after a `reset()`.\n if (this.count() === 0) return;\n this.count.update(v => v - 1);\n if (this.count() === 0) this.finish();\n }\n\n /** Cancel without animating the bar to 100%. Resets immediately. */\n reset(): void {\n this.count.set(0);\n this.stopTrickle();\n this.clearHold();\n this._progress.set(0);\n }\n\n // Internals\n\n private beginTrickle(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing paints during prerender, so there is nothing to animate. The\n // count still moves — a task really is in flight — but no 150 ms interval\n // is left spinning inside the render worker, and the serialized bar stays\n // at zero width whether or not the task finishes before serialization.\n if (!this.isBrowser) return;\n\n // Unconditionally, not `if (progress === 0)`. A task that starts inside the\n // 220 ms hold found progress at 1, kept it, and then trickled the WRONG WAY:\n // `p + (0.9 - p) * 0.08` approaches 0.9 from above, so the bar sat at ~99%\n // and crept backwards for the whole task. A redirecting route guard hits\n // that window on every navigation.\n this._progress.set(0.08);\n this.timer = setInterval(() => {\n const p = this._progress();\n // Approach 90% asymptotically — we want the user-visible final jump\n // to clearly indicate completion.\n const next = p + (0.9 - p) * 0.08;\n this._progress.set(next);\n }, 150);\n }\n\n private stopTrickle(): void {\n if (this.timer === null) return;\n clearInterval(this.timer);\n this.timer = null;\n }\n\n private clearHold(): void {\n if (this.holdTimer === null) return;\n clearTimeout(this.holdTimer);\n this.holdTimer = null;\n }\n\n private finish(): void {\n this.stopTrickle();\n this.clearHold();\n\n // Nothing animates during prerender and nothing will run the reset before\n // the HTML is serialized, so there is no 100% worth holding — go straight\n // to rest and leave the markup clean.\n if (!this.isBrowser) {\n this._progress.set(0);\n return;\n }\n\n this._progress.set(1);\n // Give the bar a moment to render the final 100% width before resetting.\n // The handle is kept so a later cycle's hold is not cut short by this\n // one's leftover timer.\n this.holdTimer = setTimeout(() => {\n this.holdTimer = null;\n if (this.count() === 0) this._progress.set(0);\n }, 220);\n }\n}\n\nexport type { WrLoadingState } from '../interfaces';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WrLoadingBar } from './services/loading-bar';\n\n/**\n * Thin progress bar fixed to the top of the viewport.\n *\n * Drop one at the root of your shell. Reads the singleton {@link WrLoadingBar},\n * which is driven manually by `start()` / `complete()` — an HTTP interceptor, a\n * long save, anything with a beginning and an end.\n *\n * Router navigations drive it too, but only once you add\n * `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router`. That is an opt-in\n * because the subscription is what pulls `@angular/router` into the bundle: this\n * component is 2.4 kB of its own code and used to carry 66 kB of router into\n * apps that never routed.\n *\n * @example\n * ```html\n * <wr-loading-bar /> <!-- top, primary color -->\n * <wr-loading-bar color=\"#9b51e0\" height=\"3px\" />\n * ```\n */\n@Component({\n selector: 'wr-loading-bar',\n templateUrl: './loading-bar.component.html',\n styleUrl: './loading-bar.scss',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-loading-bar' },\n})\nexport class WrLoadingBarComponent {\n /** Bar colour. Defaults to the primary brand colour. */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Bar height. */\n readonly height = input<string>('2px');\n\n protected readonly bar = inject(WrLoadingBar);\n\n protected readonly active = computed(() => this.bar.state() !== 'idle');\n}\n","<div class=\"wr-loading-bar__track\" [class.wr-loading-bar--active]=\"active()\">\n <div\n class=\"wr-loading-bar__fill\"\n [style.width.%]=\"bar.progress() * 100\"\n [style.background]=\"color()\"\n [style.height]=\"height()\"\n ></div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAOH;;;;;;;;;;;;;;;;;;;;;;;AAuBG;MAEU,YAAY,CAAA;IACN,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;;IAGlD,KAAK,GAAG,MAAM,CAAC,CAAC;8EAAC;;IAGjB,SAAS,GAAG,MAAM,CAAC,CAAC;kFAAC;AAC7B,IAAA,QAAQ,GAAmB,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;AAEtD,IAAA,KAAK,GAA2B,QAAQ,CAAC,MAAK;AACrD,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;AAAE,YAAA,OAAO,SAAS;AACtC,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,YAAY,GAAG,MAAM;IACrD,CAAC;8EAAC;IAEM,KAAK,GAA0C,IAAI;IACnD,SAAS,GAAyC,IAAI;;IAG9D,KAAK,GAAA;AACH,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,YAAY,EAAE;AAC3C,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B;;IAGA,QAAQ,GAAA;;;;;;AAMN,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC;YAAE;AACxB,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7B,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,CAAC,MAAM,EAAE;IACvC;;IAGA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,SAAS,EAAE;AAChB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB;;IAIQ,YAAY,GAAA;QAClB,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,SAAS,EAAE;;;;;QAMhB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;;;;;;AAOrB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,MAAK;AAC5B,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE;;;YAG1B,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI;AACjC,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QAC1B,CAAC,EAAE,GAAG,CAAC;IACT;IAEQ,WAAW,GAAA;AACjB,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI;YAAE;AACzB,QAAA,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI;IACnB;IAEQ,SAAS,GAAA;AACf,QAAA,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAAE;AAC7B,QAAA,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;AAC5B,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;IACvB;IAEQ,MAAM,GAAA;QACZ,IAAI,CAAC,WAAW,EAAE;QAClB,IAAI,CAAC,SAAS,EAAE;;;;AAKhB,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;AACnB,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YACrB;QACF;AAEA,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;;;;AAIrB,QAAA,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,MAAK;AAC/B,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC;AAAE,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC,EAAE,GAAG,CAAC;IACT;uGAvGW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,OAAA,EAAA,CAAA;wGAAZ,YAAY,EAAA,CAAA;;2FAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB;;;ACpCD;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;;;AAkBG;MAQU,qBAAqB,CAAA;;IAEvB,KAAK,GAAG,KAAK,CAAS,yBAAyB;8EAAC;;IAGhD,MAAM,GAAG,KAAK,CAAS,KAAK;+EAAC;AAEnB,IAAA,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC;AAE1B,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,MAAM;+EAAC;uGAT5D,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,qXCrClC,uQAQA,EAAA,MAAA,EAAA,CAAA,wZAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FD6Ba,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAPjC,SAAS;+BACE,gBAAgB,EAAA,aAAA,EAGX,iBAAiB,CAAC,IAAI,QAC/B,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAA,QAAA,EAAA,uQAAA,EAAA,MAAA,EAAA,CAAA,wZAAA,CAAA,EAAA;;;AEnCnC;;AAEG;;;;"}
@@ -1295,10 +1295,10 @@ class WrMarkdownHighlight {
1295
1295
  this.cache.delete(oldest.value);
1296
1296
  }
1297
1297
  }
1298
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMarkdownHighlight, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1299
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMarkdownHighlight, providedIn: 'root' });
1298
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMarkdownHighlight, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1299
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMarkdownHighlight, providedIn: 'root' });
1300
1300
  }
1301
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMarkdownHighlight, decorators: [{
1301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMarkdownHighlight, decorators: [{
1302
1302
  type: Injectable,
1303
1303
  args: [{ providedIn: 'root' }]
1304
1304
  }] });
@@ -1539,10 +1539,10 @@ class WrMarkdown {
1539
1539
  asCells(value) {
1540
1540
  return value;
1541
1541
  }
1542
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMarkdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
1543
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: WrMarkdown, isStandalone: true, selector: "wr-markdown", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, streaming: { classPropertyName: "streaming", publicName: "streaming", isSignal: true, isRequired: false, transformFunction: null }, copyable: { classPropertyName: "copyable", publicName: "copyable", isSignal: true, isRequired: false, transformFunction: null }, linkTarget: { classPropertyName: "linkTarget", publicName: "linkTarget", isSignal: true, isRequired: false, transformFunction: null }, headingIds: { classPropertyName: "headingIds", publicName: "headingIds", isSignal: true, isRequired: false, transformFunction: null }, headingIdPrefix: { classPropertyName: "headingIdPrefix", publicName: "headingIdPrefix", isSignal: true, isRequired: false, transformFunction: null }, copyLabel: { classPropertyName: "copyLabel", publicName: "copyLabel", isSignal: true, isRequired: false, transformFunction: null }, copiedLabel: { classPropertyName: "copiedLabel", publicName: "copiedLabel", isSignal: true, isRequired: false, transformFunction: null }, taskDoneLabel: { classPropertyName: "taskDoneLabel", publicName: "taskDoneLabel", isSignal: true, isRequired: false, transformFunction: null }, taskTodoLabel: { classPropertyName: "taskTodoLabel", publicName: "taskTodoLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-markdown--streaming": "streaming()" }, classAttribute: "wr-markdown" }, ngImport: i0, template: "<!--\n Recursion runs through `ngTemplateOutlet` into these templates rather than\n through a child component, so the rendered DOM is exactly the document \u2014 no\n wrapper element between a `<ul>` and its `<li>`. See `asBlocks` for the whole\n reasoning.\n-->\n<ng-template #inlineList let-raw>\n @let nodes = asInlines(raw);\n\n @for (node of nodes; track $index) {\n @switch (node.kind) {\n @case ('text') {\n <!-- Wrapped, and not for tidiness: a bare interpolation on its own line is\n ONE text node that includes the indentation around it, so `a **b** c`\n rendered with a space inside every `<strong>`. Inside an element the\n whitespace becomes separate whitespace-only nodes, which Angular\n removes, and `<ng-container>` itself renders nothing. Prettier\n reformats the bare form back, so this also has to survive `--fix`. -->\n <ng-container>{{ node.value }}</ng-container>\n }\n @case ('code') {\n <!-- `dir=\"ltr\"` because code is not prose: under RTL the browser\n reorders `foo();` to `;foo()`. -->\n <code class=\"wr-markdown__code-inline\" dir=\"ltr\">{{ node.value }}</code>\n }\n @case ('strong') {\n <strong class=\"wr-markdown__strong\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></strong>\n }\n @case ('em') {\n <em class=\"wr-markdown__em\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></em>\n }\n @case ('del') {\n <del class=\"wr-markdown__del\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></del>\n }\n @case ('link') {\n <a\n class=\"wr-markdown__link\"\n [href]=\"hrefOf(node.href)\"\n [attr.title]=\"node.title\"\n [attr.target]=\"resolvedLinkTarget()\"\n [attr.rel]=\"linkRel()\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></a>\n }\n @case ('image') {\n <img\n class=\"wr-markdown__image\"\n [src]=\"node.src\"\n [alt]=\"node.alt\"\n [attr.title]=\"node.title\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n }\n @case ('break') {\n <br />\n }\n }\n }\n</ng-template>\n\n<ng-template #itemList let-raw let-tight=\"tight\">\n @let items = asItems(raw);\n\n @for (item of items; track $index) {\n <li class=\"wr-markdown__item\" [class.wr-markdown__item--task]=\"item.checked !== null\">\n @if (item.checked !== null) {\n <!-- Presentational, with the state as text beside it: a real\n `<input type=\"checkbox\">` here would be an unlabelled form control,\n which is a serious axe violation, and making it operable would\n promise an interaction a renderer cannot honour. -->\n <span class=\"wr-markdown__task\" [class.wr-markdown__task--checked]=\"item.checked\" aria-hidden=\"true\"></span>\n <span class=\"wr-markdown__sr-only\">{{ item.checked ? resolvedTaskDoneLabel() : resolvedTaskTodoLabel() }}</span>\n }\n <ng-container\n [ngTemplateOutlet]=\"blockList\"\n [ngTemplateOutletContext]=\"{ $implicit: item.children, tight: tight }\"\n />\n </li>\n }\n</ng-template>\n\n<ng-template #blockList let-raw let-tight=\"tight\">\n @let list = asBlocks(raw);\n\n @for (block of list; track $index) {\n @switch (block.kind) {\n @case ('paragraph') {\n <!-- A tight list drops the `<p>`, which is what CommonMark specifies and\n what keeps a one-line list from being double-spaced. -->\n @if (tight) {\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n } @else {\n <p class=\"wr-markdown__paragraph\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </p>\n }\n }\n @case ('heading') {\n @switch (block.level) {\n @case (1) {\n <h1 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h1>\n }\n @case (2) {\n <h2 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h2>\n }\n @case (3) {\n <h3 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h3>\n }\n @case (4) {\n <h4 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h4>\n }\n @case (5) {\n <h5 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h5>\n }\n @default {\n <h6 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h6>\n }\n }\n }\n @case ('code') {\n @let highlighted = linesOf(block.code, block.language);\n\n <div class=\"wr-markdown__code-block\">\n <pre\n class=\"wr-markdown__pre\"\n dir=\"ltr\"\n tabindex=\"0\"\n ><code class=\"wr-markdown__code\" [attr.data-language]=\"block.language\">@if (highlighted) {@for (row of highlighted; track $index) {<span class=\"wr-markdown__line\">@for (span of row; track $index) {<span\n [style.color]=\"span.color\"\n [style.font-style]=\"span.fontStyle === 'italic' ? 'italic' : null\"\n [style.font-weight]=\"span.fontStyle === 'bold' ? 'bold' : null\"\n [style.text-decoration]=\"span.fontStyle === 'underline' ? 'underline' : null\"\n >{{ span.text }}</span>}</span>@if (!$last) {{{ newline }}}}} @else {{{ block.code }}}</code></pre>\n\n @if (resolvedCopyable() && block.closed) {\n <button\n type=\"button\"\n class=\"wr-markdown__copy\"\n [wrCopyToClipboard]=\"block.code\"\n [attr.aria-label]=\"isCopied(block) ? resolvedCopiedLabel() : resolvedCopyLabel()\"\n (copied)=\"onCopied(block)\"\n >\n <svg\n class=\"wr-markdown__copy-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @if (isCopied(block)) {\n <path d=\"M20 6 9 17l-5-5\" />\n } @else {\n <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n }\n </svg>\n </button>\n }\n </div>\n }\n @case ('quote') {\n <blockquote class=\"wr-markdown__quote\">\n <ng-container\n [ngTemplateOutlet]=\"blockList\"\n [ngTemplateOutletContext]=\"{ $implicit: block.children, tight: false }\"\n />\n </blockquote>\n }\n @case ('list') {\n @if (block.ordered) {\n <ol\n class=\"wr-markdown__list wr-markdown__list--ordered\"\n [attr.start]=\"block.start === 1 ? null : block.start\"\n >\n <ng-container\n [ngTemplateOutlet]=\"itemList\"\n [ngTemplateOutletContext]=\"{ $implicit: block.items, tight: block.tight }\"\n />\n </ol>\n } @else {\n <ul class=\"wr-markdown__list\">\n <ng-container\n [ngTemplateOutlet]=\"itemList\"\n [ngTemplateOutletContext]=\"{ $implicit: block.items, tight: block.tight }\"\n />\n </ul>\n }\n }\n @case ('table') {\n <!-- Its own scroller: a wide table must not push the page sideways, which\n is also what keeps the RTL layout gate quiet about it. -->\n <div class=\"wr-markdown__table-scroll\" tabindex=\"0\">\n <table class=\"wr-markdown__table\">\n <thead>\n <tr>\n @for (cell of block.head; track column; let column = $index) {\n <th class=\"wr-markdown__th\" scope=\"col\" [style.text-align]=\"block.align[column]\">\n <ng-container\n [ngTemplateOutlet]=\"inlineList\"\n [ngTemplateOutletContext]=\"{ $implicit: cell.inlines }\"\n />\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of block.rows; track $index) {\n <tr>\n @for (cell of asCells(row); track column; let column = $index) {\n <td class=\"wr-markdown__td\" [style.text-align]=\"block.align[column]\">\n <ng-container\n [ngTemplateOutlet]=\"inlineList\"\n [ngTemplateOutletContext]=\"{ $implicit: cell.inlines }\"\n />\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n @case ('rule') {\n <hr class=\"wr-markdown__rule\" />\n }\n }\n }\n</ng-template>\n\n<ng-container [ngTemplateOutlet]=\"blockList\" [ngTemplateOutletContext]=\"{ $implicit: blocks(), tight: false }\" />\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: WrCopyToClipboard, selector: "[wrCopyToClipboard]", inputs: ["wrCopyToClipboard"], outputs: ["copied", "copyFailed"] }], encapsulation: i0.ViewEncapsulation.None });
1542
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMarkdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
1543
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrMarkdown, isStandalone: true, selector: "wr-markdown", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, streaming: { classPropertyName: "streaming", publicName: "streaming", isSignal: true, isRequired: false, transformFunction: null }, copyable: { classPropertyName: "copyable", publicName: "copyable", isSignal: true, isRequired: false, transformFunction: null }, linkTarget: { classPropertyName: "linkTarget", publicName: "linkTarget", isSignal: true, isRequired: false, transformFunction: null }, headingIds: { classPropertyName: "headingIds", publicName: "headingIds", isSignal: true, isRequired: false, transformFunction: null }, headingIdPrefix: { classPropertyName: "headingIdPrefix", publicName: "headingIdPrefix", isSignal: true, isRequired: false, transformFunction: null }, copyLabel: { classPropertyName: "copyLabel", publicName: "copyLabel", isSignal: true, isRequired: false, transformFunction: null }, copiedLabel: { classPropertyName: "copiedLabel", publicName: "copiedLabel", isSignal: true, isRequired: false, transformFunction: null }, taskDoneLabel: { classPropertyName: "taskDoneLabel", publicName: "taskDoneLabel", isSignal: true, isRequired: false, transformFunction: null }, taskTodoLabel: { classPropertyName: "taskTodoLabel", publicName: "taskTodoLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-markdown--streaming": "streaming()" }, classAttribute: "wr-markdown" }, ngImport: i0, template: "<!--\n Recursion runs through `ngTemplateOutlet` into these templates rather than\n through a child component, so the rendered DOM is exactly the document \u2014 no\n wrapper element between a `<ul>` and its `<li>`. See `asBlocks` for the whole\n reasoning.\n-->\n<ng-template #inlineList let-raw>\n @let nodes = asInlines(raw);\n\n @for (node of nodes; track $index) {\n @switch (node.kind) {\n @case ('text') {\n <!-- Wrapped, and not for tidiness: a bare interpolation on its own line is\n ONE text node that includes the indentation around it, so `a **b** c`\n rendered with a space inside every `<strong>`. Inside an element the\n whitespace becomes separate whitespace-only nodes, which Angular\n removes, and `<ng-container>` itself renders nothing. Prettier\n reformats the bare form back, so this also has to survive `--fix`. -->\n <ng-container>{{ node.value }}</ng-container>\n }\n @case ('code') {\n <!-- `dir=\"ltr\"` because code is not prose: under RTL the browser\n reorders `foo();` to `;foo()`. -->\n <code class=\"wr-markdown__code-inline\" dir=\"ltr\">{{ node.value }}</code>\n }\n @case ('strong') {\n <strong class=\"wr-markdown__strong\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></strong>\n }\n @case ('em') {\n <em class=\"wr-markdown__em\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></em>\n }\n @case ('del') {\n <del class=\"wr-markdown__del\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></del>\n }\n @case ('link') {\n <a\n class=\"wr-markdown__link\"\n [href]=\"hrefOf(node.href)\"\n [attr.title]=\"node.title\"\n [attr.target]=\"resolvedLinkTarget()\"\n [attr.rel]=\"linkRel()\"\n ><ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: node.children }\"\n /></a>\n }\n @case ('image') {\n <img\n class=\"wr-markdown__image\"\n [src]=\"node.src\"\n [alt]=\"node.alt\"\n [attr.title]=\"node.title\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n }\n @case ('break') {\n <br />\n }\n }\n }\n</ng-template>\n\n<ng-template #itemList let-raw let-tight=\"tight\">\n @let items = asItems(raw);\n\n @for (item of items; track $index) {\n <li class=\"wr-markdown__item\" [class.wr-markdown__item--task]=\"item.checked !== null\">\n @if (item.checked !== null) {\n <!-- Presentational, with the state as text beside it: a real\n `<input type=\"checkbox\">` here would be an unlabelled form control,\n which is a serious axe violation, and making it operable would\n promise an interaction a renderer cannot honour. -->\n <span class=\"wr-markdown__task\" [class.wr-markdown__task--checked]=\"item.checked\" aria-hidden=\"true\"></span>\n <span class=\"wr-markdown__sr-only\">{{ item.checked ? resolvedTaskDoneLabel() : resolvedTaskTodoLabel() }}</span>\n }\n <ng-container\n [ngTemplateOutlet]=\"blockList\"\n [ngTemplateOutletContext]=\"{ $implicit: item.children, tight: tight }\"\n />\n </li>\n }\n</ng-template>\n\n<ng-template #blockList let-raw let-tight=\"tight\">\n @let list = asBlocks(raw);\n\n @for (block of list; track $index) {\n @switch (block.kind) {\n @case ('paragraph') {\n <!-- A tight list drops the `<p>`, which is what CommonMark specifies and\n what keeps a one-line list from being double-spaced. -->\n @if (tight) {\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n } @else {\n <p class=\"wr-markdown__paragraph\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </p>\n }\n }\n @case ('heading') {\n @switch (block.level) {\n @case (1) {\n <h1 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h1>\n }\n @case (2) {\n <h2 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h2>\n }\n @case (3) {\n <h3 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h3>\n }\n @case (4) {\n <h4 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h4>\n }\n @case (5) {\n <h5 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h5>\n }\n @default {\n <h6 class=\"wr-markdown__heading\" [attr.id]=\"idOf(block.id)\">\n <ng-container [ngTemplateOutlet]=\"inlineList\" [ngTemplateOutletContext]=\"{ $implicit: block.inlines }\" />\n </h6>\n }\n }\n }\n @case ('code') {\n @let highlighted = linesOf(block.code, block.language);\n\n <div class=\"wr-markdown__code-block\">\n <pre\n class=\"wr-markdown__pre\"\n dir=\"ltr\"\n tabindex=\"0\"\n ><code class=\"wr-markdown__code\" [attr.data-language]=\"block.language\">@if (highlighted) {@for (row of highlighted; track $index) {<span class=\"wr-markdown__line\">@for (span of row; track $index) {<span\n [style.color]=\"span.color\"\n [style.font-style]=\"span.fontStyle === 'italic' ? 'italic' : null\"\n [style.font-weight]=\"span.fontStyle === 'bold' ? 'bold' : null\"\n [style.text-decoration]=\"span.fontStyle === 'underline' ? 'underline' : null\"\n >{{ span.text }}</span>}</span>@if (!$last) {{{ newline }}}}} @else {{{ block.code }}}</code></pre>\n\n @if (resolvedCopyable() && block.closed) {\n <button\n type=\"button\"\n class=\"wr-markdown__copy\"\n [wrCopyToClipboard]=\"block.code\"\n [attr.aria-label]=\"isCopied(block) ? resolvedCopiedLabel() : resolvedCopyLabel()\"\n (copied)=\"onCopied(block)\"\n >\n <svg\n class=\"wr-markdown__copy-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @if (isCopied(block)) {\n <path d=\"M20 6 9 17l-5-5\" />\n } @else {\n <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n }\n </svg>\n </button>\n }\n </div>\n }\n @case ('quote') {\n <blockquote class=\"wr-markdown__quote\">\n <ng-container\n [ngTemplateOutlet]=\"blockList\"\n [ngTemplateOutletContext]=\"{ $implicit: block.children, tight: false }\"\n />\n </blockquote>\n }\n @case ('list') {\n @if (block.ordered) {\n <ol\n class=\"wr-markdown__list wr-markdown__list--ordered\"\n [attr.start]=\"block.start === 1 ? null : block.start\"\n >\n <ng-container\n [ngTemplateOutlet]=\"itemList\"\n [ngTemplateOutletContext]=\"{ $implicit: block.items, tight: block.tight }\"\n />\n </ol>\n } @else {\n <ul class=\"wr-markdown__list\">\n <ng-container\n [ngTemplateOutlet]=\"itemList\"\n [ngTemplateOutletContext]=\"{ $implicit: block.items, tight: block.tight }\"\n />\n </ul>\n }\n }\n @case ('table') {\n <!-- Its own scroller: a wide table must not push the page sideways, which\n is also what keeps the RTL layout gate quiet about it. -->\n <div class=\"wr-markdown__table-scroll\" tabindex=\"0\">\n <table class=\"wr-markdown__table\">\n <thead>\n <tr>\n @for (cell of block.head; track column; let column = $index) {\n <th class=\"wr-markdown__th\" scope=\"col\" [style.text-align]=\"block.align[column]\">\n <ng-container\n [ngTemplateOutlet]=\"inlineList\"\n [ngTemplateOutletContext]=\"{ $implicit: cell.inlines }\"\n />\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of block.rows; track $index) {\n <tr>\n @for (cell of asCells(row); track column; let column = $index) {\n <td class=\"wr-markdown__td\" [style.text-align]=\"block.align[column]\">\n <ng-container\n [ngTemplateOutlet]=\"inlineList\"\n [ngTemplateOutletContext]=\"{ $implicit: cell.inlines }\"\n />\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n @case ('rule') {\n <hr class=\"wr-markdown__rule\" />\n }\n }\n }\n</ng-template>\n\n<ng-container [ngTemplateOutlet]=\"blockList\" [ngTemplateOutletContext]=\"{ $implicit: blocks(), tight: false }\" />\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: WrCopyToClipboard, selector: "[wrCopyToClipboard]", inputs: ["wrCopyToClipboard"], outputs: ["copied", "copyFailed"] }], encapsulation: i0.ViewEncapsulation.None });
1544
1544
  }
1545
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMarkdown, decorators: [{
1545
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMarkdown, decorators: [{
1546
1546
  type: Component,
1547
1547
  args: [{ selector: 'wr-markdown', imports: [NgTemplateOutlet, WrCopyToClipboard], encapsulation: ViewEncapsulation.None, host: {
1548
1548
  class: 'wr-markdown',
@@ -211,10 +211,10 @@ class WrMarquee {
211
211
  raf = requestAnimationFrame(tick);
212
212
  this.destroyRef.onDestroy(() => cancelAnimationFrame(raf));
213
213
  }
214
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMarquee, deps: [], target: i0.ɵɵFactoryTarget.Component });
215
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: WrMarquee, isStandalone: true, selector: "wr-marquee", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, speed: { classPropertyName: "speed", publicName: "speed", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, pauseOnHover: { classPropertyName: "pauseOnHover", publicName: "pauseOnHover", isSignal: true, isRequired: false, transformFunction: null }, hoverSpeed: { classPropertyName: "hoverSpeed", publicName: "hoverSpeed", isSignal: true, isRequired: false, transformFunction: null }, fadeOut: { classPropertyName: "fadeOut", publicName: "fadeOut", isSignal: true, isRequired: false, transformFunction: null }, fadeOutColor: { classPropertyName: "fadeOutColor", publicName: "fadeOutColor", isSignal: true, isRequired: false, transformFunction: null }, scaleOnHover: { classPropertyName: "scaleOnHover", publicName: "scaleOnHover", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-marquee--fade": "fadeOut()", "class.wr-marquee--scale-hover": "scaleOnHover()", "style.--wr-marquee-gap.px": "gap()", "style.--wr-marquee-height.px": "itemHeight()", "style.--wr-marquee-fade-color": "fadeOutColor() || null", "attr.role": "\"region\"", "attr.aria-label": "resolvedAriaLabel()" }, classAttribute: "wr-marquee" }, viewQueries: [{ propertyName: "trackEl", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"wr-marquee__track\" #track (mouseenter)=\"onEnter()\" (mouseleave)=\"onLeave()\">\n @for (copyIndex of copyIndices(); track copyIndex) {\n <!--\n `inert` alongside `aria-hidden`, and never one without the other: the copies\n exist only to fill the track, and an item with an `href` renders a real anchor\n in every one of them. Hidden from the screen reader but still in the tab order,\n each duplicate is a tab stop that announces nothing \u2014 axe's `aria-hidden-focus`,\n and N stops on one destination for anyone using the keyboard.\n -->\n <ul\n class=\"wr-marquee__list\"\n role=\"list\"\n [attr.aria-hidden]=\"copyIndex > 0\"\n [attr.inert]=\"copyIndex > 0 ? '' : null\"\n [attr.data-copy]=\"copyIndex\"\n >\n @for (item of items(); track $index) {\n <li class=\"wr-marquee__item\" role=\"listitem\">\n @if (item.href) {\n <a\n class=\"wr-marquee__link\"\n [href]=\"item.href\"\n [attr.aria-label]=\"\n (isNodeItem(item) ? item.ariaLabel || item.title : item.alt || item.title) || resolvedLinkLabel()\n \"\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n <ng-container *ngTemplateOutlet=\"content; context: { $implicit: item }\" />\n </a>\n } @else {\n <ng-container *ngTemplateOutlet=\"content; context: { $implicit: item }\" />\n }\n </li>\n }\n </ul>\n }\n</div>\n\n<ng-template #content let-item>\n @if (isNodeItem(item)) {\n <span class=\"wr-marquee__node\" [attr.aria-hidden]=\"!!item.href && !item.ariaLabel\">\n <ng-container *ngTemplateOutlet=\"item.node\" />\n </span>\n } @else {\n <img\n [src]=\"item.src\"\n [srcset]=\"item.srcSet || null\"\n [sizes]=\"item.sizes || null\"\n [width]=\"item.width || null\"\n [height]=\"item.height || null\"\n [alt]=\"item.alt || ''\"\n [title]=\"item.title || null\"\n loading=\"lazy\"\n decoding=\"async\"\n draggable=\"false\"\n />\n }\n</ng-template>\n", styles: [".wr-marquee{--wr-marquee-gap: 32px;--wr-marquee-height: 28px;--wr-marquee-fade-color-auto: var(--wr-color-surface, #ffffff);position:relative;display:block;width:100%;overflow:hidden}.wr-marquee--scale-hover{padding-top:calc(var(--wr-marquee-height) * .1);padding-bottom:calc(var(--wr-marquee-height) * .1)}.wr-marquee__track{display:flex;width:max-content;will-change:transform;-webkit-user-select:none;user-select:none;position:relative;z-index:0}.wr-marquee__list{display:flex;align-items:center;margin:0;padding:0;list-style:none}.wr-marquee__item{flex:0 0 auto;margin-right:var(--wr-marquee-gap);font-size:var(--wr-marquee-height);line-height:1}.wr-marquee__item:last-child{margin-right:var(--wr-marquee-gap)}.wr-marquee__node{display:inline-flex;align-items:center}.wr-marquee__item img{height:var(--wr-marquee-height);width:auto;display:block;object-fit:contain;image-rendering:-webkit-optimize-contrast;-webkit-user-drag:none;pointer-events:none;transition:transform var(--wr-duration-slow) var(--wr-ease-out)}.wr-marquee--scale-hover .wr-marquee__item{overflow:visible}.wr-marquee--scale-hover .wr-marquee__item:hover img,.wr-marquee--scale-hover .wr-marquee__item:hover .wr-marquee__node{transform:scale(1.2);transform-origin:center center}.wr-marquee--scale-hover .wr-marquee__node{transition:transform var(--wr-duration-slow) var(--wr-ease-out)}.wr-marquee__link{display:inline-flex;align-items:center;text-decoration:none;border-radius:4px;transition:opacity .2s ease}.wr-marquee__link:hover{opacity:.8}.wr-marquee__link:focus-visible{outline:2px solid currentColor;outline-offset:2px}.wr-marquee--fade:before,.wr-marquee--fade:after{content:\"\";position:absolute;top:0;bottom:0;width:clamp(24px,8%,120px);pointer-events:none;z-index:10}.wr-marquee--fade:before{left:0;background:linear-gradient(to right,var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto)) 0%,rgba(0,0,0,0) 100%)}.wr-marquee--fade:after{right:0;background:linear-gradient(to left,var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto)) 0%,rgba(0,0,0,0) 100%)}@media(prefers-reduced-motion:reduce){.wr-marquee .wr-marquee__track{transform:translateZ(0)!important}.wr-marquee .wr-marquee__item img,.wr-marquee .wr-marquee__node{transition:none!important}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
214
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMarquee, deps: [], target: i0.ɵɵFactoryTarget.Component });
215
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrMarquee, isStandalone: true, selector: "wr-marquee", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, speed: { classPropertyName: "speed", publicName: "speed", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, pauseOnHover: { classPropertyName: "pauseOnHover", publicName: "pauseOnHover", isSignal: true, isRequired: false, transformFunction: null }, hoverSpeed: { classPropertyName: "hoverSpeed", publicName: "hoverSpeed", isSignal: true, isRequired: false, transformFunction: null }, fadeOut: { classPropertyName: "fadeOut", publicName: "fadeOut", isSignal: true, isRequired: false, transformFunction: null }, fadeOutColor: { classPropertyName: "fadeOutColor", publicName: "fadeOutColor", isSignal: true, isRequired: false, transformFunction: null }, scaleOnHover: { classPropertyName: "scaleOnHover", publicName: "scaleOnHover", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-marquee--fade": "fadeOut()", "class.wr-marquee--scale-hover": "scaleOnHover()", "style.--wr-marquee-gap.px": "gap()", "style.--wr-marquee-height.px": "itemHeight()", "style.--wr-marquee-fade-color": "fadeOutColor() || null", "attr.role": "\"region\"", "attr.aria-label": "resolvedAriaLabel()" }, classAttribute: "wr-marquee" }, viewQueries: [{ propertyName: "trackEl", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"wr-marquee__track\" #track (mouseenter)=\"onEnter()\" (mouseleave)=\"onLeave()\">\n @for (copyIndex of copyIndices(); track copyIndex) {\n <!--\n `inert` alongside `aria-hidden`, and never one without the other: the copies\n exist only to fill the track, and an item with an `href` renders a real anchor\n in every one of them. Hidden from the screen reader but still in the tab order,\n each duplicate is a tab stop that announces nothing \u2014 axe's `aria-hidden-focus`,\n and N stops on one destination for anyone using the keyboard.\n -->\n <ul\n class=\"wr-marquee__list\"\n role=\"list\"\n [attr.aria-hidden]=\"copyIndex > 0\"\n [attr.inert]=\"copyIndex > 0 ? '' : null\"\n [attr.data-copy]=\"copyIndex\"\n >\n @for (item of items(); track $index) {\n <li class=\"wr-marquee__item\" role=\"listitem\">\n @if (item.href) {\n <a\n class=\"wr-marquee__link\"\n [href]=\"item.href\"\n [attr.aria-label]=\"\n (isNodeItem(item) ? item.ariaLabel || item.title : item.alt || item.title) || resolvedLinkLabel()\n \"\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n <ng-container *ngTemplateOutlet=\"content; context: { $implicit: item }\" />\n </a>\n } @else {\n <ng-container *ngTemplateOutlet=\"content; context: { $implicit: item }\" />\n }\n </li>\n }\n </ul>\n }\n</div>\n\n<ng-template #content let-item>\n @if (isNodeItem(item)) {\n <span class=\"wr-marquee__node\" [attr.aria-hidden]=\"!!item.href && !item.ariaLabel\">\n <ng-container *ngTemplateOutlet=\"item.node\" />\n </span>\n } @else {\n <img\n [src]=\"item.src\"\n [srcset]=\"item.srcSet || null\"\n [sizes]=\"item.sizes || null\"\n [width]=\"item.width || null\"\n [height]=\"item.height || null\"\n [alt]=\"item.alt || ''\"\n [title]=\"item.title || null\"\n loading=\"lazy\"\n decoding=\"async\"\n draggable=\"false\"\n />\n }\n</ng-template>\n", styles: [".wr-marquee{--wr-marquee-gap: 32px;--wr-marquee-height: 28px;--wr-marquee-fade-color-auto: var(--wr-color-surface, #ffffff);position:relative;display:block;width:100%;overflow:hidden}.wr-marquee--scale-hover{padding-top:calc(var(--wr-marquee-height) * .1);padding-bottom:calc(var(--wr-marquee-height) * .1)}.wr-marquee__track{display:flex;width:max-content;will-change:transform;-webkit-user-select:none;user-select:none;position:relative;z-index:0}.wr-marquee__list{display:flex;align-items:center;margin:0;padding:0;list-style:none}.wr-marquee__item{flex:0 0 auto;margin-right:var(--wr-marquee-gap);font-size:var(--wr-marquee-height);line-height:1}.wr-marquee__item:last-child{margin-right:var(--wr-marquee-gap)}.wr-marquee__node{display:inline-flex;align-items:center}.wr-marquee__item img{height:var(--wr-marquee-height);width:auto;display:block;object-fit:contain;image-rendering:-webkit-optimize-contrast;-webkit-user-drag:none;pointer-events:none;transition:transform var(--wr-duration-slow) var(--wr-ease-out)}.wr-marquee--scale-hover .wr-marquee__item{overflow:visible}.wr-marquee--scale-hover .wr-marquee__item:hover img,.wr-marquee--scale-hover .wr-marquee__item:hover .wr-marquee__node{transform:scale(1.2);transform-origin:center center}.wr-marquee--scale-hover .wr-marquee__node{transition:transform var(--wr-duration-slow) var(--wr-ease-out)}.wr-marquee__link{display:inline-flex;align-items:center;text-decoration:none;border-radius:4px;transition:opacity .2s ease}.wr-marquee__link:hover{opacity:.8}.wr-marquee__link:focus-visible{outline:2px solid currentColor;outline-offset:2px}.wr-marquee--fade:before,.wr-marquee--fade:after{content:\"\";position:absolute;top:0;bottom:0;width:clamp(24px,8%,120px);pointer-events:none;z-index:10}.wr-marquee--fade:before{left:0;background:linear-gradient(to right,var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto)) 0%,rgba(0,0,0,0) 100%)}.wr-marquee--fade:after{right:0;background:linear-gradient(to left,var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto)) 0%,rgba(0,0,0,0) 100%)}@media(prefers-reduced-motion:reduce){.wr-marquee .wr-marquee__track{transform:translateZ(0)!important}.wr-marquee .wr-marquee__item img,.wr-marquee .wr-marquee__node{transition:none!important}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
216
216
  }
217
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMarquee, decorators: [{
217
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMarquee, decorators: [{
218
218
  type: Component,
219
219
  args: [{ selector: 'wr-marquee', encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet], host: {
220
220
  class: 'wr-marquee',
@@ -97,10 +97,10 @@ class WrMedia {
97
97
  this.destroyRef.onDestroy(() => mql.removeEventListener('change', handler));
98
98
  return sig.asReadonly();
99
99
  }
100
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMedia, deps: [], target: i0.ɵɵFactoryTarget.Service });
101
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.4", ngImport: i0, type: WrMedia });
100
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMedia, deps: [], target: i0.ɵɵFactoryTarget.Service });
101
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrMedia });
102
102
  }
103
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrMedia, decorators: [{
103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMedia, decorators: [{
104
104
  type: Service
105
105
  }] });
106
106