ngwr 14.3.1 → 14.5.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 (368) hide show
  1. package/README.md +4 -4
  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 +7 -7
  24. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  25. package/fesm2022/ngwr-burger.mjs +3 -3
  26. package/fesm2022/ngwr-button.mjs +6 -6
  27. package/fesm2022/ngwr-calendar-heatmap-testing.mjs +12 -9
  28. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
  29. package/fesm2022/ngwr-calendar-heatmap.mjs +35 -7
  30. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  31. package/fesm2022/ngwr-calendar.mjs +32 -4
  32. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  33. package/fesm2022/ngwr-card.mjs +9 -9
  34. package/fesm2022/ngwr-carousel.mjs +6 -6
  35. package/fesm2022/ngwr-cascader-testing.mjs +87 -17
  36. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
  37. package/fesm2022/ngwr-cascader.mjs +76 -5
  38. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  39. package/fesm2022/ngwr-checkbox-testing.mjs +13 -2
  40. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
  41. package/fesm2022/ngwr-checkbox.mjs +42 -7
  42. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  43. package/fesm2022/ngwr-circular-text.mjs +3 -3
  44. package/fesm2022/ngwr-click-spark.mjs +3 -3
  45. package/fesm2022/ngwr-clipboard.mjs +3 -3
  46. package/fesm2022/ngwr-collapse.mjs +9 -9
  47. package/fesm2022/ngwr-color-picker.mjs +24 -8
  48. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  49. package/fesm2022/ngwr-command-palette.mjs +16 -3
  50. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  51. package/fesm2022/ngwr-compare.mjs +3 -3
  52. package/fesm2022/ngwr-confetti.mjs +3 -3
  53. package/fesm2022/ngwr-context-menu.mjs +47 -15
  54. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  55. package/fesm2022/ngwr-cookie.mjs +3 -3
  56. package/fesm2022/ngwr-counter.mjs +6 -6
  57. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  58. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  59. package/fesm2022/ngwr-date-picker.mjs +111 -28
  60. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  61. package/fesm2022/ngwr-date.mjs +3 -3
  62. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  63. package/fesm2022/ngwr-density.mjs +6 -6
  64. package/fesm2022/ngwr-descriptions.mjs +6 -6
  65. package/fesm2022/ngwr-dialog.mjs +27 -16
  66. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  67. package/fesm2022/ngwr-directives.mjs +12 -12
  68. package/fesm2022/ngwr-divider.mjs +3 -3
  69. package/fesm2022/ngwr-donut-chart-testing.mjs +18 -2
  70. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  71. package/fesm2022/ngwr-donut-chart.mjs +4 -4
  72. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  73. package/fesm2022/ngwr-drag-drop.mjs +7 -7
  74. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  75. package/fesm2022/ngwr-drawer.mjs +66 -20
  76. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  77. package/fesm2022/ngwr-dropdown.mjs +54 -16
  78. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  79. package/fesm2022/ngwr-empty.mjs +3 -3
  80. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  81. package/fesm2022/ngwr-falling-text.mjs +3 -3
  82. package/fesm2022/ngwr-file-upload.mjs +18 -5
  83. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  84. package/fesm2022/ngwr-form.mjs +66 -14
  85. package/fesm2022/ngwr-form.mjs.map +1 -1
  86. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  87. package/fesm2022/ngwr-gauge-testing.mjs +16 -2
  88. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
  89. package/fesm2022/ngwr-gauge.mjs +3 -3
  90. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  91. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  92. package/fesm2022/ngwr-graph-testing.mjs +243 -0
  93. package/fesm2022/ngwr-graph-testing.mjs.map +1 -0
  94. package/fesm2022/ngwr-graph.mjs +1112 -0
  95. package/fesm2022/ngwr-graph.mjs.map +1 -0
  96. package/fesm2022/ngwr-hotkey.mjs +6 -6
  97. package/fesm2022/ngwr-i18n-ar.mjs +7 -0
  98. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  99. package/fesm2022/ngwr-i18n-cs.mjs +7 -0
  100. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  101. package/fesm2022/ngwr-i18n-de.mjs +7 -0
  102. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  103. package/fesm2022/ngwr-i18n-en.mjs +23 -2
  104. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  105. package/fesm2022/ngwr-i18n-es.mjs +7 -0
  106. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  107. package/fesm2022/ngwr-i18n-fr.mjs +7 -0
  108. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  109. package/fesm2022/ngwr-i18n-he.mjs +7 -0
  110. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  111. package/fesm2022/ngwr-i18n-hi.mjs +7 -0
  112. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  113. package/fesm2022/ngwr-i18n-id.mjs +7 -0
  114. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  115. package/fesm2022/ngwr-i18n-it.mjs +7 -0
  116. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  117. package/fesm2022/ngwr-i18n-ja.mjs +7 -0
  118. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  119. package/fesm2022/ngwr-i18n-ko.mjs +7 -0
  120. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  121. package/fesm2022/ngwr-i18n-nl.mjs +7 -0
  122. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  123. package/fesm2022/ngwr-i18n-pl.mjs +7 -0
  124. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  125. package/fesm2022/ngwr-i18n-pt.mjs +7 -0
  126. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  127. package/fesm2022/ngwr-i18n-ru.mjs +7 -0
  128. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  129. package/fesm2022/ngwr-i18n-sv.mjs +7 -0
  130. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  131. package/fesm2022/ngwr-i18n-tr.mjs +7 -0
  132. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  133. package/fesm2022/ngwr-i18n-uk.mjs +7 -0
  134. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  135. package/fesm2022/ngwr-i18n-vi.mjs +7 -0
  136. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  137. package/fesm2022/ngwr-i18n-zh-TW.mjs +7 -0
  138. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  139. package/fesm2022/ngwr-i18n-zh.mjs +7 -0
  140. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  141. package/fesm2022/ngwr-i18n.mjs +9 -9
  142. package/fesm2022/ngwr-icon.mjs +6 -6
  143. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  144. package/fesm2022/ngwr-input-number.mjs +15 -6
  145. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  146. package/fesm2022/ngwr-input-otp.mjs +38 -6
  147. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  148. package/fesm2022/ngwr-input.mjs +15 -15
  149. package/fesm2022/ngwr-keyboard.mjs +3 -3
  150. package/fesm2022/ngwr-knob-testing.mjs +11 -3
  151. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  152. package/fesm2022/ngwr-knob.mjs +19 -4
  153. package/fesm2022/ngwr-knob.mjs.map +1 -1
  154. package/fesm2022/ngwr-layout.mjs +15 -15
  155. package/fesm2022/ngwr-lightbox.mjs +27 -6
  156. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  157. package/fesm2022/ngwr-line-chart-testing.mjs +18 -2
  158. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
  159. package/fesm2022/ngwr-line-chart.mjs +22 -4
  160. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  161. package/fesm2022/ngwr-list.mjs +7 -7
  162. package/fesm2022/ngwr-list.mjs.map +1 -1
  163. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  164. package/fesm2022/ngwr-markdown.mjs +6 -6
  165. package/fesm2022/ngwr-marquee.mjs +3 -3
  166. package/fesm2022/ngwr-media.mjs +3 -3
  167. package/fesm2022/ngwr-mention.mjs +24 -8
  168. package/fesm2022/ngwr-mention.mjs.map +1 -1
  169. package/fesm2022/ngwr-meta.mjs +6 -6
  170. package/fesm2022/ngwr-meter-group.mjs +3 -3
  171. package/fesm2022/ngwr-overlay.mjs +125 -10
  172. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  173. package/fesm2022/ngwr-page-header.mjs +3 -3
  174. package/fesm2022/ngwr-pagination.mjs +33 -6
  175. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  176. package/fesm2022/ngwr-pipes.mjs +21 -21
  177. package/fesm2022/ngwr-platform.mjs +9 -9
  178. package/fesm2022/ngwr-popconfirm.mjs +25 -9
  179. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  180. package/fesm2022/ngwr-popover-testing.mjs +22 -5
  181. package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
  182. package/fesm2022/ngwr-popover.mjs +243 -37
  183. package/fesm2022/ngwr-popover.mjs.map +1 -1
  184. package/fesm2022/ngwr-progress.mjs +3 -3
  185. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  186. package/fesm2022/ngwr-qr.mjs +3 -3
  187. package/fesm2022/ngwr-radio.mjs +6 -6
  188. package/fesm2022/ngwr-rating-testing.mjs +12 -3
  189. package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
  190. package/fesm2022/ngwr-rating.mjs +19 -4
  191. package/fesm2022/ngwr-rating.mjs.map +1 -1
  192. package/fesm2022/ngwr-result.mjs +13 -13
  193. package/fesm2022/ngwr-result.mjs.map +1 -1
  194. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  195. package/fesm2022/ngwr-schema-form.mjs +3 -3
  196. package/fesm2022/ngwr-scroll.mjs +3 -3
  197. package/fesm2022/ngwr-segmented.mjs +37 -4
  198. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  199. package/fesm2022/ngwr-select.mjs +24 -10
  200. package/fesm2022/ngwr-select.mjs.map +1 -1
  201. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  202. package/fesm2022/ngwr-sidebar.mjs +3 -3
  203. package/fesm2022/ngwr-skeleton.mjs +3 -3
  204. package/fesm2022/ngwr-slider.mjs +18 -5
  205. package/fesm2022/ngwr-slider.mjs.map +1 -1
  206. package/fesm2022/ngwr-sparkline.mjs +3 -3
  207. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  208. package/fesm2022/ngwr-spinner.mjs +3 -3
  209. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  210. package/fesm2022/ngwr-split-text.mjs +3 -3
  211. package/fesm2022/ngwr-splitter.mjs +3 -3
  212. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  213. package/fesm2022/ngwr-squircle.mjs +28 -9
  214. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  215. package/fesm2022/ngwr-star-border.mjs +3 -3
  216. package/fesm2022/ngwr-statistic.mjs +20 -13
  217. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  218. package/fesm2022/ngwr-stepper.mjs +6 -6
  219. package/fesm2022/ngwr-storage.mjs +3 -3
  220. package/fesm2022/ngwr-switch.mjs +3 -3
  221. package/fesm2022/ngwr-table.mjs +18 -18
  222. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  223. package/fesm2022/ngwr-tabs.mjs +6 -6
  224. package/fesm2022/ngwr-textarea.mjs +3 -3
  225. package/fesm2022/ngwr-theme.mjs +3 -3
  226. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  227. package/fesm2022/ngwr-timeline.mjs +6 -6
  228. package/fesm2022/ngwr-toast.mjs +29 -12
  229. package/fesm2022/ngwr-toast.mjs.map +1 -1
  230. package/fesm2022/ngwr-toolbar.mjs +3 -3
  231. package/fesm2022/ngwr-tour.mjs +26 -12
  232. package/fesm2022/ngwr-tour.mjs.map +1 -1
  233. package/fesm2022/ngwr-transfer.mjs +88 -11
  234. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  235. package/fesm2022/ngwr-tree-testing.mjs +24 -0
  236. package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
  237. package/fesm2022/ngwr-tree.mjs +81 -9
  238. package/fesm2022/ngwr-tree.mjs.map +1 -1
  239. package/fesm2022/ngwr-typewriter.mjs +3 -3
  240. package/fesm2022/ngwr-typography.mjs +3 -3
  241. package/fesm2022/ngwr-version.mjs +1 -1
  242. package/fesm2022/ngwr-version.mjs.map +1 -1
  243. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  244. package/fesm2022/ngwr-waves.mjs +3 -3
  245. package/fesm2022/ngwr-window.mjs +30 -13
  246. package/fesm2022/ngwr-window.mjs.map +1 -1
  247. package/form/styles/_index.scss +63 -0
  248. package/graph/styles/_index.scss +113 -0
  249. package/i18n/ar.json +9 -2
  250. package/i18n/cs.json +9 -2
  251. package/i18n/de.json +9 -2
  252. package/i18n/en.json +11 -4
  253. package/i18n/es.json +9 -2
  254. package/i18n/fr.json +9 -2
  255. package/i18n/he.json +9 -2
  256. package/i18n/hi.json +9 -2
  257. package/i18n/id.json +9 -2
  258. package/i18n/it.json +9 -2
  259. package/i18n/ja.json +9 -2
  260. package/i18n/ko.json +9 -2
  261. package/i18n/nl.json +9 -2
  262. package/i18n/pl.json +9 -2
  263. package/i18n/pt.json +9 -2
  264. package/i18n/ru.json +9 -2
  265. package/i18n/sv.json +9 -2
  266. package/i18n/tr.json +9 -2
  267. package/i18n/uk.json +9 -2
  268. package/i18n/vi.json +9 -2
  269. package/i18n/zh-TW.json +9 -2
  270. package/i18n/zh.json +9 -2
  271. package/input-otp/styles/_index.scss +5 -1
  272. package/line-chart/styles/_index.scss +5 -3
  273. package/llms-full.txt +13 -3
  274. package/llms.txt +8 -6
  275. package/markdown/styles/_index.scss +4 -1
  276. package/mention/styles/_index.scss +22 -1
  277. package/package.json +10 -1
  278. package/radio/styles/_index.scss +3 -0
  279. package/result/styles/_index.scss +12 -0
  280. package/schematics/migrations/v14/index.js +6 -3
  281. package/schematics/migrations.json +1 -1
  282. package/schematics/ng-add/index.js +34 -5
  283. package/schematics/use/symbol-map.json +2 -0
  284. package/segmented/styles/_index.scss +12 -1
  285. package/select/styles/_index.scss +20 -1
  286. package/skills/ngwr/SKILL.md +1 -1
  287. package/skills/ngwr/references/catalog.md +2 -0
  288. package/statistic/styles/_index.scss +4 -0
  289. package/stepper/styles/_index.scss +36 -0
  290. package/styles.scss +1 -0
  291. package/switch/styles/_index.scss +3 -0
  292. package/table/styles/_index.scss +12 -0
  293. package/tabs/styles/_index.scss +4 -1
  294. package/textarea/styles/_index.scss +6 -1
  295. package/theme/styles/_colors.scss +11 -0
  296. package/theme/styles/_contrast.scss +136 -0
  297. package/theme/styles/_focus.scss +7 -0
  298. package/theme/styles/_index.scss +1 -0
  299. package/theme/styles/_mixins.scss +15 -8
  300. package/timeline/styles/_index.scss +28 -1
  301. package/toast/styles/_index.scss +11 -0
  302. package/tree/styles/_index.scss +27 -1
  303. package/types/ngwr-badge.d.ts +1 -1
  304. package/types/ngwr-bar-chart-testing.d.ts +11 -1
  305. package/types/ngwr-button.d.ts +1 -1
  306. package/types/ngwr-calendar-heatmap-testing.d.ts +10 -5
  307. package/types/ngwr-calendar-heatmap.d.ts +22 -0
  308. package/types/ngwr-calendar.d.ts +21 -0
  309. package/types/ngwr-cascader-testing.d.ts +74 -17
  310. package/types/ngwr-cascader.d.ts +35 -0
  311. package/types/ngwr-checkbox-testing.d.ts +12 -1
  312. package/types/ngwr-checkbox.d.ts +10 -0
  313. package/types/ngwr-clipboard.d.ts +1 -1
  314. package/types/ngwr-color-picker.d.ts +8 -0
  315. package/types/ngwr-confetti.d.ts +1 -1
  316. package/types/ngwr-context-menu.d.ts +10 -0
  317. package/types/ngwr-cookie.d.ts +1 -1
  318. package/types/ngwr-date-adapters-fns.d.ts +1 -1
  319. package/types/ngwr-date-adapters-luxon.d.ts +1 -1
  320. package/types/ngwr-date-picker.d.ts +16 -0
  321. package/types/ngwr-date.d.ts +9 -3
  322. package/types/ngwr-density.d.ts +1 -1
  323. package/types/ngwr-dialog.d.ts +2 -1
  324. package/types/ngwr-donut-chart-testing.d.ts +11 -1
  325. package/types/ngwr-drawer.d.ts +29 -1
  326. package/types/ngwr-dropdown.d.ts +25 -0
  327. package/types/ngwr-file-upload.d.ts +11 -0
  328. package/types/ngwr-form.d.ts +25 -0
  329. package/types/ngwr-gauge-testing.d.ts +9 -1
  330. package/types/ngwr-graph-testing.d.ts +190 -0
  331. package/types/ngwr-graph.d.ts +203 -0
  332. package/types/ngwr-hotkey.d.ts +1 -1
  333. package/types/ngwr-i18n.d.ts +1 -1
  334. package/types/ngwr-input-number.d.ts +12 -2
  335. package/types/ngwr-input-otp.d.ts +12 -0
  336. package/types/ngwr-knob-testing.d.ts +11 -3
  337. package/types/ngwr-knob.d.ts +13 -0
  338. package/types/ngwr-lightbox.d.ts +15 -0
  339. package/types/ngwr-line-chart-testing.d.ts +11 -1
  340. package/types/ngwr-line-chart.d.ts +18 -0
  341. package/types/ngwr-loading-bar.d.ts +1 -1
  342. package/types/ngwr-markdown.d.ts +1 -1
  343. package/types/ngwr-media.d.ts +1 -1
  344. package/types/ngwr-mention.d.ts +7 -0
  345. package/types/ngwr-meta.d.ts +1 -1
  346. package/types/ngwr-overlay.d.ts +64 -6
  347. package/types/ngwr-pagination.d.ts +16 -0
  348. package/types/ngwr-platform.d.ts +3 -3
  349. package/types/ngwr-popconfirm.d.ts +1 -0
  350. package/types/ngwr-popover-testing.d.ts +22 -5
  351. package/types/ngwr-popover.d.ts +44 -8
  352. package/types/ngwr-rating-testing.d.ts +12 -3
  353. package/types/ngwr-rating.d.ts +13 -0
  354. package/types/ngwr-scroll.d.ts +1 -1
  355. package/types/ngwr-segmented.d.ts +16 -0
  356. package/types/ngwr-select.d.ts +7 -0
  357. package/types/ngwr-squircle.d.ts +22 -3
  358. package/types/ngwr-statistic.d.ts +0 -1
  359. package/types/ngwr-storage.d.ts +1 -1
  360. package/types/ngwr-theme.d.ts +1 -1
  361. package/types/ngwr-toast.d.ts +3 -1
  362. package/types/ngwr-tour.d.ts +7 -1
  363. package/types/ngwr-transfer.d.ts +52 -0
  364. package/types/ngwr-tree-testing.d.ts +20 -0
  365. package/types/ngwr-tree.d.ts +43 -1
  366. package/types/ngwr-version.d.ts +1 -1
  367. package/types/ngwr-window.d.ts +2 -1
  368. package/typography/styles/_index.scss +26 -4
