ngwr 14.3.1 → 14.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/README.md +1 -1
  2. package/avatar/styles/_index.scss +4 -2
  3. package/badge/styles/_index.scss +4 -1
  4. package/badge/styles/_tag.scss +3 -0
  5. package/cascader/styles/_rules.scss +3 -0
  6. package/command-palette/styles/_index.scss +23 -0
  7. package/context-menu/styles/_index.scss +13 -1
  8. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  9. package/fesm2022/ngwr-affix.mjs +17 -4
  10. package/fesm2022/ngwr-affix.mjs.map +1 -1
  11. package/fesm2022/ngwr-alert.mjs +4 -4
  12. package/fesm2022/ngwr-alert.mjs.map +1 -1
  13. package/fesm2022/ngwr-anchor.mjs +3 -3
  14. package/fesm2022/ngwr-aurora.mjs +3 -3
  15. package/fesm2022/ngwr-avatar.mjs +3 -3
  16. package/fesm2022/ngwr-back-top.mjs +3 -3
  17. package/fesm2022/ngwr-badge.mjs +6 -6
  18. package/fesm2022/ngwr-bar-chart-testing.mjs +18 -2
  19. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
  20. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  21. package/fesm2022/ngwr-blur-text.mjs +3 -3
  22. package/fesm2022/ngwr-border-glow.mjs +3 -3
  23. package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
  24. package/fesm2022/ngwr-burger.mjs +3 -3
  25. package/fesm2022/ngwr-button.mjs +6 -6
  26. package/fesm2022/ngwr-calendar-heatmap-testing.mjs +12 -9
  27. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
  28. package/fesm2022/ngwr-calendar-heatmap.mjs +35 -7
  29. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  30. package/fesm2022/ngwr-calendar.mjs +32 -4
  31. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  32. package/fesm2022/ngwr-card.mjs +9 -9
  33. package/fesm2022/ngwr-carousel.mjs +6 -6
  34. package/fesm2022/ngwr-cascader-testing.mjs +87 -17
  35. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
  36. package/fesm2022/ngwr-cascader.mjs +63 -4
  37. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  38. package/fesm2022/ngwr-checkbox-testing.mjs +13 -2
  39. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
  40. package/fesm2022/ngwr-checkbox.mjs +42 -7
  41. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  42. package/fesm2022/ngwr-circular-text.mjs +3 -3
  43. package/fesm2022/ngwr-click-spark.mjs +3 -3
  44. package/fesm2022/ngwr-clipboard.mjs +3 -3
  45. package/fesm2022/ngwr-collapse.mjs +9 -9
  46. package/fesm2022/ngwr-color-picker.mjs +6 -6
  47. package/fesm2022/ngwr-command-palette.mjs +16 -3
  48. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  49. package/fesm2022/ngwr-compare.mjs +3 -3
  50. package/fesm2022/ngwr-confetti.mjs +3 -3
  51. package/fesm2022/ngwr-context-menu.mjs +12 -12
  52. package/fesm2022/ngwr-cookie.mjs +3 -3
  53. package/fesm2022/ngwr-counter.mjs +6 -6
  54. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  55. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  56. package/fesm2022/ngwr-date-picker.mjs +81 -26
  57. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  58. package/fesm2022/ngwr-date.mjs +3 -3
  59. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  60. package/fesm2022/ngwr-density.mjs +6 -6
  61. package/fesm2022/ngwr-descriptions.mjs +6 -6
  62. package/fesm2022/ngwr-dialog.mjs +15 -15
  63. package/fesm2022/ngwr-directives.mjs +12 -12
  64. package/fesm2022/ngwr-divider.mjs +3 -3
  65. package/fesm2022/ngwr-donut-chart-testing.mjs +18 -2
  66. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  67. package/fesm2022/ngwr-donut-chart.mjs +4 -4
  68. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  69. package/fesm2022/ngwr-drag-drop.mjs +6 -6
  70. package/fesm2022/ngwr-drawer.mjs +18 -18
  71. package/fesm2022/ngwr-dropdown.mjs +32 -14
  72. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  73. package/fesm2022/ngwr-empty.mjs +3 -3
  74. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  75. package/fesm2022/ngwr-falling-text.mjs +3 -3
  76. package/fesm2022/ngwr-file-upload.mjs +18 -5
  77. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  78. package/fesm2022/ngwr-form.mjs +66 -14
  79. package/fesm2022/ngwr-form.mjs.map +1 -1
  80. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  81. package/fesm2022/ngwr-gauge-testing.mjs +16 -2
  82. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
  83. package/fesm2022/ngwr-gauge.mjs +3 -3
  84. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  85. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  86. package/fesm2022/ngwr-hotkey.mjs +6 -6
  87. package/fesm2022/ngwr-i18n-ar.mjs +2 -0
  88. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  89. package/fesm2022/ngwr-i18n-cs.mjs +2 -0
  90. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  91. package/fesm2022/ngwr-i18n-de.mjs +2 -0
  92. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  93. package/fesm2022/ngwr-i18n-en.mjs +14 -2
  94. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  95. package/fesm2022/ngwr-i18n-es.mjs +2 -0
  96. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  97. package/fesm2022/ngwr-i18n-fr.mjs +2 -0
  98. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  99. package/fesm2022/ngwr-i18n-he.mjs +2 -0
  100. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  101. package/fesm2022/ngwr-i18n-hi.mjs +2 -0
  102. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  103. package/fesm2022/ngwr-i18n-id.mjs +2 -0
  104. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  105. package/fesm2022/ngwr-i18n-it.mjs +2 -0
  106. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  107. package/fesm2022/ngwr-i18n-ja.mjs +2 -0
  108. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  109. package/fesm2022/ngwr-i18n-ko.mjs +2 -0
  110. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  111. package/fesm2022/ngwr-i18n-nl.mjs +2 -0
  112. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  113. package/fesm2022/ngwr-i18n-pl.mjs +2 -0
  114. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  115. package/fesm2022/ngwr-i18n-pt.mjs +2 -0
  116. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  117. package/fesm2022/ngwr-i18n-ru.mjs +2 -0
  118. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  119. package/fesm2022/ngwr-i18n-sv.mjs +2 -0
  120. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  121. package/fesm2022/ngwr-i18n-tr.mjs +2 -0
  122. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  123. package/fesm2022/ngwr-i18n-uk.mjs +2 -0
  124. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  125. package/fesm2022/ngwr-i18n-vi.mjs +2 -0
  126. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  127. package/fesm2022/ngwr-i18n-zh-TW.mjs +2 -0
  128. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  129. package/fesm2022/ngwr-i18n-zh.mjs +2 -0
  130. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  131. package/fesm2022/ngwr-i18n.mjs +9 -9
  132. package/fesm2022/ngwr-icon.mjs +6 -6
  133. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  134. package/fesm2022/ngwr-input-number.mjs +15 -6
  135. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  136. package/fesm2022/ngwr-input-otp.mjs +38 -6
  137. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  138. package/fesm2022/ngwr-input.mjs +15 -15
  139. package/fesm2022/ngwr-keyboard.mjs +3 -3
  140. package/fesm2022/ngwr-knob-testing.mjs +11 -3
  141. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  142. package/fesm2022/ngwr-knob.mjs +19 -4
  143. package/fesm2022/ngwr-knob.mjs.map +1 -1
  144. package/fesm2022/ngwr-layout.mjs +15 -15
  145. package/fesm2022/ngwr-lightbox.mjs +3 -3
  146. package/fesm2022/ngwr-line-chart-testing.mjs +18 -2
  147. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
  148. package/fesm2022/ngwr-line-chart.mjs +22 -4
  149. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  150. package/fesm2022/ngwr-list.mjs +6 -6
  151. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  152. package/fesm2022/ngwr-markdown.mjs +6 -6
  153. package/fesm2022/ngwr-marquee.mjs +3 -3
  154. package/fesm2022/ngwr-media.mjs +3 -3
  155. package/fesm2022/ngwr-mention.mjs +6 -6
  156. package/fesm2022/ngwr-meta.mjs +6 -6
  157. package/fesm2022/ngwr-meter-group.mjs +3 -3
  158. package/fesm2022/ngwr-overlay.mjs +6 -6
  159. package/fesm2022/ngwr-page-header.mjs +3 -3
  160. package/fesm2022/ngwr-pagination.mjs +33 -6
  161. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  162. package/fesm2022/ngwr-pipes.mjs +21 -21
  163. package/fesm2022/ngwr-platform.mjs +9 -9
  164. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  165. package/fesm2022/ngwr-popover.mjs +29 -11
  166. package/fesm2022/ngwr-popover.mjs.map +1 -1
  167. package/fesm2022/ngwr-progress.mjs +3 -3
  168. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  169. package/fesm2022/ngwr-qr.mjs +3 -3
  170. package/fesm2022/ngwr-radio.mjs +6 -6
  171. package/fesm2022/ngwr-rating-testing.mjs +12 -3
  172. package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
  173. package/fesm2022/ngwr-rating.mjs +19 -4
  174. package/fesm2022/ngwr-rating.mjs.map +1 -1
  175. package/fesm2022/ngwr-result.mjs +13 -13
  176. package/fesm2022/ngwr-result.mjs.map +1 -1
  177. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  178. package/fesm2022/ngwr-schema-form.mjs +3 -3
  179. package/fesm2022/ngwr-scroll.mjs +3 -3
  180. package/fesm2022/ngwr-segmented.mjs +3 -3
  181. package/fesm2022/ngwr-select.mjs +9 -9
  182. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  183. package/fesm2022/ngwr-sidebar.mjs +3 -3
  184. package/fesm2022/ngwr-skeleton.mjs +3 -3
  185. package/fesm2022/ngwr-slider.mjs +18 -5
  186. package/fesm2022/ngwr-slider.mjs.map +1 -1
  187. package/fesm2022/ngwr-sparkline.mjs +3 -3
  188. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  189. package/fesm2022/ngwr-spinner.mjs +3 -3
  190. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  191. package/fesm2022/ngwr-split-text.mjs +3 -3
  192. package/fesm2022/ngwr-splitter.mjs +3 -3
  193. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  194. package/fesm2022/ngwr-squircle.mjs +28 -9
  195. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  196. package/fesm2022/ngwr-star-border.mjs +3 -3
  197. package/fesm2022/ngwr-statistic.mjs +20 -13
  198. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  199. package/fesm2022/ngwr-stepper.mjs +6 -6
  200. package/fesm2022/ngwr-storage.mjs +3 -3
  201. package/fesm2022/ngwr-switch.mjs +3 -3
  202. package/fesm2022/ngwr-table.mjs +18 -18
  203. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  204. package/fesm2022/ngwr-tabs.mjs +6 -6
  205. package/fesm2022/ngwr-textarea.mjs +3 -3
  206. package/fesm2022/ngwr-theme.mjs +3 -3
  207. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  208. package/fesm2022/ngwr-timeline.mjs +6 -6
  209. package/fesm2022/ngwr-toast.mjs +10 -10
  210. package/fesm2022/ngwr-toast.mjs.map +1 -1
  211. package/fesm2022/ngwr-toolbar.mjs +3 -3
  212. package/fesm2022/ngwr-tour.mjs +6 -6
  213. package/fesm2022/ngwr-transfer.mjs +88 -11
  214. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  215. package/fesm2022/ngwr-tree-testing.mjs +24 -0
  216. package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
  217. package/fesm2022/ngwr-tree.mjs +72 -7
  218. package/fesm2022/ngwr-tree.mjs.map +1 -1
  219. package/fesm2022/ngwr-typewriter.mjs +3 -3
  220. package/fesm2022/ngwr-typography.mjs +3 -3
  221. package/fesm2022/ngwr-version.mjs +1 -1
  222. package/fesm2022/ngwr-version.mjs.map +1 -1
  223. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  224. package/fesm2022/ngwr-waves.mjs +3 -3
  225. package/fesm2022/ngwr-window.mjs +12 -12
  226. package/form/styles/_index.scss +63 -0
  227. package/i18n/ar.json +4 -2
  228. package/i18n/cs.json +4 -2
  229. package/i18n/de.json +4 -2
  230. package/i18n/en.json +6 -4
  231. package/i18n/es.json +4 -2
  232. package/i18n/fr.json +4 -2
  233. package/i18n/he.json +4 -2
  234. package/i18n/hi.json +4 -2
  235. package/i18n/id.json +4 -2
  236. package/i18n/it.json +4 -2
  237. package/i18n/ja.json +4 -2
  238. package/i18n/ko.json +4 -2
  239. package/i18n/nl.json +4 -2
  240. package/i18n/pl.json +4 -2
  241. package/i18n/pt.json +4 -2
  242. package/i18n/ru.json +4 -2
  243. package/i18n/sv.json +4 -2
  244. package/i18n/tr.json +4 -2
  245. package/i18n/uk.json +4 -2
  246. package/i18n/vi.json +4 -2
  247. package/i18n/zh-TW.json +4 -2
  248. package/i18n/zh.json +4 -2
  249. package/input-otp/styles/_index.scss +5 -1
  250. package/line-chart/styles/_index.scss +5 -3
  251. package/llms-full.txt +1 -1
  252. package/markdown/styles/_index.scss +4 -1
  253. package/mention/styles/_index.scss +22 -1
  254. package/package.json +1 -1
  255. package/radio/styles/_index.scss +3 -0
  256. package/result/styles/_index.scss +12 -0
  257. package/schematics/migrations/v14/index.js +6 -3
  258. package/schematics/migrations.json +1 -1
  259. package/schematics/ng-add/index.js +34 -5
  260. package/segmented/styles/_index.scss +4 -1
  261. package/select/styles/_index.scss +20 -1
  262. package/statistic/styles/_index.scss +4 -0
  263. package/stepper/styles/_index.scss +36 -0
  264. package/switch/styles/_index.scss +3 -0
  265. package/table/styles/_index.scss +12 -0
  266. package/tabs/styles/_index.scss +4 -1
  267. package/textarea/styles/_index.scss +6 -1
  268. package/theme/styles/_colors.scss +11 -0
  269. package/theme/styles/_contrast.scss +136 -0
  270. package/theme/styles/_index.scss +1 -0
  271. package/theme/styles/_mixins.scss +15 -8
  272. package/timeline/styles/_index.scss +28 -1
  273. package/toast/styles/_index.scss +11 -0
  274. package/tree/styles/_index.scss +27 -1
  275. package/types/ngwr-badge.d.ts +1 -1
  276. package/types/ngwr-bar-chart-testing.d.ts +11 -1
  277. package/types/ngwr-button.d.ts +1 -1
  278. package/types/ngwr-calendar-heatmap-testing.d.ts +10 -5
  279. package/types/ngwr-calendar-heatmap.d.ts +22 -0
  280. package/types/ngwr-calendar.d.ts +21 -0
  281. package/types/ngwr-cascader-testing.d.ts +74 -17
  282. package/types/ngwr-cascader.d.ts +28 -0
  283. package/types/ngwr-checkbox-testing.d.ts +12 -1
  284. package/types/ngwr-checkbox.d.ts +10 -0
  285. package/types/ngwr-clipboard.d.ts +1 -1
  286. package/types/ngwr-confetti.d.ts +1 -1
  287. package/types/ngwr-cookie.d.ts +1 -1
  288. package/types/ngwr-date-adapters-fns.d.ts +1 -1
  289. package/types/ngwr-date-adapters-luxon.d.ts +1 -1
  290. package/types/ngwr-date.d.ts +9 -3
  291. package/types/ngwr-density.d.ts +1 -1
  292. package/types/ngwr-dialog.d.ts +1 -1
  293. package/types/ngwr-donut-chart-testing.d.ts +11 -1
  294. package/types/ngwr-drawer.d.ts +1 -1
  295. package/types/ngwr-dropdown.d.ts +16 -0
  296. package/types/ngwr-file-upload.d.ts +11 -0
  297. package/types/ngwr-form.d.ts +25 -0
  298. package/types/ngwr-gauge-testing.d.ts +9 -1
  299. package/types/ngwr-hotkey.d.ts +1 -1
  300. package/types/ngwr-i18n.d.ts +1 -1
  301. package/types/ngwr-input-number.d.ts +12 -2
  302. package/types/ngwr-input-otp.d.ts +12 -0
  303. package/types/ngwr-knob-testing.d.ts +11 -3
  304. package/types/ngwr-knob.d.ts +13 -0
  305. package/types/ngwr-line-chart-testing.d.ts +11 -1
  306. package/types/ngwr-line-chart.d.ts +18 -0
  307. package/types/ngwr-loading-bar.d.ts +1 -1
  308. package/types/ngwr-markdown.d.ts +1 -1
  309. package/types/ngwr-media.d.ts +1 -1
  310. package/types/ngwr-meta.d.ts +1 -1
  311. package/types/ngwr-overlay.d.ts +2 -2
  312. package/types/ngwr-pagination.d.ts +16 -0
  313. package/types/ngwr-platform.d.ts +3 -3
  314. package/types/ngwr-popover.d.ts +16 -0
  315. package/types/ngwr-rating-testing.d.ts +12 -3
  316. package/types/ngwr-rating.d.ts +13 -0
  317. package/types/ngwr-scroll.d.ts +1 -1
  318. package/types/ngwr-squircle.d.ts +22 -3
  319. package/types/ngwr-statistic.d.ts +0 -1
  320. package/types/ngwr-storage.d.ts +1 -1
  321. package/types/ngwr-theme.d.ts +1 -1
  322. package/types/ngwr-toast.d.ts +1 -1
  323. package/types/ngwr-tour.d.ts +1 -1
  324. package/types/ngwr-transfer.d.ts +52 -0
  325. package/types/ngwr-tree-testing.d.ts +20 -0
  326. package/types/ngwr-tree.d.ts +41 -0
  327. package/types/ngwr-version.d.ts +1 -1
  328. package/types/ngwr-window.d.ts +1 -1
  329. package/typography/styles/_index.scss +26 -4
