ngwr 14.3.0 → 14.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/README.md +1 -1
  2. package/avatar/styles/_index.scss +4 -2
  3. package/badge/styles/_index.scss +4 -1
  4. package/badge/styles/_tag.scss +3 -0
  5. package/cascader/styles/_rules.scss +3 -0
  6. package/command-palette/styles/_index.scss +23 -0
  7. package/context-menu/styles/_index.scss +13 -1
  8. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  9. package/fesm2022/ngwr-affix.mjs +17 -4
  10. package/fesm2022/ngwr-affix.mjs.map +1 -1
  11. package/fesm2022/ngwr-alert.mjs +4 -4
  12. package/fesm2022/ngwr-alert.mjs.map +1 -1
  13. package/fesm2022/ngwr-anchor.mjs +3 -3
  14. package/fesm2022/ngwr-aurora.mjs +3 -3
  15. package/fesm2022/ngwr-avatar.mjs +3 -3
  16. package/fesm2022/ngwr-back-top.mjs +3 -3
  17. package/fesm2022/ngwr-badge.mjs +6 -6
  18. package/fesm2022/ngwr-bar-chart-testing.mjs +18 -2
  19. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
  20. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  21. package/fesm2022/ngwr-blur-text.mjs +3 -3
  22. package/fesm2022/ngwr-border-glow.mjs +3 -3
  23. package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
  24. package/fesm2022/ngwr-burger.mjs +3 -3
  25. package/fesm2022/ngwr-button.mjs +6 -6
  26. package/fesm2022/ngwr-calendar-heatmap-testing.mjs +12 -9
  27. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
  28. package/fesm2022/ngwr-calendar-heatmap.mjs +35 -7
  29. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  30. package/fesm2022/ngwr-calendar.mjs +32 -4
  31. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  32. package/fesm2022/ngwr-card.mjs +9 -9
  33. package/fesm2022/ngwr-carousel.mjs +6 -6
  34. package/fesm2022/ngwr-cascader-testing.mjs +87 -17
  35. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
  36. package/fesm2022/ngwr-cascader.mjs +63 -4
  37. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  38. package/fesm2022/ngwr-checkbox-testing.mjs +13 -2
  39. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
  40. package/fesm2022/ngwr-checkbox.mjs +42 -7
  41. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  42. package/fesm2022/ngwr-circular-text.mjs +3 -3
  43. package/fesm2022/ngwr-click-spark.mjs +3 -3
  44. package/fesm2022/ngwr-clipboard.mjs +3 -3
  45. package/fesm2022/ngwr-collapse.mjs +9 -9
  46. package/fesm2022/ngwr-color-picker.mjs +6 -6
  47. package/fesm2022/ngwr-command-palette.mjs +16 -3
  48. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  49. package/fesm2022/ngwr-compare.mjs +3 -3
  50. package/fesm2022/ngwr-confetti.mjs +3 -3
  51. package/fesm2022/ngwr-context-menu.mjs +12 -12
  52. package/fesm2022/ngwr-cookie.mjs +3 -3
  53. package/fesm2022/ngwr-counter.mjs +6 -6
  54. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  55. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  56. package/fesm2022/ngwr-date-picker.mjs +81 -26
  57. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  58. package/fesm2022/ngwr-date.mjs +3 -3
  59. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  60. package/fesm2022/ngwr-density.mjs +6 -6
  61. package/fesm2022/ngwr-descriptions.mjs +6 -6
  62. package/fesm2022/ngwr-dialog.mjs +15 -15
  63. package/fesm2022/ngwr-directives.mjs +12 -12
  64. package/fesm2022/ngwr-divider.mjs +3 -3
  65. package/fesm2022/ngwr-donut-chart-testing.mjs +18 -2
  66. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  67. package/fesm2022/ngwr-donut-chart.mjs +4 -4
  68. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  69. package/fesm2022/ngwr-drag-drop.mjs +6 -6
  70. package/fesm2022/ngwr-drawer.mjs +18 -18
  71. package/fesm2022/ngwr-dropdown.mjs +32 -14
  72. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  73. package/fesm2022/ngwr-empty.mjs +3 -3
  74. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  75. package/fesm2022/ngwr-falling-text.mjs +3 -3
  76. package/fesm2022/ngwr-file-upload.mjs +18 -5
  77. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  78. package/fesm2022/ngwr-form.mjs +66 -14
  79. package/fesm2022/ngwr-form.mjs.map +1 -1
  80. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  81. package/fesm2022/ngwr-gauge-testing.mjs +16 -2
  82. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
  83. package/fesm2022/ngwr-gauge.mjs +3 -3
  84. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  85. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  86. package/fesm2022/ngwr-hotkey.mjs +6 -6
  87. package/fesm2022/ngwr-i18n-ar.mjs +2 -0
  88. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  89. package/fesm2022/ngwr-i18n-cs.mjs +2 -0
  90. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  91. package/fesm2022/ngwr-i18n-de.mjs +2 -0
  92. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  93. package/fesm2022/ngwr-i18n-en.mjs +14 -2
  94. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  95. package/fesm2022/ngwr-i18n-es.mjs +2 -0
  96. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  97. package/fesm2022/ngwr-i18n-fr.mjs +2 -0
  98. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  99. package/fesm2022/ngwr-i18n-he.mjs +2 -0
  100. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  101. package/fesm2022/ngwr-i18n-hi.mjs +2 -0
  102. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  103. package/fesm2022/ngwr-i18n-id.mjs +2 -0
  104. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  105. package/fesm2022/ngwr-i18n-it.mjs +2 -0
  106. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  107. package/fesm2022/ngwr-i18n-ja.mjs +2 -0
  108. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  109. package/fesm2022/ngwr-i18n-ko.mjs +2 -0
  110. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  111. package/fesm2022/ngwr-i18n-nl.mjs +2 -0
  112. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  113. package/fesm2022/ngwr-i18n-pl.mjs +2 -0
  114. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  115. package/fesm2022/ngwr-i18n-pt.mjs +2 -0
  116. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  117. package/fesm2022/ngwr-i18n-ru.mjs +2 -0
  118. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  119. package/fesm2022/ngwr-i18n-sv.mjs +2 -0
  120. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  121. package/fesm2022/ngwr-i18n-tr.mjs +2 -0
  122. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  123. package/fesm2022/ngwr-i18n-uk.mjs +2 -0
  124. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  125. package/fesm2022/ngwr-i18n-vi.mjs +2 -0
  126. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  127. package/fesm2022/ngwr-i18n-zh-TW.mjs +2 -0
  128. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  129. package/fesm2022/ngwr-i18n-zh.mjs +2 -0
  130. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  131. package/fesm2022/ngwr-i18n.mjs +9 -9
  132. package/fesm2022/ngwr-icon.mjs +6 -6
  133. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  134. package/fesm2022/ngwr-input-number.mjs +15 -6
  135. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  136. package/fesm2022/ngwr-input-otp.mjs +38 -6
  137. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  138. package/fesm2022/ngwr-input.mjs +15 -15
  139. package/fesm2022/ngwr-keyboard.mjs +3 -3
  140. package/fesm2022/ngwr-knob-testing.mjs +11 -3
  141. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  142. package/fesm2022/ngwr-knob.mjs +19 -4
  143. package/fesm2022/ngwr-knob.mjs.map +1 -1
  144. package/fesm2022/ngwr-layout.mjs +15 -15
  145. package/fesm2022/ngwr-lightbox.mjs +3 -3
  146. package/fesm2022/ngwr-line-chart-testing.mjs +18 -2
  147. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
  148. package/fesm2022/ngwr-line-chart.mjs +22 -4
  149. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  150. package/fesm2022/ngwr-list.mjs +6 -6
  151. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  152. package/fesm2022/ngwr-markdown.mjs +6 -6
  153. package/fesm2022/ngwr-marquee.mjs +3 -3
  154. package/fesm2022/ngwr-media.mjs +3 -3
  155. package/fesm2022/ngwr-mention.mjs +6 -6
  156. package/fesm2022/ngwr-meta.mjs +6 -6
  157. package/fesm2022/ngwr-meter-group.mjs +3 -3
  158. package/fesm2022/ngwr-overlay.mjs +6 -6
  159. package/fesm2022/ngwr-page-header.mjs +3 -3
  160. package/fesm2022/ngwr-pagination.mjs +33 -6
  161. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  162. package/fesm2022/ngwr-pipes.mjs +21 -21
  163. package/fesm2022/ngwr-platform.mjs +9 -9
  164. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  165. package/fesm2022/ngwr-popover.mjs +29 -11
  166. package/fesm2022/ngwr-popover.mjs.map +1 -1
  167. package/fesm2022/ngwr-progress.mjs +3 -3
  168. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  169. package/fesm2022/ngwr-qr.mjs +3 -3
  170. package/fesm2022/ngwr-radio.mjs +6 -6
  171. package/fesm2022/ngwr-rating-testing.mjs +12 -3
  172. package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
  173. package/fesm2022/ngwr-rating.mjs +19 -4
  174. package/fesm2022/ngwr-rating.mjs.map +1 -1
  175. package/fesm2022/ngwr-result.mjs +13 -13
  176. package/fesm2022/ngwr-result.mjs.map +1 -1
  177. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  178. package/fesm2022/ngwr-schema-form.mjs +40 -4
  179. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  180. package/fesm2022/ngwr-scroll.mjs +3 -3
  181. package/fesm2022/ngwr-segmented.mjs +3 -3
  182. package/fesm2022/ngwr-select.mjs +9 -9
  183. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  184. package/fesm2022/ngwr-sidebar.mjs +3 -3
  185. package/fesm2022/ngwr-skeleton.mjs +3 -3
  186. package/fesm2022/ngwr-slider.mjs +18 -5
  187. package/fesm2022/ngwr-slider.mjs.map +1 -1
  188. package/fesm2022/ngwr-sparkline.mjs +3 -3
  189. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  190. package/fesm2022/ngwr-spinner.mjs +3 -3
  191. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  192. package/fesm2022/ngwr-split-text.mjs +3 -3
  193. package/fesm2022/ngwr-splitter.mjs +3 -3
  194. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  195. package/fesm2022/ngwr-squircle.mjs +28 -9
  196. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  197. package/fesm2022/ngwr-star-border.mjs +3 -3
  198. package/fesm2022/ngwr-statistic.mjs +20 -13
  199. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  200. package/fesm2022/ngwr-stepper.mjs +6 -6
  201. package/fesm2022/ngwr-storage.mjs +3 -3
  202. package/fesm2022/ngwr-switch.mjs +3 -3
  203. package/fesm2022/ngwr-table.mjs +18 -18
  204. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  205. package/fesm2022/ngwr-tabs.mjs +6 -6
  206. package/fesm2022/ngwr-textarea.mjs +3 -3
  207. package/fesm2022/ngwr-theme.mjs +3 -3
  208. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  209. package/fesm2022/ngwr-timeline.mjs +6 -6
  210. package/fesm2022/ngwr-toast.mjs +10 -10
  211. package/fesm2022/ngwr-toast.mjs.map +1 -1
  212. package/fesm2022/ngwr-toolbar.mjs +3 -3
  213. package/fesm2022/ngwr-tour.mjs +6 -6
  214. package/fesm2022/ngwr-transfer.mjs +88 -11
  215. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  216. package/fesm2022/ngwr-tree-testing.mjs +24 -0
  217. package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
  218. package/fesm2022/ngwr-tree.mjs +72 -7
  219. package/fesm2022/ngwr-tree.mjs.map +1 -1
  220. package/fesm2022/ngwr-typewriter.mjs +3 -3
  221. package/fesm2022/ngwr-typography.mjs +3 -3
  222. package/fesm2022/ngwr-version.mjs +1 -1
  223. package/fesm2022/ngwr-version.mjs.map +1 -1
  224. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  225. package/fesm2022/ngwr-waves.mjs +3 -3
  226. package/fesm2022/ngwr-window.mjs +12 -12
  227. package/form/styles/_index.scss +63 -0
  228. package/i18n/ar.json +4 -2
  229. package/i18n/cs.json +4 -2
  230. package/i18n/de.json +4 -2
  231. package/i18n/en.json +6 -4
  232. package/i18n/es.json +4 -2
  233. package/i18n/fr.json +4 -2
  234. package/i18n/he.json +4 -2
  235. package/i18n/hi.json +4 -2
  236. package/i18n/id.json +4 -2
  237. package/i18n/it.json +4 -2
  238. package/i18n/ja.json +4 -2
  239. package/i18n/ko.json +4 -2
  240. package/i18n/nl.json +4 -2
  241. package/i18n/pl.json +4 -2
  242. package/i18n/pt.json +4 -2
  243. package/i18n/ru.json +4 -2
  244. package/i18n/sv.json +4 -2
  245. package/i18n/tr.json +4 -2
  246. package/i18n/uk.json +4 -2
  247. package/i18n/vi.json +4 -2
  248. package/i18n/zh-TW.json +4 -2
  249. package/i18n/zh.json +4 -2
  250. package/input-otp/styles/_index.scss +5 -1
  251. package/line-chart/styles/_index.scss +5 -3
  252. package/llms-full.txt +1 -1
  253. package/markdown/styles/_index.scss +4 -1
  254. package/mention/styles/_index.scss +22 -1
  255. package/package.json +1 -1
  256. package/radio/styles/_index.scss +3 -0
  257. package/result/styles/_index.scss +12 -0
  258. package/schematics/migrations/v14/index.js +6 -3
  259. package/schematics/migrations.json +1 -1
  260. package/schematics/ng-add/index.js +34 -5
  261. package/segmented/styles/_index.scss +4 -1
  262. package/select/styles/_index.scss +20 -1
  263. package/statistic/styles/_index.scss +4 -0
  264. package/stepper/styles/_index.scss +36 -0
  265. package/switch/styles/_index.scss +3 -0
  266. package/table/styles/_index.scss +12 -0
  267. package/tabs/styles/_index.scss +4 -1
  268. package/textarea/styles/_index.scss +6 -1
  269. package/theme/styles/_colors.scss +11 -0
  270. package/theme/styles/_contrast.scss +136 -0
  271. package/theme/styles/_index.scss +1 -0
  272. package/theme/styles/_mixins.scss +15 -8
  273. package/timeline/styles/_index.scss +28 -1
  274. package/toast/styles/_index.scss +11 -0
  275. package/tree/styles/_index.scss +27 -1
  276. package/types/ngwr-badge.d.ts +1 -1
  277. package/types/ngwr-bar-chart-testing.d.ts +11 -1
  278. package/types/ngwr-button.d.ts +1 -1
  279. package/types/ngwr-calendar-heatmap-testing.d.ts +10 -5
  280. package/types/ngwr-calendar-heatmap.d.ts +22 -0
  281. package/types/ngwr-calendar.d.ts +21 -0
  282. package/types/ngwr-cascader-testing.d.ts +74 -17
  283. package/types/ngwr-cascader.d.ts +28 -0
  284. package/types/ngwr-checkbox-testing.d.ts +12 -1
  285. package/types/ngwr-checkbox.d.ts +10 -0
  286. package/types/ngwr-clipboard.d.ts +1 -1
  287. package/types/ngwr-confetti.d.ts +1 -1
  288. package/types/ngwr-cookie.d.ts +1 -1
  289. package/types/ngwr-date-adapters-fns.d.ts +1 -1
  290. package/types/ngwr-date-adapters-luxon.d.ts +1 -1
  291. package/types/ngwr-date.d.ts +9 -3
  292. package/types/ngwr-density.d.ts +1 -1
  293. package/types/ngwr-dialog.d.ts +1 -1
  294. package/types/ngwr-donut-chart-testing.d.ts +11 -1
  295. package/types/ngwr-drawer.d.ts +1 -1
  296. package/types/ngwr-dropdown.d.ts +16 -0
  297. package/types/ngwr-file-upload.d.ts +11 -0
  298. package/types/ngwr-form.d.ts +25 -0
  299. package/types/ngwr-gauge-testing.d.ts +9 -1
  300. package/types/ngwr-hotkey.d.ts +1 -1
  301. package/types/ngwr-i18n.d.ts +1 -1
  302. package/types/ngwr-input-number.d.ts +12 -2
  303. package/types/ngwr-input-otp.d.ts +12 -0
  304. package/types/ngwr-knob-testing.d.ts +11 -3
  305. package/types/ngwr-knob.d.ts +13 -0
  306. package/types/ngwr-line-chart-testing.d.ts +11 -1
  307. package/types/ngwr-line-chart.d.ts +18 -0
  308. package/types/ngwr-loading-bar.d.ts +1 -1
  309. package/types/ngwr-markdown.d.ts +1 -1
  310. package/types/ngwr-media.d.ts +1 -1
  311. package/types/ngwr-meta.d.ts +1 -1
  312. package/types/ngwr-overlay.d.ts +2 -2
  313. package/types/ngwr-pagination.d.ts +16 -0
  314. package/types/ngwr-platform.d.ts +3 -3
  315. package/types/ngwr-popover.d.ts +16 -0
  316. package/types/ngwr-rating-testing.d.ts +12 -3
  317. package/types/ngwr-rating.d.ts +13 -0
  318. package/types/ngwr-scroll.d.ts +1 -1
  319. package/types/ngwr-squircle.d.ts +22 -3
  320. package/types/ngwr-statistic.d.ts +0 -1
  321. package/types/ngwr-storage.d.ts +1 -1
  322. package/types/ngwr-theme.d.ts +1 -1
  323. package/types/ngwr-toast.d.ts +1 -1
  324. package/types/ngwr-tour.d.ts +1 -1
  325. package/types/ngwr-transfer.d.ts +52 -0
  326. package/types/ngwr-tree-testing.d.ts +20 -0
  327. package/types/ngwr-tree.d.ts +41 -0
  328. package/types/ngwr-version.d.ts +1 -1
  329. package/types/ngwr-window.d.ts +1 -1
  330. package/typography/styles/_index.scss +26 -4
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-rating.mjs","sources":["../../../projects/lib/rating/rating.ts","../../../projects/lib/rating/rating.html","../../../projects/lib/rating/ngwr-rating.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, inject, input, model, output, signal } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { useFormFieldAria } from 'ngwr/form';\nimport { useI18nText } from 'ngwr/i18n';\nimport { clamp } from 'ngwr/utils';\n\n/**\n * Star rating input. Click or hover to set a value; supports half-star\n * increments via `step=\"0.5\"`. Value is `number | null`.\n *\n * `[0, count]` bounds what this control's OWN edits produce — a click, an arrow\n * key, `End`. A value written from outside is displayed and announced clamped\n * (a slider cannot report an `aria-valuenow` past its own `aria-valuemax`) and\n * left in the model as it stands, the same rule `wr-slider` and\n * `wr-input-number` follow.\n *\n * A signal-forms native control: it implements `FormValueControl<number | null>`,\n * so `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone.\n *\n * Keyboard: `←` / `→` bump by `step`, `Home` / `End` jump to 0 / max.\n * Clicking the current value clears it (toggle off).\n *\n * The stars sit on the inline axis, so under `dir=\"rtl\"` the row is mirrored and\n * both halves of the input mirror with it: `→` walks toward the low end, and a\n * click is measured from the star's inline-start (right) edge.\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-rating [formField]=\"form.score\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-rating [(value)]=\"score\" [count]=\"10\" step=\"0.5\" />\n * <wr-rating [value]=\"4.5\" [readonly]=\"true\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/rating\n */\nexport type WrRatingSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-rating',\n templateUrl: './rating.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrRating implements FormValueControl<number | null> {\n /** Total number of slots. @default 5 */\n readonly count = input(5, { transform: (v: unknown): number => Math.max(1, coerceNumberProperty(v, 5)) });\n\n /** Step granularity — `1` for whole stars, `0.5` for halves. @default 1 */\n readonly step = input(1 as 0.5 | 1, {\n transform: (v: unknown): 0.5 | 1 => (Number(v) === 0.5 ? 0.5 : 1),\n });\n\n /** Read-only — value is displayed but not interactive. @default false */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Disable interaction. Bound automatically from the field's disabled state\n * when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Control size — scales the icons + gaps. @default 'md' */\n readonly size = input<WrRatingSize>('md');\n\n /** Accessible label. Falls back to `rating.label`, then `'Rating'`. */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'rating.label', 'Rating');\n\n /** The rating. Bound by `[formField]`, or two-way via `[(value)]`. */\n readonly value = model<number | null>(null);\n\n /** Emitted on blur so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /** Transient hover preview — overrides `value` for display when set. */\n protected readonly hoverValue = signal<number | null>(null);\n\n protected readonly interactive = computed(() => !this.disabled() && !this.readonly());\n\n /**\n * Whether the control keeps its tab stop — `disabled` only, never `readonly`.\n *\n * The two states differ precisely here: a disabled control leaves the tab\n * order, a read-only one stays in it and keeps announcing `aria-valuenow`,\n * because a keyboard user still has to be able to READ a value they cannot\n * change. Driving `tabindex` off `interactive()` collapsed that distinction\n * and made `readonly()` unreachable — with an `aria-describedby` pointing at\n * an error message on an element nobody could focus.\n */\n protected readonly focusable = computed(() => !this.disabled());\n\n /**\n * What we actually render — hover wins while hovering.\n *\n * Clamped, because there is no such thing as drawing six stars in a row of\n * five, and the same number is what `aria-valuenow` reports: a `role=\"slider\"`\n * whose value sits outside its own min / max is an invalid slider whatever the\n * model holds. The MODEL is left alone — see the note above `fillFor` for why\n * the clamp is not written back.\n */\n protected readonly displayValue = computed(() => clamp(this.hoverValue() ?? this.value() ?? 0, 0, this.count()));\n\n /**\n * What the slider REPORTS, and where the arrows start from.\n *\n * Deliberately not `displayValue`: a hover preview is a pointer affordance and\n * must not be announced as the current value, and an arrow press after a hover\n * has to step from the committed number rather than from wherever the mouse\n * happened to rest.\n */\n protected readonly announcedValue = computed(() => clamp(this.value() ?? 0, 0, this.count()));\n\n protected readonly slots = computed(() => Array.from({ length: this.count() }, (_, i) => i));\n\n /**\n * Reading direction, for the two places it changes the answer: the arrows and\n * the pointer ratio inside a star.\n *\n * `optional` because a consumer who never set a direction should not have to\n * provide anything — `Directionality` is root-provided, so this only resolves\n * to `null` in a bare `TestBed`, where LTR is the right assumption. Read per\n * interaction rather than cached, so a runtime flip needs no subscription.\n */\n private readonly directionality = inject(Directionality, { optional: true });\n\n /** The surrounding `<wr-form-field>`'s error state. @internal */\n protected readonly fieldAria = useFormFieldAria();\n\n protected readonly classes = computed(() => {\n const parts = ['wr-rating'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-rating--${size}`);\n if (this.readonly()) parts.push('wr-rating--readonly');\n if (this.disabled()) parts.push('wr-rating--disabled');\n return parts.join(' ');\n });\n\n /*\n * There is deliberately no effect re-clamping `value` into `[0, count]`.\n *\n * There was one — it wrote the clamp back into the model, which the old CVA\n * `writeValue` also did — and under `[formField]` that write is\n * indistinguishable from the user moving the stars: a `FormControl(9)` on a\n * five-star rating became `5`, `dirty`, and emitted through `valueChanges`\n * before anything had been touched. So an unsaved-changes guard fired on a\n * form nobody had edited, and the out-of-range value that a `max()` rule\n * exists to REPORT was deleted by the control it was reported on (binding\n * `[count]` beside `[formField]` cannot help — the schema's rules are the only\n * bounds that reach here).\n *\n * `wr-slider` and `wr-input-number` had both already settled this the other\n * way, for the same two reasons, and this one was the odd control out.\n * `displayValue` clamps what is drawn and announced; `computeValue` and\n * `onKeydown` clamp what this control itself produces; the model is the\n * consumer's until they touch a star.\n */\n /** Fill ratio for slot `i` in `[0, 1]` — drives the CSS clip width. */\n protected fillFor(i: number): number {\n return clamp(this.displayValue() - i, 0, 1);\n }\n\n // Template handlers\n\n protected onSlotMove(event: MouseEvent, index: number): void {\n if (!this.interactive()) return;\n this.hoverValue.set(this.computeValue(event, index));\n }\n\n protected onLeave(): void {\n this.hoverValue.set(null);\n }\n\n protected onSlotClick(event: MouseEvent, index: number): void {\n if (!this.interactive()) return;\n const next = this.computeValue(event, index);\n // Click the current value → clear it.\n const final = next === this.value() ? null : next;\n this.commit(final);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (!this.interactive()) return;\n const max = this.count();\n const step = this.step();\n // The clamped reading, so an arrow after an out-of-range external write\n // steps from the star the user can see rather than from a number off the row.\n const current = this.announcedValue();\n // Arrows follow VISUAL order (WAI-ARIA APG). The row lays its stars along the\n // inline axis, so under `dir=\"rtl\"` the first star is the RIGHTMOST one and\n // `→` walks down the scale. Up / Down are the block axis and never flip;\n // Home / End mean first / last, a semantic position rather than a physical\n // one, so they don't either.\n const inline = this.isRtl() ? -step : step;\n let next: number | null;\n switch (event.key) {\n case 'ArrowRight':\n next = clamp(current + inline, 0, max);\n break;\n case 'ArrowUp':\n next = clamp(current + step, 0, max);\n break;\n case 'ArrowLeft':\n next = clamp(current - inline, 0, max);\n break;\n case 'ArrowDown':\n next = clamp(current - step, 0, max);\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = max;\n break;\n case 'Delete':\n case 'Backspace':\n next = null;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.commit(next);\n }\n\n protected onBlur(): void {\n this.touch.emit();\n }\n\n // Internals\n\n /** Whether the row reads right-to-left. */\n private isRtl(): boolean {\n return this.directionality?.value === 'rtl';\n }\n\n /**\n * How far into the star the pointer sits, `0` to `1`, measured from its\n * INLINE-start edge — the left one in LTR, the right one in RTL, where the row\n * is mirrored. Taken from `rect.left` alone it reads 1 exactly where an RTL\n * user sees the start of the star, which inverts every half step.\n */\n private inlineRatio(clientX: number, rect: DOMRect): number {\n const offset = this.isRtl() ? rect.right - clientX : clientX - rect.left;\n return clamp(offset / rect.width, 0, 1);\n }\n\n /** Convert a mouse position over slot `index` to a snapped value. */\n private computeValue(event: MouseEvent, index: number): number {\n const target = event.currentTarget as HTMLElement;\n const rect = target.getBoundingClientRect();\n const ratio = this.inlineRatio(event.clientX, rect);\n const raw = index + ratio;\n const step = this.step();\n const snapped = Math.ceil(raw / step) * step;\n return clamp(snapped, step, this.count());\n }\n\n private commit(value: number | null): void {\n this.value.set(value);\n this.hoverValue.set(null);\n }\n}\n","<div\n class=\"wr-rating__row\"\n role=\"slider\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"count()\"\n [attr.aria-valuenow]=\"announcedValue()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"focusable() ? 0 : -1\"\n (keydown)=\"onKeydown($event)\"\n (mouseleave)=\"onLeave()\"\n (blur)=\"onBlur()\"\n>\n @for (slot of slots(); track $index) {\n <!-- The parent row owns keyboard focus + handlers; slots are pointer-only\n click targets, so the a11y rules below are intentionally suppressed. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <span\n class=\"wr-rating__slot\"\n [class.wr-rating__slot--interactive]=\"interactive()\"\n [style.--wr-rating-fill]=\"fillFor($index)\"\n (mousemove)=\"onSlotMove($event, $index)\"\n (click)=\"onSlotClick($event, $index)\"\n >\n <!-- Outline (always visible) -->\n <svg class=\"wr-rating__icon wr-rating__icon--bg\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n d=\"M12 2.5l2.95 5.98 6.6.96-4.78 4.66 1.13 6.58L12 17.6l-5.9 3.08 1.13-6.58L2.45 9.44l6.6-.96L12 2.5z\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <!-- Filled overlay, clipped by --wr-rating-fill (0..1) -->\n <svg class=\"wr-rating__icon wr-rating__icon--fg\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n d=\"M12 2.5l2.95 5.98 6.6.96-4.78 4.66 1.13 6.58L12 17.6l-5.9 3.08 1.13-6.58L2.45 9.44l6.6-.96L12 2.5z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n }\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-rating.mjs","sources":["../../../projects/lib/rating/rating.ts","../../../projects/lib/rating/rating.html","../../../projects/lib/rating/ngwr-rating.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, inject, input, model, output, signal } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { useFormFieldAria } from 'ngwr/form';\nimport { useI18nText } from 'ngwr/i18n';\nimport { clamp } from 'ngwr/utils';\n\n/**\n * Star rating input. Click or hover to set a value; supports half-star\n * increments via `step=\"0.5\"`. Value is `number | null`.\n *\n * `[0, count]` bounds what this control's OWN edits produce — a click, an arrow\n * key, `End`. A value written from outside is displayed and announced clamped\n * (a slider cannot report an `aria-valuenow` past its own `aria-valuemax`) and\n * left in the model as it stands, the same rule `wr-slider` and\n * `wr-input-number` follow.\n *\n * A signal-forms native control: it implements `FormValueControl<number | null>`,\n * so `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone.\n *\n * Keyboard: `←` / `→` bump by `step`, `Home` / `End` jump to 0 / max.\n * Clicking the current value clears it (toggle off).\n *\n * The stars sit on the inline axis, so under `dir=\"rtl\"` the row is mirrored and\n * both halves of the input mirror with it: `→` walks toward the low end, and a\n * click is measured from the star's inline-start (right) edge.\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-rating [formField]=\"form.score\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-rating [(value)]=\"score\" [count]=\"10\" step=\"0.5\" />\n * <wr-rating [value]=\"4.5\" [readonly]=\"true\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/rating\n */\nexport type WrRatingSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-rating',\n templateUrl: './rating.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrRating implements FormValueControl<number | null> {\n /** Total number of slots. @default 5 */\n readonly count = input(5, { transform: (v: unknown): number => Math.max(1, coerceNumberProperty(v, 5)) });\n\n /** Step granularity — `1` for whole stars, `0.5` for halves. @default 1 */\n readonly step = input(1 as 0.5 | 1, {\n transform: (v: unknown): 0.5 | 1 => (Number(v) === 0.5 ? 0.5 : 1),\n });\n\n /** Read-only — value is displayed but not interactive. @default false */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Disable interaction. Bound automatically from the field's disabled state\n * when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /** Control size — scales the icons + gaps. @default 'md' */\n readonly size = input<WrRatingSize>('md');\n\n /** Accessible label. Falls back to `rating.label`, then `'Rating'`. */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'rating.label', 'Rating');\n\n /** The rating. Bound by `[formField]`, or two-way via `[(value)]`. */\n readonly value = model<number | null>(null);\n\n /** Emitted on blur so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /** Transient hover preview — overrides `value` for display when set. */\n protected readonly hoverValue = signal<number | null>(null);\n\n protected readonly interactive = computed(() => !this.disabled() && !this.readonly());\n\n /**\n * Whether the control keeps its tab stop — `disabled` only, never `readonly`.\n *\n * The two states differ precisely here: a disabled control leaves the tab\n * order, a read-only one stays in it and keeps announcing `aria-valuenow`,\n * because a keyboard user still has to be able to READ a value they cannot\n * change. Driving `tabindex` off `interactive()` collapsed that distinction\n * and made `readonly()` unreachable — with an `aria-describedby` pointing at\n * an error message on an element nobody could focus.\n */\n protected readonly focusable = computed(() => !this.disabled());\n\n /**\n * What we actually render — hover wins while hovering.\n *\n * Clamped, because there is no such thing as drawing six stars in a row of\n * five, and the same number is what `aria-valuenow` reports: a `role=\"slider\"`\n * whose value sits outside its own min / max is an invalid slider whatever the\n * model holds. The MODEL is left alone — see the note above `fillFor` for why\n * the clamp is not written back.\n */\n protected readonly displayValue = computed(() => clamp(this.hoverValue() ?? this.value() ?? 0, 0, this.count()));\n\n /**\n * What the slider REPORTS, and where the arrows start from.\n *\n * Deliberately not `displayValue`: a hover preview is a pointer affordance and\n * must not be announced as the current value, and an arrow press after a hover\n * has to step from the committed number rather than from wherever the mouse\n * happened to rest.\n */\n protected readonly announcedValue = computed(() => clamp(this.value() ?? 0, 0, this.count()));\n\n protected readonly slots = computed(() => Array.from({ length: this.count() }, (_, i) => i));\n\n /**\n * Reading direction, for the two places it changes the answer: the arrows and\n * the pointer ratio inside a star.\n *\n * `optional` because a consumer who never set a direction should not have to\n * provide anything — `Directionality` is root-provided, so this only resolves\n * to `null` in a bare `TestBed`, where LTR is the right assumption. Read per\n * interaction rather than cached, so a runtime flip needs no subscription.\n */\n private readonly directionality = inject(Directionality, { optional: true });\n\n /** The surrounding `<wr-form-field>`'s error state. @internal */\n protected readonly fieldAria = useFormFieldAria();\n\n /**\n * The field's label wins over the built-in default, and an explicit\n * `ariaLabel` wins over both.\n *\n * `<wr-form-field label=\"…\">` renders a `<label for>` that cannot reach this\n * control — `for` binds only to a LABELABLE element and the focusable part\n * here carries a role instead — so the field's label named nothing and this\n * announced its own generic default. A consumer who wrote\n * `<wr-form-field label=\"Overall satisfaction\">` heard \"Rating\".\n */\n protected readonly labelledBy = computed(() => (this.ariaLabel() ? null : this.fieldAria.labelledBy()));\n\n /** `null` once `aria-labelledby` is carrying the name, or the two are announced together. */\n protected readonly nameLabel = computed(() => (this.labelledBy() ? null : this.resolvedAriaLabel()));\n\n protected readonly classes = computed(() => {\n const parts = ['wr-rating'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-rating--${size}`);\n if (this.readonly()) parts.push('wr-rating--readonly');\n if (this.disabled()) parts.push('wr-rating--disabled');\n return parts.join(' ');\n });\n\n /*\n * There is deliberately no effect re-clamping `value` into `[0, count]`.\n *\n * There was one — it wrote the clamp back into the model, which the old CVA\n * `writeValue` also did — and under `[formField]` that write is\n * indistinguishable from the user moving the stars: a `FormControl(9)` on a\n * five-star rating became `5`, `dirty`, and emitted through `valueChanges`\n * before anything had been touched. So an unsaved-changes guard fired on a\n * form nobody had edited, and the out-of-range value that a `max()` rule\n * exists to REPORT was deleted by the control it was reported on (binding\n * `[count]` beside `[formField]` cannot help — the schema's rules are the only\n * bounds that reach here).\n *\n * `wr-slider` and `wr-input-number` had both already settled this the other\n * way, for the same two reasons, and this one was the odd control out.\n * `displayValue` clamps what is drawn and announced; `computeValue` and\n * `onKeydown` clamp what this control itself produces; the model is the\n * consumer's until they touch a star.\n */\n /** Fill ratio for slot `i` in `[0, 1]` — drives the CSS clip width. */\n protected fillFor(i: number): number {\n return clamp(this.displayValue() - i, 0, 1);\n }\n\n // Template handlers\n\n protected onSlotMove(event: MouseEvent, index: number): void {\n if (!this.interactive()) return;\n this.hoverValue.set(this.computeValue(event, index));\n }\n\n protected onLeave(): void {\n this.hoverValue.set(null);\n }\n\n protected onSlotClick(event: MouseEvent, index: number): void {\n if (!this.interactive()) return;\n const next = this.computeValue(event, index);\n // Click the current value → clear it.\n const final = next === this.value() ? null : next;\n this.commit(final);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (!this.interactive()) return;\n const max = this.count();\n const step = this.step();\n // The clamped reading, so an arrow after an out-of-range external write\n // steps from the star the user can see rather than from a number off the row.\n const current = this.announcedValue();\n // Arrows follow VISUAL order (WAI-ARIA APG). The row lays its stars along the\n // inline axis, so under `dir=\"rtl\"` the first star is the RIGHTMOST one and\n // `→` walks down the scale. Up / Down are the block axis and never flip;\n // Home / End mean first / last, a semantic position rather than a physical\n // one, so they don't either.\n const inline = this.isRtl() ? -step : step;\n let next: number | null;\n switch (event.key) {\n case 'ArrowRight':\n next = clamp(current + inline, 0, max);\n break;\n case 'ArrowUp':\n next = clamp(current + step, 0, max);\n break;\n case 'ArrowLeft':\n next = clamp(current - inline, 0, max);\n break;\n case 'ArrowDown':\n next = clamp(current - step, 0, max);\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = max;\n break;\n case 'Delete':\n case 'Backspace':\n next = null;\n break;\n default:\n return;\n }\n event.preventDefault();\n this.commit(next);\n }\n\n protected onBlur(): void {\n this.touch.emit();\n }\n\n // Internals\n\n /** Whether the row reads right-to-left. */\n private isRtl(): boolean {\n return this.directionality?.value === 'rtl';\n }\n\n /**\n * How far into the star the pointer sits, `0` to `1`, measured from its\n * INLINE-start edge — the left one in LTR, the right one in RTL, where the row\n * is mirrored. Taken from `rect.left` alone it reads 1 exactly where an RTL\n * user sees the start of the star, which inverts every half step.\n */\n private inlineRatio(clientX: number, rect: DOMRect): number {\n const offset = this.isRtl() ? rect.right - clientX : clientX - rect.left;\n return clamp(offset / rect.width, 0, 1);\n }\n\n /** Convert a mouse position over slot `index` to a snapped value. */\n private computeValue(event: MouseEvent, index: number): number {\n const target = event.currentTarget as HTMLElement;\n const rect = target.getBoundingClientRect();\n const ratio = this.inlineRatio(event.clientX, rect);\n const raw = index + ratio;\n const step = this.step();\n const snapped = Math.ceil(raw / step) * step;\n return clamp(snapped, step, this.count());\n }\n\n private commit(value: number | null): void {\n this.value.set(value);\n this.hoverValue.set(null);\n }\n}\n","<div\n class=\"wr-rating__row\"\n role=\"slider\"\n [attr.aria-label]=\"nameLabel()\"\n [attr.aria-labelledby]=\"labelledBy()\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"count()\"\n [attr.aria-valuenow]=\"announcedValue()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"focusable() ? 0 : -1\"\n (keydown)=\"onKeydown($event)\"\n (mouseleave)=\"onLeave()\"\n (blur)=\"onBlur()\"\n>\n @for (slot of slots(); track $index) {\n <!-- The parent row owns keyboard focus + handlers; slots are pointer-only\n click targets, so the a11y rules below are intentionally suppressed. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <span\n class=\"wr-rating__slot\"\n [class.wr-rating__slot--interactive]=\"interactive()\"\n [style.--wr-rating-fill]=\"fillFor($index)\"\n (mousemove)=\"onSlotMove($event, $index)\"\n (click)=\"onSlotClick($event, $index)\"\n >\n <!-- Outline (always visible) -->\n <svg class=\"wr-rating__icon wr-rating__icon--bg\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n d=\"M12 2.5l2.95 5.98 6.6.96-4.78 4.66 1.13 6.58L12 17.6l-5.9 3.08 1.13-6.58L2.45 9.44l6.6-.96L12 2.5z\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <!-- Filled overlay, clipped by --wr-rating-fill (0..1) -->\n <svg class=\"wr-rating__icon wr-rating__icon--fg\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n d=\"M12 2.5l2.95 5.98 6.6.96-4.78 4.66 1.13 6.58L12 17.6l-5.9 3.08 1.13-6.58L2.45 9.44l6.6-.96L12 2.5z\"\n fill=\"currentColor\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -34,12 +34,12 @@ class WrResult {
34
34
  ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
35
35
  classes = computed(() => `wr-result wr-result--${this.status()}`, /* @ts-ignore */
36
36
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
37
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult, deps: [], target: i0.ɵɵFactoryTarget.Component });
38
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrResult, isStandalone: true, selector: "wr-result", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 36 M32 44 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 20 L32 36 M32 42 L32 44\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
37
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult, deps: [], target: i0.ɵɵFactoryTarget.Component });
38
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrResult, isStandalone: true, selector: "wr-result", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n <!-- A TRIANGLE, and the shape is the point twice over. Warning used to sit\n in the same circle as info holding a near-identical exclamation mark \u2014\n the two paths differed by 2 user units, which is under 2px at the\n rendered size \u2014 and `warning` against `info` is a hue difference the\n palette cannot widen. It also brings this component into line with\n `wr-alert`, which has drawn warning as a triangle all along; the two\n disagreeing about what a warning looks like was its own small defect. -->\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <path d=\"M32 8 L60 54 L4 54 Z\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 26 L32 40 M32 47 L32 49\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 20 M32 28 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
39
39
  }
40
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult, decorators: [{
40
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult, decorators: [{
41
41
  type: Component,
42
- args: [{ selector: 'wr-result', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 36 M32 44 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 20 L32 36 M32 42 L32 44\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\n" }]
42
+ args: [{ selector: 'wr-result', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n <!-- A TRIANGLE, and the shape is the point twice over. Warning used to sit\n in the same circle as info holding a near-identical exclamation mark \u2014\n the two paths differed by 2 user units, which is under 2px at the\n rendered size \u2014 and `warning` against `info` is a hue difference the\n palette cannot widen. It also brings this component into line with\n `wr-alert`, which has drawn warning as a triangle all along; the two\n disagreeing about what a warning looks like was its own small defect. -->\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <path d=\"M32 8 L60 54 L4 54 Z\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 26 L32 40 M32 47 L32 49\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 20 M32 28 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\n" }]
43
43
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }] } });
44
44
 
45
45
  /**
@@ -67,10 +67,10 @@ class WrResult404 {
67
67
  description = input(null, /* @ts-ignore */
68
68
  ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
69
69
  desc = useI18nText(this.description, 'result.notFound', 'Sorry, the page you visited does not exist.');
70
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult404, deps: [], target: i0.ɵɵFactoryTarget.Component });
71
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrResult404, isStandalone: true, selector: "wr-result-404", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
70
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult404, deps: [], target: i0.ɵɵFactoryTarget.Component });
71
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrResult404, isStandalone: true, selector: "wr-result-404", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
72
72
  }