@@ -1,6 +1,6 @@
1
1
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
2
2
  import * as i0 from '@angular/core';
3
- import { InjectionToken, input, model, output, inject, computed, ViewEncapsulation, Component, forwardRef } from '@angular/core';
3
+ import { InjectionToken, input, computed, model, output, inject, ViewEncapsulation, Component, forwardRef } from '@angular/core';
4
4
  import { useConfigValue } from 'ngwr/config';
5
5
  import { useFormFieldAria } from 'ngwr/form';
6
6
  import { WrIcon } from 'ngwr/icon';
@@ -43,6 +43,27 @@ class WrCheckbox {
43
43
  */
44
44
  checkboxValue = input(null, /* @ts-ignore */
45
45
  ...(ngDevMode ? [{ debugName: "checkboxValue" }] : /* istanbul ignore next */ []));
46
+ /**
47
+ * `checkboxValue` as an attribute, when it can be one.
48
+ *
49
+ * A primitive round-trips through the DOM and is what a group identity is in
50
+ * practice. Anything else — an object, an array — has no honest attribute
51
+ * form, so the attribute is ABSENT rather than `[object Object]`: a harness
52
+ * reading it then gets `null`, which is true, instead of a string that looks
53
+ * like data and identifies nothing.
54
+ */
55
+ reflectedValue = computed(() => {
56
+ const value = this.checkboxValue();
57
+ // Narrowed inline rather than through a `typeof` held in a variable, which
58
+ // TypeScript does not follow — and the linter is right to refuse it: the
59
+ // point of this guard is that `String()` never sees an object.
60
+ if (typeof value === 'string')
61
+ return value;
62
+ if (typeof value === 'number' || typeof value === 'boolean')
63
+ return String(value);
64
+ return null;
65
+ }, /* @ts-ignore */
66
+ ...(ngDevMode ? [{ debugName: "reflectedValue" }] : /* istanbul ignore next */ []));
46
67
  /**
47
68
  * Accessible name for a checkbox used WITHOUT projected text — a selection
48
69
  * cell in a table, say. The wrapping `<label>` names the control whenever
@@ -177,10 +198,10 @@ class WrCheckbox {
177
198
  this.group.blurred();
178
199
  this.touch.emit();
179
200
  }
180
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
181
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrCheckbox, isStandalone: true, selector: "wr-checkbox", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, checkboxValue: { classPropertyName: "checkboxValue", publicName: "checkboxValue", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", 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 }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", touch: "touch" }, host: { properties: { "class": "classes()", "attr.id": "null" } }, ngImport: i0, template: "<label class=\"wr-checkbox__label\" [for]=\"id()\">\n <input\n class=\"wr-checkbox__input\"\n type=\"checkbox\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"effectiveDisabled()\"\n [attr.aria-readonly]=\"effectiveReadonly() || null\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"onInputClick($event)\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n />\n\n <span class=\"wr-checkbox__box\" aria-hidden=\"true\">\n @if (indeterminate()) {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__dash\">\n <line x1=\"3.5\" y1=\"8\" x2=\"12.5\" y2=\"8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n } @else if (icon(); as iconName) {\n <wr-icon class=\"wr-checkbox__icon\" [name]=\"iconName\" />\n } @else {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__mark\">\n <polyline\n points=\"3.5 8.5 6.5 11.5 12.5 5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </span>\n\n <span class=\"wr-checkbox__text\">\n <ng-content />\n </span>\n</label>\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
201
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
202
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrCheckbox, isStandalone: true, selector: "wr-checkbox", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, checkboxValue: { classPropertyName: "checkboxValue", publicName: "checkboxValue", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", 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 }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", touch: "touch" }, host: { properties: { "class": "classes()", "attr.id": "null", "attr.data-checkbox-value": "reflectedValue()" } }, ngImport: i0, template: "<label class=\"wr-checkbox__label\" [for]=\"id()\">\n <input\n class=\"wr-checkbox__input\"\n type=\"checkbox\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"effectiveDisabled()\"\n [attr.aria-readonly]=\"effectiveReadonly() || null\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"onInputClick($event)\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n />\n\n <span class=\"wr-checkbox__box\" aria-hidden=\"true\">\n @if (indeterminate()) {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__dash\">\n <line x1=\"3.5\" y1=\"8\" x2=\"12.5\" y2=\"8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n } @else if (icon(); as iconName) {\n <wr-icon class=\"wr-checkbox__icon\" [name]=\"iconName\" />\n } @else {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__mark\">\n <polyline\n points=\"3.5 8.5 6.5 11.5 12.5 5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </span>\n\n <span class=\"wr-checkbox__text\">\n <ng-content />\n </span>\n</label>\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
182
203
  }
183
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCheckbox, decorators: [{
204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCheckbox, decorators: [{
184
205
  type: Component,
185
206
  args: [{ selector: 'wr-checkbox', encapsulation: ViewEncapsulation.None, host: {
186
207
  '[class]': 'classes()',
@@ -191,6 +212,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
191
212
  // `getElementById` to the host — not a labelable element, so `input.labels`
192
213
  // went from 1 to 0 and `document.getElementById(id)` returned the wrong node.
193
214
  '[attr.id]': 'null',
215
+ // The group identity, reflected so a HARNESS can read it. It is the only
216
+ // way: `checkboxValue` is an `unknown`-typed TypeScript value that reaches
217
+ // no attribute otherwise, and `WrCheckboxHarness.getCheckboxValue()` read
218
+ // `value` off the inner `<input>` — which nothing writes, so it answered
219
+ // `null` for every checkbox in every state. A harness method that answers
220
+ // the same for a working component and a broken one is the one thing the
221
+ // harness rules forbid outright.
222
+ //
223
+ // `data-`, deliberately, and NOT `value`: a leftover static `value="x"` from
224
+ // before v9 still lands on this host as a plain attribute, so reading
225
+ // `value` here would report the identity a consumer THOUGHT they set while
226
+ // the component used `null`. That is the exact confusion migration-v9
227
+ // exists to end.
228
+ '[attr.data-checkbox-value]': 'reflectedValue()',
194
229
  }, imports: [WrIcon], template: "<label class=\"wr-checkbox__label\" [for]=\"id()\">\n <input\n class=\"wr-checkbox__input\"\n type=\"checkbox\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"effectiveDisabled()\"\n [attr.aria-readonly]=\"effectiveReadonly() || null\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"onInputClick($event)\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n />\n\n <span class=\"wr-checkbox__box\" aria-hidden=\"true\">\n @if (indeterminate()) {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__dash\">\n <line x1=\"3.5\" y1=\"8\" x2=\"12.5\" y2=\"8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n } @else if (icon(); as iconName) {\n <wr-icon class=\"wr-checkbox__icon\" [name]=\"iconName\" />\n } @else {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__mark\">\n <polyline\n points=\"3.5 8.5 6.5 11.5 12.5 5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </span>\n\n <span class=\"wr-checkbox__text\">\n <ng-content />\n </span>\n</label>\n" }]
195
230
  }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], checkboxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkboxValue", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], touch: [{ type: i0.Output, args: ["touch"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }] } });
196
231
 
@@ -274,8 +309,8 @@ class WrCheckboxGroup {
274
309
  blurred() {
275
310
  this.touch.emit();
276
311
  }
277
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCheckboxGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
278
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrCheckboxGroup, isStandalone: true, selector: "wr-checkbox-group", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { attributes: { "role": "group" }, properties: { "attr.aria-invalid": "fieldAria.ariaInvalid()", "attr.aria-describedby": "fieldAria.describedBy()" }, classAttribute: "wr-checkbox-group" }, providers: [
312
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCheckboxGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
313
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrCheckboxGroup, isStandalone: true, selector: "wr-checkbox-group", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { attributes: { "role": "group" }, properties: { "attr.aria-invalid": "fieldAria.ariaInvalid()", "attr.aria-describedby": "fieldAria.describedBy()" }, classAttribute: "wr-checkbox-group" }, providers: [
279
314
  {
280
315
  provide: WR_CHECKBOX_GROUP,
281
316
  // eslint-disable-next-line @angular-eslint/no-forward-ref
@@ -283,7 +318,7 @@ class WrCheckboxGroup {
283
318
  },
284
319
  ], ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
285
320
  }
286
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCheckboxGroup, decorators: [{
321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCheckboxGroup, decorators: [{
287
322
  type: Component,
288
323
  args: [{
289
324
  selector: 'wr-checkbox-group',
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-checkbox.mjs","sources":["../../../projects/lib/checkbox/tokens/checkbox-group.token.ts","../../../projects/lib/checkbox/checkbox.ts","../../../projects/lib/checkbox/checkbox.html","../../../projects/lib/checkbox/checkbox-group.ts","../../../projects/lib/checkbox/ngwr-checkbox.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 { InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Contract a checkbox uses to talk to its parent `<wr-checkbox-group>`.\n *\n * @internal\n */\nexport interface WrCheckboxGroupContext {\n /** Is the given value currently selected? */\n isSelected(value: unknown): boolean;\n /** Toggle the given value in the group. */\n toggle(value: unknown): void;\n /**\n * A child lost focus.\n *\n * The group is the control a form binds to, so it is the group that has to\n * report touched — and a child's own `touch` output goes nowhere, since the\n * group never listens to it. Without this channel the only way to mark a\n * group touched was to CHANGE it: tabbing through every box and picking none\n * left the field pristine, so a `required` group showed no error until the\n * user toggled something, which is the one thing they had decided not to do.\n */\n blurred(): void;\n /** Whether the entire group is disabled. */\n readonly isDisabled: Signal<boolean>;\n /** Whether the entire group refuses edits while staying focusable. */\n readonly isReadonly: Signal<boolean>;\n}\n\n/**\n * Token a `<wr-checkbox>` injects to read selection state from — and\n * toggle values in — its parent `<wr-checkbox-group>` (when present).\n *\n * @internal\n */\nexport const WR_CHECKBOX_GROUP = new InjectionToken<WrCheckboxGroupContext>('WR_CHECKBOX_GROUP');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, inject, input, model, output } from '@angular/core';\nimport type { FormCheckboxControl } from '@angular/forms/signals';\n\nimport { useConfigValue } from 'ngwr/config';\nimport { useFormFieldAria } from 'ngwr/form';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { randomId } from 'ngwr/utils';\n\nimport { WR_CHECKBOX_GROUP } from './tokens';\n\n/**\n * Two-state checkbox.\n *\n * A signal-forms native control: it implements `FormCheckboxControl`, so\n * `[formField]` binds straight to its `checked` model — no\n * `ControlValueAccessor` in between. `[(checked)]` works standalone, and\n * classic `[(ngModel)]` / reactive forms keep working through Angular's bridge.\n *\n * @example\n * ```html\n * <wr-checkbox [(checked)]=\"agree\">I agree</wr-checkbox>\n * <wr-checkbox [formField]=\"form.agree\">I agree</wr-checkbox>\n * ```\n *\n * **Inside `<wr-checkbox-group>`** — the checkbox's `checkboxValue` is added to\n * or removed from the group's array, and the group is the native form control.\n * (The identity input is `checkboxValue`, not `value`, because\n * `FormCheckboxControl` reserves `value` — its form state is the boolean\n * `checked`.)\n *\n * @example\n * ```html\n * <wr-checkbox-group [formField]=\"form.features\">\n * <wr-checkbox checkboxValue=\"autosave\">Autosave</wr-checkbox>\n * <wr-checkbox checkboxValue=\"notifications\">Notifications</wr-checkbox>\n * </wr-checkbox-group>\n * ```\n *\n * @see https://ngwr.dev/reference/components/checkbox\n */\nexport type WrCheckboxSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-checkbox',\n templateUrl: './checkbox.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // The `id` input belongs to the native input, not to this element. A static\n // `id=\"x\"` in a consumer's template is written to the host as a plain\n // attribute AS WELL as fed to the input, which put two elements with the\n // same id in the document and made `<label for>` resolve through\n // `getElementById` to the host — not a labelable element, so `input.labels`\n // went from 1 to 0 and `document.getElementById(id)` returned the wrong node.\n '[attr.id]': 'null',\n },\n imports: [WrIcon],\n})\nexport class WrCheckbox implements FormCheckboxControl {\n /**\n * Stable id used to associate the native input with its label. Lands on the\n * inner `<input>`; the host never keeps it.\n *\n * @default Randomly generated\n */\n readonly id = input<string>(randomId('wr-checkbox'));\n\n /**\n * This checkbox's identity when inside a `<wr-checkbox-group>` — the value\n * added to / removed from the group's array. Ignored in standalone mode.\n * (Named `checkboxValue`, not `value`, because `FormCheckboxControl` reserves\n * `value`.)\n */\n readonly checkboxValue = input<unknown>(null);\n\n /**\n * Accessible name for a checkbox used WITHOUT projected text — a selection\n * cell in a table, say. The wrapping `<label>` names the control whenever\n * content is projected; with none, the native input has no name, and an\n * `aria-label` put on the host lands on a `<wr-checkbox>` element that no\n * screen reader ever announces.\n */\n readonly ariaLabel = input<string | null>(null);\n\n /**\n * Checked state — the form value. Bound by `[formField]`, two-way via\n * `[(checked)]`, or `[(ngModel)]`. Ignored inside a `<wr-checkbox-group>`,\n * where the group's array is the source of truth.\n */\n readonly checked = model<boolean>(false);\n\n /** Emitted on blur so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /**\n * Disable the checkbox. 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 /**\n * Refuse edits while staying focusable and submittable. Bound automatically\n * from the field's readonly state when used with `[formField]`.\n *\n * A native `<input type=\"checkbox\">` ignores the `readonly` attribute, so this\n * cancels the click's activation behaviour instead — which covers Space too,\n * since a checkbox turns Space into a click — and mirrors the state as\n * `aria-readonly`, which role `checkbox` supports.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Control size — shares the `--wr-control-*` contract. Unset falls back to the\n * `checkbox.size` app default from `provideWrConfig()`. @default 'md'\n */\n readonly size = input<WrCheckboxSize | null>(null);\n\n /** `size`, then the app config, then `md`. @internal */\n protected readonly resolvedSize = useConfigValue(this.size, c => c.checkbox?.size, 'md');\n\n /**\n * Optional icon name rendered inside the box when checked, in place of the\n * default checkmark. Use any registered NGWR icon.\n */\n readonly icon = input<WrIconName | null>(null);\n\n /**\n * Show the indeterminate (\"mixed\") state — a dash instead of a check. Visual\n * only and controlled: set it yourself for a parent \"select all\" whose\n * children are partly checked, and clear it on the next toggle. Takes visual\n * precedence over `checked`; the native input reports `aria-checked=\"mixed\"`.\n *\n * @default false\n */\n readonly indeterminate = input(false, { transform: coerceBooleanProperty });\n\n private readonly group = inject(WR_CHECKBOX_GROUP, { optional: true });\n\n /** Rendered \"is checked\" — reads the group when grouped, else the `checked` model. */\n protected readonly isChecked = computed(() =>\n this.group ? this.group.isSelected(this.checkboxValue()) : this.checked()\n );\n\n /** Effective disabled — the `disabled` input wins, then the group. */\n protected readonly effectiveDisabled = computed(() => {\n if (this.disabled()) return true;\n return this.group ? this.group.isDisabled() : false;\n });\n\n /** Effective readonly — this box's own `readonly` input, or the group's. */\n protected readonly effectiveReadonly = computed(() => {\n if (this.readonly()) return true;\n return this.group ? this.group.isReadonly() : false;\n });\n\n /**\n * The surrounding `<wr-form-field>`'s error state, mirrored onto the native\n * input. Inside a `<wr-checkbox-group>` the GROUP is the bound control and\n * carries the state, so a grouped box shields itself and stays silent — nine\n * boxes each announcing the group's one error is noise, not information.\n */\n private readonly fieldAria = useFormFieldAria();\n protected readonly ariaInvalid = computed(() => (this.group ? null : this.fieldAria.ariaInvalid()));\n protected readonly describedBy = computed(() => (this.group ? null : this.fieldAria.describedBy()));\n\n protected readonly classes = computed(() => {\n const parts = ['wr-checkbox'];\n const size = this.resolvedSize();\n if (size !== 'md') parts.push(`wr-checkbox--${size}`);\n if (this.indeterminate()) parts.push('wr-checkbox--indeterminate');\n else if (this.isChecked()) parts.push('wr-checkbox--checked');\n if (this.effectiveDisabled()) parts.push('wr-checkbox--disabled');\n else if (this.effectiveReadonly()) parts.push('wr-checkbox--readonly');\n return parts.join(' ');\n });\n\n // Template handlers\n\n /**\n * Cancel the toggle while readonly. `change` never fires for a click whose\n * default was prevented, so this is the only guard the pointer and Space\n * paths need; `onInputChange` keeps its own for a synthetic `change`.\n */\n protected onInputClick(event: Event): void {\n if (this.effectiveReadonly()) event.preventDefault();\n }\n\n protected onInputChange(event: Event): void {\n if (this.effectiveReadonly()) {\n // A synthetic `change` cannot be prevented — put the DOM back instead.\n (event.target as HTMLInputElement).checked = this.isChecked();\n return;\n }\n if (this.group) {\n this.group.toggle(this.checkboxValue());\n return;\n }\n this.checked.set((event.target as HTMLInputElement).checked);\n }\n\n protected onInputBlur(): void {\n // Inside a group the GROUP is the bound control, and its own `touch` is\n // what a form listens to; the child's output is wired to nothing there.\n if (this.group) this.group.blurred();\n this.touch.emit();\n }\n}\n","<label class=\"wr-checkbox__label\" [for]=\"id()\">\n <input\n class=\"wr-checkbox__input\"\n type=\"checkbox\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"effectiveDisabled()\"\n [attr.aria-readonly]=\"effectiveReadonly() || null\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"onInputClick($event)\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n />\n\n <span class=\"wr-checkbox__box\" aria-hidden=\"true\">\n @if (indeterminate()) {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__dash\">\n <line x1=\"3.5\" y1=\"8\" x2=\"12.5\" y2=\"8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n } @else if (icon(); as iconName) {\n <wr-icon class=\"wr-checkbox__icon\" [name]=\"iconName\" />\n } @else {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__mark\">\n <polyline\n points=\"3.5 8.5 6.5 11.5 12.5 5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </span>\n\n <span class=\"wr-checkbox__text\">\n <ng-content />\n </span>\n</label>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, forwardRef, input, model, output } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { useFormFieldAria } from 'ngwr/form';\n\nimport { WR_CHECKBOX_GROUP, type WrCheckboxGroupContext } from './tokens';\n\n/**\n * Manages a group of `<wr-checkbox>` children as a single form value\n * (an array of the checked items' `value` inputs).\n *\n * A signal-forms native control: it implements `FormValueControl<unknown[]>`,\n * so `[formField]` binds to its `value` model. `[(value)]` works standalone,\n * and classic `[(ngModel)]` / reactive forms keep working through the bridge.\n *\n * @example\n * ```html\n * <wr-checkbox-group [formField]=\"form.features\">\n * <wr-checkbox checkboxValue=\"autosave\">Autosave</wr-checkbox>\n * <wr-checkbox checkboxValue=\"notifications\">Notifications</wr-checkbox>\n * <wr-checkbox checkboxValue=\"darkmode\">Dark mode</wr-checkbox>\n * </wr-checkbox-group>\n * ```\n *\n * @see https://ngwr.dev/reference/components/checkbox\n */\n@Component({\n selector: 'wr-checkbox-group',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-checkbox-group',\n role: 'group',\n '[attr.aria-invalid]': 'fieldAria.ariaInvalid()',\n '[attr.aria-describedby]': 'fieldAria.describedBy()',\n },\n providers: [\n {\n provide: WR_CHECKBOX_GROUP,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => WrCheckboxGroup),\n },\n ],\n})\nexport class WrCheckboxGroup implements FormValueControl<unknown[]>, WrCheckboxGroupContext {\n /**\n * Disable every child checkbox. Bound automatically from the field's\n * disabled state when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse edits on every child while they stay focusable and the value still\n * submits. Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * No `aria-readonly` on the host: role `group` does not support it (the state\n * is not global), so each child box mirrors its own instead.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** The surrounding `<wr-form-field>`'s error state. @internal */\n protected readonly fieldAria = useFormFieldAria();\n\n /** The checked items' values. Bound by `[formField]`, or two-way via `[(value)]`. */\n readonly value = model<unknown[]>([]);\n\n /** Emitted when a child toggles so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n // The current selection as a guaranteed array — a classic-forms binding can\n // write null even though the type is `unknown[]`, so normalise every read.\n private readonly selected = computed<readonly unknown[]>(() => {\n const v = this.value();\n return Array.isArray(v) ? v : [];\n });\n\n /** Effective disabled state (WrCheckboxGroupContext). */\n readonly isDisabled = computed(() => this.disabled());\n\n /** Effective readonly state (WrCheckboxGroupContext). */\n readonly isReadonly = computed(() => this.readonly());\n\n // WrCheckboxGroupContext\n\n isSelected(value: unknown): boolean {\n return this.selected().includes(value);\n }\n\n toggle(value: unknown): void {\n if (this.isDisabled() || this.isReadonly()) return;\n const current = this.selected();\n const next = current.includes(value) ? current.filter(v => v !== value) : [...current, value];\n this.value.set(next);\n this.touch.emit();\n }\n\n /** @internal A child checkbox lost focus — see {@link WrCheckboxGroupContext.blurred}. */\n blurred(): void {\n this.touch.emit();\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-checkbox.mjs","sources":["../../../projects/lib/checkbox/tokens/checkbox-group.token.ts","../../../projects/lib/checkbox/checkbox.ts","../../../projects/lib/checkbox/checkbox.html","../../../projects/lib/checkbox/checkbox-group.ts","../../../projects/lib/checkbox/ngwr-checkbox.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 { InjectionToken, type Signal } from '@angular/core';\n\n/**\n * Contract a checkbox uses to talk to its parent `<wr-checkbox-group>`.\n *\n * @internal\n */\nexport interface WrCheckboxGroupContext {\n /** Is the given value currently selected? */\n isSelected(value: unknown): boolean;\n /** Toggle the given value in the group. */\n toggle(value: unknown): void;\n /**\n * A child lost focus.\n *\n * The group is the control a form binds to, so it is the group that has to\n * report touched — and a child's own `touch` output goes nowhere, since the\n * group never listens to it. Without this channel the only way to mark a\n * group touched was to CHANGE it: tabbing through every box and picking none\n * left the field pristine, so a `required` group showed no error until the\n * user toggled something, which is the one thing they had decided not to do.\n */\n blurred(): void;\n /** Whether the entire group is disabled. */\n readonly isDisabled: Signal<boolean>;\n /** Whether the entire group refuses edits while staying focusable. */\n readonly isReadonly: Signal<boolean>;\n}\n\n/**\n * Token a `<wr-checkbox>` injects to read selection state from — and\n * toggle values in — its parent `<wr-checkbox-group>` (when present).\n *\n * @internal\n */\nexport const WR_CHECKBOX_GROUP = new InjectionToken<WrCheckboxGroupContext>('WR_CHECKBOX_GROUP');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, inject, input, model, output } from '@angular/core';\nimport type { FormCheckboxControl } from '@angular/forms/signals';\n\nimport { useConfigValue } from 'ngwr/config';\nimport { useFormFieldAria } from 'ngwr/form';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { randomId } from 'ngwr/utils';\n\nimport { WR_CHECKBOX_GROUP } from './tokens';\n\n/**\n * Two-state checkbox.\n *\n * A signal-forms native control: it implements `FormCheckboxControl`, so\n * `[formField]` binds straight to its `checked` model — no\n * `ControlValueAccessor` in between. `[(checked)]` works standalone, and\n * classic `[(ngModel)]` / reactive forms keep working through Angular's bridge.\n *\n * @example\n * ```html\n * <wr-checkbox [(checked)]=\"agree\">I agree</wr-checkbox>\n * <wr-checkbox [formField]=\"form.agree\">I agree</wr-checkbox>\n * ```\n *\n * **Inside `<wr-checkbox-group>`** — the checkbox's `checkboxValue` is added to\n * or removed from the group's array, and the group is the native form control.\n * (The identity input is `checkboxValue`, not `value`, because\n * `FormCheckboxControl` reserves `value` — its form state is the boolean\n * `checked`.)\n *\n * @example\n * ```html\n * <wr-checkbox-group [formField]=\"form.features\">\n * <wr-checkbox checkboxValue=\"autosave\">Autosave</wr-checkbox>\n * <wr-checkbox checkboxValue=\"notifications\">Notifications</wr-checkbox>\n * </wr-checkbox-group>\n * ```\n *\n * @see https://ngwr.dev/reference/components/checkbox\n */\nexport type WrCheckboxSize = 'sm' | 'md' | 'lg';\n\n@Component({\n selector: 'wr-checkbox',\n templateUrl: './checkbox.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n // The `id` input belongs to the native input, not to this element. A static\n // `id=\"x\"` in a consumer's template is written to the host as a plain\n // attribute AS WELL as fed to the input, which put two elements with the\n // same id in the document and made `<label for>` resolve through\n // `getElementById` to the host — not a labelable element, so `input.labels`\n // went from 1 to 0 and `document.getElementById(id)` returned the wrong node.\n '[attr.id]': 'null',\n // The group identity, reflected so a HARNESS can read it. It is the only\n // way: `checkboxValue` is an `unknown`-typed TypeScript value that reaches\n // no attribute otherwise, and `WrCheckboxHarness.getCheckboxValue()` read\n // `value` off the inner `<input>` — which nothing writes, so it answered\n // `null` for every checkbox in every state. A harness method that answers\n // the same for a working component and a broken one is the one thing the\n // harness rules forbid outright.\n //\n // `data-`, deliberately, and NOT `value`: a leftover static `value=\"x\"` from\n // before v9 still lands on this host as a plain attribute, so reading\n // `value` here would report the identity a consumer THOUGHT they set while\n // the component used `null`. That is the exact confusion migration-v9\n // exists to end.\n '[attr.data-checkbox-value]': 'reflectedValue()',\n },\n imports: [WrIcon],\n})\nexport class WrCheckbox implements FormCheckboxControl {\n /**\n * Stable id used to associate the native input with its label. Lands on the\n * inner `<input>`; the host never keeps it.\n *\n * @default Randomly generated\n */\n readonly id = input<string>(randomId('wr-checkbox'));\n\n /**\n * This checkbox's identity when inside a `<wr-checkbox-group>` — the value\n * added to / removed from the group's array. Ignored in standalone mode.\n * (Named `checkboxValue`, not `value`, because `FormCheckboxControl` reserves\n * `value`.)\n */\n readonly checkboxValue = input<unknown>(null);\n\n /**\n * `checkboxValue` as an attribute, when it can be one.\n *\n * A primitive round-trips through the DOM and is what a group identity is in\n * practice. Anything else — an object, an array — has no honest attribute\n * form, so the attribute is ABSENT rather than `[object Object]`: a harness\n * reading it then gets `null`, which is true, instead of a string that looks\n * like data and identifies nothing.\n */\n protected readonly reflectedValue = computed(() => {\n const value = this.checkboxValue();\n // Narrowed inline rather than through a `typeof` held in a variable, which\n // TypeScript does not follow — and the linter is right to refuse it: the\n // point of this guard is that `String()` never sees an object.\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return null;\n });\n\n /**\n * Accessible name for a checkbox used WITHOUT projected text — a selection\n * cell in a table, say. The wrapping `<label>` names the control whenever\n * content is projected; with none, the native input has no name, and an\n * `aria-label` put on the host lands on a `<wr-checkbox>` element that no\n * screen reader ever announces.\n */\n readonly ariaLabel = input<string | null>(null);\n\n /**\n * Checked state — the form value. Bound by `[formField]`, two-way via\n * `[(checked)]`, or `[(ngModel)]`. Ignored inside a `<wr-checkbox-group>`,\n * where the group's array is the source of truth.\n */\n readonly checked = model<boolean>(false);\n\n /** Emitted on blur so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n /**\n * Disable the checkbox. 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 /**\n * Refuse edits while staying focusable and submittable. Bound automatically\n * from the field's readonly state when used with `[formField]`.\n *\n * A native `<input type=\"checkbox\">` ignores the `readonly` attribute, so this\n * cancels the click's activation behaviour instead — which covers Space too,\n * since a checkbox turns Space into a click — and mirrors the state as\n * `aria-readonly`, which role `checkbox` supports.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Control size — shares the `--wr-control-*` contract. Unset falls back to the\n * `checkbox.size` app default from `provideWrConfig()`. @default 'md'\n */\n readonly size = input<WrCheckboxSize | null>(null);\n\n /** `size`, then the app config, then `md`. @internal */\n protected readonly resolvedSize = useConfigValue(this.size, c => c.checkbox?.size, 'md');\n\n /**\n * Optional icon name rendered inside the box when checked, in place of the\n * default checkmark. Use any registered NGWR icon.\n */\n readonly icon = input<WrIconName | null>(null);\n\n /**\n * Show the indeterminate (\"mixed\") state — a dash instead of a check. Visual\n * only and controlled: set it yourself for a parent \"select all\" whose\n * children are partly checked, and clear it on the next toggle. Takes visual\n * precedence over `checked`; the native input reports `aria-checked=\"mixed\"`.\n *\n * @default false\n */\n readonly indeterminate = input(false, { transform: coerceBooleanProperty });\n\n private readonly group = inject(WR_CHECKBOX_GROUP, { optional: true });\n\n /** Rendered \"is checked\" — reads the group when grouped, else the `checked` model. */\n protected readonly isChecked = computed(() =>\n this.group ? this.group.isSelected(this.checkboxValue()) : this.checked()\n );\n\n /** Effective disabled — the `disabled` input wins, then the group. */\n protected readonly effectiveDisabled = computed(() => {\n if (this.disabled()) return true;\n return this.group ? this.group.isDisabled() : false;\n });\n\n /** Effective readonly — this box's own `readonly` input, or the group's. */\n protected readonly effectiveReadonly = computed(() => {\n if (this.readonly()) return true;\n return this.group ? this.group.isReadonly() : false;\n });\n\n /**\n * The surrounding `<wr-form-field>`'s error state, mirrored onto the native\n * input. Inside a `<wr-checkbox-group>` the GROUP is the bound control and\n * carries the state, so a grouped box shields itself and stays silent — nine\n * boxes each announcing the group's one error is noise, not information.\n */\n private readonly fieldAria = useFormFieldAria();\n protected readonly ariaInvalid = computed(() => (this.group ? null : this.fieldAria.ariaInvalid()));\n protected readonly describedBy = computed(() => (this.group ? null : this.fieldAria.describedBy()));\n\n protected readonly classes = computed(() => {\n const parts = ['wr-checkbox'];\n const size = this.resolvedSize();\n if (size !== 'md') parts.push(`wr-checkbox--${size}`);\n if (this.indeterminate()) parts.push('wr-checkbox--indeterminate');\n else if (this.isChecked()) parts.push('wr-checkbox--checked');\n if (this.effectiveDisabled()) parts.push('wr-checkbox--disabled');\n else if (this.effectiveReadonly()) parts.push('wr-checkbox--readonly');\n return parts.join(' ');\n });\n\n // Template handlers\n\n /**\n * Cancel the toggle while readonly. `change` never fires for a click whose\n * default was prevented, so this is the only guard the pointer and Space\n * paths need; `onInputChange` keeps its own for a synthetic `change`.\n */\n protected onInputClick(event: Event): void {\n if (this.effectiveReadonly()) event.preventDefault();\n }\n\n protected onInputChange(event: Event): void {\n if (this.effectiveReadonly()) {\n // A synthetic `change` cannot be prevented — put the DOM back instead.\n (event.target as HTMLInputElement).checked = this.isChecked();\n return;\n }\n if (this.group) {\n this.group.toggle(this.checkboxValue());\n return;\n }\n this.checked.set((event.target as HTMLInputElement).checked);\n }\n\n protected onInputBlur(): void {\n // Inside a group the GROUP is the bound control, and its own `touch` is\n // what a form listens to; the child's output is wired to nothing there.\n if (this.group) this.group.blurred();\n this.touch.emit();\n }\n}\n","<label class=\"wr-checkbox__label\" [for]=\"id()\">\n <input\n class=\"wr-checkbox__input\"\n type=\"checkbox\"\n [id]=\"id()\"\n [attr.aria-label]=\"ariaLabel()\"\n [checked]=\"isChecked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"effectiveDisabled()\"\n [attr.aria-readonly]=\"effectiveReadonly() || null\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-describedby]=\"describedBy()\"\n (click)=\"onInputClick($event)\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n />\n\n <span class=\"wr-checkbox__box\" aria-hidden=\"true\">\n @if (indeterminate()) {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__dash\">\n <line x1=\"3.5\" y1=\"8\" x2=\"12.5\" y2=\"8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n } @else if (icon(); as iconName) {\n <wr-icon class=\"wr-checkbox__icon\" [name]=\"iconName\" />\n } @else {\n <svg viewBox=\"0 0 16 16\" class=\"wr-checkbox__mark\">\n <polyline\n points=\"3.5 8.5 6.5 11.5 12.5 5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n </span>\n\n <span class=\"wr-checkbox__text\">\n <ng-content />\n </span>\n</label>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, forwardRef, input, model, output } from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { useFormFieldAria } from 'ngwr/form';\n\nimport { WR_CHECKBOX_GROUP, type WrCheckboxGroupContext } from './tokens';\n\n/**\n * Manages a group of `<wr-checkbox>` children as a single form value\n * (an array of the checked items' `value` inputs).\n *\n * A signal-forms native control: it implements `FormValueControl<unknown[]>`,\n * so `[formField]` binds to its `value` model. `[(value)]` works standalone,\n * and classic `[(ngModel)]` / reactive forms keep working through the bridge.\n *\n * @example\n * ```html\n * <wr-checkbox-group [formField]=\"form.features\">\n * <wr-checkbox checkboxValue=\"autosave\">Autosave</wr-checkbox>\n * <wr-checkbox checkboxValue=\"notifications\">Notifications</wr-checkbox>\n * <wr-checkbox checkboxValue=\"darkmode\">Dark mode</wr-checkbox>\n * </wr-checkbox-group>\n * ```\n *\n * @see https://ngwr.dev/reference/components/checkbox\n */\n@Component({\n selector: 'wr-checkbox-group',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-checkbox-group',\n role: 'group',\n '[attr.aria-invalid]': 'fieldAria.ariaInvalid()',\n '[attr.aria-describedby]': 'fieldAria.describedBy()',\n },\n providers: [\n {\n provide: WR_CHECKBOX_GROUP,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => WrCheckboxGroup),\n },\n ],\n})\nexport class WrCheckboxGroup implements FormValueControl<unknown[]>, WrCheckboxGroupContext {\n /**\n * Disable every child checkbox. Bound automatically from the field's\n * disabled state when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse edits on every child while they stay focusable and the value still\n * submits. Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * No `aria-readonly` on the host: role `group` does not support it (the state\n * is not global), so each child box mirrors its own instead.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** The surrounding `<wr-form-field>`'s error state. @internal */\n protected readonly fieldAria = useFormFieldAria();\n\n /** The checked items' values. Bound by `[formField]`, or two-way via `[(value)]`. */\n readonly value = model<unknown[]>([]);\n\n /** Emitted when a child toggles so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n // The current selection as a guaranteed array — a classic-forms binding can\n // write null even though the type is `unknown[]`, so normalise every read.\n private readonly selected = computed<readonly unknown[]>(() => {\n const v = this.value();\n return Array.isArray(v) ? v : [];\n });\n\n /** Effective disabled state (WrCheckboxGroupContext). */\n readonly isDisabled = computed(() => this.disabled());\n\n /** Effective readonly state (WrCheckboxGroupContext). */\n readonly isReadonly = computed(() => this.readonly());\n\n // WrCheckboxGroupContext\n\n isSelected(value: unknown): boolean {\n return this.selected().includes(value);\n }\n\n toggle(value: unknown): void {\n if (this.isDisabled() || this.isReadonly()) return;\n const current = this.selected();\n const next = current.includes(value) ? current.filter(v => v !== value) : [...current, value];\n this.value.set(next);\n this.touch.emit();\n }\n\n /** @internal A child checkbox lost focus — see {@link WrCheckboxGroupContext.blurred}. */\n blurred(): void {\n this.touch.emit();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -169,10 +169,10 @@ class WrCircularText {
169
169
  this.rotation = this.spinEl().nativeElement.animate([{ transform: 'rotate(0deg)' }, { transform: 'rotate(360deg)' }], { duration: newDurMs, iterations: Infinity, easing: 'linear' });