@@ -186,10 +186,10 @@ class WrSidebar {
186
186
  }
187
187
  return null;
188
188
  }
189
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSidebar, deps: [], target: i0.ɵɵFactoryTarget.Component });
190
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSidebar, isStandalone: true, selector: "wr-sidebar", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, defaultGroupIcon: { classPropertyName: "defaultGroupIcon", publicName: "defaultGroupIcon", isSignal: true, isRequired: false, transformFunction: null }, defaultItemIcon: { classPropertyName: "defaultItemIcon", publicName: "defaultItemIcon", isSignal: true, isRequired: false, transformFunction: null }, autoExpand: { classPropertyName: "autoExpand", publicName: "autoExpand", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedAriaLabel()" }, classAttribute: "wr-sidebar" }, ngImport: i0, template: "<!-- A div, not a <nav>: the host already IS the navigation landmark, and two\n nested ones announce the same list twice. -->\n<div class=\"wr-sidebar__inner\">\n @for (entry of entries(); track entry.title) {\n @if (!isGroup(entry)) {\n <!--\n A span, not a greyed anchor, exactly as the nested branch below does it.\n `--disabled` only paints: `pointer-events: none` stops a real pointer but\n not the keyboard, so a disabled entry stayed in the tab order and Enter\n navigated \u2014 `disabled` on a `WrSidebarItem` is documented as \"no\n navigation\". An empty `url` is the same case: `[routerLink]=\"[]\"` resolves\n to the current route, which is a link that goes nowhere.\n -->\n @if (asItem(entry).disabled || !asItem(entry).url.length) {\n <span class=\"wr-sidebar__entry wr-sidebar__entry--disabled\">\n @if (asItem(entry).icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n @if (asItem(entry).badge) {\n <small class=\"wr-sidebar__badge\">{{ asItem(entry).badge }}</small>\n }\n </span>\n } @else {\n <a class=\"wr-sidebar__entry\" routerLinkActive=\"wr-sidebar__entry--active\" [routerLink]=\"asItem(entry).url\">\n @if (asItem(entry).icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n @if (asItem(entry).badge) {\n <small class=\"wr-sidebar__badge\">{{ asItem(entry).badge }}</small>\n }\n </a>\n }\n } @else {\n <section class=\"wr-sidebar__group\" [class.wr-sidebar__group--collapsed]=\"!isOpen(entry.title)\">\n <button\n type=\"button\"\n class=\"wr-sidebar__group-toggle\"\n [attr.aria-expanded]=\"isOpen(entry.title)\"\n [attr.aria-controls]=\"groupBodyId($index)\"\n (click)=\"toggleGroup(entry.title)\"\n >\n @if (asGroup(entry).icon || defaultGroupIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n <!-- Inline chrome chevron \u2014 not user-customizable. -->\n <svg\n class=\"wr-icon__svg wr-sidebar__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 <div\n class=\"wr-sidebar__group-wrap\"\n [attr.id]=\"groupBodyId($index)\"\n [attr.inert]=\"!isOpen(entry.title) ? '' : null\"\n >\n <div class=\"wr-sidebar__group-body\">\n <ul class=\"wr-sidebar__list\">\n @for (child of asGroup(entry).children; track child.title) {\n <li>\n @if (child.disabled || !child.url.length) {\n <span class=\"wr-sidebar__item wr-sidebar__item--disabled\">\n @if (child.icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__item-title\">{{ child.title }}</span>\n @if (child.badge) {\n <small class=\"wr-sidebar__badge\">{{ child.badge }}</small>\n }\n </span>\n } @else {\n <a class=\"wr-sidebar__item\" routerLinkActive=\"wr-sidebar__item--active\" [routerLink]=\"child.url\">\n @if (child.icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__item-title\">{{ child.title }}</span>\n @if (child.badge) {\n <small class=\"wr-sidebar__badge\">{{ child.badge }}</small>\n }\n </a>\n }\n </li>\n }\n </ul>\n </div>\n </div>\n </section>\n }\n }\n</div>\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
189
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSidebar, deps: [], target: i0.ɵɵFactoryTarget.Component });
190
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrSidebar, isStandalone: true, selector: "wr-sidebar", inputs: { entries: { classPropertyName: "entries", publicName: "entries", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, defaultGroupIcon: { classPropertyName: "defaultGroupIcon", publicName: "defaultGroupIcon", isSignal: true, isRequired: false, transformFunction: null }, defaultItemIcon: { classPropertyName: "defaultItemIcon", publicName: "defaultItemIcon", isSignal: true, isRequired: false, transformFunction: null }, autoExpand: { classPropertyName: "autoExpand", publicName: "autoExpand", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "resolvedAriaLabel()" }, classAttribute: "wr-sidebar" }, ngImport: i0, template: "<!-- A div, not a <nav>: the host already IS the navigation landmark, and two\n nested ones announce the same list twice. -->\n<div class=\"wr-sidebar__inner\">\n @for (entry of entries(); track entry.title) {\n @if (!isGroup(entry)) {\n <!--\n A span, not a greyed anchor, exactly as the nested branch below does it.\n `--disabled` only paints: `pointer-events: none` stops a real pointer but\n not the keyboard, so a disabled entry stayed in the tab order and Enter\n navigated \u2014 `disabled` on a `WrSidebarItem` is documented as \"no\n navigation\". An empty `url` is the same case: `[routerLink]=\"[]\"` resolves\n to the current route, which is a link that goes nowhere.\n -->\n @if (asItem(entry).disabled || !asItem(entry).url.length) {\n <span class=\"wr-sidebar__entry wr-sidebar__entry--disabled\">\n @if (asItem(entry).icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n @if (asItem(entry).badge) {\n <small class=\"wr-sidebar__badge\">{{ asItem(entry).badge }}</small>\n }\n </span>\n } @else {\n <a class=\"wr-sidebar__entry\" routerLinkActive=\"wr-sidebar__entry--active\" [routerLink]=\"asItem(entry).url\">\n @if (asItem(entry).icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n @if (asItem(entry).badge) {\n <small class=\"wr-sidebar__badge\">{{ asItem(entry).badge }}</small>\n }\n </a>\n }\n } @else {\n <section class=\"wr-sidebar__group\" [class.wr-sidebar__group--collapsed]=\"!isOpen(entry.title)\">\n <button\n type=\"button\"\n class=\"wr-sidebar__group-toggle\"\n [attr.aria-expanded]=\"isOpen(entry.title)\"\n [attr.aria-controls]=\"groupBodyId($index)\"\n (click)=\"toggleGroup(entry.title)\"\n >\n @if (asGroup(entry).icon || defaultGroupIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n <!-- Inline chrome chevron \u2014 not user-customizable. -->\n <svg\n class=\"wr-icon__svg wr-sidebar__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 <div\n class=\"wr-sidebar__group-wrap\"\n [attr.id]=\"groupBodyId($index)\"\n [attr.inert]=\"!isOpen(entry.title) ? '' : null\"\n >\n <div class=\"wr-sidebar__group-body\">\n <ul class=\"wr-sidebar__list\">\n @for (child of asGroup(entry).children; track child.title) {\n <li>\n @if (child.disabled || !child.url.length) {\n <span class=\"wr-sidebar__item wr-sidebar__item--disabled\">\n @if (child.icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__item-title\">{{ child.title }}</span>\n @if (child.badge) {\n <small class=\"wr-sidebar__badge\">{{ child.badge }}</small>\n }\n </span>\n } @else {\n <a class=\"wr-sidebar__item\" routerLinkActive=\"wr-sidebar__item--active\" [routerLink]=\"child.url\">\n @if (child.icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__item-title\">{{ child.title }}</span>\n @if (child.badge) {\n <small class=\"wr-sidebar__badge\">{{ child.badge }}</small>\n }\n </a>\n }\n </li>\n }\n </ul>\n </div>\n </div>\n </section>\n }\n }\n</div>\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
191
191
  }