73
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult404, decorators: [{
73
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult404, decorators: [{
74
74
  type: Component,
75
75
  args: [{ selector: 'wr-result-404', encapsulation: ViewEncapsulation.None, imports: [WrResult], template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n" }]
76
76
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
@@ -84,10 +84,10 @@ class WrResult403 {
84
84
  description = input(null, /* @ts-ignore */
85
85
  ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
86
86
  desc = useI18nText(this.description, 'result.forbidden', 'Sorry, you are not authorized to access this page.');
87
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult403, deps: [], target: i0.ɵɵFactoryTarget.Component });
88
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrResult403, isStandalone: true, selector: "wr-result-403", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
87
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult403, deps: [], target: i0.ɵɵFactoryTarget.Component });
88
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrResult403, isStandalone: true, selector: "wr-result-403", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
89
89
  }
90
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult403, decorators: [{
90
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult403, decorators: [{
91
91
  type: Component,
92
92
  args: [{ selector: 'wr-result-403', encapsulation: ViewEncapsulation.None, imports: [WrResult], template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n" }]
93
93
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
@@ -101,10 +101,10 @@ class WrResult500 {
101
101
  description = input(null, /* @ts-ignore */
102
102
  ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
103
103
  desc = useI18nText(this.description, 'result.serverError', 'Sorry, something went wrong.');
104
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult500, deps: [], target: i0.ɵɵFactoryTarget.Component });
105
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrResult500, isStandalone: true, selector: "wr-result-500", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
104
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult500, deps: [], target: i0.ɵɵFactoryTarget.Component });
105
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrResult500, isStandalone: true, selector: "wr-result-500", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n", dependencies: [{ kind: "component", type: WrResult, selector: "wr-result", inputs: ["title", "description", "status"] }], encapsulation: i0.ViewEncapsulation.None });
106
106
  }
107
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrResult500, decorators: [{
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrResult500, decorators: [{
108
108
  type: Component,
109
109
  args: [{ selector: 'wr-result-500', encapsulation: ViewEncapsulation.None, imports: [WrResult], template: "<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently \u2014\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n" }]
110
110
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-result.mjs","sources":["../../../projects/lib/result/result.ts","../../../projects/lib/result/result.html","../../../projects/lib/result/presets.ts","../../../projects/lib/result/presets.html","../../../projects/lib/result/ngwr-result.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 { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport type { WrResultStatus } from './interfaces';\n\n/**\n * Large-illustration result / empty-state. Use after a successful action,\n * for empty list states, or 404 / 500 pages.\n *\n * @example\n * ```html\n * <wr-result status=\"success\" title=\"Submitted!\" description=\"We'll be in touch.\">\n * <button wr-btn color=\"primary\" wrResultExtra>Continue</button>\n * </wr-result>\n *\n * <wr-result status=\"empty\" title=\"No projects yet\">\n * <button wr-btn wrResultExtra>Create one</button>\n * </wr-result>\n * ```\n *\n * @see https://ngwr.dev/reference/components/result\n */\n@Component({\n selector: 'wr-result',\n templateUrl: './result.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrResult {\n readonly title = input<string>('');\n readonly description = input<string>('');\n readonly status = input<WrResultStatus>('info');\n\n protected readonly classes = computed(() => `wr-result wr-result--${this.status()}`);\n}\n\nexport type { WrResultStatus } from './interfaces';\n","<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 36 M32 44 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 20 L32 36 M32 42 L32 44\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\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, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\nimport type { WrResultStatus } from './interfaces';\nimport { WrResult } from './result';\n\n/**\n * Pre-set 404 result. Override `title` / `description` for localisation.\n *\n * @example\n * ```html\n * <wr-result-404>\n * <button wr-btn wrResultExtra>Back home</button>\n * </wr-result-404>\n * ```\n */\n@Component({\n selector: 'wr-result-404',\n templateUrl: './presets.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrResult],\n})\nexport class WrResult404 {\n /** Bound by the shared template; not an input — a preset IS its status. */\n protected readonly status: WrResultStatus = 'warning';\n\n readonly title = input<string>('404');\n\n /** Body text. Falls back to `result.notFound` from WrI18n. */\n readonly description = input<string | null>(null);\n\n protected readonly desc = useI18nText(\n this.description,\n 'result.notFound',\n 'Sorry, the page you visited does not exist.'\n );\n}\n\n/** Pre-set 403 result — forbidden / no access. */\n@Component({\n selector: 'wr-result-403',\n templateUrl: './presets.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrResult],\n})\nexport class WrResult403 {\n /** Bound by the shared template; not an input — a preset IS its status. */\n protected readonly status: WrResultStatus = 'error';\n\n readonly title = input<string>('403');\n\n /** Body text. Falls back to `result.forbidden` from WrI18n. */\n readonly description = input<string | null>(null);\n\n protected readonly desc = useI18nText(\n this.description,\n 'result.forbidden',\n 'Sorry, you are not authorized to access this page.'\n );\n}\n\n/** Pre-set 500 result — internal server error. */\n@Component({\n selector: 'wr-result-500',\n templateUrl: './presets.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrResult],\n})\nexport class WrResult500 {\n /** Bound by the shared template; not an input — a preset IS its status. */\n protected readonly status: WrResultStatus = 'error';\n\n readonly title = input<string>('500');\n\n /** Body text. Falls back to `result.serverError` from WrI18n. */\n readonly description = input<string | null>(null);\n\n protected readonly desc = useI18nText(this.description, 'result.serverError', 'Sorry, something went wrong.');\n}\n","<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently —\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\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-result.mjs","sources":["../../../projects/lib/result/result.ts","../../../projects/lib/result/result.html","../../../projects/lib/result/presets.ts","../../../projects/lib/result/presets.html","../../../projects/lib/result/ngwr-result.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 { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport type { WrResultStatus } from './interfaces';\n\n/**\n * Large-illustration result / empty-state. Use after a successful action,\n * for empty list states, or 404 / 500 pages.\n *\n * @example\n * ```html\n * <wr-result status=\"success\" title=\"Submitted!\" description=\"We'll be in touch.\">\n * <button wr-btn color=\"primary\" wrResultExtra>Continue</button>\n * </wr-result>\n *\n * <wr-result status=\"empty\" title=\"No projects yet\">\n * <button wr-btn wrResultExtra>Create one</button>\n * </wr-result>\n * ```\n *\n * @see https://ngwr.dev/reference/components/result\n */\n@Component({\n selector: 'wr-result',\n templateUrl: './result.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrResult {\n readonly title = input<string>('');\n readonly description = input<string>('');\n readonly status = input<WrResultStatus>('info');\n\n protected readonly classes = computed(() => `wr-result wr-result--${this.status()}`);\n}\n\nexport type { WrResultStatus } from './interfaces';\n","<div class=\"wr-result__icon\" aria-hidden=\"true\">\n @switch (status()) {\n @case ('success') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M20 32 L28 40 L44 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n <!-- A TRIANGLE, and the shape is the point twice over. Warning used to sit\n in the same circle as info holding a near-identical exclamation mark —\n the two paths differed by 2 user units, which is under 2px at the\n rendered size — and `warning` against `info` is a hue difference the\n palette cannot widen. It also brings this component into line with\n `wr-alert`, which has drawn warning as a triangle all along; the two\n disagreeing about what a warning looks like was its own small defect. -->\n @case ('warning') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <path d=\"M32 8 L60 54 L4 54 Z\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 26 L32 40 M32 47 L32 49\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('error') {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M22 22 L42 42 M42 22 L22 42\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n @case ('empty') {\n <svg width=\"72\" height=\"56\" viewBox=\"0 0 72 56\">\n <rect x=\"6\" y=\"14\" width=\"60\" height=\"36\" rx=\"4\" fill=\"currentColor\" opacity=\"0.12\" />\n <path d=\"M6 26 L36 26 L40 20 L66 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" />\n </svg>\n }\n @default {\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 64 64\">\n <circle cx=\"32\" cy=\"32\" r=\"28\" fill=\"currentColor\" opacity=\"0.12\" />\n <path\n d=\"M32 18 L32 20 M32 28 L32 46\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n }\n</div>\n\n@if (title()) {\n <h2 class=\"wr-result__title\">{{ title() }}</h2>\n}\n@if (description()) {\n <p class=\"wr-result__description\">{{ description() }}</p>\n}\n\n<div class=\"wr-result__extra\">\n <ng-content select=\"[wrResultExtra]\" />\n</div>\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, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\nimport type { WrResultStatus } from './interfaces';\nimport { WrResult } from './result';\n\n/**\n * Pre-set 404 result. Override `title` / `description` for localisation.\n *\n * @example\n * ```html\n * <wr-result-404>\n * <button wr-btn wrResultExtra>Back home</button>\n * </wr-result-404>\n * ```\n */\n@Component({\n selector: 'wr-result-404',\n templateUrl: './presets.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrResult],\n})\nexport class WrResult404 {\n /** Bound by the shared template; not an input — a preset IS its status. */\n protected readonly status: WrResultStatus = 'warning';\n\n readonly title = input<string>('404');\n\n /** Body text. Falls back to `result.notFound` from WrI18n. */\n readonly description = input<string | null>(null);\n\n protected readonly desc = useI18nText(\n this.description,\n 'result.notFound',\n 'Sorry, the page you visited does not exist.'\n );\n}\n\n/** Pre-set 403 result — forbidden / no access. */\n@Component({\n selector: 'wr-result-403',\n templateUrl: './presets.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrResult],\n})\nexport class WrResult403 {\n /** Bound by the shared template; not an input — a preset IS its status. */\n protected readonly status: WrResultStatus = 'error';\n\n readonly title = input<string>('403');\n\n /** Body text. Falls back to `result.forbidden` from WrI18n. */\n readonly description = input<string | null>(null);\n\n protected readonly desc = useI18nText(\n this.description,\n 'result.forbidden',\n 'Sorry, you are not authorized to access this page.'\n );\n}\n\n/** Pre-set 500 result — internal server error. */\n@Component({\n selector: 'wr-result-500',\n templateUrl: './presets.html',\n encapsulation: ViewEncapsulation.None,\n imports: [WrResult],\n})\nexport class WrResult500 {\n /** Bound by the shared template; not an input — a preset IS its status. */\n protected readonly status: WrResultStatus = 'error';\n\n readonly title = input<string>('500');\n\n /** Body text. Falls back to `result.serverError` from WrI18n. */\n readonly description = input<string | null>(null);\n\n protected readonly desc = useI18nText(this.description, 'result.serverError', 'Sorry, something went wrong.');\n}\n","<!--\n Shared by the three status presets, which differ only in the `status` each\n class declares.\n\n `ngProjectAs` is load-bearing: `<wr-result>` projects one slot,\n `select=\"[wrResultExtra]\"`, and it matches that selector against the nodes in\n THIS template. A bare `<ng-content />` does not carry the attribute, so\n everything a consumer projected into `<wr-result-404>` was dropped silently —\n including the button each preset's own `@example` shows. `ngProjectAs` is what\n tells the outer slot what this pass-through stands for.\n-->\n<wr-result [status]=\"status\" [title]=\"title()\" [description]=\"desc()\">\n <ng-content ngProjectAs=\"[wrResultExtra]\" />\n</wr-result>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;AAgBG;MAOU,QAAQ,CAAA;IACV,KAAK,GAAG,KAAK,CAAS,EAAE;8EAAC;IACzB,WAAW,GAAG,KAAK,CAAS,EAAE;oFAAC;IAC/B,MAAM,GAAG,KAAK,CAAiB,MAAM;+EAAC;IAE5B,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA,qBAAA,EAAwB,IAAI,CAAC,MAAM,EAAE,CAAA,CAAE;gFAAC;uGALzE,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAR,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,QAAQ,8fClCrB,gxFA6EA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FD3Ca,QAAQ,EAAA,UAAA,EAAA,CAAA;kBANpB,SAAS;+BACE,WAAW,EAAA,aAAA,EAEN,iBAAiB,CAAC,IAAI,QAC/B,EAAE,SAAS,EAAE,WAAW,EAAE,EAAA,QAAA,EAAA,gxFAAA,EAAA;;;AEhClC;;;;;AAKG;AASH;;;;;;;;;AASG;MAOU,WAAW,CAAA;;IAEH,MAAM,GAAmB,SAAS;IAE5C,KAAK,GAAG,KAAK,CAAS,KAAK;8EAAC;;IAG5B,WAAW,GAAG,KAAK,CAAgB,IAAI;oFAAC;IAE9B,IAAI,GAAG,WAAW,CACnC,IAAI,CAAC,WAAW,EAChB,iBAAiB,EACjB,6CAA6C,CAC9C;uGAbU,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAX,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC9BxB,ksBAcA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDcY,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAEP,WAAW,EAAA,UAAA,EAAA,CAAA;kBANvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,iBAEV,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B,CAAC,QAAQ,CAAC,EAAA,QAAA,EAAA,ksBAAA,EAAA;;AAkBrB;MAOa,WAAW,CAAA;;IAEH,MAAM,GAAmB,OAAO;IAE1C,KAAK,GAAG,KAAK,CAAS,KAAK;8EAAC;;IAG5B,WAAW,GAAG,KAAK,CAAgB,IAAI;oFAAC;IAE9B,IAAI,GAAG,WAAW,CACnC,IAAI,CAAC,WAAW,EAChB,kBAAkB,EAClB,oDAAoD,CACrD;uGAbU,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAX,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECrDxB,ksBAcA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDqCY,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAEP,WAAW,EAAA,UAAA,EAAA,CAAA;kBANvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,iBAEV,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B,CAAC,QAAQ,CAAC,EAAA,QAAA,EAAA,ksBAAA,EAAA;;AAkBrB;MAOa,WAAW,CAAA;;IAEH,MAAM,GAAmB,OAAO;IAE1C,KAAK,GAAG,KAAK,CAAS,KAAK;8EAAC;;IAG5B,WAAW,GAAG,KAAK,CAAgB,IAAI;oFAAC;IAE9B,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,oBAAoB,EAAE,8BAA8B,CAAC;uGATlG,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAX,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC5ExB,ksBAcA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED4DY,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAEP,WAAW,EAAA,UAAA,EAAA,CAAA;kBANvB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,iBAEV,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B,CAAC,QAAQ,CAAC,EAAA,QAAA,EAAA,ksBAAA,EAAA;;;AE1ErB;;AAEG;;;;"}
@@ -262,10 +262,10 @@ class WrRotatingText {
262
262
  return i * stagger;
263
263
  }
264
264
  }
265
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrRotatingText, deps: [], target: i0.ɵɵFactoryTarget.Component });
266
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrRotatingText, isStandalone: true, selector: "wr-rotating-text", inputs: { texts: { classPropertyName: "texts", publicName: "texts", isSignal: true, isRequired: true, transformFunction: null }, rotationInterval: { classPropertyName: "rotationInterval", publicName: "rotationInterval", isSignal: true, isRequired: false, transformFunction: null }, splitBy: { classPropertyName: "splitBy", publicName: "splitBy", isSignal: true, isRequired: false, transformFunction: null }, auto: { classPropertyName: "auto", publicName: "auto", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, easing: { classPropertyName: "easing", publicName: "easing", isSignal: true, isRequired: false, transformFunction: null }, staggerDuration: { classPropertyName: "staggerDuration", publicName: "staggerDuration", isSignal: true, isRequired: false, transformFunction: null }, staggerFrom: { classPropertyName: "staggerFrom", publicName: "staggerFrom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nextChange: "nextChange" }, host: { classAttribute: "wr-rotating-text" }, ngImport: i0, template: "<!--\n The readable text, once: the spans below are per-character. Deliberately NOT a\n live region \u2014 `auto` rotates every two seconds by default, and the APG's answer\n for self-advancing content is silence, not an announcement every two seconds.\n-->\n\n<span class=\"wr-rotating-text__sr-only\">{{ current() }}</span>\n\n<!-- Animated visual content. -->\n<span class=\"wr-rotating-text__inner\" aria-hidden=\"true\">\n @for (word of words(); track $index) {\n <span class=\"wr-rotating-text__word\">\n @for (char of word.characters; track $index) {\n <span class=\"wr-rotating-text__char\">{{ char }}</span>\n }\n @if (word.needsSpace) {\n <span class=\"wr-rotating-text__space\">&nbsp;</span>\n }\n </span>\n }\n</span>\n", styles: [".wr-rotating-text{display:inline-flex;align-items:center;overflow:hidden;vertical-align:bottom}.wr-rotating-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-rotating-text__inner{display:inline-flex;flex-wrap:wrap}.wr-rotating-text__word{display:inline-flex;align-items:center}.wr-rotating-text__char{display:inline-block;will-change:transform,opacity}.wr-rotating-text__space{display:inline;white-space:pre}\n"], encapsulation: i0.ViewEncapsulation.None });
265
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrRotatingText, deps: [], target: i0.ɵɵFactoryTarget.Component });
266
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrRotatingText, isStandalone: true, selector: "wr-rotating-text", inputs: { texts: { classPropertyName: "texts", publicName: "texts", isSignal: true, isRequired: true, transformFunction: null }, rotationInterval: { classPropertyName: "rotationInterval", publicName: "rotationInterval", isSignal: true, isRequired: false, transformFunction: null }, splitBy: { classPropertyName: "splitBy", publicName: "splitBy", isSignal: true, isRequired: false, transformFunction: null }, auto: { classPropertyName: "auto", publicName: "auto", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, easing: { classPropertyName: "easing", publicName: "easing", isSignal: true, isRequired: false, transformFunction: null }, staggerDuration: { classPropertyName: "staggerDuration", publicName: "staggerDuration", isSignal: true, isRequired: false, transformFunction: null }, staggerFrom: { classPropertyName: "staggerFrom", publicName: "staggerFrom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nextChange: "nextChange" }, host: { classAttribute: "wr-rotating-text" }, ngImport: i0, template: "<!--\n The readable text, once: the spans below are per-character. Deliberately NOT a\n live region \u2014 `auto` rotates every two seconds by default, and the APG's answer\n for self-advancing content is silence, not an announcement every two seconds.\n-->\n\n<span class=\"wr-rotating-text__sr-only\">{{ current() }}</span>\n\n<!-- Animated visual content. -->\n<span class=\"wr-rotating-text__inner\" aria-hidden=\"true\">\n @for (word of words(); track $index) {\n <span class=\"wr-rotating-text__word\">\n @for (char of word.characters; track $index) {\n <span class=\"wr-rotating-text__char\">{{ char }}</span>\n }\n @if (word.needsSpace) {\n <span class=\"wr-rotating-text__space\">&nbsp;</span>\n }\n </span>\n }\n</span>\n", styles: [".wr-rotating-text{display:inline-flex;align-items:center;overflow:hidden;vertical-align:bottom}.wr-rotating-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-rotating-text__inner{display:inline-flex;flex-wrap:wrap}.wr-rotating-text__word{display:inline-flex;align-items:center}.wr-rotating-text__char{display:inline-block;will-change:transform,opacity}.wr-rotating-text__space{display:inline;white-space:pre}\n"], encapsulation: i0.ViewEncapsulation.None });
267
267
  }
268
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrRotatingText, decorators: [{
268
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrRotatingText, decorators: [{
269
269
  type: Component,
270
270
  args: [{ selector: 'wr-rotating-text', encapsulation: ViewEncapsulation.None, host: { class: 'wr-rotating-text' }, template: "<!--\n The readable text, once: the spans below are per-character. Deliberately NOT a\n live region \u2014 `auto` rotates every two seconds by default, and the APG's answer\n for self-advancing content is silence, not an announcement every two seconds.\n-->\n\n<span class=\"wr-rotating-text__sr-only\">{{ current() }}</span>\n\n<!-- Animated visual content. -->\n<span class=\"wr-rotating-text__inner\" aria-hidden=\"true\">\n @for (word of words(); track $index) {\n <span class=\"wr-rotating-text__word\">\n @for (char of word.characters; track $index) {\n <span class=\"wr-rotating-text__char\">{{ char }}</span>\n }\n @if (word.needsSpace) {\n <span class=\"wr-rotating-text__space\">&nbsp;</span>\n }\n </span>\n }\n</span>\n", styles: [".wr-rotating-text{display:inline-flex;align-items:center;overflow:hidden;vertical-align:bottom}.wr-rotating-text__sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.wr-rotating-text__inner{display:inline-flex;flex-wrap:wrap}.wr-rotating-text__word{display:inline-flex;align-items:center}.wr-rotating-text__char{display:inline-block;will-change:transform,opacity}.wr-rotating-text__space{display:inline;white-space:pre}\n"] }]
271
271
  }], ctorParameters: () => [], propDecorators: { texts: [{ type: i0.Input, args: [{ isSignal: true, alias: "texts", required: true }] }], rotationInterval: [{ type: i0.Input, args: [{ isSignal: true, alias: "rotationInterval", required: false }] }], splitBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "splitBy", required: false }] }], auto: [{ type: i0.Input, args: [{ isSignal: true, alias: "auto", required: false }] }], loop: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], easing: [{ type: i0.Input, args: [{ isSignal: true, alias: "easing", required: false }] }], staggerDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "staggerDuration", required: false }] }], staggerFrom: [{ type: i0.Input, args: [{ isSignal: true, alias: "staggerFrom", required: false }] }], nextChange: [{ type: i0.Output, args: ["nextChange"] }] } });
@@ -33,6 +33,39 @@ const EXPECTED_TYPE = {
33
33
  switch: 'boolean',
34
34
  slider: 'number',
35
35
  };
36
+ /**
37
+ * Warn when a group's described fields are about to be drawn by nothing.
38
+ *
39
+ * A field tree is iterated one level deep, so an object-valued field with no
40
+ * `WR_FIELD` of its own is skipped exactly like an undescribed leaf — and its
41
+ * children go with it. That is the right default (a model nests for reasons
42
+ * that have nothing to do with a screen), but it is indistinguishable from a
43
+ * half-drawn form: nothing is missing from the DOM, so nothing looks wrong.
44
+ *
45
+ * Describing the children and getting none of them is never intentional, so
46
+ * that exact shape is what this reports. A group whose children carry no spec
47
+ * either is silent, because it is a model detail this screen does not render.
48
+ */
49
+ function warnOnUndrawnGroup(key, group) {
50
+ // A field tree over a primitive is not iterable, and every undescribed leaf
51
+ // arrives here — so the guard is what keeps this from throwing on the common
52
+ // case rather than a defence against an exotic one.
53
+ const subfields = group[Symbol.iterator];
54
+ if (typeof subfields !== 'function')
55
+ return;
56
+ let described = 0;
57
+ for (const [, child] of group) {
58
+ if (isFieldTree(child) && child().metadata(WR_FIELD)?.())
59
+ described++;
60
+ }
61
+ if (described === 0)
62
+ return;
63
+ // eslint-disable-next-line no-console -- dev-mode validation
64
+ console.warn(`[NGWR] <wr-schema-form>: "${key}" is a group holding ${described} described ` +
65
+ `field(s), and none of them are drawn — a field tree is walked one level deep. ` +
66
+ `Draw the group with a second <wr-schema-form [field]="form.${key}" />, or give ` +
67
+ `"${key}" a WR_FIELD of its own if this screen is meant to skip it.`);
68
+ }
36
69
  /**
37
70
  * Warn when a `kind` contradicts what the field actually holds.
38
71
  *
@@ -134,8 +167,11 @@ class WrSchemaForm {
134
167
  continue;
135
168
  const field = child;
136
169
  const spec = field().metadata(WR_FIELD)?.();
137
- if (!spec)
170
+ if (!spec) {
171
+ if (isDevMode())
172
+ warnOnUndrawnGroup(key, child);
138
173
  continue;
174
+ }
139
175
  const label = spec.label ?? wrFieldLabel(key);
140
176
  const span = Math.min(Math.max(Math.round(spec.span ?? 1), 1), columns);
141
177
  out.push({
@@ -152,10 +188,10 @@ class WrSchemaForm {
152
188
  return out;
153
189
  }, /* @ts-ignore */
154
190
  ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
155
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSchemaForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
156
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSchemaForm, isStandalone: true, selector: "wr-schema-form", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.grid-template-columns": "template()" }, classAttribute: "wr-schema-form" }, ngImport: i0, template: "@for (f of fields(); track f.key) {\n @let state = f.field();\n\n <!-- Angular's `hidden()` does not hide anything on its own; the docs are\n explicit that the template has to honour it. -->\n @if (!state.hidden()) {\n <div class=\"wr-schema-form__field\" [style.grid-column]=\"f.column\">\n <wr-form-field [label]=\"f.labelAbove\" [hint]=\"f.spec.hint ?? ''\" [required]=\"state.required()\">\n @switch (f.spec.kind) {\n @case ('textarea') {\n <wr-textarea [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('number') {\n <wr-input-number\n [formField]=\"f.field\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n [step]=\"f.spec.step ?? 1\"\n [ariaLabel]=\"f.label\"\n />\n }\n @case ('select') {\n <wr-select [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? null\" [ariaLabel]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-option [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-option>\n }\n </wr-select>\n }\n @case ('checkbox') {\n <wr-checkbox [formField]=\"f.field\">{{ f.label }}</wr-checkbox>\n }\n @case ('switch') {\n <wr-switch [formField]=\"f.field\">{{ f.label }}</wr-switch>\n }\n @case ('radio') {\n <!-- `wr-radio-group` has no `ariaLabel` input, and needs none: its\n host is a `role=\"radiogroup\"`, where `aria-label` is legal. -->\n <wr-radio-group [formField]=\"f.field\" [attr.aria-label]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-radio [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-radio>\n }\n </wr-radio-group>\n }\n @case ('date') {\n <wr-date-picker [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('slider') {\n <wr-slider [formField]=\"f.field\" [step]=\"f.spec.step ?? 1\" [ariaLabel]=\"f.label\" />\n }\n @default {\n <input\n wrInput\n [formField]=\"f.field\"\n [type]=\"f.spec.type ?? 'text'\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n />\n }\n }\n </wr-form-field>\n </div>\n }\n}\n", dependencies: [{ kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "component", type: WrCheckbox, selector: "wr-checkbox", inputs: ["id", "checkboxValue", "ariaLabel", "checked", "disabled", "readonly", "size", "icon", "indeterminate"], outputs: ["checkedChange", "touch"] }, { kind: "component", type: WrDatePicker, selector: "wr-date-picker", inputs: ["mode", "format", "placeholder", "min", "max", "dateFilter", "timeFormat", "showSeconds", "step", "disabled", "readonly", "value", "ariaLabel", "panelAriaLabel"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrFormField, selector: "wr-form-field", inputs: ["label", "hint", "required", "optional", "optionalLabel", "controlId", "autoErrors"] }, { kind: "directive", type: WrInput, selector: "input[wrInput], textarea[wrInput]", inputs: ["size", "rounded"] }, { kind: "component", type: WrInputNumber, selector: "wr-input-number", inputs: ["min", "max", "step", "decimals", "showSteppers", "size", "rounded", "prefix", "suffix", "placeholder", "ariaLabel", "incrementLabel", "decrementLabel", "disabled", "readonly", "value"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrOption, selector: "wr-option", inputs: ["value", "disabled"] }, { kind: "component", type: WrRadio, selector: "wr-radio", inputs: ["id", "value", "icon", "size", "disabled"] }, { kind: "component", type: WrRadioGroup, selector: "wr-radio-group", inputs: ["name", "disabled", "readonly", "value"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrSelect, selector: "wr-select", inputs: ["placeholder", "clearLabel", "ariaLabel", "disabled", "readonly", "rounded", "size", "responsive", "mode", "searchable", "searchQuery", "options", "displayWith", "loader", "serverSearch", "debounceMs", "minChars", "freeText", "virtualScroll", "rowHeight", "viewportHeight", "overscan", "noResultsText", "loadingText", "loading", "separators", "allowDuplicates", "validate", "clearable", "maxItems", "maxTagCount", "value"], outputs: ["searchQueryChange", "searchChange", "valueChange", "touch"] }, { kind: "component", type: WrSlider, selector: "wr-slider", inputs: ["min", "max", "step", "range", "disabled", "readonly", "showLabel", "ariaLabel", "upperLabel", "value"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrSwitch, selector: "wr-switch", inputs: ["ariaLabel", "id", "disabled", "readonly", "size", "checked"], outputs: ["checkedChange", "touch"] }, { kind: "component", type: WrTextarea, selector: "wr-textarea", inputs: ["placeholder", "ariaLabel", "size", "rows", "resizable", "resize", "readonly", "autosize", "maxRows", "disabled", "value"], outputs: ["valueChange", "touch"] }], encapsulation: i0.ViewEncapsulation.None });
191
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSchemaForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
192
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrSchemaForm, isStandalone: true, selector: "wr-schema-form", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.grid-template-columns": "template()" }, classAttribute: "wr-schema-form" }, ngImport: i0, template: "@for (f of fields(); track f.key) {\n @let state = f.field();\n\n <!-- Angular's `hidden()` does not hide anything on its own; the docs are\n explicit that the template has to honour it. -->\n @if (!state.hidden()) {\n <div class=\"wr-schema-form__field\" [style.grid-column]=\"f.column\">\n <wr-form-field [label]=\"f.labelAbove\" [hint]=\"f.spec.hint ?? ''\" [required]=\"state.required()\">\n @switch (f.spec.kind) {\n @case ('textarea') {\n <wr-textarea [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('number') {\n <wr-input-number\n [formField]=\"f.field\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n [step]=\"f.spec.step ?? 1\"\n [ariaLabel]=\"f.label\"\n />\n }\n @case ('select') {\n <wr-select [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? null\" [ariaLabel]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-option [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-option>\n }\n </wr-select>\n }\n @case ('checkbox') {\n <wr-checkbox [formField]=\"f.field\">{{ f.label }}</wr-checkbox>\n }\n @case ('switch') {\n <wr-switch [formField]=\"f.field\">{{ f.label }}</wr-switch>\n }\n @case ('radio') {\n <!-- `wr-radio-group` has no `ariaLabel` input, and needs none: its\n host is a `role=\"radiogroup\"`, where `aria-label` is legal. -->\n <wr-radio-group [formField]=\"f.field\" [attr.aria-label]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-radio [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-radio>\n }\n </wr-radio-group>\n }\n @case ('date') {\n <wr-date-picker [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('slider') {\n <wr-slider [formField]=\"f.field\" [step]=\"f.spec.step ?? 1\" [ariaLabel]=\"f.label\" />\n }\n @default {\n <input\n wrInput\n [formField]=\"f.field\"\n [type]=\"f.spec.type ?? 'text'\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n />\n }\n }\n </wr-form-field>\n </div>\n }\n}\n", dependencies: [{ kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "component", type: WrCheckbox, selector: "wr-checkbox", inputs: ["id", "checkboxValue", "ariaLabel", "checked", "disabled", "readonly", "size", "icon", "indeterminate"], outputs: ["checkedChange", "touch"] }, { kind: "component", type: WrDatePicker, selector: "wr-date-picker", inputs: ["mode", "format", "placeholder", "min", "max", "dateFilter", "timeFormat", "showSeconds", "step", "disabled", "readonly", "value", "ariaLabel", "panelAriaLabel"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrFormField, selector: "wr-form-field", inputs: ["label", "hint", "required", "optional", "optionalLabel", "controlId", "autoErrors"] }, { kind: "directive", type: WrInput, selector: "input[wrInput], textarea[wrInput]", inputs: ["size", "rounded"] }, { kind: "component", type: WrInputNumber, selector: "wr-input-number", inputs: ["min", "max", "step", "decimals", "showSteppers", "size", "rounded", "prefix", "suffix", "placeholder", "ariaLabel", "incrementLabel", "decrementLabel", "disabled", "readonly", "value"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrOption, selector: "wr-option", inputs: ["value", "disabled"] }, { kind: "component", type: WrRadio, selector: "wr-radio", inputs: ["id", "value", "icon", "size", "disabled"] }, { kind: "component", type: WrRadioGroup, selector: "wr-radio-group", inputs: ["name", "disabled", "readonly", "value"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrSelect, selector: "wr-select", inputs: ["placeholder", "clearLabel", "ariaLabel", "disabled", "readonly", "rounded", "size", "responsive", "mode", "searchable", "searchQuery", "options", "displayWith", "loader", "serverSearch", "debounceMs", "minChars", "freeText", "virtualScroll", "rowHeight", "viewportHeight", "overscan", "noResultsText", "loadingText", "loading", "separators", "allowDuplicates", "validate", "clearable", "maxItems", "maxTagCount", "value"], outputs: ["searchQueryChange", "searchChange", "valueChange", "touch"] }, { kind: "component", type: WrSlider, selector: "wr-slider", inputs: ["min", "max", "step", "range", "disabled", "readonly", "showLabel", "ariaLabel", "upperLabel", "value"], outputs: ["valueChange", "touch"] }, { kind: "component", type: WrSwitch, selector: "wr-switch", inputs: ["ariaLabel", "id", "disabled", "readonly", "size", "checked"], outputs: ["checkedChange", "touch"] }, { kind: "component", type: WrTextarea, selector: "wr-textarea", inputs: ["placeholder", "ariaLabel", "size", "rows", "resizable", "resize", "readonly", "autosize", "maxRows", "disabled", "value"], outputs: ["valueChange", "touch"] }], encapsulation: i0.ViewEncapsulation.None });
157
193
  }
158
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSchemaForm, decorators: [{
194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSchemaForm, decorators: [{
159
195
  type: Component,
160
196
  args: [{ selector: 'wr-schema-form', encapsulation: ViewEncapsulation.None, imports: [
161
197
  FormField,
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-schema-form.mjs","sources":["../../../projects/lib/schema-form/schema-form.ts","../../../projects/lib/schema-form/schema-form.html","../../../projects/lib/schema-form/ngwr-schema-form.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 { Component, ViewEncapsulation, computed, input, isDevMode } from '@angular/core';\nimport { FormField, type Field, type FieldTree, isFieldTree } from '@angular/forms/signals';\n\nimport { WrCheckbox } from 'ngwr/checkbox';\nimport { WrDatePicker } from 'ngwr/date-picker';\nimport { WR_FIELD, WrFormField, wrFieldLabel, type WrFieldSpec } from 'ngwr/form';\nimport { WrInput } from 'ngwr/input';\nimport { WrInputNumber } from 'ngwr/input-number';\nimport { WrRadio, WrRadioGroup } from 'ngwr/radio';\nimport { WrOption, WrSelect } from 'ngwr/select';\nimport { WrSlider } from 'ngwr/slider';\nimport { WrSwitch } from 'ngwr/switch';\nimport { WrTextarea } from 'ngwr/textarea';\nimport { numAttr } from 'ngwr/utils';\n\n/** One field the template draws, resolved once per schema change. */\ninterface WrRenderedField {\n readonly key: string;\n readonly field: Field<never>;\n readonly spec: WrFieldSpec;\n /** `spec.label`, or the key de-camel-cased. */\n readonly label: string;\n /**\n * The same text, or `''` for the two kinds that carry their own label inside\n * the control. Resolved here rather than in the template: a method call in a\n * template is re-run on every pass, and this is decided once per schema.\n */\n readonly labelAbove: string;\n /** `grid-column`, already clamped to the form's own `columns`. */\n readonly column: string;\n}\n\n/**\n * The two kinds that carry their own label. Everything else gets one above the\n * control, from `<wr-form-field>`.\n */\nconst SELF_LABELLING = new Set<WrFieldSpec['kind']>(['checkbox', 'switch']);\n\n/** What each kind writes into the model, for the dev-mode mismatch warning. */\nconst EXPECTED_TYPE: Partial<Record<WrFieldSpec['kind'], string>> = {\n input: 'string',\n textarea: 'string',\n number: 'number',\n checkbox: 'boolean',\n switch: 'boolean',\n slider: 'number',\n};\n\n/**\n * Warn when a `kind` contradicts what the field actually holds.\n *\n * This is the one failure mode of the whole component that nothing else\n * reports: `kind` is a string on a metadata value, so TypeScript cannot hold it\n * against the field's own type, and a `kind: 'number'` on a `string` field\n * renders a `<wr-input-number>` that writes numbers into it forever. The runtime\n * value is the only evidence available, so an empty or nullish one says nothing\n * and is left alone.\n */\nfunction warnOnKindMismatch(f: WrRenderedField): void {\n const expected = EXPECTED_TYPE[f.spec.kind];\n const value = f.field().value();\n if (!expected || value === null || value === undefined || value === '') return;\n if (typeof value === expected) return;\n\n // eslint-disable-next-line no-console -- dev-mode validation\n console.warn(\n `[NGWR] <wr-schema-form>: field \"${f.key}\" is described as kind '${f.spec.kind}', ` +\n `which writes a ${expected}, but the field holds a ${typeof value}. ` +\n `The control will overwrite the model with the wrong type.`\n );\n}\n\n/**\n * A form drawn from a Signal Forms schema — one `<wr-form-field>`, one control\n * and one set of error messages per described field, laid out on a grid.\n *\n * The presentation rides on the SAME schema as the validation, through the\n * `WR_FIELD` metadata key from `ngwr/form`:\n *\n * ```ts\n * const profile = form(model, path => {\n * required(path.email);\n * email(path.email);\n * metadata(path.email, WR_FIELD, () => ({ kind: 'input', type: 'email' }));\n * metadata(path.role, WR_FIELD, () => ({ kind: 'select', options: ROLES }));\n * });\n * ```\n * ```html\n * <wr-schema-form [field]=\"profile\" [columns]=\"2\" />\n * ```\n *\n * **A field with no `WR_FIELD` metadata is skipped**, silently and on purpose: a\n * schema may describe more than one screen renders, and guessing a control from\n * a field's type would draw a `wr-switch` for every boolean flag in the model.\n * Order is the model's own key order.\n *\n * **`required`, `disabled`, `readonly` and `hidden` are NOT in the spec.** They\n * are Angular's own schema functions, `[formField]` already applies the first\n * three to the control, and this component reads `hidden()` to decide whether to\n * draw the field at all — which Angular's docs say a template has to do itself.\n * Re-declaring any of them here would be a second source of truth for state the\n * form already owns.\n *\n * **Why its own entry point rather than `ngwr/form`.** Drawing nine kinds means\n * depending on nine controls, and `ngwr/form` is the layout primitive every\n * form imports — folding this in would put a date picker and a slider into the\n * bundle of an app that only wanted `<wr-form-field>`.\n *\n * @see https://ngwr.dev/reference/components/schema-form\n */\n@Component({\n selector: 'wr-schema-form',\n templateUrl: './schema-form.html',\n encapsulation: ViewEncapsulation.None,\n imports: [\n FormField,\n WrCheckbox,\n WrDatePicker,\n WrFormField,\n WrInput,\n WrInputNumber,\n WrOption,\n WrRadio,\n WrRadioGroup,\n WrSelect,\n WrSlider,\n WrSwitch,\n WrTextarea,\n ],\n host: {\n class: 'wr-schema-form',\n '[style.grid-template-columns]': 'template()',\n },\n})\nexport class WrSchemaForm<T extends object> {\n // Generic, rather than `FieldTree<Record<string, unknown>>`, because a model\n // declared as an `interface` has no index signature and is not assignable to\n // that: every consumer would have had to declare their model as a type alias\n // just to bind it. `T extends object` still refuses a field tree over a\n // primitive, which has no subfields and would draw nothing.\n /**\n * The form to draw — the value `form()` returned, or any object-valued field\n * inside one.\n */\n readonly field = input.required<FieldTree<T>>();\n\n /**\n * Grid columns. A field spans one of them unless its spec says otherwise.\n * @default 1\n */\n readonly columns = input(1, { transform: numAttr(1) });\n\n /**\n * The track list, written as a style rather than published as a\n * `--wr-schema-form-columns` hook: `columns` always has a value, so the\n * inline style would win over any declaration a consumer wrote and the hook\n * would be one nobody could use.\n */\n protected readonly template = computed(() => `repeat(${Math.max(1, this.columns())}, minmax(0, 1fr))`);\n\n /**\n * The described fields, in the model's key order.\n *\n * A field tree over an object is iterable as `[key, field]` pairs, which is\n * the whole reason this component needs no field list of its own. `isFieldTree`\n * guards the pair: a model carrying a method or a non-field property would\n * otherwise be read as a field and answer `undefined` to everything.\n */\n protected readonly fields = computed<readonly WrRenderedField[]>(() => {\n const columns = this.columns();\n const out: WrRenderedField[] = [];\n\n for (const [key, child] of this.field() as unknown as Iterable<[string, unknown]>) {\n if (!isFieldTree(child)) continue;\n\n const field = child as Field<never>;\n const spec = field().metadata(WR_FIELD)?.();\n if (!spec) continue;\n\n const label = spec.label ?? wrFieldLabel(key);\n const span = Math.min(Math.max(Math.round(spec.span ?? 1), 1), columns);\n out.push({\n key,\n field,\n spec,\n label,\n labelAbove: SELF_LABELLING.has(spec.kind) ? '' : label,\n column: `span ${span}`,\n });\n }\n\n if (isDevMode()) out.forEach(f => warnOnKindMismatch(f));\n return out;\n });\n}\n","@for (f of fields(); track f.key) {\n @let state = f.field();\n\n <!-- Angular's `hidden()` does not hide anything on its own; the docs are\n explicit that the template has to honour it. -->\n @if (!state.hidden()) {\n <div class=\"wr-schema-form__field\" [style.grid-column]=\"f.column\">\n <wr-form-field [label]=\"f.labelAbove\" [hint]=\"f.spec.hint ?? ''\" [required]=\"state.required()\">\n @switch (f.spec.kind) {\n @case ('textarea') {\n <wr-textarea [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('number') {\n <wr-input-number\n [formField]=\"f.field\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n [step]=\"f.spec.step ?? 1\"\n [ariaLabel]=\"f.label\"\n />\n }\n @case ('select') {\n <wr-select [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? null\" [ariaLabel]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-option [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-option>\n }\n </wr-select>\n }\n @case ('checkbox') {\n <wr-checkbox [formField]=\"f.field\">{{ f.label }}</wr-checkbox>\n }\n @case ('switch') {\n <wr-switch [formField]=\"f.field\">{{ f.label }}</wr-switch>\n }\n @case ('radio') {\n <!-- `wr-radio-group` has no `ariaLabel` input, and needs none: its\n host is a `role=\"radiogroup\"`, where `aria-label` is legal. -->\n <wr-radio-group [formField]=\"f.field\" [attr.aria-label]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-radio [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-radio>\n }\n </wr-radio-group>\n }\n @case ('date') {\n <wr-date-picker [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('slider') {\n <wr-slider [formField]=\"f.field\" [step]=\"f.spec.step ?? 1\" [ariaLabel]=\"f.label\" />\n }\n @default {\n <input\n wrInput\n [formField]=\"f.field\"\n [type]=\"f.spec.type ?? 'text'\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n />\n }\n }\n </wr-form-field>\n </div>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-schema-form.mjs","sources":["../../../projects/lib/schema-form/schema-form.ts","../../../projects/lib/schema-form/schema-form.html","../../../projects/lib/schema-form/ngwr-schema-form.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 { Component, ViewEncapsulation, computed, input, isDevMode } from '@angular/core';\nimport { FormField, type Field, type FieldTree, isFieldTree } from '@angular/forms/signals';\n\nimport { WrCheckbox } from 'ngwr/checkbox';\nimport { WrDatePicker } from 'ngwr/date-picker';\nimport { WR_FIELD, WrFormField, wrFieldLabel, type WrFieldSpec } from 'ngwr/form';\nimport { WrInput } from 'ngwr/input';\nimport { WrInputNumber } from 'ngwr/input-number';\nimport { WrRadio, WrRadioGroup } from 'ngwr/radio';\nimport { WrOption, WrSelect } from 'ngwr/select';\nimport { WrSlider } from 'ngwr/slider';\nimport { WrSwitch } from 'ngwr/switch';\nimport { WrTextarea } from 'ngwr/textarea';\nimport { numAttr } from 'ngwr/utils';\n\n/** One field the template draws, resolved once per schema change. */\ninterface WrRenderedField {\n readonly key: string;\n readonly field: Field<never>;\n readonly spec: WrFieldSpec;\n /** `spec.label`, or the key de-camel-cased. */\n readonly label: string;\n /**\n * The same text, or `''` for the two kinds that carry their own label inside\n * the control. Resolved here rather than in the template: a method call in a\n * template is re-run on every pass, and this is decided once per schema.\n */\n readonly labelAbove: string;\n /** `grid-column`, already clamped to the form's own `columns`. */\n readonly column: string;\n}\n\n/**\n * The two kinds that carry their own label. Everything else gets one above the\n * control, from `<wr-form-field>`.\n */\nconst SELF_LABELLING = new Set<WrFieldSpec['kind']>(['checkbox', 'switch']);\n\n/** What each kind writes into the model, for the dev-mode mismatch warning. */\nconst EXPECTED_TYPE: Partial<Record<WrFieldSpec['kind'], string>> = {\n input: 'string',\n textarea: 'string',\n number: 'number',\n checkbox: 'boolean',\n switch: 'boolean',\n slider: 'number',\n};\n\n/**\n * Warn when a group's described fields are about to be drawn by nothing.\n *\n * A field tree is iterated one level deep, so an object-valued field with no\n * `WR_FIELD` of its own is skipped exactly like an undescribed leaf — and its\n * children go with it. That is the right default (a model nests for reasons\n * that have nothing to do with a screen), but it is indistinguishable from a\n * half-drawn form: nothing is missing from the DOM, so nothing looks wrong.\n *\n * Describing the children and getting none of them is never intentional, so\n * that exact shape is what this reports. A group whose children carry no spec\n * either is silent, because it is a model detail this screen does not render.\n */\nfunction warnOnUndrawnGroup(key: string, group: unknown): void {\n // A field tree over a primitive is not iterable, and every undescribed leaf\n // arrives here — so the guard is what keeps this from throwing on the common\n // case rather than a defence against an exotic one.\n const subfields = (group as Partial<Iterable<[string, unknown]>>)[Symbol.iterator];\n if (typeof subfields !== 'function') return;\n\n let described = 0;\n for (const [, child] of group as Iterable<[string, unknown]>) {\n if (isFieldTree(child) && (child as Field<never>)().metadata(WR_FIELD)?.()) described++;\n }\n if (described === 0) return;\n\n // eslint-disable-next-line no-console -- dev-mode validation\n console.warn(\n `[NGWR] <wr-schema-form>: \"${key}\" is a group holding ${described} described ` +\n `field(s), and none of them are drawn — a field tree is walked one level deep. ` +\n `Draw the group with a second <wr-schema-form [field]=\"form.${key}\" />, or give ` +\n `\"${key}\" a WR_FIELD of its own if this screen is meant to skip it.`\n );\n}\n\n/**\n * Warn when a `kind` contradicts what the field actually holds.\n *\n * This is the one failure mode of the whole component that nothing else\n * reports: `kind` is a string on a metadata value, so TypeScript cannot hold it\n * against the field's own type, and a `kind: 'number'` on a `string` field\n * renders a `<wr-input-number>` that writes numbers into it forever. The runtime\n * value is the only evidence available, so an empty or nullish one says nothing\n * and is left alone.\n */\nfunction warnOnKindMismatch(f: WrRenderedField): void {\n const expected = EXPECTED_TYPE[f.spec.kind];\n const value = f.field().value();\n if (!expected || value === null || value === undefined || value === '') return;\n if (typeof value === expected) return;\n\n // eslint-disable-next-line no-console -- dev-mode validation\n console.warn(\n `[NGWR] <wr-schema-form>: field \"${f.key}\" is described as kind '${f.spec.kind}', ` +\n `which writes a ${expected}, but the field holds a ${typeof value}. ` +\n `The control will overwrite the model with the wrong type.`\n );\n}\n\n/**\n * A form drawn from a Signal Forms schema — one `<wr-form-field>`, one control\n * and one set of error messages per described field, laid out on a grid.\n *\n * The presentation rides on the SAME schema as the validation, through the\n * `WR_FIELD` metadata key from `ngwr/form`:\n *\n * ```ts\n * const profile = form(model, path => {\n * required(path.email);\n * email(path.email);\n * metadata(path.email, WR_FIELD, () => ({ kind: 'input', type: 'email' }));\n * metadata(path.role, WR_FIELD, () => ({ kind: 'select', options: ROLES }));\n * });\n * ```\n * ```html\n * <wr-schema-form [field]=\"profile\" [columns]=\"2\" />\n * ```\n *\n * **A field with no `WR_FIELD` metadata is skipped**, silently and on purpose: a\n * schema may describe more than one screen renders, and guessing a control from\n * a field's type would draw a `wr-switch` for every boolean flag in the model.\n * Order is the model's own key order.\n *\n * **`required`, `disabled`, `readonly` and `hidden` are NOT in the spec.** They\n * are Angular's own schema functions, `[formField]` already applies the first\n * three to the control, and this component reads `hidden()` to decide whether to\n * draw the field at all — which Angular's docs say a template has to do itself.\n * Re-declaring any of them here would be a second source of truth for state the\n * form already owns.\n *\n * **Why its own entry point rather than `ngwr/form`.** Drawing nine kinds means\n * depending on nine controls, and `ngwr/form` is the layout primitive every\n * form imports — folding this in would put a date picker and a slider into the\n * bundle of an app that only wanted `<wr-form-field>`.\n *\n * @see https://ngwr.dev/reference/components/schema-form\n */\n@Component({\n selector: 'wr-schema-form',\n templateUrl: './schema-form.html',\n encapsulation: ViewEncapsulation.None,\n imports: [\n FormField,\n WrCheckbox,\n WrDatePicker,\n WrFormField,\n WrInput,\n WrInputNumber,\n WrOption,\n WrRadio,\n WrRadioGroup,\n WrSelect,\n WrSlider,\n WrSwitch,\n WrTextarea,\n ],\n host: {\n class: 'wr-schema-form',\n '[style.grid-template-columns]': 'template()',\n },\n})\nexport class WrSchemaForm<T extends object> {\n // Generic, rather than `FieldTree<Record<string, unknown>>`, because a model\n // declared as an `interface` has no index signature and is not assignable to\n // that: every consumer would have had to declare their model as a type alias\n // just to bind it. `T extends object` still refuses a field tree over a\n // primitive, which has no subfields and would draw nothing.\n /**\n * The form to draw — the value `form()` returned, or any object-valued field\n * inside one.\n */\n readonly field = input.required<FieldTree<T>>();\n\n /**\n * Grid columns. A field spans one of them unless its spec says otherwise.\n * @default 1\n */\n readonly columns = input(1, { transform: numAttr(1) });\n\n /**\n * The track list, written as a style rather than published as a\n * `--wr-schema-form-columns` hook: `columns` always has a value, so the\n * inline style would win over any declaration a consumer wrote and the hook\n * would be one nobody could use.\n */\n protected readonly template = computed(() => `repeat(${Math.max(1, this.columns())}, minmax(0, 1fr))`);\n\n /**\n * The described fields, in the model's key order.\n *\n * A field tree over an object is iterable as `[key, field]` pairs, which is\n * the whole reason this component needs no field list of its own. `isFieldTree`\n * guards the pair: a model carrying a method or a non-field property would\n * otherwise be read as a field and answer `undefined` to everything.\n */\n protected readonly fields = computed<readonly WrRenderedField[]>(() => {\n const columns = this.columns();\n const out: WrRenderedField[] = [];\n\n for (const [key, child] of this.field() as unknown as Iterable<[string, unknown]>) {\n if (!isFieldTree(child)) continue;\n\n const field = child as Field<never>;\n const spec = field().metadata(WR_FIELD)?.();\n if (!spec) {\n if (isDevMode()) warnOnUndrawnGroup(key, child);\n continue;\n }\n\n const label = spec.label ?? wrFieldLabel(key);\n const span = Math.min(Math.max(Math.round(spec.span ?? 1), 1), columns);\n out.push({\n key,\n field,\n spec,\n label,\n labelAbove: SELF_LABELLING.has(spec.kind) ? '' : label,\n column: `span ${span}`,\n });\n }\n\n if (isDevMode()) out.forEach(f => warnOnKindMismatch(f));\n return out;\n });\n}\n","@for (f of fields(); track f.key) {\n @let state = f.field();\n\n <!-- Angular's `hidden()` does not hide anything on its own; the docs are\n explicit that the template has to honour it. -->\n @if (!state.hidden()) {\n <div class=\"wr-schema-form__field\" [style.grid-column]=\"f.column\">\n <wr-form-field [label]=\"f.labelAbove\" [hint]=\"f.spec.hint ?? ''\" [required]=\"state.required()\">\n @switch (f.spec.kind) {\n @case ('textarea') {\n <wr-textarea [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('number') {\n <wr-input-number\n [formField]=\"f.field\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n [step]=\"f.spec.step ?? 1\"\n [ariaLabel]=\"f.label\"\n />\n }\n @case ('select') {\n <wr-select [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? null\" [ariaLabel]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-option [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-option>\n }\n </wr-select>\n }\n @case ('checkbox') {\n <wr-checkbox [formField]=\"f.field\">{{ f.label }}</wr-checkbox>\n }\n @case ('switch') {\n <wr-switch [formField]=\"f.field\">{{ f.label }}</wr-switch>\n }\n @case ('radio') {\n <!-- `wr-radio-group` has no `ariaLabel` input, and needs none: its\n host is a `role=\"radiogroup\"`, where `aria-label` is legal. -->\n <wr-radio-group [formField]=\"f.field\" [attr.aria-label]=\"f.label\">\n @for (option of f.spec.options ?? []; track option.value) {\n <wr-radio [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">{{ option.label }}</wr-radio>\n }\n </wr-radio-group>\n }\n @case ('date') {\n <wr-date-picker [formField]=\"f.field\" [placeholder]=\"f.spec.placeholder ?? ''\" [ariaLabel]=\"f.label\" />\n }\n @case ('slider') {\n <wr-slider [formField]=\"f.field\" [step]=\"f.spec.step ?? 1\" [ariaLabel]=\"f.label\" />\n }\n @default {\n <input\n wrInput\n [formField]=\"f.field\"\n [type]=\"f.spec.type ?? 'text'\"\n [placeholder]=\"f.spec.placeholder ?? ''\"\n />\n }\n }\n </wr-form-field>\n </div>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -92,10 +92,10 @@ class WrScroll {
92
92
  else
93
93
  container.scrollTo(options);
94
94
  }
95
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrScroll, deps: [], target: i0.ɵɵFactoryTarget.Service });
96
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrScroll });
95
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrScroll, deps: [], target: i0.ɵɵFactoryTarget.Service });
96
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.6", ngImport: i0, type: WrScroll });
97
97
  }
98
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrScroll, decorators: [{
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrScroll, decorators: [{
99
99
  type: Service
100
100
  }] });
101
101
 
@@ -197,10 +197,10 @@ class WrSegmented {
197
197
  return;
198
198
  this.touch.emit();
199
199
  }
200
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSegmented, deps: [], target: i0.ɵɵFactoryTarget.Component });
201
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSegmented, isStandalone: true, selector: "wr-segmented", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { attributes: { "role": "group" }, listeners: { "focusout": "onFocusOut($event)" }, properties: { "class": "classes()", "style": "thumbStyle()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "ariaInvalid()" } }, ngImport: i0, template: "<span class=\"wr-segmented__thumb\" aria-hidden=\"true\"></span>\n\n<!--\n `id` on the FIRST segment only: it is the id a surrounding `<wr-form-field>`\n already points its `<label for>` at, and a `for` may only name a labelable\n element \u2014 see `controlId` in the component. `null` without a field, so a bare\n strip stamps no document-global id on anything.\n-->\n@for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"wr-segmented__option\"\n [attr.id]=\"$first ? controlId() : null\"\n [class.wr-segmented__option--selected]=\"isSelected(option)\"\n [disabled]=\"disabled() || !!option.disabled\"\n [attr.aria-pressed]=\"isSelected(option)\"\n [attr.aria-label]=\"option.label ? null : (option.ariaLabel ?? option.value)\"\n (click)=\"select(option)\"\n >\n @if (option.icon) {\n <wr-icon class=\"wr-segmented__icon\" [name]=\"option.icon\" />\n }\n @if (option.label) {\n <span class=\"wr-segmented__label\">{{ option.label }}</span>\n }\n </button>\n}\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
200
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSegmented, deps: [], target: i0.ɵɵFactoryTarget.Component });
201
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrSegmented, isStandalone: true, selector: "wr-segmented", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { attributes: { "role": "group" }, listeners: { "focusout": "onFocusOut($event)" }, properties: { "class": "classes()", "style": "thumbStyle()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "ariaInvalid()" } }, ngImport: i0, template: "<span class=\"wr-segmented__thumb\" aria-hidden=\"true\"></span>\n\n<!--\n `id` on the FIRST segment only: it is the id a surrounding `<wr-form-field>`\n already points its `<label for>` at, and a `for` may only name a labelable\n element \u2014 see `controlId` in the component. `null` without a field, so a bare\n strip stamps no document-global id on anything.\n-->\n@for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"wr-segmented__option\"\n [attr.id]=\"$first ? controlId() : null\"\n [class.wr-segmented__option--selected]=\"isSelected(option)\"\n [disabled]=\"disabled() || !!option.disabled\"\n [attr.aria-pressed]=\"isSelected(option)\"\n [attr.aria-label]=\"option.label ? null : (option.ariaLabel ?? option.value)\"\n (click)=\"select(option)\"\n >\n @if (option.icon) {\n <wr-icon class=\"wr-segmented__icon\" [name]=\"option.icon\" />\n }\n @if (option.label) {\n <span class=\"wr-segmented__label\">{{ option.label }}</span>\n }\n </button>\n}\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
202
202
  }
203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSegmented, decorators: [{
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSegmented, decorators: [{
204
204
  type: Component,
205
205
  args: [{ selector: 'wr-segmented', encapsulation: ViewEncapsulation.None, host: {
206
206
  '[class]': 'classes()',