170
170
  this.rotation.currentTime = ratio * newDurMs;
171
171
  }
172
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCircularText, deps: [], target: i0.ɵɵFactoryTarget.Component });
173
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrCircularText, isStandalone: true, selector: "wr-circular-text", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, spinDuration: { classPropertyName: "spinDuration", publicName: "spinDuration", isSignal: true, isRequired: false, transformFunction: null }, onHover: { classPropertyName: "onHover", publicName: "onHover", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-circular-text--bonkers": "onHover() === 'goBonkers'" }, classAttribute: "wr-circular-text" }, viewQueries: [{ propertyName: "spinEl", first: true, predicate: ["spin"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n The readable text, once: the ring below is per-character spans, which a screen\n reader may read out one letter at a time. Same shape as `wr-blur-text` and\n `wr-decrypt-text` \u2014 the string is carried here and the pieces are taken out of\n the tree with one `aria-hidden` on the wrapper rather than N on the chars, so\n the attribute stays off the nodes the rotation touches. It sits OUTSIDE\n `__spin`, or it would be hidden with the chars and would spin with them.\n-->\n<span class=\"wr-circular-text__sr-only\">{{ text() }}</span>\n<span class=\"wr-circular-text__spin\" aria-hidden=\"true\" #spin>\n @for (c of chars(); track $index) {\n <span class=\"wr-circular-text__char\" [style.transform]=\"c.transform\">{{ c.ch }}</span>\n }\n</span>\n", styles: [".wr-circular-text{--wr-circular-text-size: 12rem;--wr-circular-text-radius: calc(var(--wr-circular-text-size) / 2);position:relative;display:inline-block;width:var(--wr-circular-text-size);height:var(--wr-circular-text-size);border-radius:50%;font-weight:700;text-align:center;-webkit-user-select:none;user-select:none;transition:transform .6s var(--wr-ease-spring)}.wr-circular-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-circular-text__spin{position:absolute;inset:0;will-change:transform}.wr-circular-text__char{position:absolute;top:50%;left:50%;display:inline-block;margin-left:-.5em;margin-top:-.5em;line-height:1}.wr-circular-text--bonkers:hover{transform:scale(.8)}\n"], encapsulation: i0.ViewEncapsulation.None });
172
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCircularText, deps: [], target: i0.ɵɵFactoryTarget.Component });
173
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrCircularText, isStandalone: true, selector: "wr-circular-text", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, spinDuration: { classPropertyName: "spinDuration", publicName: "spinDuration", isSignal: true, isRequired: false, transformFunction: null }, onHover: { classPropertyName: "onHover", publicName: "onHover", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-circular-text--bonkers": "onHover() === 'goBonkers'" }, classAttribute: "wr-circular-text" }, viewQueries: [{ propertyName: "spinEl", first: true, predicate: ["spin"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n The readable text, once: the ring below is per-character spans, which a screen\n reader may read out one letter at a time. Same shape as `wr-blur-text` and\n `wr-decrypt-text` \u2014 the string is carried here and the pieces are taken out of\n the tree with one `aria-hidden` on the wrapper rather than N on the chars, so\n the attribute stays off the nodes the rotation touches. It sits OUTSIDE\n `__spin`, or it would be hidden with the chars and would spin with them.\n-->\n<span class=\"wr-circular-text__sr-only\">{{ text() }}</span>\n<span class=\"wr-circular-text__spin\" aria-hidden=\"true\" #spin>\n @for (c of chars(); track $index) {\n <span class=\"wr-circular-text__char\" [style.transform]=\"c.transform\">{{ c.ch }}</span>\n }\n</span>\n", styles: [".wr-circular-text{--wr-circular-text-size: 12rem;--wr-circular-text-radius: calc(var(--wr-circular-text-size) / 2);position:relative;display:inline-block;width:var(--wr-circular-text-size);height:var(--wr-circular-text-size);border-radius:50%;font-weight:700;text-align:center;-webkit-user-select:none;user-select:none;transition:transform .6s var(--wr-ease-spring)}.wr-circular-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-circular-text__spin{position:absolute;inset:0;will-change:transform}.wr-circular-text__char{position:absolute;top:50%;left:50%;display:inline-block;margin-left:-.5em;margin-top:-.5em;line-height:1}.wr-circular-text--bonkers:hover{transform:scale(.8)}\n"], encapsulation: i0.ViewEncapsulation.None });
174
174
  }