192
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSidebar, decorators: [{
192
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSidebar, decorators: [{
193
193
  type: Component,
194
194
  args: [{ selector: 'wr-sidebar', encapsulation: ViewEncapsulation.None, host: { class: 'wr-sidebar', role: 'navigation', '[attr.aria-label]': 'resolvedAriaLabel()' }, imports: [RouterLink, RouterLinkActive, WrIcon], template: "<!-- A div, not a <nav>: the host already IS the navigation landmark, and two\n nested ones announce the same list twice. -->\n<div class=\"wr-sidebar__inner\">\n @for (entry of entries(); track entry.title) {\n @if (!isGroup(entry)) {\n <!--\n A span, not a greyed anchor, exactly as the nested branch below does it.\n `--disabled` only paints: `pointer-events: none` stops a real pointer but\n not the keyboard, so a disabled entry stayed in the tab order and Enter\n navigated \u2014 `disabled` on a `WrSidebarItem` is documented as \"no\n navigation\". An empty `url` is the same case: `[routerLink]=\"[]\"` resolves\n to the current route, which is a link that goes nowhere.\n -->\n @if (asItem(entry).disabled || !asItem(entry).url.length) {\n <span class=\"wr-sidebar__entry wr-sidebar__entry--disabled\">\n @if (asItem(entry).icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n @if (asItem(entry).badge) {\n <small class=\"wr-sidebar__badge\">{{ asItem(entry).badge }}</small>\n }\n </span>\n } @else {\n <a class=\"wr-sidebar__entry\" routerLinkActive=\"wr-sidebar__entry--active\" [routerLink]=\"asItem(entry).url\">\n @if (asItem(entry).icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n @if (asItem(entry).badge) {\n <small class=\"wr-sidebar__badge\">{{ asItem(entry).badge }}</small>\n }\n </a>\n }\n } @else {\n <section class=\"wr-sidebar__group\" [class.wr-sidebar__group--collapsed]=\"!isOpen(entry.title)\">\n <button\n type=\"button\"\n class=\"wr-sidebar__group-toggle\"\n [attr.aria-expanded]=\"isOpen(entry.title)\"\n [attr.aria-controls]=\"groupBodyId($index)\"\n (click)=\"toggleGroup(entry.title)\"\n >\n @if (asGroup(entry).icon || defaultGroupIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__title\">{{ entry.title }}</span>\n <!-- Inline chrome chevron \u2014 not user-customizable. -->\n <svg\n class=\"wr-icon__svg wr-sidebar__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 <div\n class=\"wr-sidebar__group-wrap\"\n [attr.id]=\"groupBodyId($index)\"\n [attr.inert]=\"!isOpen(entry.title) ? '' : null\"\n >\n <div class=\"wr-sidebar__group-body\">\n <ul class=\"wr-sidebar__list\">\n @for (child of asGroup(entry).children; track child.title) {\n <li>\n @if (child.disabled || !child.url.length) {\n <span class=\"wr-sidebar__item wr-sidebar__item--disabled\">\n @if (child.icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__item-title\">{{ child.title }}</span>\n @if (child.badge) {\n <small class=\"wr-sidebar__badge\">{{ child.badge }}</small>\n }\n </span>\n } @else {\n <a class=\"wr-sidebar__item\" routerLinkActive=\"wr-sidebar__item--active\" [routerLink]=\"child.url\">\n @if (child.icon || defaultItemIcon(); as name) {\n <wr-icon class=\"wr-sidebar__icon\" [name]=\"name\" />\n }\n <span class=\"wr-sidebar__item-title\">{{ child.title }}</span>\n @if (child.badge) {\n <small class=\"wr-sidebar__badge\">{{ child.badge }}</small>\n }\n </a>\n }\n </li>\n }\n </ul>\n </div>\n </div>\n </section>\n }\n }\n</div>\n" }]
195
195
  }], ctorParameters: () => [], propDecorators: { entries: [{ type: i0.Input, args: [{ isSignal: true, alias: "entries", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], defaultGroupIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultGroupIcon", required: false }] }], defaultItemIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultItemIcon", required: false }] }], autoExpand: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoExpand", required: false }] }] } });
@@ -49,10 +49,10 @@ class WrSkeleton {
49
49
  return parts.join(' ');
50
50
  }, /* @ts-ignore */
51
51
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
52
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Component });
53
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrSkeleton, isStandalone: true, selector: "wr-skeleton", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-busy": "true", "aria-live": "polite" }, properties: { "class": "classes()" } }, ngImport: i0, template: '', isInline: true, encapsulation: i0.ViewEncapsulation.None });
52
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Component });
53
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrSkeleton, isStandalone: true, selector: "wr-skeleton", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-busy": "true", "aria-live": "polite" }, properties: { "class": "classes()" } }, ngImport: i0, template: '', isInline: true, encapsulation: i0.ViewEncapsulation.None });
54
54
  }
55
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSkeleton, decorators: [{
55
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSkeleton, decorators: [{
56
56
  type: Component,
57
57
  args: [{
58
58
  selector: 'wr-skeleton',
@@ -233,8 +233,21 @@ class WrSlider {
233
233
  const v = this.value();
234
234
  if (Array.isArray(v)) {
235
235
  const tuple = v;
236
- const lo = this.clampToBounds(tuple[0]);
237
- const hi = this.clampToBounds(tuple[1]);
236
+ const a = this.clampToBounds(tuple[0]);
237
+ const b = this.clampToBounds(tuple[1]);
238
+ // ORDERED, and only for the display — the same asymmetry as the clamp
239
+ // above, for the same reason. An external `[80, 20]` used to seed
240
+ // `low = 80` and `high = 20`, which made each thumb report an
241
+ // `aria-valuenow` outside its OWN `aria-valuemin`/`aria-valuemax` (the
242
+ // two bound each other), and left the fill with a start and no width,
243
+ // so a range that is real simply vanished.
244
+ //
245
+ // This does not contradict the recorded contract that an edit to one
246
+ // end is never reordered: that one is scoped to "while the user is
247
+ // still on it", and ordering settles when the interaction ends. An
248
+ // external write IS the end — there is no interaction in progress.
249
+ const lo = Math.min(a, b);
250
+ const hi = Math.max(a, b);
238
251
  this.low.set(lo);
239
252
  this.high.set(hi);
240
253
  this.highSeeded = true;
@@ -416,10 +429,10 @@ class WrSlider {
416
429
  const value = this.range() ? [this.low(), this.high()] : this.low();
417
430
  this.value.set(value);
418
431
  }
419
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSlider, deps: [], target: i0.ɵɵFactoryTarget.Component });
420
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSlider, isStandalone: true, selector: "wr-slider", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", 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 }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, upperLabel: { classPropertyName: "upperLabel", publicName: "upperLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { listeners: { "focusout": "onFocusOut($event)" }, properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "track", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #track class=\"wr-slider__track\" (pointerdown)=\"onTrackPointerDown($event)\">\n <!--\n Positioned on the INLINE axis, not with `left`: `inset-inline-start` is the\n same edge in LTR and mirrors under `dir=\"rtl\"`, so the track paints itself\n the right way round without the component reading a direction to draw.\n -->\n <span class=\"wr-slider__fill\" [style.inset-inline-start.%]=\"fillStart()\" [style.width.%]=\"fillWidth()\"></span>\n\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--low\"\n role=\"slider\"\n [attr.id]=\"thumbId()\"\n [style.inset-inline-start.%]=\"lowPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"range() ? high() : max()\"\n [attr.aria-valuenow]=\"low()\"\n [attr.aria-label]=\"resolvedLowLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n (pointerdown)=\"onPointerDown($event, 'low')\"\n (keydown)=\"onKey($event, 'low')\"\n ></button>\n\n @if (range()) {\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--high\"\n role=\"slider\"\n [style.inset-inline-start.%]=\"highPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"low()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"high()\"\n [attr.aria-label]=\"resolvedUpperLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n (pointerdown)=\"onPointerDown($event, 'high')\"\n (keydown)=\"onKey($event, 'high')\"\n ></button>\n }\n</div>\n\n@if (showLabel()) {\n <div class=\"wr-slider__label\">{{ label() }}</div>\n}\n", encapsulation: i0.ViewEncapsulation.None });
432
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSlider, deps: [], target: i0.ɵɵFactoryTarget.Component });
433
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrSlider, isStandalone: true, selector: "wr-slider", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", 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 }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, upperLabel: { classPropertyName: "upperLabel", publicName: "upperLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { listeners: { "focusout": "onFocusOut($event)" }, properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "track", first: true, predicate: ["track"], descendants: true, isSignal: true }], ngImport: i0, template: "<div #track class=\"wr-slider__track\" (pointerdown)=\"onTrackPointerDown($event)\">\n <!--\n Positioned on the INLINE axis, not with `left`: `inset-inline-start` is the\n same edge in LTR and mirrors under `dir=\"rtl\"`, so the track paints itself\n the right way round without the component reading a direction to draw.\n -->\n <span class=\"wr-slider__fill\" [style.inset-inline-start.%]=\"fillStart()\" [style.width.%]=\"fillWidth()\"></span>\n\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--low\"\n role=\"slider\"\n [attr.id]=\"thumbId()\"\n [style.inset-inline-start.%]=\"lowPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"range() ? high() : max()\"\n [attr.aria-valuenow]=\"low()\"\n [attr.aria-label]=\"resolvedLowLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n (pointerdown)=\"onPointerDown($event, 'low')\"\n (keydown)=\"onKey($event, 'low')\"\n ></button>\n\n @if (range()) {\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--high\"\n role=\"slider\"\n [style.inset-inline-start.%]=\"highPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"low()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"high()\"\n [attr.aria-label]=\"resolvedUpperLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n (pointerdown)=\"onPointerDown($event, 'high')\"\n (keydown)=\"onKey($event, 'high')\"\n ></button>\n }\n</div>\n\n@if (showLabel()) {\n <div class=\"wr-slider__label\">{{ label() }}</div>\n}\n", encapsulation: i0.ViewEncapsulation.None });
421
434
  }
422
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSlider, decorators: [{
435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSlider, decorators: [{
423
436
  type: Component,
424
437
  args: [{ selector: 'wr-slider', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()', '(focusout)': 'onFocusOut($event)' }, template: "<div #track class=\"wr-slider__track\" (pointerdown)=\"onTrackPointerDown($event)\">\n <!--\n Positioned on the INLINE axis, not with `left`: `inset-inline-start` is the\n same edge in LTR and mirrors under `dir=\"rtl\"`, so the track paints itself\n the right way round without the component reading a direction to draw.\n -->\n <span class=\"wr-slider__fill\" [style.inset-inline-start.%]=\"fillStart()\" [style.width.%]=\"fillWidth()\"></span>\n\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--low\"\n role=\"slider\"\n [attr.id]=\"thumbId()\"\n [style.inset-inline-start.%]=\"lowPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"range() ? high() : max()\"\n [attr.aria-valuenow]=\"low()\"\n [attr.aria-label]=\"resolvedLowLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n (pointerdown)=\"onPointerDown($event, 'low')\"\n (keydown)=\"onKey($event, 'low')\"\n ></button>\n\n @if (range()) {\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--high\"\n role=\"slider\"\n [style.inset-inline-start.%]=\"highPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"low()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"high()\"\n [attr.aria-label]=\"resolvedUpperLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n (pointerdown)=\"onPointerDown($event, 'high')\"\n (keydown)=\"onKey($event, 'high')\"\n ></button>\n }\n</div>\n\n@if (showLabel()) {\n <div class=\"wr-slider__label\">{{ label() }}</div>\n}\n" }]
425
438
  }], ctorParameters: () => [], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], range: [{ type: i0.Input, args: [{ isSignal: true, alias: "range", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], upperLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "upperLabel", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touch: [{ type: i0.Output, args: ["touch"] }], track: [{ type: i0.ViewChild, args: ['track', { isSignal: true }] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-slider.mjs","sources":["../../../projects/lib/slider/slider.ts","../../../projects/lib/slider/slider.html","../../../projects/lib/slider/ngwr-slider.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport type { ElementRef } from '@angular/core';\nimport {\n Component,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { WR_FORM_FIELD, useFormFieldAria } from 'ngwr/form';\nimport { useI18nText } from 'ngwr/i18n';\nimport { clamp, round } from 'ngwr/utils';\n\nimport type { WrSliderValue } from './interfaces';\n\n/** Trim float drift from step calculations. */\n\n/**\n * Numeric slider with optional dual-thumb range mode.\n *\n * A signal-forms native control: it implements `FormValueControl<WrSliderValue>`,\n * so `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone. The value\n * shape depends on `range`: `number` (default) or `[number, number]` when\n * `range=\"true\"`.\n *\n * Keyboard: ← / → adjust by `step`; ↑ / ↓ same; Shift+arrow by `step × 10`;\n * Home / End jump to min / max; PageUp / PageDown by `step × 10`.\n *\n * Reading direction: the arrows follow the VISUAL track, so under `dir=\"rtl\"`\n * → moves toward the lower end and ← toward the higher one, and a drag reads\n * its ratio from the right edge. ↑ / ↓, PageUp / PageDown and Home / End are\n * unchanged — they name a value, not a side of the screen.\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-slider [formField]=\"form.volume\" min=\"0\" max=\"100\" step=\"5\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-slider [(value)]=\"range\" range min=\"0\" max=\"1000\" step=\"10\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/slider\n */\n@Component({\n selector: 'wr-slider',\n templateUrl: './slider.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()', '(focusout)': 'onFocusOut($event)' },\n})\nexport class WrSlider implements FormValueControl<WrSliderValue> {\n // Typed `WrSliderValue | undefined` (not `number`) to satisfy the reserved\n // `FormUiControl` min/max slots, which are keyed to the control's value type.\n // The transform still coerces to a plain number, so the bounds stay numeric\n // at runtime; `minValue`/`maxValue` narrow them back for arithmetic.\n /** Lower bound. @default 0 */\n readonly min = input<WrSliderValue | undefined>(0, { transform: (v: unknown): number => coerceNumberProperty(v, 0) });\n /** Upper bound. @default 100 */\n readonly max = input<WrSliderValue | undefined>(100, {\n transform: (v: unknown): number => coerceNumberProperty(v, 100),\n });\n\n /** Resolved numeric lower bound for internal arithmetic. */\n private readonly minValue = computed(() => {\n const m = this.min();\n return typeof m === 'number' ? m : 0;\n });\n /** Resolved numeric upper bound for internal arithmetic. */\n private readonly maxValue = computed(() => {\n const m = this.max();\n return typeof m === 'number' ? m : 100;\n });\n\n /** Step size for keyboard and drag. @default 1 */\n readonly step = input(1, { transform: (v: unknown): number => Math.max(0.0001, coerceNumberProperty(v, 1)) });\n /** Render two thumbs and emit `[low, high]`. @default false */\n readonly range = input(false, { transform: coerceBooleanProperty });\n /**\n * Disable interaction. Bound automatically from the field's disabled state\n * when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse value changes while the thumbs stay focusable and the value still\n * submits. Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * The thumbs keep their tab stop and keep announcing their value — arrow keys,\n * Home / End and the pointer simply move nothing — which is the whole\n * difference from `disabled`, where they would leave the tab order entirely.\n * Mirrored as `aria-readonly`, which role `slider` supports.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n /** Render the current value below the track. @default true */\n readonly showLabel = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Accessible name of the thumb — the single one, or the LOWER one in range\n * mode. Falls back to `slider.label` / `slider.lower`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n /** Accessible name of the upper thumb in range mode. Falls back to `slider.upper`. */\n readonly upperLabel = input<string | null>(null);\n\n /**\n * A thumb projects no text, so these ARE the accessible names — and they were\n * hard-coded English with no key behind them, so every slider on a page\n * announced the same untranslated \"Value\" whatever it controlled.\n *\n * Range mode reads `ariaLabel` as the LOWER end rather than as the whole\n * control: a name given once must land on something, and naming both thumbs\n * the same thing would read two different values under one name.\n */\n private readonly singleLabel = useI18nText(this.ariaLabel, 'slider.label', 'Value');\n private readonly lowerLabel = useI18nText(this.ariaLabel, 'slider.lower', 'Lower value');\n protected readonly resolvedUpperLabel = useI18nText(this.upperLabel, 'slider.upper', 'Upper value');\n protected readonly resolvedLowLabel = computed(() => (this.range() ? this.lowerLabel() : this.singleLabel()));\n\n private readonly field = inject(WR_FORM_FIELD, { optional: true });\n\n /**\n * Id the surrounding `<wr-form-field>`'s `<label for>` points at, put on the\n * single thumb — the LOWER one in range mode, the same end `ariaLabel` names.\n *\n * The field renders its label before it can see what was projected into it, so\n * the id travels the other way and the control adopts it, exactly as\n * `[wrInput]` does. Without this the `for` named an element that was nowhere\n * in the document: clicking the label did nothing, and the field's own text\n * reached the thumb through no path at all.\n *\n * It lands on the THUMB rather than on the host because only a labelable\n * element can be a label's target, and `<wr-slider>` is not one — a `for`\n * pointing at the host would resolve and still name nothing. The thumb is a\n * real `<button>`, so it is.\n *\n * What this does NOT change is the thumb's name: an `aria-label` outranks a\n * `<label>` in the accname order, and the thumb keeps its own because the\n * field cannot promise it has one to give — `<wr-form-field>` renders a label\n * only when `label` is set, and a slider that traded a generic name for no\n * name would be the worse bug. Set `[ariaLabel]` to the field's label where\n * the two should read alike.\n */\n protected readonly thumbId = computed(() => this.field?.controlId() ?? null);\n\n /**\n * The field's error message, wired to the thumb the same way `wrInput` wires it\n * to its native element.\n *\n * Without this the messages `<wr-form-field>` renders are visible and nothing\n * else: a screen reader on the thumb never learns the field is invalid, nor\n * what the message says. `aria-invalid` is keyed on the message EXISTING rather\n * than on `errorKeys()`, because the field only publishes an id once it is\n * showing something — announcing \"invalid\" while pointing at nothing is worse\n * than staying quiet.\n */\n // Through the shared helper, not a local pair: the hint is described by\n // `hintId`, which only `useFormFieldAria()` composes, and `aria-invalid` keys\n // on the error COUNT rather than on \"something is described\". Hand-rolled here,\n // these three announced the error and never the hint — and `<input wrInput>` is\n // the control the report was filed against.\n private readonly fieldAria = useFormFieldAria();\n protected readonly describedBy = this.fieldAria.describedBy;\n protected readonly ariaInvalid = this.fieldAria.ariaInvalid;\n\n /**\n * Current value. Bound by `[formField]`, or two-way via `[(value)]`. Shape\n * follows `range`: a plain `number`, or `[low, high]` in range mode.\n */\n readonly value = model<WrSliderValue>(0);\n\n /** Emitted on blur so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n protected readonly low = signal(0);\n /**\n * The high thumb's cell. Its literal default stands in for `maxValue()`,\n * which cannot be read at field-initialisation time — see `highSeeded` and\n * the constructor effect.\n */\n protected readonly high = signal(100);\n\n /**\n * Whether `high` has ever been told a real value by the model.\n *\n * `<wr-slider range [min]=\"200\" [max]=\"300\" />` binds no value, so the model\n * holds its own scalar default and the tuple branch below never runs: `high`\n * kept the literal 100, which is not inside every `[min, max]`. The thumb\n * rendered off the track and the first interaction committed `[low, 100]` —\n * a value the slider itself calls out of range.\n */\n private highSeeded = false;\n\n protected readonly track = viewChild.required<ElementRef<HTMLElement>>('track');\n\n /**\n * Ambient reading direction. Optional so a bare `TestBed` — or any consumer\n * that never set a direction — needs no provider; `Directionality` is\n * root-provided, so `null` only ever means \"nobody asked\", which is LTR.\n *\n * Nothing caches a direction-derived value: the thumbs are painted with\n * `inset-inline-start`, so the track mirrors from CSS alone, and `isRtl()` is\n * read inside the event handlers. A runtime flip therefore needs no\n * subscription to `Directionality.change`.\n */\n private readonly dir = inject(Directionality, { optional: true });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-slider'];\n if (this.range()) parts.push('wr-slider--range');\n if (this.disabled()) parts.push('wr-slider--disabled');\n else if (this.readonly()) parts.push('wr-slider--readonly');\n return parts.join(' ');\n });\n\n protected readonly lowPercent = computed(() => this.percentOf(this.low()));\n protected readonly highPercent = computed(() => this.percentOf(this.high()));\n\n /** Offset of the fill from the track's START edge — the left one in LTR, the right one in RTL. */\n protected readonly fillStart = computed(() => (this.range() ? this.lowPercent() : 0));\n protected readonly fillWidth = computed(() =>\n this.range() ? this.highPercent() - this.lowPercent() : this.lowPercent()\n );\n\n protected readonly label = computed(() => (this.range() ? `${this.low()} – ${this.high()}` : `${this.low()}`));\n\n constructor() {\n // Keep the internal thumbs in sync with external writes to `value`\n // (the old `writeValue`): split the tuple / clamp into the low & high cells.\n // The cells are clamped and the MODEL IS NOT TOUCHED, and the asymmetry is\n // deliberate. A thumb cannot render outside its own track, so the display\n // has no choice — but writing that clamp back into `value` would erase the\n // error it represents: under `[formField]` the bounds reach this component\n // only through the schema's `min()` / `max()` rules (binding `[min]` beside\n // `[formField]` is an NG8022 compile error), so the write-back deleted the\n // out-of-range value those rules exist to report, and marked a pristine\n // form dirty on first paint besides. The first real interaction emits an\n // in-range number through `emitChange` and the two agree from then on.\n effect(() => {\n const v = this.value();\n\n if (Array.isArray(v)) {\n const tuple = v as readonly [number, number];\n const lo = this.clampToBounds(tuple[0]);\n const hi = this.clampToBounds(tuple[1]);\n this.low.set(lo);\n this.high.set(hi);\n this.highSeeded = true;\n return;\n }\n\n if (typeof v !== 'number') return;\n const lo = this.clampToBounds(v);\n this.low.set(lo);\n\n if (!this.range()) return;\n\n // Range mode holding a scalar: the high thumb has never been told\n // anything, and its literal default is not inside every `[min, max]`.\n // Seed it at the top of the range — which is what the 100 meant back when\n // the bounds were 0–100. The MODEL is left alone here too; the shape it\n // holds is the consumer's business until they move a thumb.\n this.high.set(this.highSeeded ? this.clampToBounds(untracked(this.high)) : this.maxValue());\n this.highSeeded = true;\n });\n }\n\n // Interaction\n\n protected onPointerDown(event: PointerEvent, thumb: 'low' | 'high'): void {\n if (this.disabled() || this.readonly()) return;\n event.preventDefault();\n const target = event.currentTarget as HTMLElement;\n target.setPointerCapture(event.pointerId);\n // `preventDefault` above also suppresses the default focus, so the arrows\n // did nothing after a mouse drag until the thumb was found again with Tab —\n // while a click on the bare TRACK focused it. Synchronously, not through\n // `focusThumb`: `event.currentTarget` is already the thumb, so that\n // helper's `queueMicrotask` would only defer a focus nothing is waiting on.\n target.focus();\n\n const move = (e: PointerEvent): void => this.updateFromEvent(e, thumb);\n const cleanup = (e: PointerEvent): void => {\n target.releasePointerCapture(e.pointerId);\n target.removeEventListener('pointermove', move);\n target.removeEventListener('pointerup', cleanup);\n target.removeEventListener('pointercancel', cleanup);\n this.touch.emit();\n };\n\n target.addEventListener('pointermove', move);\n target.addEventListener('pointerup', cleanup);\n // `pointercancel` is never followed by a `pointerup`, so without this the\n // move listener outlived the drag: the thumb kept following a pointer that\n // was merely hovering over it, with no button held.\n target.addEventListener('pointercancel', cleanup);\n this.updateFromEvent(event, thumb);\n }\n\n protected onTrackPointerDown(event: PointerEvent): void {\n if (this.disabled() || this.readonly()) return;\n if ((event.target as HTMLElement).closest('.wr-slider__thumb')) return;\n const thumb = this.nearestThumb(event);\n this.updateFromEvent(event, thumb);\n this.focusThumb(thumb);\n }\n\n protected onKey(event: KeyboardEvent, thumb: 'low' | 'high'): void {\n if (this.disabled() || this.readonly()) return;\n const big = event.shiftKey || event.key === 'PageUp' || event.key === 'PageDown' ? 10 : 1;\n const delta = this.step() * big;\n const current = thumb === 'low' ? this.low() : this.high();\n // The horizontal arrows name a SIDE of the track, so they follow the\n // reading direction; every other key names a value and does not.\n const inline = this.isRtl() ? -delta : delta;\n let next: number | null = null;\n\n switch (event.key) {\n case 'ArrowRight':\n next = current + inline;\n break;\n case 'ArrowLeft':\n next = current - inline;\n break;\n case 'ArrowUp':\n case 'PageUp':\n next = current + delta;\n break;\n case 'ArrowDown':\n case 'PageDown':\n next = current - delta;\n break;\n case 'Home':\n next = this.minValue();\n break;\n case 'End':\n next = this.maxValue();\n break;\n }\n\n if (next === null) return;\n event.preventDefault();\n this.setThumb(thumb, next);\n this.emitChange();\n this.touch.emit();\n }\n\n /**\n * A bound field learns it may show its validation copy from `touch`, and\n * pointer-up plus a value-changing keypress cannot be the only sources: a\n * slider tabbed into and out of without an arrow press left the field\n * untouched forever — which is exactly the case `touched` exists for, and\n * what this output has always documented itself as doing. `wr-knob` and\n * `wr-rating` bind `(blur)` on the one element they own; this component has\n * two thumbs, so it listens for the bubbling `focusout` on its host instead\n * — and ignores the one that only moves focus from one thumb to the other.\n */\n protected onFocusOut(event: FocusEvent): void {\n if (this.track().nativeElement.contains(event.relatedTarget as Node | null)) return;\n this.touch.emit();\n }\n\n // Internals\n\n private isRtl(): boolean {\n return this.dir?.value === 'rtl';\n }\n\n /**\n * The value under a pointer, measured along the track's INLINE axis.\n *\n * The offset is taken from whichever edge the track starts at — the left one\n * in LTR, the right one in RTL — so the whole component needs the direction\n * in exactly one place. Measuring from `rect.left` regardless would read 0 at\n * the visual maximum of a mirrored track.\n */\n private valueAt(event: PointerEvent): number {\n const rect = this.track().nativeElement.getBoundingClientRect();\n const offset = this.isRtl() ? rect.right - event.clientX : event.clientX - rect.left;\n const ratio = clamp(offset / rect.width, 0, 1);\n return this.minValue() + ratio * (this.maxValue() - this.minValue());\n }\n\n private updateFromEvent(event: PointerEvent, thumb: 'low' | 'high'): void {\n this.setThumb(thumb, this.valueAt(event));\n this.emitChange();\n }\n\n /**\n * Which thumb a track click grabs: the one nearest the pointer ON SCREEN.\n *\n * Value distance is the same thing as visual distance once {@link valueAt}\n * has mirrored the ratio — in RTL the low thumb is the RIGHT one, and a click\n * near the right edge lands close to `low` in value space too.\n */\n private nearestThumb(event: PointerEvent): 'low' | 'high' {\n if (!this.range()) return 'low';\n const raw = this.valueAt(event);\n return Math.abs(raw - this.low()) <= Math.abs(raw - this.high()) ? 'low' : 'high';\n }\n\n private focusThumb(thumb: 'low' | 'high'): void {\n queueMicrotask(() => {\n const root = this.track().nativeElement;\n const el = root.querySelector<HTMLElement>(`.wr-slider__thumb--${thumb}`);\n el?.focus();\n });\n }\n\n private setThumb(thumb: 'low' | 'high', raw: number): void {\n const stepped = this.snap(raw);\n if (thumb === 'low') {\n const next = this.range() ? Math.min(stepped, this.high()) : stepped;\n this.low.set(next);\n } else {\n this.high.set(Math.max(stepped, this.low()));\n }\n }\n\n private snap(value: number): number {\n const stepped = Math.round((value - this.minValue()) / this.step()) * this.step() + this.minValue();\n return this.clampToBounds(round(stepped, 6));\n }\n\n private clampToBounds(v: number): number {\n return clamp(v, this.minValue(), this.maxValue());\n }\n\n private percentOf(v: number): number {\n const span = this.maxValue() - this.minValue();\n if (span <= 0) return 0;\n return ((v - this.minValue()) / span) * 100;\n }\n\n private emitChange(): void {\n const value: WrSliderValue = this.range() ? [this.low(), this.high()] : this.low();\n this.value.set(value);\n }\n}\n","<div #track class=\"wr-slider__track\" (pointerdown)=\"onTrackPointerDown($event)\">\n <!--\n Positioned on the INLINE axis, not with `left`: `inset-inline-start` is the\n same edge in LTR and mirrors under `dir=\"rtl\"`, so the track paints itself\n the right way round without the component reading a direction to draw.\n -->\n <span class=\"wr-slider__fill\" [style.inset-inline-start.%]=\"fillStart()\" [style.width.%]=\"fillWidth()\"></span>\n\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--low\"\n role=\"slider\"\n [attr.id]=\"thumbId()\"\n [style.inset-inline-start.%]=\"lowPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"range() ? high() : max()\"\n [attr.aria-valuenow]=\"low()\"\n [attr.aria-label]=\"resolvedLowLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n (pointerdown)=\"onPointerDown($event, 'low')\"\n (keydown)=\"onKey($event, 'low')\"\n ></button>\n\n @if (range()) {\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--high\"\n role=\"slider\"\n [style.inset-inline-start.%]=\"highPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"low()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"high()\"\n [attr.aria-label]=\"resolvedUpperLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n (pointerdown)=\"onPointerDown($event, 'high')\"\n (keydown)=\"onKey($event, 'high')\"\n ></button>\n }\n</div>\n\n@if (showLabel()) {\n <div class=\"wr-slider__label\">{{ label() }}</div>\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-slider.mjs","sources":["../../../projects/lib/slider/slider.ts","../../../projects/lib/slider/slider.html","../../../projects/lib/slider/ngwr-slider.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directionality } from '@angular/cdk/bidi';\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport type { ElementRef } from '@angular/core';\nimport {\n Component,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\nimport { WR_FORM_FIELD, useFormFieldAria } from 'ngwr/form';\nimport { useI18nText } from 'ngwr/i18n';\nimport { clamp, round } from 'ngwr/utils';\n\nimport type { WrSliderValue } from './interfaces';\n\n/** Trim float drift from step calculations. */\n\n/**\n * Numeric slider with optional dual-thumb range mode.\n *\n * A signal-forms native control: it implements `FormValueControl<WrSliderValue>`,\n * so `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone. The value\n * shape depends on `range`: `number` (default) or `[number, number]` when\n * `range=\"true\"`.\n *\n * Keyboard: ← / → adjust by `step`; ↑ / ↓ same; Shift+arrow by `step × 10`;\n * Home / End jump to min / max; PageUp / PageDown by `step × 10`.\n *\n * Reading direction: the arrows follow the VISUAL track, so under `dir=\"rtl\"`\n * → moves toward the lower end and ← toward the higher one, and a drag reads\n * its ratio from the right edge. ↑ / ↓, PageUp / PageDown and Home / End are\n * unchanged — they name a value, not a side of the screen.\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-slider [formField]=\"form.volume\" min=\"0\" max=\"100\" step=\"5\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-slider [(value)]=\"range\" range min=\"0\" max=\"1000\" step=\"10\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/slider\n */\n@Component({\n selector: 'wr-slider',\n templateUrl: './slider.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()', '(focusout)': 'onFocusOut($event)' },\n})\nexport class WrSlider implements FormValueControl<WrSliderValue> {\n // Typed `WrSliderValue | undefined` (not `number`) to satisfy the reserved\n // `FormUiControl` min/max slots, which are keyed to the control's value type.\n // The transform still coerces to a plain number, so the bounds stay numeric\n // at runtime; `minValue`/`maxValue` narrow them back for arithmetic.\n /** Lower bound. @default 0 */\n readonly min = input<WrSliderValue | undefined>(0, { transform: (v: unknown): number => coerceNumberProperty(v, 0) });\n /** Upper bound. @default 100 */\n readonly max = input<WrSliderValue | undefined>(100, {\n transform: (v: unknown): number => coerceNumberProperty(v, 100),\n });\n\n /** Resolved numeric lower bound for internal arithmetic. */\n private readonly minValue = computed(() => {\n const m = this.min();\n return typeof m === 'number' ? m : 0;\n });\n /** Resolved numeric upper bound for internal arithmetic. */\n private readonly maxValue = computed(() => {\n const m = this.max();\n return typeof m === 'number' ? m : 100;\n });\n\n /** Step size for keyboard and drag. @default 1 */\n readonly step = input(1, { transform: (v: unknown): number => Math.max(0.0001, coerceNumberProperty(v, 1)) });\n /** Render two thumbs and emit `[low, high]`. @default false */\n readonly range = input(false, { transform: coerceBooleanProperty });\n /**\n * Disable interaction. Bound automatically from the field's disabled state\n * when used with `[formField]`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Refuse value changes while the thumbs stay focusable and the value still\n * submits. Bound automatically from the field's readonly state when used with\n * `[formField]`.\n *\n * The thumbs keep their tab stop and keep announcing their value — arrow keys,\n * Home / End and the pointer simply move nothing — which is the whole\n * difference from `disabled`, where they would leave the tab order entirely.\n * Mirrored as `aria-readonly`, which role `slider` supports.\n *\n * @default false\n */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n /** Render the current value below the track. @default true */\n readonly showLabel = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Accessible name of the thumb — the single one, or the LOWER one in range\n * mode. Falls back to `slider.label` / `slider.lower`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n /** Accessible name of the upper thumb in range mode. Falls back to `slider.upper`. */\n readonly upperLabel = input<string | null>(null);\n\n /**\n * A thumb projects no text, so these ARE the accessible names — and they were\n * hard-coded English with no key behind them, so every slider on a page\n * announced the same untranslated \"Value\" whatever it controlled.\n *\n * Range mode reads `ariaLabel` as the LOWER end rather than as the whole\n * control: a name given once must land on something, and naming both thumbs\n * the same thing would read two different values under one name.\n */\n private readonly singleLabel = useI18nText(this.ariaLabel, 'slider.label', 'Value');\n private readonly lowerLabel = useI18nText(this.ariaLabel, 'slider.lower', 'Lower value');\n protected readonly resolvedUpperLabel = useI18nText(this.upperLabel, 'slider.upper', 'Upper value');\n protected readonly resolvedLowLabel = computed(() => (this.range() ? this.lowerLabel() : this.singleLabel()));\n\n private readonly field = inject(WR_FORM_FIELD, { optional: true });\n\n /**\n * Id the surrounding `<wr-form-field>`'s `<label for>` points at, put on the\n * single thumb — the LOWER one in range mode, the same end `ariaLabel` names.\n *\n * The field renders its label before it can see what was projected into it, so\n * the id travels the other way and the control adopts it, exactly as\n * `[wrInput]` does. Without this the `for` named an element that was nowhere\n * in the document: clicking the label did nothing, and the field's own text\n * reached the thumb through no path at all.\n *\n * It lands on the THUMB rather than on the host because only a labelable\n * element can be a label's target, and `<wr-slider>` is not one — a `for`\n * pointing at the host would resolve and still name nothing. The thumb is a\n * real `<button>`, so it is.\n *\n * What this does NOT change is the thumb's name: an `aria-label` outranks a\n * `<label>` in the accname order, and the thumb keeps its own because the\n * field cannot promise it has one to give — `<wr-form-field>` renders a label\n * only when `label` is set, and a slider that traded a generic name for no\n * name would be the worse bug. Set `[ariaLabel]` to the field's label where\n * the two should read alike.\n */\n protected readonly thumbId = computed(() => this.field?.controlId() ?? null);\n\n /**\n * The field's error message, wired to the thumb the same way `wrInput` wires it\n * to its native element.\n *\n * Without this the messages `<wr-form-field>` renders are visible and nothing\n * else: a screen reader on the thumb never learns the field is invalid, nor\n * what the message says. `aria-invalid` is keyed on the message EXISTING rather\n * than on `errorKeys()`, because the field only publishes an id once it is\n * showing something — announcing \"invalid\" while pointing at nothing is worse\n * than staying quiet.\n */\n // Through the shared helper, not a local pair: the hint is described by\n // `hintId`, which only `useFormFieldAria()` composes, and `aria-invalid` keys\n // on the error COUNT rather than on \"something is described\". Hand-rolled here,\n // these three announced the error and never the hint — and `<input wrInput>` is\n // the control the report was filed against.\n private readonly fieldAria = useFormFieldAria();\n protected readonly describedBy = this.fieldAria.describedBy;\n protected readonly ariaInvalid = this.fieldAria.ariaInvalid;\n\n /**\n * Current value. Bound by `[formField]`, or two-way via `[(value)]`. Shape\n * follows `range`: a plain `number`, or `[low, high]` in range mode.\n */\n readonly value = model<WrSliderValue>(0);\n\n /** Emitted on blur so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n protected readonly low = signal(0);\n /**\n * The high thumb's cell. Its literal default stands in for `maxValue()`,\n * which cannot be read at field-initialisation time — see `highSeeded` and\n * the constructor effect.\n */\n protected readonly high = signal(100);\n\n /**\n * Whether `high` has ever been told a real value by the model.\n *\n * `<wr-slider range [min]=\"200\" [max]=\"300\" />` binds no value, so the model\n * holds its own scalar default and the tuple branch below never runs: `high`\n * kept the literal 100, which is not inside every `[min, max]`. The thumb\n * rendered off the track and the first interaction committed `[low, 100]` —\n * a value the slider itself calls out of range.\n */\n private highSeeded = false;\n\n protected readonly track = viewChild.required<ElementRef<HTMLElement>>('track');\n\n /**\n * Ambient reading direction. Optional so a bare `TestBed` — or any consumer\n * that never set a direction — needs no provider; `Directionality` is\n * root-provided, so `null` only ever means \"nobody asked\", which is LTR.\n *\n * Nothing caches a direction-derived value: the thumbs are painted with\n * `inset-inline-start`, so the track mirrors from CSS alone, and `isRtl()` is\n * read inside the event handlers. A runtime flip therefore needs no\n * subscription to `Directionality.change`.\n */\n private readonly dir = inject(Directionality, { optional: true });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-slider'];\n if (this.range()) parts.push('wr-slider--range');\n if (this.disabled()) parts.push('wr-slider--disabled');\n else if (this.readonly()) parts.push('wr-slider--readonly');\n return parts.join(' ');\n });\n\n protected readonly lowPercent = computed(() => this.percentOf(this.low()));\n protected readonly highPercent = computed(() => this.percentOf(this.high()));\n\n /** Offset of the fill from the track's START edge — the left one in LTR, the right one in RTL. */\n protected readonly fillStart = computed(() => (this.range() ? this.lowPercent() : 0));\n protected readonly fillWidth = computed(() =>\n this.range() ? this.highPercent() - this.lowPercent() : this.lowPercent()\n );\n\n protected readonly label = computed(() => (this.range() ? `${this.low()} – ${this.high()}` : `${this.low()}`));\n\n constructor() {\n // Keep the internal thumbs in sync with external writes to `value`\n // (the old `writeValue`): split the tuple / clamp into the low & high cells.\n // The cells are clamped and the MODEL IS NOT TOUCHED, and the asymmetry is\n // deliberate. A thumb cannot render outside its own track, so the display\n // has no choice — but writing that clamp back into `value` would erase the\n // error it represents: under `[formField]` the bounds reach this component\n // only through the schema's `min()` / `max()` rules (binding `[min]` beside\n // `[formField]` is an NG8022 compile error), so the write-back deleted the\n // out-of-range value those rules exist to report, and marked a pristine\n // form dirty on first paint besides. The first real interaction emits an\n // in-range number through `emitChange` and the two agree from then on.\n effect(() => {\n const v = this.value();\n\n if (Array.isArray(v)) {\n const tuple = v as readonly [number, number];\n const a = this.clampToBounds(tuple[0]);\n const b = this.clampToBounds(tuple[1]);\n // ORDERED, and only for the display — the same asymmetry as the clamp\n // above, for the same reason. An external `[80, 20]` used to seed\n // `low = 80` and `high = 20`, which made each thumb report an\n // `aria-valuenow` outside its OWN `aria-valuemin`/`aria-valuemax` (the\n // two bound each other), and left the fill with a start and no width,\n // so a range that is real simply vanished.\n //\n // This does not contradict the recorded contract that an edit to one\n // end is never reordered: that one is scoped to \"while the user is\n // still on it\", and ordering settles when the interaction ends. An\n // external write IS the end — there is no interaction in progress.\n const lo = Math.min(a, b);\n const hi = Math.max(a, b);\n this.low.set(lo);\n this.high.set(hi);\n this.highSeeded = true;\n return;\n }\n\n if (typeof v !== 'number') return;\n const lo = this.clampToBounds(v);\n this.low.set(lo);\n\n if (!this.range()) return;\n\n // Range mode holding a scalar: the high thumb has never been told\n // anything, and its literal default is not inside every `[min, max]`.\n // Seed it at the top of the range — which is what the 100 meant back when\n // the bounds were 0–100. The MODEL is left alone here too; the shape it\n // holds is the consumer's business until they move a thumb.\n this.high.set(this.highSeeded ? this.clampToBounds(untracked(this.high)) : this.maxValue());\n this.highSeeded = true;\n });\n }\n\n // Interaction\n\n protected onPointerDown(event: PointerEvent, thumb: 'low' | 'high'): void {\n if (this.disabled() || this.readonly()) return;\n event.preventDefault();\n const target = event.currentTarget as HTMLElement;\n target.setPointerCapture(event.pointerId);\n // `preventDefault` above also suppresses the default focus, so the arrows\n // did nothing after a mouse drag until the thumb was found again with Tab —\n // while a click on the bare TRACK focused it. Synchronously, not through\n // `focusThumb`: `event.currentTarget` is already the thumb, so that\n // helper's `queueMicrotask` would only defer a focus nothing is waiting on.\n target.focus();\n\n const move = (e: PointerEvent): void => this.updateFromEvent(e, thumb);\n const cleanup = (e: PointerEvent): void => {\n target.releasePointerCapture(e.pointerId);\n target.removeEventListener('pointermove', move);\n target.removeEventListener('pointerup', cleanup);\n target.removeEventListener('pointercancel', cleanup);\n this.touch.emit();\n };\n\n target.addEventListener('pointermove', move);\n target.addEventListener('pointerup', cleanup);\n // `pointercancel` is never followed by a `pointerup`, so without this the\n // move listener outlived the drag: the thumb kept following a pointer that\n // was merely hovering over it, with no button held.\n target.addEventListener('pointercancel', cleanup);\n this.updateFromEvent(event, thumb);\n }\n\n protected onTrackPointerDown(event: PointerEvent): void {\n if (this.disabled() || this.readonly()) return;\n if ((event.target as HTMLElement).closest('.wr-slider__thumb')) return;\n const thumb = this.nearestThumb(event);\n this.updateFromEvent(event, thumb);\n this.focusThumb(thumb);\n }\n\n protected onKey(event: KeyboardEvent, thumb: 'low' | 'high'): void {\n if (this.disabled() || this.readonly()) return;\n const big = event.shiftKey || event.key === 'PageUp' || event.key === 'PageDown' ? 10 : 1;\n const delta = this.step() * big;\n const current = thumb === 'low' ? this.low() : this.high();\n // The horizontal arrows name a SIDE of the track, so they follow the\n // reading direction; every other key names a value and does not.\n const inline = this.isRtl() ? -delta : delta;\n let next: number | null = null;\n\n switch (event.key) {\n case 'ArrowRight':\n next = current + inline;\n break;\n case 'ArrowLeft':\n next = current - inline;\n break;\n case 'ArrowUp':\n case 'PageUp':\n next = current + delta;\n break;\n case 'ArrowDown':\n case 'PageDown':\n next = current - delta;\n break;\n case 'Home':\n next = this.minValue();\n break;\n case 'End':\n next = this.maxValue();\n break;\n }\n\n if (next === null) return;\n event.preventDefault();\n this.setThumb(thumb, next);\n this.emitChange();\n this.touch.emit();\n }\n\n /**\n * A bound field learns it may show its validation copy from `touch`, and\n * pointer-up plus a value-changing keypress cannot be the only sources: a\n * slider tabbed into and out of without an arrow press left the field\n * untouched forever — which is exactly the case `touched` exists for, and\n * what this output has always documented itself as doing. `wr-knob` and\n * `wr-rating` bind `(blur)` on the one element they own; this component has\n * two thumbs, so it listens for the bubbling `focusout` on its host instead\n * — and ignores the one that only moves focus from one thumb to the other.\n */\n protected onFocusOut(event: FocusEvent): void {\n if (this.track().nativeElement.contains(event.relatedTarget as Node | null)) return;\n this.touch.emit();\n }\n\n // Internals\n\n private isRtl(): boolean {\n return this.dir?.value === 'rtl';\n }\n\n /**\n * The value under a pointer, measured along the track's INLINE axis.\n *\n * The offset is taken from whichever edge the track starts at — the left one\n * in LTR, the right one in RTL — so the whole component needs the direction\n * in exactly one place. Measuring from `rect.left` regardless would read 0 at\n * the visual maximum of a mirrored track.\n */\n private valueAt(event: PointerEvent): number {\n const rect = this.track().nativeElement.getBoundingClientRect();\n const offset = this.isRtl() ? rect.right - event.clientX : event.clientX - rect.left;\n const ratio = clamp(offset / rect.width, 0, 1);\n return this.minValue() + ratio * (this.maxValue() - this.minValue());\n }\n\n private updateFromEvent(event: PointerEvent, thumb: 'low' | 'high'): void {\n this.setThumb(thumb, this.valueAt(event));\n this.emitChange();\n }\n\n /**\n * Which thumb a track click grabs: the one nearest the pointer ON SCREEN.\n *\n * Value distance is the same thing as visual distance once {@link valueAt}\n * has mirrored the ratio — in RTL the low thumb is the RIGHT one, and a click\n * near the right edge lands close to `low` in value space too.\n */\n private nearestThumb(event: PointerEvent): 'low' | 'high' {\n if (!this.range()) return 'low';\n const raw = this.valueAt(event);\n return Math.abs(raw - this.low()) <= Math.abs(raw - this.high()) ? 'low' : 'high';\n }\n\n private focusThumb(thumb: 'low' | 'high'): void {\n queueMicrotask(() => {\n const root = this.track().nativeElement;\n const el = root.querySelector<HTMLElement>(`.wr-slider__thumb--${thumb}`);\n el?.focus();\n });\n }\n\n private setThumb(thumb: 'low' | 'high', raw: number): void {\n const stepped = this.snap(raw);\n if (thumb === 'low') {\n const next = this.range() ? Math.min(stepped, this.high()) : stepped;\n this.low.set(next);\n } else {\n this.high.set(Math.max(stepped, this.low()));\n }\n }\n\n private snap(value: number): number {\n const stepped = Math.round((value - this.minValue()) / this.step()) * this.step() + this.minValue();\n return this.clampToBounds(round(stepped, 6));\n }\n\n private clampToBounds(v: number): number {\n return clamp(v, this.minValue(), this.maxValue());\n }\n\n private percentOf(v: number): number {\n const span = this.maxValue() - this.minValue();\n if (span <= 0) return 0;\n return ((v - this.minValue()) / span) * 100;\n }\n\n private emitChange(): void {\n const value: WrSliderValue = this.range() ? [this.low(), this.high()] : this.low();\n this.value.set(value);\n }\n}\n","<div #track class=\"wr-slider__track\" (pointerdown)=\"onTrackPointerDown($event)\">\n <!--\n Positioned on the INLINE axis, not with `left`: `inset-inline-start` is the\n same edge in LTR and mirrors under `dir=\"rtl\"`, so the track paints itself\n the right way round without the component reading a direction to draw.\n -->\n <span class=\"wr-slider__fill\" [style.inset-inline-start.%]=\"fillStart()\" [style.width.%]=\"fillWidth()\"></span>\n\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--low\"\n role=\"slider\"\n [attr.id]=\"thumbId()\"\n [style.inset-inline-start.%]=\"lowPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"range() ? high() : max()\"\n [attr.aria-valuenow]=\"low()\"\n [attr.aria-label]=\"resolvedLowLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n (pointerdown)=\"onPointerDown($event, 'low')\"\n (keydown)=\"onKey($event, 'low')\"\n ></button>\n\n @if (range()) {\n <button\n type=\"button\"\n class=\"wr-slider__thumb wr-slider__thumb--high\"\n role=\"slider\"\n [style.inset-inline-start.%]=\"highPercent()\"\n [disabled]=\"disabled()\"\n [attr.aria-valuemin]=\"low()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"high()\"\n [attr.aria-label]=\"resolvedUpperLabel()\"\n [attr.aria-readonly]=\"readonly() || null\"\n (pointerdown)=\"onPointerDown($event, 'high')\"\n (keydown)=\"onKey($event, 'high')\"\n ></button>\n }\n</div>\n\n@if (showLabel()) {\n <div class=\"wr-slider__label\">{{ label() }}</div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -108,10 +108,10 @@ class WrSparkline {
108
108
  }, /* @ts-ignore */
109
109
  ...(ngDevMode ? [{ debugName: "tipPoint" }] : /* istanbul ignore next */ []));
110
110
  viewBox = `0 0 ${this.vbW} ${this.vbH}`;
111
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSparkline, deps: [], target: i0.ɵɵFactoryTarget.Component });
112
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSparkline, isStandalone: true, selector: "wr-sparkline", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, showArea: { classPropertyName: "showArea", publicName: "showArea", isSignal: true, isRequired: false, transformFunction: null }, showTip: { classPropertyName: "showTip", publicName: "showTip", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-sparkline" }, ngImport: i0, template: "<svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n>\n @if (showArea() && areaPath()) {\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" fill-opacity=\"0.15\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n @if (showTip() && tipPoint(); as tip) {\n <circle class=\"wr-sparkline__tip\" [attr.cx]=\"tip.x\" [attr.cy]=\"tip.y\" r=\"1.5\" [attr.fill]=\"color()\" />\n }\n</svg>\n", encapsulation: i0.ViewEncapsulation.None });
111
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSparkline, deps: [], target: i0.ɵɵFactoryTarget.Component });
112
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrSparkline, isStandalone: true, selector: "wr-sparkline", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, showArea: { classPropertyName: "showArea", publicName: "showArea", isSignal: true, isRequired: false, transformFunction: null }, showTip: { classPropertyName: "showTip", publicName: "showTip", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-sparkline" }, ngImport: i0, template: "<svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n>\n @if (showArea() && areaPath()) {\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" fill-opacity=\"0.15\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n @if (showTip() && tipPoint(); as tip) {\n <circle class=\"wr-sparkline__tip\" [attr.cx]=\"tip.x\" [attr.cy]=\"tip.y\" r=\"1.5\" [attr.fill]=\"color()\" />\n }\n</svg>\n", encapsulation: i0.ViewEncapsulation.None });
113
113
  }
114
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSparkline, decorators: [{
114
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSparkline, decorators: [{
115
115
  type: Component,
116
116
  args: [{ selector: 'wr-sparkline', encapsulation: ViewEncapsulation.None, host: { class: 'wr-sparkline' }, template: "<svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n>\n @if (showArea() && areaPath()) {\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" fill-opacity=\"0.15\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n @if (showTip() && tipPoint(); as tip) {\n <circle class=\"wr-sparkline__tip\" [attr.cx]=\"tip.x\" [attr.cy]=\"tip.y\" r=\"1.5\" [attr.fill]=\"color()\" />\n }\n</svg>\n" }]
117
117
  }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], showArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "showArea", required: false }] }], showTip: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTip", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
@@ -127,10 +127,10 @@ class WrSpeedDial {
127
127
  initial(label) {
128
128
  return [...label][0] ?? '';
129
129
  }
130
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpeedDial, deps: [], target: i0.ɵɵFactoryTarget.Component });
131
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSpeedDial, isStandalone: true, selector: "wr-speed-dial", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, triggerLabel: { classPropertyName: "triggerLabel", publicName: "triggerLabel", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, safeArea: { classPropertyName: "safeArea", publicName: "safeArea", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", pick: "pick" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n #trigger\n type=\"button\"\n class=\"wr-speed-dial__trigger\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"menuId\"\n [attr.aria-label]=\"resolvedTriggerLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onTrigger()\"\n>\n <wr-icon [name]=\"icon()\" />\n</button>\n\n<!--\n A LIST of buttons, deliberately not a `role=\"menu\"`. The dial used to announce\n aria-haspopup=\"menu\" over role=\"menuitem\" buttons while handling no menu key at\n all \u2014 no arrows, no Home/End, no focus moving in on open \u2014 and the actions were\n N tab stops rather than the pattern's one. That role also puts a screen reader\n into focus mode, so the arrow keys it promises stop reading the page and then do\n nothing here. The structure now says what the component does: a disclosure\n button (aria-expanded / aria-controls) revealing ordinary buttons that Tab\n reaches and Enter activates, with Escape as the way back.\n\n `role=\"list\"` is written out because `list-style: none` (styles/_index.scss)\n drops the implicit list semantics in Safari.\n-->\n<ul class=\"wr-speed-dial__actions\" role=\"list\" [attr.id]=\"menuId\">\n @for (action of actions(); track action.id) {\n <li class=\"wr-speed-dial__action-wrap\" [style.--wr-speed-dial-i]=\"$index + 1\">\n <button\n type=\"button\"\n class=\"wr-speed-dial__action\"\n [attr.aria-label]=\"action.label\"\n [title]=\"action.label\"\n [disabled]=\"disabled()\"\n (click)=\"onPick(action)\"\n >\n @if (action.icon) {\n <wr-icon [name]=\"action.icon\" />\n } @else {\n <span>{{ initial(action.label) }}</span>\n }\n </button>\n </li>\n }\n</ul>\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
130
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpeedDial, deps: [], target: i0.ɵɵFactoryTarget.Component });
131
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrSpeedDial, isStandalone: true, selector: "wr-speed-dial", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, triggerLabel: { classPropertyName: "triggerLabel", publicName: "triggerLabel", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, safeArea: { classPropertyName: "safeArea", publicName: "safeArea", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", pick: "pick" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n #trigger\n type=\"button\"\n class=\"wr-speed-dial__trigger\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"menuId\"\n [attr.aria-label]=\"resolvedTriggerLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onTrigger()\"\n>\n <wr-icon [name]=\"icon()\" />\n</button>\n\n<!--\n A LIST of buttons, deliberately not a `role=\"menu\"`. The dial used to announce\n aria-haspopup=\"menu\" over role=\"menuitem\" buttons while handling no menu key at\n all \u2014 no arrows, no Home/End, no focus moving in on open \u2014 and the actions were\n N tab stops rather than the pattern's one. That role also puts a screen reader\n into focus mode, so the arrow keys it promises stop reading the page and then do\n nothing here. The structure now says what the component does: a disclosure\n button (aria-expanded / aria-controls) revealing ordinary buttons that Tab\n reaches and Enter activates, with Escape as the way back.\n\n `role=\"list\"` is written out because `list-style: none` (styles/_index.scss)\n drops the implicit list semantics in Safari.\n-->\n<ul class=\"wr-speed-dial__actions\" role=\"list\" [attr.id]=\"menuId\">\n @for (action of actions(); track action.id) {\n <li class=\"wr-speed-dial__action-wrap\" [style.--wr-speed-dial-i]=\"$index + 1\">\n <button\n type=\"button\"\n class=\"wr-speed-dial__action\"\n [attr.aria-label]=\"action.label\"\n [title]=\"action.label\"\n [disabled]=\"disabled()\"\n (click)=\"onPick(action)\"\n >\n @if (action.icon) {\n <wr-icon [name]=\"action.icon\" />\n } @else {\n <span>{{ initial(action.label) }}</span>\n }\n </button>\n </li>\n }\n</ul>\n", dependencies: [{ kind: "component", type: WrIcon, selector: "wr-icon", inputs: ["name"] }], encapsulation: i0.ViewEncapsulation.None });
132
132
  }