175
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCircularText, decorators: [{
175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCircularText, decorators: [{
176
176
  type: Component,
177
177
  args: [{ selector: 'wr-circular-text', encapsulation: ViewEncapsulation.None, host: {
178
178
  class: 'wr-circular-text',
@@ -184,10 +184,10 @@ class WrClickSpark {
184
184
  this.raf = requestAnimationFrame(draw);
185
185
  this.destroyRef.onDestroy(() => cancelAnimationFrame(this.raf));
186
186
  }
187
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrClickSpark, deps: [], target: i0.ɵɵFactoryTarget.Component });
188
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.5", type: WrClickSpark, isStandalone: true, selector: "wr-click-spark", inputs: { sparkColor: { classPropertyName: "sparkColor", publicName: "sparkColor", isSignal: true, isRequired: false, transformFunction: null }, sparkSize: { classPropertyName: "sparkSize", publicName: "sparkSize", isSignal: true, isRequired: false, transformFunction: null }, sparkRadius: { classPropertyName: "sparkRadius", publicName: "sparkRadius", isSignal: true, isRequired: false, transformFunction: null }, sparkCount: { classPropertyName: "sparkCount", publicName: "sparkCount", 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 }, extraScale: { classPropertyName: "extraScale", publicName: "extraScale", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" }, classAttribute: "wr-click-spark" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Decoration over the projected content \u2014 the same treatment `WrConfetti`\n gives its own canvas. -->\n<canvas #canvas class=\"wr-click-spark__canvas\" aria-hidden=\"true\"></canvas>\n<ng-content />\n", styles: [".wr-click-spark{position:relative;display:block}.wr-click-spark__canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;user-select:none;z-index:1}\n"], encapsulation: i0.ViewEncapsulation.None });
187
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrClickSpark, deps: [], target: i0.ɵɵFactoryTarget.Component });
188
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.6", type: WrClickSpark, isStandalone: true, selector: "wr-click-spark", inputs: { sparkColor: { classPropertyName: "sparkColor", publicName: "sparkColor", isSignal: true, isRequired: false, transformFunction: null }, sparkSize: { classPropertyName: "sparkSize", publicName: "sparkSize", isSignal: true, isRequired: false, transformFunction: null }, sparkRadius: { classPropertyName: "sparkRadius", publicName: "sparkRadius", isSignal: true, isRequired: false, transformFunction: null }, sparkCount: { classPropertyName: "sparkCount", publicName: "sparkCount", 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 }, extraScale: { classPropertyName: "extraScale", publicName: "extraScale", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" }, classAttribute: "wr-click-spark" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Decoration over the projected content \u2014 the same treatment `WrConfetti`\n gives its own canvas. -->\n<canvas #canvas class=\"wr-click-spark__canvas\" aria-hidden=\"true\"></canvas>\n<ng-content />\n", styles: [".wr-click-spark{position:relative;display:block}.wr-click-spark__canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;user-select:none;z-index:1}\n"], encapsulation: i0.ViewEncapsulation.None });
189
189
  }