133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpeedDial, decorators: [{
133
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpeedDial, decorators: [{
134
134
  type: Component,
135
135
  args: [{ selector: 'wr-speed-dial', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()', '(keydown)': 'onKeydown($event)' }, imports: [WrIcon], template: "<button\n #trigger\n type=\"button\"\n class=\"wr-speed-dial__trigger\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"menuId\"\n [attr.aria-label]=\"resolvedTriggerLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"onTrigger()\"\n>\n <wr-icon [name]=\"icon()\" />\n</button>\n\n<!--\n A LIST of buttons, deliberately not a `role=\"menu\"`. The dial used to announce\n aria-haspopup=\"menu\" over role=\"menuitem\" buttons while handling no menu key at\n all \u2014 no arrows, no Home/End, no focus moving in on open \u2014 and the actions were\n N tab stops rather than the pattern's one. That role also puts a screen reader\n into focus mode, so the arrow keys it promises stop reading the page and then do\n nothing here. The structure now says what the component does: a disclosure\n button (aria-expanded / aria-controls) revealing ordinary buttons that Tab\n reaches and Enter activates, with Escape as the way back.\n\n `role=\"list\"` is written out because `list-style: none` (styles/_index.scss)\n drops the implicit list semantics in Safari.\n-->\n<ul class=\"wr-speed-dial__actions\" role=\"list\" [attr.id]=\"menuId\">\n @for (action of actions(); track action.id) {\n <li class=\"wr-speed-dial__action-wrap\" [style.--wr-speed-dial-i]=\"$index + 1\">\n <button\n type=\"button\"\n class=\"wr-speed-dial__action\"\n [attr.aria-label]=\"action.label\"\n [title]=\"action.label\"\n [disabled]=\"disabled()\"\n (click)=\"onPick(action)\"\n >\n @if (action.icon) {\n <wr-icon [name]=\"action.icon\" />\n } @else {\n <span>{{ initial(action.label) }}</span>\n }\n </button>\n </li>\n }\n</ul>\n" }]
136
136
  }], ctorParameters: () => [], propDecorators: { actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], triggerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerLabel", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], safeArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "safeArea", required: false }] }], pick: [{ type: i0.Output, args: ["pick"] }], triggerEl: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
@@ -42,10 +42,10 @@ class WrSpinner {
42
42
  return size === 'md' ? 'wr-spinner' : `wr-spinner wr-spinner--${size}`;
43
43
  }, /* @ts-ignore */
44
44
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
45
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrSpinner, isStandalone: true, selector: "wr-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "attr.aria-label": "resolvedAriaLabel()", "class": "classes()" } }, ngImport: i0, template: "<svg viewBox=\"0 0 50 50\" aria-hidden=\"true\">\n <circle class=\"wr-spinner__path\" cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke-width=\"5\" />\n</svg>\n", encapsulation: i0.ViewEncapsulation.None });
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrSpinner, isStandalone: true, selector: "wr-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "attr.aria-label": "resolvedAriaLabel()", "class": "classes()" } }, ngImport: i0, template: "<svg viewBox=\"0 0 50 50\" aria-hidden=\"true\">\n <circle class=\"wr-spinner__path\" cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke-width=\"5\" />\n</svg>\n", encapsulation: i0.ViewEncapsulation.None });
47
47
  }
48
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpinner, decorators: [{
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpinner, decorators: [{
49
49
  type: Component,
50
50
  args: [{ selector: 'wr-spinner', encapsulation: ViewEncapsulation.None, host: {
51
51
  role: 'status',
@@ -951,10 +951,10 @@ class WrSplashCursor {
951
951
  onCleanup(teardown);
952
952
  });
953
953
  }
954
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSplashCursor, deps: [], target: i0.ɵɵFactoryTarget.Component });
955
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.5", type: WrSplashCursor, isStandalone: true, selector: "wr-splash-cursor", inputs: { fullscreen: { classPropertyName: "fullscreen", publicName: "fullscreen", isSignal: true, isRequired: false, transformFunction: null }, simResolution: { classPropertyName: "simResolution", publicName: "simResolution", isSignal: true, isRequired: false, transformFunction: null }, dyeResolution: { classPropertyName: "dyeResolution", publicName: "dyeResolution", isSignal: true, isRequired: false, transformFunction: null }, densityDissipation: { classPropertyName: "densityDissipation", publicName: "densityDissipation", isSignal: true, isRequired: false, transformFunction: null }, velocityDissipation: { classPropertyName: "velocityDissipation", publicName: "velocityDissipation", isSignal: true, isRequired: false, transformFunction: null }, pressure: { classPropertyName: "pressure", publicName: "pressure", isSignal: true, isRequired: false, transformFunction: null }, pressureIterations: { classPropertyName: "pressureIterations", publicName: "pressureIterations", isSignal: true, isRequired: false, transformFunction: null }, curl: { classPropertyName: "curl", publicName: "curl", isSignal: true, isRequired: false, transformFunction: null }, splatRadius: { classPropertyName: "splatRadius", publicName: "splatRadius", isSignal: true, isRequired: false, transformFunction: null }, splatForce: { classPropertyName: "splatForce", publicName: "splatForce", isSignal: true, isRequired: false, transformFunction: null }, shading: { classPropertyName: "shading", publicName: "shading", isSignal: true, isRequired: false, transformFunction: null }, colorUpdateSpeed: { classPropertyName: "colorUpdateSpeed", publicName: "colorUpdateSpeed", isSignal: true, isRequired: false, transformFunction: null }, rainbow: { classPropertyName: "rainbow", publicName: "rainbow", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-splash-cursor--contained": "!fullscreen()" }, classAttribute: "wr-splash-cursor" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: '<canvas #canvas class="wr-splash-cursor__canvas" aria-hidden="true"></canvas>', isInline: true, styles: [".wr-splash-cursor{position:fixed;inset:0;z-index:50;display:block;pointer-events:none}.wr-splash-cursor__canvas{display:block;width:100vw;height:100vh;height:100dvh}.wr-splash-cursor--contained{position:absolute;z-index:0}.wr-splash-cursor--contained .wr-splash-cursor__canvas{width:100%;height:100%}\n"], encapsulation: i0.ViewEncapsulation.None });
954
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSplashCursor, deps: [], target: i0.ɵɵFactoryTarget.Component });
955
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.6", type: WrSplashCursor, isStandalone: true, selector: "wr-splash-cursor", inputs: { fullscreen: { classPropertyName: "fullscreen", publicName: "fullscreen", isSignal: true, isRequired: false, transformFunction: null }, simResolution: { classPropertyName: "simResolution", publicName: "simResolution", isSignal: true, isRequired: false, transformFunction: null }, dyeResolution: { classPropertyName: "dyeResolution", publicName: "dyeResolution", isSignal: true, isRequired: false, transformFunction: null }, densityDissipation: { classPropertyName: "densityDissipation", publicName: "densityDissipation", isSignal: true, isRequired: false, transformFunction: null }, velocityDissipation: { classPropertyName: "velocityDissipation", publicName: "velocityDissipation", isSignal: true, isRequired: false, transformFunction: null }, pressure: { classPropertyName: "pressure", publicName: "pressure", isSignal: true, isRequired: false, transformFunction: null }, pressureIterations: { classPropertyName: "pressureIterations", publicName: "pressureIterations", isSignal: true, isRequired: false, transformFunction: null }, curl: { classPropertyName: "curl", publicName: "curl", isSignal: true, isRequired: false, transformFunction: null }, splatRadius: { classPropertyName: "splatRadius", publicName: "splatRadius", isSignal: true, isRequired: false, transformFunction: null }, splatForce: { classPropertyName: "splatForce", publicName: "splatForce", isSignal: true, isRequired: false, transformFunction: null }, shading: { classPropertyName: "shading", publicName: "shading", isSignal: true, isRequired: false, transformFunction: null }, colorUpdateSpeed: { classPropertyName: "colorUpdateSpeed", publicName: "colorUpdateSpeed", isSignal: true, isRequired: false, transformFunction: null }, rainbow: { classPropertyName: "rainbow", publicName: "rainbow", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-splash-cursor--contained": "!fullscreen()" }, classAttribute: "wr-splash-cursor" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }], ngImport: i0, template: '<canvas #canvas class="wr-splash-cursor__canvas" aria-hidden="true"></canvas>', isInline: true, styles: [".wr-splash-cursor{position:fixed;inset:0;z-index:50;display:block;pointer-events:none}.wr-splash-cursor__canvas{display:block;width:100vw;height:100vh;height:100dvh}.wr-splash-cursor--contained{position:absolute;z-index:0}.wr-splash-cursor--contained .wr-splash-cursor__canvas{width:100%;height:100%}\n"], encapsulation: i0.ViewEncapsulation.None });
956
956
  }