190
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrClickSpark, decorators: [{
190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrClickSpark, decorators: [{
191
191
  type: Component,
192
192
  args: [{ selector: 'wr-click-spark', encapsulation: ViewEncapsulation.None, host: {
193
193
  class: 'wr-click-spark',
@@ -150,10 +150,10 @@ class WrClipboard {
150
150
  }
151
151
  }
152
152
  }
153
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrClipboard, deps: [], target: i0.ɵɵFactoryTarget.Service });
154
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrClipboard });
153
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrClipboard, deps: [], target: i0.ɵɵFactoryTarget.Service });
154
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.6", ngImport: i0, type: WrClipboard });
155
155
  }
156
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrClipboard, decorators: [{
156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrClipboard, decorators: [{
157
157
  type: Service
158
158
  }] });
159
159
 
@@ -94,10 +94,10 @@ class WrCollapse {
94
94
  return;
95
95
  this.open.update(v => !v);
96
96
  }
97
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCollapse, deps: [], target: i0.ɵɵFactoryTarget.Component });
98
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrCollapse, isStandalone: true, selector: "wr-collapse", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"wr-collapse__header\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"bodyId\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n <span class=\"wr-collapse__title\">{{ title() }}</span>\n <svg\n class=\"wr-icon__svg wr-collapse__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n</button>\n\n<div\n class=\"wr-collapse__body\"\n [attr.id]=\"bodyId\"\n [class.wr-collapse__body--open]=\"open()\"\n [attr.aria-hidden]=\"!open()\"\n [attr.inert]=\"!open() ? '' : null\"\n>\n <div class=\"wr-collapse__content\">\n <div class=\"wr-collapse__inner\">\n <ng-content />\n </div>\n </div>\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
97
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCollapse, deps: [], target: i0.ɵɵFactoryTarget.Component });
98
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrCollapse, isStandalone: true, selector: "wr-collapse", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"wr-collapse__header\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"bodyId\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n <span class=\"wr-collapse__title\">{{ title() }}</span>\n <svg\n class=\"wr-icon__svg wr-collapse__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n</button>\n\n<div\n class=\"wr-collapse__body\"\n [attr.id]=\"bodyId\"\n [class.wr-collapse__body--open]=\"open()\"\n [attr.aria-hidden]=\"!open()\"\n [attr.inert]=\"!open() ? '' : null\"\n>\n <div class=\"wr-collapse__content\">\n <div class=\"wr-collapse__inner\">\n <ng-content />\n </div>\n </div>\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
99
99
  }