957
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSplashCursor, decorators: [{
957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSplashCursor, decorators: [{
958
958
  type: Component,
959
959
  args: [{ selector: 'wr-splash-cursor', template: '<canvas #canvas class="wr-splash-cursor__canvas" aria-hidden="true"></canvas>', encapsulation: ViewEncapsulation.None, host: {
960
960
  class: 'wr-splash-cursor',
@@ -210,10 +210,10 @@ class WrSplitText {
210
210
  };
211
211
  });
212
212
  }
213
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSplitText, deps: [], target: i0.ɵɵFactoryTarget.Component });
214
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrSplitText, isStandalone: true, selector: "wr-split-text", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, splitType: { classPropertyName: "splitType", publicName: "splitType", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", 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 }, from: { classPropertyName: "from", publicName: "from", isSignal: true, isRequired: false, transformFunction: null }, to: { classPropertyName: "to", publicName: "to", isSignal: true, isRequired: false, transformFunction: null }, threshold: { classPropertyName: "threshold", publicName: "threshold", isSignal: true, isRequired: false, transformFunction: null }, rootMargin: { classPropertyName: "rootMargin", publicName: "rootMargin", isSignal: true, isRequired: false, transformFunction: null }, textAlign: { classPropertyName: "textAlign", publicName: "textAlign", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { animationComplete: "animationComplete" }, host: { properties: { "style.text-align": "textAlign()" }, classAttribute: "wr-split-text" }, ngImport: i0, template: "<!-- The readable text, once: the pieces below are per-character spans. -->\n<span class=\"wr-split-text__sr-only\">{{ text() }}</span>\n@for (p of pieces(); track $index) {\n @if (p.kind === 'piece') {\n <span class=\"wr-split-text__piece\" aria-hidden=\"true\">{{ p.text }}</span>\n } @else {\n <span class=\"wr-split-text__space\" aria-hidden=\"true\">{{ p.text }}</span>\n }\n}\n", styles: [".wr-split-text{display:inline-block;overflow:hidden;padding-bottom:.15em;margin-bottom:-.15em;white-space:normal;overflow-wrap:break-word;will-change:transform,opacity}.wr-split-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-split-text__piece{display:inline-block;will-change:transform,opacity}.wr-split-text__space{display:inline;white-space:pre}\n"], encapsulation: i0.ViewEncapsulation.None });
213
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSplitText, deps: [], target: i0.ɵɵFactoryTarget.Component });
214
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrSplitText, isStandalone: true, selector: "wr-split-text", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, splitType: { classPropertyName: "splitType", publicName: "splitType", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", 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 }, from: { classPropertyName: "from", publicName: "from", isSignal: true, isRequired: false, transformFunction: null }, to: { classPropertyName: "to", publicName: "to", isSignal: true, isRequired: false, transformFunction: null }, threshold: { classPropertyName: "threshold", publicName: "threshold", isSignal: true, isRequired: false, transformFunction: null }, rootMargin: { classPropertyName: "rootMargin", publicName: "rootMargin", isSignal: true, isRequired: false, transformFunction: null }, textAlign: { classPropertyName: "textAlign", publicName: "textAlign", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { animationComplete: "animationComplete" }, host: { properties: { "style.text-align": "textAlign()" }, classAttribute: "wr-split-text" }, ngImport: i0, template: "<!-- The readable text, once: the pieces below are per-character spans. -->\n<span class=\"wr-split-text__sr-only\">{{ text() }}</span>\n@for (p of pieces(); track $index) {\n @if (p.kind === 'piece') {\n <span class=\"wr-split-text__piece\" aria-hidden=\"true\">{{ p.text }}</span>\n } @else {\n <span class=\"wr-split-text__space\" aria-hidden=\"true\">{{ p.text }}</span>\n }\n}\n", styles: [".wr-split-text{display:inline-block;overflow:hidden;padding-bottom:.15em;margin-bottom:-.15em;white-space:normal;overflow-wrap:break-word;will-change:transform,opacity}.wr-split-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-split-text__piece{display:inline-block;will-change:transform,opacity}.wr-split-text__space{display:inline;white-space:pre}\n"], encapsulation: i0.ViewEncapsulation.None });
215
215
  }
216
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSplitText, decorators: [{
216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSplitText, decorators: [{
217
217
  type: Component,
218
218
  args: [{ selector: 'wr-split-text', encapsulation: ViewEncapsulation.None, host: { class: 'wr-split-text', '[style.text-align]': 'textAlign()' }, template: "<!-- The readable text, once: the pieces below are per-character spans. -->\n<span class=\"wr-split-text__sr-only\">{{ text() }}</span>\n@for (p of pieces(); track $index) {\n @if (p.kind === 'piece') {\n <span class=\"wr-split-text__piece\" aria-hidden=\"true\">{{ p.text }}</span>\n } @else {\n <span class=\"wr-split-text__space\" aria-hidden=\"true\">{{ p.text }}</span>\n }\n}\n", styles: [".wr-split-text{display:inline-block;overflow:hidden;padding-bottom:.15em;margin-bottom:-.15em;white-space:normal;overflow-wrap:break-word;will-change:transform,opacity}.wr-split-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-split-text__piece{display:inline-block;will-change:transform,opacity}.wr-split-text__space{display:inline;white-space:pre}\n"] }]
219
219
  }], ctorParameters: () => [], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], splitType: [{ type: i0.Input, args: [{ isSignal: true, alias: "splitType", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], easing: [{ type: i0.Input, args: [{ isSignal: true, alias: "easing", required: false }] }], from: [{ type: i0.Input, args: [{ isSignal: true, alias: "from", required: false }] }], to: [{ type: i0.Input, args: [{ isSignal: true, alias: "to", required: false }] }], threshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "threshold", required: false }] }], rootMargin: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootMargin", required: false }] }], textAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "textAlign", required: false }] }], animationComplete: [{ type: i0.Output, args: ["animationComplete"] }] } });
@@ -170,10 +170,10 @@ class WrSplitter {
170
170
  isRtl() {
171
171
  return this.dir?.value === 'rtl';
172
172
  }
173
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSplitter, deps: [], target: i0.ɵɵFactoryTarget.Component });
174
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrSplitter, isStandalone: true, selector: "wr-splitter", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, minPosition: { classPropertyName: "minPosition", publicName: "minPosition", isSignal: true, isRequired: false, transformFunction: null }, maxPosition: { classPropertyName: "maxPosition", publicName: "maxPosition", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, dividerLabel: { classPropertyName: "dividerLabel", publicName: "dividerLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { position: "positionChange" }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-splitter__pane wr-splitter__pane--start\" [style.flex-basis]=\"startStyle()\">\n <ng-content select=\"[wrSplitterStart]\" />\n</div>\n\n<!-- Roving focus + arrow keys for keyboard resizing. -->\n<div\n class=\"wr-splitter__divider\"\n role=\"separator\"\n [attr.aria-label]=\"resolvedDividerLabel()\"\n [attr.aria-orientation]=\"orientation() === 'horizontal' ? 'vertical' : 'horizontal'\"\n [attr.aria-valuemin]=\"minPosition()\"\n [attr.aria-valuemax]=\"maxPosition()\"\n [attr.aria-valuenow]=\"position()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeydown($event)\"\n>\n <span class=\"wr-splitter__handle\" aria-hidden=\"true\"></span>\n</div>\n\n<div class=\"wr-splitter__pane wr-splitter__pane--end\" [style.flex-basis]=\"endStyle()\">\n <ng-content select=\"[wrSplitterEnd]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
173
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSplitter, deps: [], target: i0.ɵɵFactoryTarget.Component });
174
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrSplitter, isStandalone: true, selector: "wr-splitter", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, minPosition: { classPropertyName: "minPosition", publicName: "minPosition", isSignal: true, isRequired: false, transformFunction: null }, maxPosition: { classPropertyName: "maxPosition", publicName: "maxPosition", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, dividerLabel: { classPropertyName: "dividerLabel", publicName: "dividerLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { position: "positionChange" }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-splitter__pane wr-splitter__pane--start\" [style.flex-basis]=\"startStyle()\">\n <ng-content select=\"[wrSplitterStart]\" />\n</div>\n\n<!-- Roving focus + arrow keys for keyboard resizing. -->\n<div\n class=\"wr-splitter__divider\"\n role=\"separator\"\n [attr.aria-label]=\"resolvedDividerLabel()\"\n [attr.aria-orientation]=\"orientation() === 'horizontal' ? 'vertical' : 'horizontal'\"\n [attr.aria-valuemin]=\"minPosition()\"\n [attr.aria-valuemax]=\"maxPosition()\"\n [attr.aria-valuenow]=\"position()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeydown($event)\"\n>\n <span class=\"wr-splitter__handle\" aria-hidden=\"true\"></span>\n</div>\n\n<div class=\"wr-splitter__pane wr-splitter__pane--end\" [style.flex-basis]=\"endStyle()\">\n <ng-content select=\"[wrSplitterEnd]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
175
175
  }
176
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSplitter, decorators: [{
176
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSplitter, decorators: [{
177
177
  type: Component,
178
178
  args: [{ selector: 'wr-splitter', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<div class=\"wr-splitter__pane wr-splitter__pane--start\" [style.flex-basis]=\"startStyle()\">\n <ng-content select=\"[wrSplitterStart]\" />\n</div>\n\n<!-- Roving focus + arrow keys for keyboard resizing. -->\n<div\n class=\"wr-splitter__divider\"\n role=\"separator\"\n [attr.aria-label]=\"resolvedDividerLabel()\"\n [attr.aria-orientation]=\"orientation() === 'horizontal' ? 'vertical' : 'horizontal'\"\n [attr.aria-valuemin]=\"minPosition()\"\n [attr.aria-valuemax]=\"maxPosition()\"\n [attr.aria-valuenow]=\"position()\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeydown($event)\"\n>\n <span class=\"wr-splitter__handle\" aria-hidden=\"true\"></span>\n</div>\n\n<div class=\"wr-splitter__pane wr-splitter__pane--end\" [style.flex-basis]=\"endStyle()\">\n <ng-content select=\"[wrSplitterEnd]\" />\n</div>\n" }]
179
179
  }], ctorParameters: () => [], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }, { type: i0.Output, args: ["positionChange"] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], minPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "minPosition", required: false }] }], maxPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxPosition", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], dividerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dividerLabel", required: false }] }] } });
@@ -44,10 +44,10 @@ class WrSpotlightCard {
44
44
  host.style.setProperty('--wr-spotlight-x', `${event.clientX - rect.left}px`);
45
45
  host.style.setProperty('--wr-spotlight-y', `${event.clientY - rect.top}px`);
46
46
  }
47
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpotlightCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
48
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.5", type: WrSpotlightCard, isStandalone: true, selector: "wr-spotlight-card", inputs: { spotlightColor: { classPropertyName: "spotlightColor", publicName: "spotlightColor", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mousemove": "onMouseMove($event)" }, properties: { "style.--wr-spotlight-color": "spotlightColor()", "style.--wr-spotlight-radius": "radius() + \"%\"" }, classAttribute: "wr-spotlight-card" }, ngImport: i0, template: '<ng-content />', isInline: true, styles: [".wr-spotlight-card{--wr-spotlight-x: 50%;--wr-spotlight-y: 50%;--wr-spotlight-color: rgba(var(--wr-color-on-surface-rgb), .15);position:relative;display:block;border-radius:1.5rem;border:1px solid var(--wr-color-outline);background-color:var(--wr-color-surface);padding:2rem;overflow:hidden;color:var(--wr-color-on-surface)}.wr-spotlight-card:before{content:\"\";position:absolute;inset:0;background:radial-gradient(circle at var(--wr-spotlight-x) var(--wr-spotlight-y),var(--wr-spotlight-color),transparent var(--wr-spotlight-radius, 80%));opacity:0;transition:opacity .5s ease;pointer-events:none}.wr-spotlight-card:hover:before,.wr-spotlight-card:focus-within:before{opacity:.6}\n"], encapsulation: i0.ViewEncapsulation.None });
47
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpotlightCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
48
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrSpotlightCard, isStandalone: true, selector: "wr-spotlight-card", inputs: { spotlightColor: { classPropertyName: "spotlightColor", publicName: "spotlightColor", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mousemove": "onMouseMove($event)" }, properties: { "style.--wr-spotlight-color": "spotlightColor()", "style.--wr-spotlight-radius": "radius() + \"%\"" }, classAttribute: "wr-spotlight-card" }, ngImport: i0, template: '<ng-content />', isInline: true, styles: [".wr-spotlight-card{--wr-spotlight-x: 50%;--wr-spotlight-y: 50%;--wr-spotlight-color: rgba(var(--wr-color-on-surface-rgb), .15);position:relative;display:block;border-radius:1.5rem;border:1px solid var(--wr-color-outline);background-color:var(--wr-color-surface);padding:2rem;overflow:hidden;color:var(--wr-color-on-surface)}.wr-spotlight-card:before{content:\"\";position:absolute;inset:0;background:radial-gradient(circle at var(--wr-spotlight-x) var(--wr-spotlight-y),var(--wr-spotlight-color),transparent var(--wr-spotlight-radius, 80%));opacity:0;transition:opacity .5s ease;pointer-events:none}.wr-spotlight-card:hover:before,.wr-spotlight-card:focus-within:before{opacity:.6}\n"], encapsulation: i0.ViewEncapsulation.None });
49
49
  }
50
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpotlightCard, decorators: [{
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpotlightCard, decorators: [{
51
51
  type: Component,
52
52
  args: [{ selector: 'wr-spotlight-card', template: '<ng-content />', encapsulation: ViewEncapsulation.None, host: {
53
53
  class: 'wr-spotlight-card',
@@ -119,10 +119,10 @@ class WrSpotlight {
119
119
  host.style.setProperty('--wr-spotlight-x', this.resetX());
120
120
  host.style.setProperty('--wr-spotlight-y', this.resetY());
121
121
  }
122
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpotlight, deps: [], target: i0.ɵɵFactoryTarget.Directive });
123
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.5", type: WrSpotlight, isStandalone: true, selector: "[wrSpotlight]", inputs: { resetX: { classPropertyName: "resetX", publicName: "resetX", isSignal: true, isRequired: false, transformFunction: null }, resetY: { classPropertyName: "resetY", publicName: "resetY", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointermove": "onMove($event)", "pointerleave": "onLeave()" } }, ngImport: i0 });
122
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpotlight, deps: [], target: i0.ɵɵFactoryTarget.Directive });
123
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: WrSpotlight, isStandalone: true, selector: "[wrSpotlight]", inputs: { resetX: { classPropertyName: "resetX", publicName: "resetX", isSignal: true, isRequired: false, transformFunction: null }, resetY: { classPropertyName: "resetY", publicName: "resetY", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointermove": "onMove($event)", "pointerleave": "onLeave()" } }, ngImport: i0 });
124
124
  }
125
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrSpotlight, decorators: [{
125
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrSpotlight, decorators: [{
126
126
  type: Directive,
127
127
  args: [{
128
128
  selector: '[wrSpotlight]',