100
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCollapse, decorators: [{
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCollapse, decorators: [{
101
101
  type: Component,
102
102
  args: [{ selector: 'wr-collapse', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<button\n type=\"button\"\n class=\"wr-collapse__header\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"bodyId\"\n [disabled]=\"disabled()\"\n (click)=\"toggle()\"\n>\n <span class=\"wr-collapse__title\">{{ title() }}</span>\n <svg\n class=\"wr-icon__svg wr-collapse__chevron\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n</button>\n\n<div\n class=\"wr-collapse__body\"\n [attr.id]=\"bodyId\"\n [class.wr-collapse__body--open]=\"open()\"\n [attr.aria-hidden]=\"!open()\"\n [attr.inert]=\"!open() ? '' : null\"\n>\n <div class=\"wr-collapse__content\">\n <div class=\"wr-collapse__inner\">\n <ng-content />\n </div>\n </div>\n</div>\n" }]
103
103
  }], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
@@ -132,8 +132,8 @@ class WrCollapseGroup {
132
132
  member.close();
133
133
  }
134
134
  }
135
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCollapseGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
136
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrCollapseGroup, isStandalone: true, selector: "wr-collapse-group", inputs: { accordion: { classPropertyName: "accordion", publicName: "accordion", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-collapse-group" }, providers: [
135
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCollapseGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
136
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrCollapseGroup, isStandalone: true, selector: "wr-collapse-group", inputs: { accordion: { classPropertyName: "accordion", publicName: "accordion", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-collapse-group" }, providers: [
137
137
  {
138
138
  provide: WR_COLLAPSE_GROUP,
139
139
  // eslint-disable-next-line @angular-eslint/no-forward-ref
@@ -141,7 +141,7 @@ class WrCollapseGroup {
141
141
  },
142
142
  ], ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
143
143
  }
144
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrCollapseGroup, decorators: [{
144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCollapseGroup, decorators: [{
145
145
  type: Component,
146
146
  args: [{
147
147
  selector: 'wr-collapse-group',
@@ -198,8 +198,8 @@ class WrAccordion {
198
198
  member.close();
199
199
  }
200
200
  }
201
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrAccordion, deps: [], target: i0.ɵɵFactoryTarget.Component });
202
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.5", type: WrAccordion, isStandalone: true, selector: "wr-accordion", host: { classAttribute: "wr-collapse-group wr-collapse-group--accordion" }, providers: [
201
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrAccordion, deps: [], target: i0.ɵɵFactoryTarget.Component });
202
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: WrAccordion, isStandalone: true, selector: "wr-accordion", host: { classAttribute: "wr-collapse-group wr-collapse-group--accordion" }, providers: [
203
203
  {
204
204
  provide: WR_COLLAPSE_GROUP,
205
205
  // eslint-disable-next-line @angular-eslint/no-forward-ref
@@ -207,7 +207,7 @@ class WrAccordion {
207
207
  },
208
208
  ], ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
209
209
  }
210
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrAccordion, decorators: [{
210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrAccordion, decorators: [{
211
211
  type: Component,
212
212
  args: [{
213
213
  selector: 'wr-accordion',
@@ -2,7 +2,7 @@ import { Directionality } from '@angular/cdk/bidi';
2
2
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
3
3
  import { DecimalPipe } from '@angular/common';
4
4
  import * as i0 from '@angular/core';
5
- import { input, model, output, signal, computed, inject, effect, ViewEncapsulation, Component, ElementRef, ViewContainerRef, DestroyRef, Directive } from '@angular/core';
5
+ import { input, model, output, signal, computed, inject, effect, ViewEncapsulation, Component, ElementRef, ViewContainerRef, DestroyRef, Injector, Directive } from '@angular/core';
6
6
  import { useFormFieldAria, WR_FORM_FIELD } from 'ngwr/form';
7
7
  import { useI18nFormatter, readI18nText } from 'ngwr/i18n';
8
8
  import { WrSegmented } from 'ngwr/segmented';
@@ -10,7 +10,7 @@ import { clamp } from 'ngwr/utils';
10
10
  import { ScrollStrategyOptions } from '@angular/cdk/overlay';
11
11
  import { ComponentPortal } from '@angular/cdk/portal';
12
12
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
13
- import { WR_OVERLAY, WrOutsideClick } from 'ngwr/overlay';
13
+ import { WR_OVERLAY, WrOutsideClick, wrFollowDirection } from 'ngwr/overlay';
14
14
 
15
15
  /**
16
16
  * @license
@@ -798,10 +798,10 @@ class WrColorPicker {
798
798
  this.a.set(hsv.a);
799
799
  this.emit();
800
800
  }
801
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrColorPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
802
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrColorPicker, isStandalone: true, selector: "wr-color-picker", inputs: { alpha: { classPropertyName: "alpha", publicName: "alpha", 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 }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, swatches: { classPropertyName: "swatches", publicName: "swatches", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { properties: { "class": "classes()", "style.--wr-color-picker-hue": "hueCss()", "style.--wr-color-picker-rgb": "rgbCss()" } }, providers: [{ provide: WR_FORM_FIELD, useValue: null }], ngImport: i0, template: "<!--\n `role=\"group\"` rather than `role=\"slider\"`, because this surface holds TWO\n values and a slider has one `aria-valuenow`; and rather than\n `role=\"application\"`, which would switch the reader out of its own browse mode\n for the whole subtree \u2014 the call `wr-image-cropper` already made. A group has\n no value of its own, so the two percentages ride in its accessible name, which\n is where a reader querying the focused element finds them.\n-->\n<div\n class=\"wr-color-picker__sv\"\n role=\"group\"\n [attr.aria-label]=\"resolvedAreaLabel()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, 'sv')\"\n (keydown)=\"onAreaKeydown($event)\"\n (blur)=\"onSurfaceBlur()\"\n>\n <span class=\"wr-color-picker__thumb\" [style.left.%]=\"svThumbX()\" [style.top.%]=\"svThumbY()\"></span>\n</div>\n\n<div\n class=\"wr-color-picker__slider wr-color-picker__slider--hue\"\n role=\"slider\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n [attr.aria-label]=\"resolvedHueLabel()\"\n [attr.aria-valuenow]=\"hueValue()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, 'hue')\"\n (keydown)=\"onSliderKeydown($event, 'hue')\"\n (blur)=\"onSurfaceBlur()\"\n>\n <!--\n `inset-inline-start`, not `left`: this is a one-value track, so it mirrors\n under `dir=\"rtl\"` the way `wr-slider` does. The SV thumb above keeps `left` \u2014\n the canvas is a picture and does not flip.\n -->\n <span class=\"wr-color-picker__thumb wr-color-picker__thumb--slider\" [style.inset-inline-start.%]=\"hueThumbX()\"></span>\n</div>\n\n@if (alpha()) {\n <div\n class=\"wr-color-picker__slider wr-color-picker__slider--alpha\"\n role=\"slider\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-label]=\"resolvedAlphaLabel()\"\n [attr.aria-valuenow]=\"alphaPercent()\"\n [attr.aria-valuetext]=\"`${alphaPercent()}%`\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, 'alpha')\"\n (keydown)=\"onSliderKeydown($event, 'alpha')\"\n (blur)=\"onSurfaceBlur()\"\n >\n <span\n class=\"wr-color-picker__thumb wr-color-picker__thumb--slider\"\n [style.inset-inline-start.%]=\"alphaThumbX()\"\n ></span>\n </div>\n}\n\n<div class=\"wr-color-picker__chrome\">\n <span class=\"wr-color-picker__preview\" [style.background]=\"hex()\"></span>\n <wr-segmented\n class=\"wr-color-picker__tabs\"\n [options]=\"tabOptions()\"\n [value]=\"activeTab()\"\n (valueChange)=\"onTabChange($event)\"\n />\n</div>\n\n@switch (activeTab()) {\n @case ('hex') {\n <div class=\"wr-color-picker__inputs wr-color-picker__inputs--hex\">\n <label class=\"wr-color-picker__field wr-color-picker__field--wide\">\n <input\n type=\"text\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n [value]=\"hexInput()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHexInput($event)\"\n (blur)=\"onHexBlur()\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelHexLabel() }}</span>\n </label>\n </div>\n }\n @case ('rgb') {\n <div class=\"wr-color-picker__inputs\">\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"255\"\n [value]=\"rgb().r\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onRgbChannel('r', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelRedLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"255\"\n [value]=\"rgb().g\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onRgbChannel('g', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelGreenLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"255\"\n [value]=\"rgb().b\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onRgbChannel('b', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelBlueLabel() }}</span>\n </label>\n @if (alpha()) {\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"alphaPercent()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onAlphaPercent($event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelAlphaLabel() }}</span>\n </label>\n }\n </div>\n }\n @case ('hsl') {\n <div class=\"wr-color-picker__inputs\">\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"360\"\n [value]=\"hslView().h | number: '1.0-0'\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHslChannel('h', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelHueLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"hslView().s * 100 | number: '1.0-0'\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHslChannel('s', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelSaturationLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"hslView().l * 100 | number: '1.0-0'\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHslChannel('l', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelLightnessLabel() }}</span>\n </label>\n @if (alpha()) {\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"alphaPercent()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onAlphaPercent($event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelAlphaLabel() }}</span>\n </label>\n }\n </div>\n }\n}\n\n@if (swatches().length > 0) {\n <div class=\"wr-color-picker__swatches\">\n @for (color of swatches(); track color) {\n <button\n type=\"button\"\n class=\"wr-color-picker__swatch\"\n [style.background]=\"color\"\n [attr.aria-label]=\"color\"\n [disabled]=\"disabled() || readonly()\"\n (click)=\"onSwatchClick(color)\"\n ></button>\n }\n </div>\n}\n", dependencies: [{ kind: "component", type: WrSegmented, selector: "wr-segmented", inputs: ["options", "value", "disabled", "readonly", "size"], outputs: ["valueChange", "touch"] }, { kind: "pipe", type: DecimalPipe, name: "number" }], encapsulation: i0.ViewEncapsulation.None });
801
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrColorPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
802
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrColorPicker, isStandalone: true, selector: "wr-color-picker", inputs: { alpha: { classPropertyName: "alpha", publicName: "alpha", 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 }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, swatches: { classPropertyName: "swatches", publicName: "swatches", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { properties: { "class": "classes()", "style.--wr-color-picker-hue": "hueCss()", "style.--wr-color-picker-rgb": "rgbCss()" } }, providers: [{ provide: WR_FORM_FIELD, useValue: null }], ngImport: i0, template: "<!--\n `role=\"group\"` rather than `role=\"slider\"`, because this surface holds TWO\n values and a slider has one `aria-valuenow`; and rather than\n `role=\"application\"`, which would switch the reader out of its own browse mode\n for the whole subtree \u2014 the call `wr-image-cropper` already made. A group has\n no value of its own, so the two percentages ride in its accessible name, which\n is where a reader querying the focused element finds them.\n-->\n<div\n class=\"wr-color-picker__sv\"\n role=\"group\"\n [attr.aria-label]=\"resolvedAreaLabel()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, 'sv')\"\n (keydown)=\"onAreaKeydown($event)\"\n (blur)=\"onSurfaceBlur()\"\n>\n <span class=\"wr-color-picker__thumb\" [style.left.%]=\"svThumbX()\" [style.top.%]=\"svThumbY()\"></span>\n</div>\n\n<div\n class=\"wr-color-picker__slider wr-color-picker__slider--hue\"\n role=\"slider\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n [attr.aria-label]=\"resolvedHueLabel()\"\n [attr.aria-valuenow]=\"hueValue()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, 'hue')\"\n (keydown)=\"onSliderKeydown($event, 'hue')\"\n (blur)=\"onSurfaceBlur()\"\n>\n <!--\n `inset-inline-start`, not `left`: this is a one-value track, so it mirrors\n under `dir=\"rtl\"` the way `wr-slider` does. The SV thumb above keeps `left` \u2014\n the canvas is a picture and does not flip.\n -->\n <span class=\"wr-color-picker__thumb wr-color-picker__thumb--slider\" [style.inset-inline-start.%]=\"hueThumbX()\"></span>\n</div>\n\n@if (alpha()) {\n <div\n class=\"wr-color-picker__slider wr-color-picker__slider--alpha\"\n role=\"slider\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-label]=\"resolvedAlphaLabel()\"\n [attr.aria-valuenow]=\"alphaPercent()\"\n [attr.aria-valuetext]=\"`${alphaPercent()}%`\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-invalid]=\"fieldAria.ariaInvalid()\"\n [attr.aria-describedby]=\"fieldAria.describedBy()\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, 'alpha')\"\n (keydown)=\"onSliderKeydown($event, 'alpha')\"\n (blur)=\"onSurfaceBlur()\"\n >\n <span\n class=\"wr-color-picker__thumb wr-color-picker__thumb--slider\"\n [style.inset-inline-start.%]=\"alphaThumbX()\"\n ></span>\n </div>\n}\n\n<div class=\"wr-color-picker__chrome\">\n <span class=\"wr-color-picker__preview\" [style.background]=\"hex()\"></span>\n <wr-segmented\n class=\"wr-color-picker__tabs\"\n [options]=\"tabOptions()\"\n [value]=\"activeTab()\"\n (valueChange)=\"onTabChange($event)\"\n />\n</div>\n\n@switch (activeTab()) {\n @case ('hex') {\n <div class=\"wr-color-picker__inputs wr-color-picker__inputs--hex\">\n <label class=\"wr-color-picker__field wr-color-picker__field--wide\">\n <input\n type=\"text\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n [value]=\"hexInput()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHexInput($event)\"\n (blur)=\"onHexBlur()\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelHexLabel() }}</span>\n </label>\n </div>\n }\n @case ('rgb') {\n <div class=\"wr-color-picker__inputs\">\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"255\"\n [value]=\"rgb().r\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onRgbChannel('r', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelRedLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"255\"\n [value]=\"rgb().g\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onRgbChannel('g', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelGreenLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"255\"\n [value]=\"rgb().b\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onRgbChannel('b', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelBlueLabel() }}</span>\n </label>\n @if (alpha()) {\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"alphaPercent()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onAlphaPercent($event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelAlphaLabel() }}</span>\n </label>\n }\n </div>\n }\n @case ('hsl') {\n <div class=\"wr-color-picker__inputs\">\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"360\"\n [value]=\"hslView().h | number: '1.0-0'\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHslChannel('h', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelHueLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"hslView().s * 100 | number: '1.0-0'\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHslChannel('s', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelSaturationLabel() }}</span>\n </label>\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"hslView().l * 100 | number: '1.0-0'\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onHslChannel('l', $event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelLightnessLabel() }}</span>\n </label>\n @if (alpha()) {\n <label class=\"wr-color-picker__field\">\n <input\n type=\"number\"\n min=\"0\"\n max=\"100\"\n [value]=\"alphaPercent()\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onAlphaPercent($event)\"\n />\n <span class=\"wr-color-picker__field-label\">{{ channelAlphaLabel() }}</span>\n </label>\n }\n </div>\n }\n}\n\n@if (swatches().length > 0) {\n <div class=\"wr-color-picker__swatches\">\n @for (color of swatches(); track color) {\n <button\n type=\"button\"\n class=\"wr-color-picker__swatch\"\n [style.background]=\"color\"\n [attr.aria-label]=\"color\"\n [disabled]=\"disabled() || readonly()\"\n (click)=\"onSwatchClick(color)\"\n ></button>\n }\n </div>\n}\n", dependencies: [{ kind: "component", type: WrSegmented, selector: "wr-segmented", inputs: ["options", "value", "disabled", "readonly", "size"], outputs: ["valueChange", "touch"] }, { kind: "pipe", type: DecimalPipe, name: "number" }], encapsulation: i0.ViewEncapsulation.None });
803
803
  }
804
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrColorPicker, decorators: [{
804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrColorPicker, decorators: [{
805
805
  type: Component,
806
806
  args: [{ selector: 'wr-color-picker', encapsulation: ViewEncapsulation.None, host: {
807
807
  '[class]': 'classes()',
@@ -863,6 +863,14 @@ class WrColorPickerTrigger {
863
863
  vcr = inject(ViewContainerRef);
864
864
  scrollStrategies = inject(ScrollStrategyOptions);
865
865
  destroyRef = inject(DestroyRef);
866
+ injector = inject(Injector);
867
+ /**
868
+ * Ambient reading direction, for the open panel alone — nothing in this
869
+ * directive reads it directly. Optional so a bare `TestBed` needs no
870
+ * provider; `Directionality` is root-provided anyway, and a missing one
871
+ * simply reads as `ltr`.
872
+ */
873
+ dir = inject(Directionality, { optional: true });
866
874
  isOpen = signal(false, /* @ts-ignore */
867
875
  ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
868
876
  overlayRef = null;
@@ -902,6 +910,14 @@ class WrColorPickerTrigger {
902
910
  panelClass: 'wr-color-picker-overlay',
903
911
  });
904
912
  this.overlayRef.overlayElement.id = this.panelId;
913
+ // Two of the four fallbacks anchor on `end`, and the CDK resolves start /
914
+ // end against the direction it captured when this ref was created. The
915
+ // `<wr-segmented>` the picker draws its HEX / RGB / HSL tabs with is the
916
+ // visible half: its thumb reads `Directionality` LIVE, so a flip while this
917
+ // panel was open slid the thumb to the other slot inside a pane still drawn
918
+ // `ltr` — parked under the wrong tab, which is the symptom that started all
919
+ // of this.
920
+ wrFollowDirection(this.overlayRef, this.dir, this.injector);
905
921
  const portal = new ComponentPortal(WrColorPicker, this.vcr);
906
922
  const ref = this.overlayRef.attach(portal);
907
923
  ref.setInput('alpha', this.alpha());
@@ -970,10 +986,10 @@ class WrColorPickerTrigger {
970
986
  this.overlayRef = null;
971
987
  }
972
988
  }
973
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrColorPickerTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
974
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.5", type: WrColorPickerTrigger, isStandalone: true, selector: "[wrColorPickerTrigger]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, swatches: { classPropertyName: "swatches", publicName: "swatches", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", opened: "opened", closed: "closed" }, host: { listeners: { "click": "toggle()" }, properties: { "attr.aria-haspopup": "\"dialog\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? panelId : null", "attr.aria-disabled": "disabled() ? true : null" } }, exportAs: ["wrColorPickerTrigger"], ngImport: i0 });
989
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrColorPickerTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
990
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: WrColorPickerTrigger, isStandalone: true, selector: "[wrColorPickerTrigger]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, swatches: { classPropertyName: "swatches", publicName: "swatches", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", opened: "opened", closed: "closed" }, host: { listeners: { "click": "toggle()" }, properties: { "attr.aria-haspopup": "\"dialog\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? panelId : null", "attr.aria-disabled": "disabled() ? true : null" } }, exportAs: ["wrColorPickerTrigger"], ngImport: i0 });
975
991
  }
976
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrColorPickerTrigger, decorators: [{
992
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrColorPickerTrigger, decorators: [{
977
993
  type: Directive,
978
994
  args: [{
979
995
  selector: '[wrColorPickerTrigger]',