ngwr 8.0.0 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/README.md +76 -29
  2. package/action-sheet/styles/_index.scss +93 -0
  3. package/alert/styles/_index.scss +10 -10
  4. package/anchor/styles/_index.scss +3 -3
  5. package/back-top/styles/_index.scss +1 -1
  6. package/badge/styles/_tag.scss +3 -3
  7. package/bar-chart/styles/_index.scss +4 -4
  8. package/border-glow/styles/_index.scss +3 -3
  9. package/breadcrumbs/styles/_index.scss +3 -3
  10. package/burger/styles/_index.scss +1 -1
  11. package/button/styles/_index.scss +4 -4
  12. package/calendar/styles/_index.scss +4 -4
  13. package/calendar-heatmap/styles/_index.scss +3 -3
  14. package/card/styles/_index.scss +5 -5
  15. package/carousel/styles/_index.scss +5 -5
  16. package/cascader/styles/_index.scss +15 -15
  17. package/checkbox/styles/_index.scss +20 -5
  18. package/collapse/styles/_index.scss +6 -6
  19. package/color-picker/styles/_index.scss +15 -9
  20. package/command-palette/styles/_index.scss +19 -16
  21. package/compare/styles/_index.scss +3 -3
  22. package/context-menu/styles/_index.scss +16 -6
  23. package/counter/styles/_index.scss +12 -1
  24. package/date-picker/styles/_index.scss +8 -8
  25. package/descriptions/styles/_index.scss +9 -9
  26. package/dialog/styles/_index.scss +7 -6
  27. package/divider/styles/_index.scss +2 -2
  28. package/donut-chart/styles/_index.scss +3 -3
  29. package/drag-drop/styles/_index.scss +11 -6
  30. package/drawer/styles/_index.scss +15 -6
  31. package/dropdown/styles/_index.scss +5 -5
  32. package/empty/styles/_index.scss +4 -4
  33. package/fesm2022/ngwr-action-sheet.mjs +81 -0
  34. package/fesm2022/ngwr-action-sheet.mjs.map +1 -0
  35. package/fesm2022/ngwr-affix.mjs +3 -3
  36. package/fesm2022/ngwr-alert.mjs +4 -4
  37. package/fesm2022/ngwr-alert.mjs.map +1 -1
  38. package/fesm2022/ngwr-anchor.mjs +4 -4
  39. package/fesm2022/ngwr-anchor.mjs.map +1 -1
  40. package/fesm2022/ngwr-aurora.mjs +5 -4
  41. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  42. package/fesm2022/ngwr-avatar.mjs +4 -4
  43. package/fesm2022/ngwr-avatar.mjs.map +1 -1
  44. package/fesm2022/ngwr-back-top.mjs +4 -4
  45. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  46. package/fesm2022/ngwr-badge.mjs +8 -8
  47. package/fesm2022/ngwr-badge.mjs.map +1 -1
  48. package/fesm2022/ngwr-bar-chart.mjs +4 -4
  49. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  50. package/fesm2022/ngwr-blur-text.mjs +3 -3
  51. package/fesm2022/ngwr-border-glow.mjs +4 -4
  52. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  53. package/fesm2022/ngwr-breadcrumbs.mjs +8 -8
  54. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  55. package/fesm2022/ngwr-burger.mjs +4 -4
  56. package/fesm2022/ngwr-burger.mjs.map +1 -1
  57. package/fesm2022/ngwr-button.mjs +8 -8
  58. package/fesm2022/ngwr-button.mjs.map +1 -1
  59. package/fesm2022/ngwr-calendar-heatmap.mjs +4 -4
  60. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  61. package/fesm2022/ngwr-calendar.mjs +4 -4
  62. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  63. package/fesm2022/ngwr-card.mjs +11 -11
  64. package/fesm2022/ngwr-card.mjs.map +1 -1
  65. package/fesm2022/ngwr-carousel.mjs +7 -7
  66. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  67. package/fesm2022/ngwr-cascader.mjs +52 -60
  68. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  69. package/fesm2022/ngwr-checkbox.mjs +74 -106
  70. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  71. package/fesm2022/ngwr-circular-text.mjs +5 -4
  72. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  73. package/fesm2022/ngwr-click-spark.mjs +5 -4
  74. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  75. package/fesm2022/ngwr-clipboard.mjs +4 -4
  76. package/fesm2022/ngwr-clipboard.mjs.map +1 -1
  77. package/fesm2022/ngwr-collapse.mjs +12 -12
  78. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  79. package/fesm2022/ngwr-color-picker.mjs +58 -66
  80. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  81. package/fesm2022/ngwr-command-palette.mjs +4 -4
  82. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  83. package/fesm2022/ngwr-compare.mjs +4 -4
  84. package/fesm2022/ngwr-compare.mjs.map +1 -1
  85. package/fesm2022/ngwr-confetti.mjs +3 -3
  86. package/fesm2022/ngwr-context-menu.mjs +86 -15
  87. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  88. package/fesm2022/ngwr-cookie.mjs +19 -6
  89. package/fesm2022/ngwr-cookie.mjs.map +1 -1
  90. package/fesm2022/ngwr-counter.mjs +26 -12
  91. package/fesm2022/ngwr-counter.mjs.map +1 -1
  92. package/fesm2022/ngwr-date-adapter-fns.mjs +3 -3
  93. package/fesm2022/ngwr-date-adapter-luxon.mjs +3 -3
  94. package/fesm2022/ngwr-date-adapter.mjs +10 -5
  95. package/fesm2022/ngwr-date-adapter.mjs.map +1 -1
  96. package/fesm2022/ngwr-date-picker.mjs +128 -123
  97. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  98. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  99. package/fesm2022/ngwr-density.mjs +7 -7
  100. package/fesm2022/ngwr-density.mjs.map +1 -1
  101. package/fesm2022/ngwr-descriptions.mjs +7 -7
  102. package/fesm2022/ngwr-descriptions.mjs.map +1 -1
  103. package/fesm2022/ngwr-dialog.mjs +16 -16
  104. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  105. package/fesm2022/ngwr-directives.mjs +21 -15
  106. package/fesm2022/ngwr-directives.mjs.map +1 -1
  107. package/fesm2022/ngwr-divider.mjs +4 -4
  108. package/fesm2022/ngwr-divider.mjs.map +1 -1
  109. package/fesm2022/ngwr-donut-chart.mjs +4 -4
  110. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  111. package/fesm2022/ngwr-drag-drop.mjs +10 -9
  112. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  113. package/fesm2022/ngwr-drawer.mjs +19 -18
  114. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  115. package/fesm2022/ngwr-dropdown.mjs +13 -12
  116. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  117. package/fesm2022/ngwr-empty.mjs +4 -4
  118. package/fesm2022/ngwr-empty.mjs.map +1 -1
  119. package/fesm2022/ngwr-falling-text.mjs +5 -4
  120. package/fesm2022/ngwr-falling-text.mjs.map +1 -1
  121. package/fesm2022/ngwr-file-upload.mjs +58 -60
  122. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  123. package/fesm2022/ngwr-form.mjs +11 -11
  124. package/fesm2022/ngwr-form.mjs.map +1 -1
  125. package/fesm2022/ngwr-fuzzy-text.mjs +5 -4
  126. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  127. package/fesm2022/ngwr-gauge.mjs +4 -4
  128. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  129. package/fesm2022/ngwr-glitch-text.mjs +4 -4
  130. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  131. package/fesm2022/ngwr-gradient-text.mjs +4 -4
  132. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  133. package/fesm2022/ngwr-hotkey.mjs +7 -7
  134. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  135. package/fesm2022/ngwr-i18n.mjs +10 -10
  136. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  137. package/fesm2022/ngwr-icon-adapters-lucide.mjs +6 -7
  138. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  139. package/fesm2022/ngwr-icon.mjs +4 -4
  140. package/fesm2022/ngwr-icon.mjs.map +1 -1
  141. package/fesm2022/ngwr-image-cropper.mjs +6 -5
  142. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  143. package/fesm2022/ngwr-input-number.mjs +56 -73
  144. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  145. package/fesm2022/ngwr-input-otp.mjs +46 -52
  146. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  147. package/fesm2022/ngwr-input.mjs +17 -17
  148. package/fesm2022/ngwr-input.mjs.map +1 -1
  149. package/fesm2022/ngwr-keyboard.mjs +4 -4
  150. package/fesm2022/ngwr-keyboard.mjs.map +1 -1
  151. package/fesm2022/ngwr-knob.mjs +47 -58
  152. package/fesm2022/ngwr-knob.mjs.map +1 -1
  153. package/fesm2022/ngwr-layout.mjs +16 -16
  154. package/fesm2022/ngwr-layout.mjs.map +1 -1
  155. package/fesm2022/ngwr-lightbox.mjs +7 -6
  156. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  157. package/fesm2022/ngwr-line-chart.mjs +4 -4
  158. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  159. package/fesm2022/ngwr-list.mjs +8 -8
  160. package/fesm2022/ngwr-list.mjs.map +1 -1
  161. package/fesm2022/ngwr-loading-bar.mjs +7 -7
  162. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  163. package/fesm2022/ngwr-marquee.mjs +6 -5
  164. package/fesm2022/ngwr-marquee.mjs.map +1 -1
  165. package/fesm2022/ngwr-media.mjs +4 -4
  166. package/fesm2022/ngwr-media.mjs.map +1 -1
  167. package/fesm2022/ngwr-mention.mjs +15 -9
  168. package/fesm2022/ngwr-mention.mjs.map +1 -1
  169. package/fesm2022/ngwr-meta.mjs +7 -7
  170. package/fesm2022/ngwr-meta.mjs.map +1 -1
  171. package/fesm2022/ngwr-meter-group.mjs +4 -4
  172. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  173. package/fesm2022/ngwr-overlay.mjs +9 -4
  174. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  175. package/fesm2022/ngwr-page-header.mjs +4 -4
  176. package/fesm2022/ngwr-page-header.mjs.map +1 -1
  177. package/fesm2022/ngwr-pagination.mjs +4 -4
  178. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  179. package/fesm2022/ngwr-pipes.mjs +21 -21
  180. package/fesm2022/ngwr-platform.mjs +169 -5
  181. package/fesm2022/ngwr-platform.mjs.map +1 -1
  182. package/fesm2022/ngwr-popconfirm.mjs +7 -7
  183. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  184. package/fesm2022/ngwr-popover.mjs +7 -7
  185. package/fesm2022/ngwr-popover.mjs.map +1 -1
  186. package/fesm2022/ngwr-progress.mjs +4 -4
  187. package/fesm2022/ngwr-progress.mjs.map +1 -1
  188. package/fesm2022/ngwr-pull-to-refresh.mjs +172 -0
  189. package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -0
  190. package/fesm2022/ngwr-qr.mjs +5 -5
  191. package/fesm2022/ngwr-qr.mjs.map +1 -1
  192. package/fesm2022/ngwr-radio.mjs +27 -52
  193. package/fesm2022/ngwr-radio.mjs.map +1 -1
  194. package/fesm2022/ngwr-rating.mjs +35 -48
  195. package/fesm2022/ngwr-rating.mjs.map +1 -1
  196. package/fesm2022/ngwr-result.mjs +13 -13
  197. package/fesm2022/ngwr-result.mjs.map +1 -1
  198. package/fesm2022/ngwr-rotating-text.mjs +15 -4
  199. package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
  200. package/fesm2022/ngwr-scroll.mjs +4 -4
  201. package/fesm2022/ngwr-scroll.mjs.map +1 -1
  202. package/fesm2022/ngwr-segmented.mjs +3 -3
  203. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  204. package/fesm2022/ngwr-select.mjs +289 -85
  205. package/fesm2022/ngwr-select.mjs.map +1 -1
  206. package/fesm2022/ngwr-shiny-text.mjs +7 -7
  207. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  208. package/fesm2022/ngwr-sidebar.mjs +4 -4
  209. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  210. package/fesm2022/ngwr-skeleton.mjs +4 -4
  211. package/fesm2022/ngwr-skeleton.mjs.map +1 -1
  212. package/fesm2022/ngwr-slider.mjs +79 -73
  213. package/fesm2022/ngwr-slider.mjs.map +1 -1
  214. package/fesm2022/ngwr-sparkline.mjs +4 -4
  215. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  216. package/fesm2022/ngwr-speed-dial.mjs +13 -5
  217. package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
  218. package/fesm2022/ngwr-spinner.mjs +4 -4
  219. package/fesm2022/ngwr-spinner.mjs.map +1 -1
  220. package/fesm2022/ngwr-splash-cursor.mjs +4 -4
  221. package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
  222. package/fesm2022/ngwr-split-text.mjs +3 -3
  223. package/fesm2022/ngwr-splitter.mjs +4 -4
  224. package/fesm2022/ngwr-splitter.mjs.map +1 -1
  225. package/fesm2022/ngwr-spotlight-card.mjs +7 -7
  226. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  227. package/fesm2022/ngwr-squircle.mjs +7 -7
  228. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  229. package/fesm2022/ngwr-star-border.mjs +4 -4
  230. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  231. package/fesm2022/ngwr-statistic.mjs +65 -10
  232. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  233. package/fesm2022/ngwr-stepper.mjs +8 -8
  234. package/fesm2022/ngwr-stepper.mjs.map +1 -1
  235. package/fesm2022/ngwr-storage.mjs +4 -4
  236. package/fesm2022/ngwr-storage.mjs.map +1 -1
  237. package/fesm2022/ngwr-switch.mjs +16 -48
  238. package/fesm2022/ngwr-switch.mjs.map +1 -1
  239. package/fesm2022/ngwr-table.mjs +824 -20
  240. package/fesm2022/ngwr-table.mjs.map +1 -1
  241. package/fesm2022/ngwr-tabs.mjs +9 -8
  242. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  243. package/fesm2022/ngwr-textarea.mjs +18 -50
  244. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  245. package/fesm2022/ngwr-theme.mjs +20 -5
  246. package/fesm2022/ngwr-theme.mjs.map +1 -1
  247. package/fesm2022/ngwr-tilt-card.mjs +27 -11
  248. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  249. package/fesm2022/ngwr-timeline.mjs +7 -7
  250. package/fesm2022/ngwr-timeline.mjs.map +1 -1
  251. package/fesm2022/ngwr-toast.mjs +10 -10
  252. package/fesm2022/ngwr-toast.mjs.map +1 -1
  253. package/fesm2022/ngwr-toolbar.mjs +4 -4
  254. package/fesm2022/ngwr-toolbar.mjs.map +1 -1
  255. package/fesm2022/ngwr-tree.mjs +280 -84
  256. package/fesm2022/ngwr-tree.mjs.map +1 -1
  257. package/fesm2022/ngwr-typewriter.mjs +10 -5
  258. package/fesm2022/ngwr-typewriter.mjs.map +1 -1
  259. package/fesm2022/ngwr-typography.mjs +4 -4
  260. package/fesm2022/ngwr-typography.mjs.map +1 -1
  261. package/fesm2022/ngwr-validators.mjs +1 -1
  262. package/fesm2022/ngwr-validators.mjs.map +1 -1
  263. package/fesm2022/ngwr-version.mjs +1 -1
  264. package/fesm2022/ngwr-version.mjs.map +1 -1
  265. package/fesm2022/ngwr-virtual-scroll.mjs +9 -7
  266. package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
  267. package/fesm2022/ngwr-waves.mjs +6 -5
  268. package/fesm2022/ngwr-waves.mjs.map +1 -1
  269. package/fesm2022/ngwr-window.mjs +16 -15
  270. package/fesm2022/ngwr-window.mjs.map +1 -1
  271. package/file-upload/styles/_index.scss +11 -11
  272. package/form/styles/_index.scss +4 -4
  273. package/gauge/styles/_index.scss +2 -2
  274. package/glitch-text/styles/_index.scss +1 -1
  275. package/gradient-text/styles/_index.scss +1 -1
  276. package/image-cropper/styles/_index.scss +5 -4
  277. package/input/styles/_index.scss +9 -9
  278. package/input-number/styles/_index.scss +1 -1
  279. package/input-otp/styles/_index.scss +5 -5
  280. package/keyboard/styles/_index.scss +5 -5
  281. package/knob/styles/_index.scss +6 -2
  282. package/layout/styles/_index.scss +12 -12
  283. package/lightbox/styles/_index.scss +10 -8
  284. package/line-chart/styles/_index.scss +5 -5
  285. package/list/styles/_index.scss +3 -3
  286. package/llms-full.txt +31 -5
  287. package/llms.txt +48 -32
  288. package/marquee/styles/_index.scss +1 -1
  289. package/mention/styles/_index.scss +4 -4
  290. package/meter-group/styles/_index.scss +4 -4
  291. package/overlay/styles/_index.scss +8 -0
  292. package/package.json +21 -9
  293. package/page-header/styles/_index.scss +4 -4
  294. package/pagination/styles/_index.scss +3 -3
  295. package/popconfirm/styles/_index.scss +3 -3
  296. package/popover/styles/_index.scss +5 -5
  297. package/progress/styles/_index.scss +1 -1
  298. package/pull-to-refresh/styles/_index.scss +38 -0
  299. package/radio/styles/_index.scss +4 -4
  300. package/rating/styles/_index.scss +1 -1
  301. package/result/styles/_index.scss +3 -3
  302. package/schematics/migrations/v9/index.js +71 -0
  303. package/schematics/migrations.json +5 -0
  304. package/schematics/ng-add/schema.json +1 -1
  305. package/schematics/use/symbol-map.json +13 -0
  306. package/segmented/styles/_index.scss +4 -4
  307. package/select/styles/_index.scss +53 -18
  308. package/shiny-text/styles/_index.scss +4 -4
  309. package/sidebar/styles/_index.scss +12 -12
  310. package/slider/styles/_index.scss +5 -5
  311. package/speed-dial/styles/_index.scss +22 -6
  312. package/splash-cursor/styles/_index.scss +1 -0
  313. package/splitter/styles/_index.scss +7 -4
  314. package/spotlight-card/styles/_index.scss +7 -7
  315. package/star-border/styles/_index.scss +3 -3
  316. package/statistic/styles/_index.scss +51 -4
  317. package/stepper/styles/_index.scss +6 -6
  318. package/styles/_typography.scss +4 -1
  319. package/styles.scss +2 -0
  320. package/switch/styles/_index.scss +4 -4
  321. package/table/styles/_index.scss +447 -17
  322. package/tabs/styles/_index.scss +3 -3
  323. package/textarea/styles/_index.scss +7 -7
  324. package/theme/styles/_colors.scss +27 -3
  325. package/tilt-card/styles/_index.scss +4 -4
  326. package/timeline/styles/_index.scss +7 -6
  327. package/toast/styles/_index.scss +11 -11
  328. package/toolbar/styles/_index.scss +4 -4
  329. package/tree/styles/_index.scss +45 -15
  330. package/types/ngwr-action-sheet.d.ts +75 -0
  331. package/types/ngwr-alert.d.ts +1 -1
  332. package/types/ngwr-anchor.d.ts +1 -1
  333. package/types/ngwr-avatar.d.ts +1 -1
  334. package/types/ngwr-back-top.d.ts +1 -1
  335. package/types/ngwr-badge.d.ts +4 -4
  336. package/types/ngwr-bar-chart.d.ts +1 -1
  337. package/types/ngwr-breadcrumbs.d.ts +1 -1
  338. package/types/ngwr-burger.d.ts +1 -1
  339. package/types/ngwr-button.d.ts +3 -3
  340. package/types/ngwr-calendar-heatmap.d.ts +1 -1
  341. package/types/ngwr-calendar.d.ts +1 -1
  342. package/types/ngwr-card.d.ts +1 -1
  343. package/types/ngwr-carousel.d.ts +1 -1
  344. package/types/ngwr-cascader.d.ts +27 -16
  345. package/types/ngwr-checkbox.d.ts +63 -43
  346. package/types/ngwr-clipboard.d.ts +1 -1
  347. package/types/ngwr-collapse.d.ts +3 -3
  348. package/types/ngwr-color-picker.d.ts +24 -19
  349. package/types/ngwr-command-palette.d.ts +1 -1
  350. package/types/ngwr-compare.d.ts +1 -1
  351. package/types/ngwr-context-menu.d.ts +25 -1
  352. package/types/ngwr-cookie.d.ts +7 -1
  353. package/types/ngwr-counter.d.ts +9 -2
  354. package/types/ngwr-date-picker.d.ts +36 -23
  355. package/types/ngwr-density.d.ts +1 -1
  356. package/types/ngwr-descriptions.d.ts +1 -1
  357. package/types/ngwr-dialog.d.ts +1 -1
  358. package/types/ngwr-directives.d.ts +1 -0
  359. package/types/ngwr-divider.d.ts +2 -2
  360. package/types/ngwr-donut-chart.d.ts +1 -1
  361. package/types/ngwr-drag-drop.d.ts +1 -1
  362. package/types/ngwr-drawer.d.ts +1 -1
  363. package/types/ngwr-dropdown.d.ts +1 -1
  364. package/types/ngwr-empty.d.ts +1 -1
  365. package/types/ngwr-file-upload.d.ts +28 -17
  366. package/types/ngwr-form.d.ts +2 -2
  367. package/types/ngwr-gauge.d.ts +1 -1
  368. package/types/ngwr-hotkey.d.ts +1 -1
  369. package/types/ngwr-i18n.d.ts +1 -1
  370. package/types/ngwr-icon-adapters-lucide.d.ts +5 -3
  371. package/types/ngwr-icon.d.ts +1 -1
  372. package/types/ngwr-image-cropper.d.ts +1 -1
  373. package/types/ngwr-input-number.d.ts +25 -19
  374. package/types/ngwr-input-otp.d.ts +23 -17
  375. package/types/ngwr-input.d.ts +2 -2
  376. package/types/ngwr-keyboard.d.ts +1 -1
  377. package/types/ngwr-knob.d.ts +24 -19
  378. package/types/ngwr-layout.d.ts +1 -1
  379. package/types/ngwr-lightbox.d.ts +1 -1
  380. package/types/ngwr-line-chart.d.ts +1 -1
  381. package/types/ngwr-list.d.ts +1 -1
  382. package/types/ngwr-loading-bar.d.ts +1 -1
  383. package/types/ngwr-marquee.d.ts +1 -1
  384. package/types/ngwr-media.d.ts +1 -1
  385. package/types/ngwr-mention.d.ts +1 -1
  386. package/types/ngwr-meta.d.ts +1 -1
  387. package/types/ngwr-meter-group.d.ts +1 -1
  388. package/types/ngwr-page-header.d.ts +1 -1
  389. package/types/ngwr-pagination.d.ts +1 -1
  390. package/types/ngwr-platform.d.ts +93 -2
  391. package/types/ngwr-popconfirm.d.ts +3 -3
  392. package/types/ngwr-progress.d.ts +2 -2
  393. package/types/ngwr-pull-to-refresh.d.ts +69 -0
  394. package/types/ngwr-qr.d.ts +1 -1
  395. package/types/ngwr-radio.d.ts +25 -22
  396. package/types/ngwr-rating.d.ts +28 -20
  397. package/types/ngwr-result.d.ts +1 -1
  398. package/types/ngwr-rotating-text.d.ts +1 -0
  399. package/types/ngwr-scroll.d.ts +1 -1
  400. package/types/ngwr-segmented.d.ts +1 -1
  401. package/types/ngwr-select.d.ts +93 -26
  402. package/types/ngwr-sidebar.d.ts +1 -1
  403. package/types/ngwr-skeleton.d.ts +2 -2
  404. package/types/ngwr-slider.d.ts +35 -21
  405. package/types/ngwr-sparkline.d.ts +1 -1
  406. package/types/ngwr-speed-dial.d.ts +8 -2
  407. package/types/ngwr-spinner.d.ts +1 -1
  408. package/types/ngwr-splitter.d.ts +1 -1
  409. package/types/ngwr-squircle.d.ts +1 -1
  410. package/types/ngwr-statistic.d.ts +40 -5
  411. package/types/ngwr-stepper.d.ts +2 -2
  412. package/types/ngwr-storage.d.ts +1 -1
  413. package/types/ngwr-switch.d.ts +20 -16
  414. package/types/ngwr-table.d.ts +417 -6
  415. package/types/ngwr-tabs.d.ts +1 -1
  416. package/types/ngwr-textarea.d.ts +21 -18
  417. package/types/ngwr-theme.d.ts +7 -2
  418. package/types/ngwr-tilt-card.d.ts +3 -0
  419. package/types/ngwr-timeline.d.ts +1 -1
  420. package/types/ngwr-toast.d.ts +1 -1
  421. package/types/ngwr-toolbar.d.ts +1 -1
  422. package/types/ngwr-tree.d.ts +100 -19
  423. package/types/ngwr-typography.d.ts +1 -1
  424. package/types/ngwr-validators.d.ts +1 -1
  425. package/types/ngwr-version.d.ts +1 -1
  426. package/types/ngwr-virtual-scroll.d.ts +1 -1
  427. package/types/ngwr-window.d.ts +1 -1
  428. package/typography/styles/_index.scss +11 -11
  429. package/virtual-scroll/styles/_index.scss +1 -1
  430. package/waves/styles/_index.scss +1 -1
  431. package/window/styles/_index.scss +18 -18
@@ -1,9 +1,7 @@
1
1
  import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
2
2
  import { isPlatformBrowser } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { input, signal, computed, viewChild, inject, PLATFORM_ID, ElementRef, effect, forwardRef, ViewEncapsulation, Component } from '@angular/core';
5
- import { NG_VALUE_ACCESSOR } from '@angular/forms';
6
- import { noop } from 'ngwr/utils';
4
+ import { input, model, output, signal, viewChild, computed, inject, PLATFORM_ID, ElementRef, effect, ViewEncapsulation, Component } from '@angular/core';
7
5
 
8
6
  /**
9
7
  * @license
@@ -33,20 +31,21 @@ class WrTextarea {
33
31
  maxRows = input(null, /* @ts-ignore */
34
32
  ...(ngDevMode ? [{ debugName: "maxRows" }] : /* istanbul ignore next */ []));
35
33
  /**
36
- * Disable the textarea. Also set by Angular forms via `setDisabledState`.
34
+ * Disable the textarea. Bound automatically from the field's disabled state
35
+ * when used with `[formField]`.
37
36
  *
38
37
  * @default false
39
38
  */
40
39
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
41
- value = signal('', /* @ts-ignore */
40
+ /** The edited text. Bound by `[formField]`, or two-way via `[(value)]`. */
41
+ value = model('', /* @ts-ignore */
42
42
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
43
- disabledFromCva = signal(false, /* @ts-ignore */
44
- ...(ngDevMode ? [{ debugName: "disabledFromCva" }] : /* istanbul ignore next */ []));
43
+ /** Emitted on blur so a bound field can mark itself touched. */
44
+ touch = output();
45
45
  focused = signal(false, /* @ts-ignore */
46
46
  ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
47
- effectiveDisabled = computed(() => this.disabled() || this.disabledFromCva(), /* @ts-ignore */
48
- ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
49
- native = viewChild.required('native');
47
+ native = viewChild.required('native', /* @ts-ignore */
48
+ ...(ngDevMode ? [{ debugName: "native" }] : /* istanbul ignore next */ []));
50
49
  /** Resize direction, gated by `resizable` (false → 'none'). */
51
50
  effectiveResize = computed(() => (this.resizable() ? this.resize() : 'none'), /* @ts-ignore */
52
51
  ...(ngDevMode ? [{ debugName: "effectiveResize" }] : /* istanbul ignore next */ []));
@@ -62,19 +61,17 @@ class WrTextarea {
62
61
  parts.push('wr-textarea--resize-x');
63
62
  if (this.focused())
64
63
  parts.push('wr-textarea--focused');
65
- if (this.effectiveDisabled())
64
+ if (this.disabled())
66
65
  parts.push('wr-textarea--disabled');
67
66
  return parts.join(' ');
68
67
  }, /* @ts-ignore */
69
68
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
70
69
  /** Show the corner grip (hidden when direction is 'none' / autosize / disabled). */
71
- showHandle = computed(() => this.effectiveResize() !== 'none' && !this.autosize() && !this.effectiveDisabled(), /* @ts-ignore */
70
+ showHandle = computed(() => this.effectiveResize() !== 'none' && !this.autosize() && !this.disabled(), /* @ts-ignore */
72
71
  ...(ngDevMode ? [{ debugName: "showHandle" }] : /* istanbul ignore next */ []));
73
72
  platformId = inject(PLATFORM_ID);
74
73
  isBrowser = isPlatformBrowser(this.platformId);
75
74
  hostEl = inject(ElementRef);
76
- onChange = noop;
77
- onTouched = noop;
78
75
  // Custom resize-grip drag state (replaces the native corner handle).
79
76
  resizing = false;
80
77
  resizeStartY = 0;
@@ -93,28 +90,13 @@ class WrTextarea {
93
90
  requestAnimationFrame(() => this.autofit());
94
91
  });
95
92
  }
96
- // ControlValueAccessor
97
- writeValue(value) {
98
- this.value.set(value ?? '');
99
- }
100
- registerOnChange(fn) {
101
- this.onChange = fn;
102
- }
103
- registerOnTouched(fn) {
104
- this.onTouched = fn;
105
- }
106
- setDisabledState(isDisabled) {
107
- this.disabledFromCva.set(isDisabled);
108
- }
109
93
  // Template handlers
110
94
  onInput(event) {
111
- const next = event.target.value;
112
- this.value.set(next);
113
- this.onChange(next);
95
+ this.value.set(event.target.value);
114
96
  }
115
97
  onBlur() {
116
98
  this.focused.set(false);
117
- this.onTouched();
99
+ this.touch.emit();
118
100
  }
119
101
  // Custom resize — drag the corner grip; direction comes from `effectiveResize`.
120
102
  // Pointer capture keeps move/up on the grip even when the cursor leaves it.
@@ -181,27 +163,13 @@ class WrTextarea {
181
163
  el.style.overflowY = 'hidden';
182
164
  }
183
165
  }
184
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTextarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
185
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: WrTextarea, isStandalone: true, selector: "wr-textarea", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resize: { classPropertyName: "resize", publicName: "resize", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, autosize: { classPropertyName: "autosize", publicName: "autosize", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, providers: [
186
- {
187
- provide: NG_VALUE_ACCESSOR,
188
- // eslint-disable-next-line @angular-eslint/no-forward-ref
189
- useExisting: forwardRef(() => WrTextarea),
190
- multi: true,
191
- },
192
- ], viewQueries: [{ propertyName: "native", first: true, predicate: ["native"], descendants: true, isSignal: true }], ngImport: i0, template: "<textarea\n #native\n class=\"wr-textarea__native\"\n [placeholder]=\"placeholder()\"\n [rows]=\"rows()\"\n [readonly]=\"readonly()\"\n [disabled]=\"effectiveDisabled()\"\n [value]=\"value()\"\n (input)=\"onInput($event)\"\n (focus)=\"focused.set(true)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (showHandle()) {\n <!-- Custom corner grip \u2014 the lucide icon + cursor follow the `resize`\n direction. Icons inlined so no icon registration is required. -->\n <span\n [class]=\"`wr-textarea__resize wr-textarea__resize--${effectiveResize()}`\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event)\"\n (pointermove)=\"onResize($event)\"\n (pointerup)=\"endResize($event)\"\n (pointercancel)=\"endResize($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\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 @switch (effectiveResize()) {\n @case ('vertical') {\n <path d=\"M12 2v20\" />\n <path d=\"m8 18 4 4 4-4\" />\n <path d=\"m8 6 4-4 4 4\" />\n }\n @case ('horizontal') {\n <path d=\"M2 12h20\" />\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"m6 8-4 4 4 4\" />\n }\n @default {\n <path d=\"M19 13v6h-6\" />\n <path d=\"M5 11V5h6\" />\n <path d=\"m5 5 14 14\" />\n }\n }\n </svg>\n </span>\n}\n", encapsulation: i0.ViewEncapsulation.None });
166
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTextarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
167
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: WrTextarea, isStandalone: true, selector: "wr-textarea", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resize: { classPropertyName: "resize", publicName: "resize", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, autosize: { classPropertyName: "autosize", publicName: "autosize", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touch: "touch" }, host: { properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "native", first: true, predicate: ["native"], descendants: true, isSignal: true }], ngImport: i0, template: "<textarea\n #native\n class=\"wr-textarea__native\"\n [placeholder]=\"placeholder()\"\n [rows]=\"rows()\"\n [readonly]=\"readonly()\"\n [disabled]=\"disabled()\"\n [value]=\"value()\"\n (input)=\"onInput($event)\"\n (focus)=\"focused.set(true)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (showHandle()) {\n <!-- Custom corner grip \u2014 the lucide icon + cursor follow the `resize`\n direction. Icons inlined so no icon registration is required. -->\n <span\n [class]=\"`wr-textarea__resize wr-textarea__resize--${effectiveResize()}`\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event)\"\n (pointermove)=\"onResize($event)\"\n (pointerup)=\"endResize($event)\"\n (pointercancel)=\"endResize($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\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 @switch (effectiveResize()) {\n @case ('vertical') {\n <path d=\"M12 2v20\" />\n <path d=\"m8 18 4 4 4-4\" />\n <path d=\"m8 6 4-4 4 4\" />\n }\n @case ('horizontal') {\n <path d=\"M2 12h20\" />\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"m6 8-4 4 4 4\" />\n }\n @default {\n <path d=\"M19 13v6h-6\" />\n <path d=\"M5 11V5h6\" />\n <path d=\"m5 5 14 14\" />\n }\n }\n </svg>\n </span>\n}\n", encapsulation: i0.ViewEncapsulation.None });
193
168
  }
194
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTextarea, decorators: [{
169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTextarea, decorators: [{
195
170
  type: Component,
196
- args: [{ selector: 'wr-textarea', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, providers: [
197
- {
198
- provide: NG_VALUE_ACCESSOR,
199
- // eslint-disable-next-line @angular-eslint/no-forward-ref
200
- useExisting: forwardRef(() => WrTextarea),
201
- multi: true,
202
- },
203
- ], template: "<textarea\n #native\n class=\"wr-textarea__native\"\n [placeholder]=\"placeholder()\"\n [rows]=\"rows()\"\n [readonly]=\"readonly()\"\n [disabled]=\"effectiveDisabled()\"\n [value]=\"value()\"\n (input)=\"onInput($event)\"\n (focus)=\"focused.set(true)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (showHandle()) {\n <!-- Custom corner grip \u2014 the lucide icon + cursor follow the `resize`\n direction. Icons inlined so no icon registration is required. -->\n <span\n [class]=\"`wr-textarea__resize wr-textarea__resize--${effectiveResize()}`\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event)\"\n (pointermove)=\"onResize($event)\"\n (pointerup)=\"endResize($event)\"\n (pointercancel)=\"endResize($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\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 @switch (effectiveResize()) {\n @case ('vertical') {\n <path d=\"M12 2v20\" />\n <path d=\"m8 18 4 4 4-4\" />\n <path d=\"m8 6 4-4 4 4\" />\n }\n @case ('horizontal') {\n <path d=\"M2 12h20\" />\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"m6 8-4 4 4 4\" />\n }\n @default {\n <path d=\"M19 13v6h-6\" />\n <path d=\"M5 11V5h6\" />\n <path d=\"m5 5 14 14\" />\n }\n }\n </svg>\n </span>\n}\n" }]
204
- }], ctorParameters: () => [], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], resize: [{ type: i0.Input, args: [{ isSignal: true, alias: "resize", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], autosize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosize", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], native: [{ type: i0.ViewChild, args: ['native', { isSignal: true }] }] } });
171
+ args: [{ selector: 'wr-textarea', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<textarea\n #native\n class=\"wr-textarea__native\"\n [placeholder]=\"placeholder()\"\n [rows]=\"rows()\"\n [readonly]=\"readonly()\"\n [disabled]=\"disabled()\"\n [value]=\"value()\"\n (input)=\"onInput($event)\"\n (focus)=\"focused.set(true)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (showHandle()) {\n <!-- Custom corner grip \u2014 the lucide icon + cursor follow the `resize`\n direction. Icons inlined so no icon registration is required. -->\n <span\n [class]=\"`wr-textarea__resize wr-textarea__resize--${effectiveResize()}`\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event)\"\n (pointermove)=\"onResize($event)\"\n (pointerup)=\"endResize($event)\"\n (pointercancel)=\"endResize($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\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 @switch (effectiveResize()) {\n @case ('vertical') {\n <path d=\"M12 2v20\" />\n <path d=\"m8 18 4 4 4-4\" />\n <path d=\"m8 6 4-4 4 4\" />\n }\n @case ('horizontal') {\n <path d=\"M2 12h20\" />\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"m6 8-4 4 4 4\" />\n }\n @default {\n <path d=\"M19 13v6h-6\" />\n <path d=\"M5 11V5h6\" />\n <path d=\"m5 5 14 14\" />\n }\n }\n </svg>\n </span>\n}\n" }]
172
+ }], ctorParameters: () => [], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], resize: [{ type: i0.Input, args: [{ isSignal: true, alias: "resize", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], autosize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosize", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], touch: [{ type: i0.Output, args: ["touch"] }], native: [{ type: i0.ViewChild, args: ['native', { isSignal: true }] }] } });
205
173
 
206
174
  /**
207
175
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-textarea.mjs","sources":["../../../projects/lib/textarea/textarea.ts","../../../projects/lib/textarea/textarea.html","../../../projects/lib/textarea/ngwr-textarea.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n computed,\n effect,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { type ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nimport { noop } from 'ngwr/utils';\n\n/**\n * Multi-line text input.\n *\n * Implements `ControlValueAccessor`. Optional `autosize` grows the\n * textarea with its content, capped at `maxRows` if provided.\n *\n * @example\n * ```html\n * <wr-textarea placeholder=\"Notes\" [(ngModel)]=\"text\" />\n * <wr-textarea autosize [maxRows]=\"6\" [(ngModel)]=\"text\" />\n * ```\n *\n * @see https://ngwr.dev/components/textarea\n */\nexport type WrTextareaSize = 'sm' | 'md' | 'lg';\n\nexport type WrTextareaResize = 'none' | 'vertical' | 'horizontal' | 'both';\n\n@Component({\n selector: 'wr-textarea',\n templateUrl: './textarea.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n // eslint-disable-next-line @angular-eslint/no-forward-ref\n useExisting: forwardRef(() => WrTextarea),\n multi: true,\n },\n ],\n})\nexport class WrTextarea implements ControlValueAccessor {\n /** Native placeholder text. @default '' */\n readonly placeholder = input<string>('');\n\n /** Control size — shares the `--wr-control-*` contract. @default 'md' */\n readonly size = input<WrTextareaSize>('md');\n\n /** Visible row count. @default 3 */\n readonly rows = input(3, { transform: (v: unknown): number => coerceNumberProperty(v, 3) });\n\n /** Allow user resize via the corner grip. @default true */\n readonly resizable = input(true, { transform: coerceBooleanProperty });\n\n /** Resize direction of the corner grip (the grip icon adapts). @default 'vertical' */\n readonly resize = input<WrTextareaResize>('vertical');\n\n /** Read-only state. @default false */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** Grow the textarea to fit its content. @default false */\n readonly autosize = input(false, { transform: coerceBooleanProperty });\n\n /** Cap autosize at this many rows. Ignored when `autosize` is false. */\n readonly maxRows = input<number | null>(null);\n\n /**\n * Disable the textarea. Also set by Angular forms via `setDisabledState`.\n *\n * @default false\n */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly value = signal<string>('');\n protected readonly disabledFromCva = signal(false);\n protected readonly focused = signal(false);\n\n protected readonly effectiveDisabled = computed(() => this.disabled() || this.disabledFromCva());\n\n protected readonly native = viewChild.required<ElementRef<HTMLTextAreaElement>>('native');\n\n /** Resize direction, gated by `resizable` (false → 'none'). */\n protected readonly effectiveResize = computed<WrTextareaResize>(() => (this.resizable() ? this.resize() : 'none'));\n\n protected readonly classes = computed(() => {\n const parts = ['wr-textarea'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-textarea--${size}`);\n if (this.autosize()) parts.push('wr-textarea--no-resize');\n const resize = this.effectiveResize();\n if (resize === 'horizontal' || resize === 'both') parts.push('wr-textarea--resize-x');\n if (this.focused()) parts.push('wr-textarea--focused');\n if (this.effectiveDisabled()) parts.push('wr-textarea--disabled');\n return parts.join(' ');\n });\n\n /** Show the corner grip (hidden when direction is 'none' / autosize / disabled). */\n protected readonly showHandle = computed(\n () => this.effectiveResize() !== 'none' && !this.autosize() && !this.effectiveDisabled()\n );\n\n private readonly platformId = inject(PLATFORM_ID);\n private readonly isBrowser = isPlatformBrowser(this.platformId);\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef);\n\n private onChange: (value: string) => void = noop;\n private onTouched: () => void = noop;\n\n // Custom resize-grip drag state (replaces the native corner handle).\n private resizing = false;\n private resizeStartY = 0;\n private resizeStartX = 0;\n private resizeStartHeight = 0;\n private resizeStartWidth = 0;\n private resizeMinHeight = 36;\n private resizeMaxWidth = Number.POSITIVE_INFINITY;\n\n constructor() {\n // Autosize: re-fit whenever value or autosize toggles.\n effect(() => {\n if (!this.autosize() || !this.isBrowser) return;\n // Read `value` to register dependency\n this.value();\n requestAnimationFrame(() => this.autofit());\n });\n }\n\n // ControlValueAccessor\n\n writeValue(value: string | null): void {\n this.value.set(value ?? '');\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabledFromCva.set(isDisabled);\n }\n\n // Template handlers\n\n protected onInput(event: Event): void {\n const next = (event.target as HTMLTextAreaElement).value;\n this.value.set(next);\n this.onChange(next);\n }\n\n protected onBlur(): void {\n this.focused.set(false);\n this.onTouched();\n }\n\n // Custom resize — drag the corner grip; direction comes from `effectiveResize`.\n // Pointer capture keeps move/up on the grip even when the cursor leaves it.\n protected startResize(event: PointerEvent): void {\n const el = this.native()?.nativeElement;\n if (!el) return;\n const host = this.hostEl.nativeElement;\n this.resizing = true;\n this.resizeStartY = event.clientY;\n this.resizeStartX = event.clientX;\n this.resizeStartHeight = el.offsetHeight;\n this.resizeStartWidth = host.offsetWidth;\n // Height floor = fits the current content, so shrinking never opens an\n // overflow scrollbar. Measured once, synchronously (no paint between).\n const borderY = el.offsetHeight - el.clientHeight;\n const prevHeight = el.style.height;\n el.style.height = 'auto';\n this.resizeMinHeight = el.scrollHeight + borderY;\n el.style.height = prevHeight;\n // Width ceiling = parent inner width, so horizontal drag can't overflow.\n this.resizeMaxWidth = host.parentElement?.clientWidth ?? Number.POSITIVE_INFINITY;\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n event.preventDefault();\n }\n\n protected onResize(event: PointerEvent): void {\n if (!this.resizing) return;\n const el = this.native()?.nativeElement;\n if (!el) return;\n const dir = this.effectiveResize();\n if (dir === 'vertical' || dir === 'both') {\n const h = Math.max(this.resizeMinHeight, this.resizeStartHeight + (event.clientY - this.resizeStartY));\n el.style.height = `${h}px`;\n }\n if (dir === 'horizontal' || dir === 'both') {\n const w = Math.min(\n this.resizeMaxWidth,\n Math.max(64, this.resizeStartWidth + (event.clientX - this.resizeStartX))\n );\n this.hostEl.nativeElement.style.width = `${w}px`;\n }\n }\n\n protected endResize(event: PointerEvent): void {\n if (!this.resizing) return;\n this.resizing = false;\n (event.target as HTMLElement).releasePointerCapture(event.pointerId);\n }\n\n private autofit(): void {\n const el = this.native()?.nativeElement;\n if (!el) return;\n\n el.style.height = 'auto';\n\n const maxRows = this.maxRows();\n if (maxRows && maxRows > 0) {\n const cs = getComputedStyle(el);\n const lineHeight = parseFloat(cs.lineHeight) || parseFloat(cs.fontSize) * 1.2;\n const cap = lineHeight * maxRows;\n const next = Math.min(el.scrollHeight, cap);\n el.style.height = `${next}px`;\n el.style.overflowY = el.scrollHeight > cap ? 'auto' : 'hidden';\n } else {\n el.style.height = `${el.scrollHeight}px`;\n el.style.overflowY = 'hidden';\n }\n }\n}\n","<textarea\n #native\n class=\"wr-textarea__native\"\n [placeholder]=\"placeholder()\"\n [rows]=\"rows()\"\n [readonly]=\"readonly()\"\n [disabled]=\"effectiveDisabled()\"\n [value]=\"value()\"\n (input)=\"onInput($event)\"\n (focus)=\"focused.set(true)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (showHandle()) {\n <!-- Custom corner grip — the lucide icon + cursor follow the `resize`\n direction. Icons inlined so no icon registration is required. -->\n <span\n [class]=\"`wr-textarea__resize wr-textarea__resize--${effectiveResize()}`\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event)\"\n (pointermove)=\"onResize($event)\"\n (pointerup)=\"endResize($event)\"\n (pointercancel)=\"endResize($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\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 @switch (effectiveResize()) {\n @case ('vertical') {\n <path d=\"M12 2v20\" />\n <path d=\"m8 18 4 4 4-4\" />\n <path d=\"m8 6 4-4 4 4\" />\n }\n @case ('horizontal') {\n <path d=\"M2 12h20\" />\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"m6 8-4 4 4 4\" />\n }\n @default {\n <path d=\"M19 13v6h-6\" />\n <path d=\"M5 11V5h6\" />\n <path d=\"m5 5 14 14\" />\n }\n }\n </svg>\n </span>\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-textarea.mjs","sources":["../../../projects/lib/textarea/textarea.ts","../../../projects/lib/textarea/textarea.html","../../../projects/lib/textarea/ngwr-textarea.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport type { FormValueControl } from '@angular/forms/signals';\n\n/**\n * Multi-line text input.\n *\n * A signal-forms native control: it implements `FormValueControl<string>`, so\n * `[formField]` binds straight to its `value` model — no\n * `ControlValueAccessor` in between. `[(value)]` works standalone.\n *\n * Optional `autosize` grows the textarea with its content, capped at\n * `maxRows` if provided.\n *\n * @example\n * ```html\n * <!-- signal forms -->\n * <wr-textarea placeholder=\"Notes\" [formField]=\"form.notes\" />\n *\n * <!-- standalone two-way binding -->\n * <wr-textarea autosize [maxRows]=\"6\" [(value)]=\"text\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/textarea\n */\nexport type WrTextareaSize = 'sm' | 'md' | 'lg';\n\nexport type WrTextareaResize = 'none' | 'vertical' | 'horizontal' | 'both';\n\n@Component({\n selector: 'wr-textarea',\n templateUrl: './textarea.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrTextarea implements FormValueControl<string> {\n /** Native placeholder text. @default '' */\n readonly placeholder = input<string>('');\n\n /** Control size — shares the `--wr-control-*` contract. @default 'md' */\n readonly size = input<WrTextareaSize>('md');\n\n /** Visible row count. @default 3 */\n readonly rows = input(3, { transform: (v: unknown): number => coerceNumberProperty(v, 3) });\n\n /** Allow user resize via the corner grip. @default true */\n readonly resizable = input(true, { transform: coerceBooleanProperty });\n\n /** Resize direction of the corner grip (the grip icon adapts). @default 'vertical' */\n readonly resize = input<WrTextareaResize>('vertical');\n\n /** Read-only state. @default false */\n readonly readonly = input(false, { transform: coerceBooleanProperty });\n\n /** Grow the textarea to fit its content. @default false */\n readonly autosize = input(false, { transform: coerceBooleanProperty });\n\n /** Cap autosize at this many rows. Ignored when `autosize` is false. */\n readonly maxRows = input<number | null>(null);\n\n /**\n * Disable the textarea. 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 /** The edited text. Bound by `[formField]`, or two-way via `[(value)]`. */\n readonly value = model<string>('');\n\n /** Emitted on blur so a bound field can mark itself touched. */\n readonly touch = output<void>();\n\n protected readonly focused = signal(false);\n\n protected readonly native = viewChild.required<ElementRef<HTMLTextAreaElement>>('native');\n\n /** Resize direction, gated by `resizable` (false → 'none'). */\n protected readonly effectiveResize = computed<WrTextareaResize>(() => (this.resizable() ? this.resize() : 'none'));\n\n protected readonly classes = computed(() => {\n const parts = ['wr-textarea'];\n const size = this.size();\n if (size !== 'md') parts.push(`wr-textarea--${size}`);\n if (this.autosize()) parts.push('wr-textarea--no-resize');\n const resize = this.effectiveResize();\n if (resize === 'horizontal' || resize === 'both') parts.push('wr-textarea--resize-x');\n if (this.focused()) parts.push('wr-textarea--focused');\n if (this.disabled()) parts.push('wr-textarea--disabled');\n return parts.join(' ');\n });\n\n /** Show the corner grip (hidden when direction is 'none' / autosize / disabled). */\n protected readonly showHandle = computed(\n () => this.effectiveResize() !== 'none' && !this.autosize() && !this.disabled()\n );\n\n private readonly platformId = inject(PLATFORM_ID);\n private readonly isBrowser = isPlatformBrowser(this.platformId);\n private readonly hostEl = inject<ElementRef<HTMLElement>>(ElementRef);\n\n // Custom resize-grip drag state (replaces the native corner handle).\n private resizing = false;\n private resizeStartY = 0;\n private resizeStartX = 0;\n private resizeStartHeight = 0;\n private resizeStartWidth = 0;\n private resizeMinHeight = 36;\n private resizeMaxWidth = Number.POSITIVE_INFINITY;\n\n constructor() {\n // Autosize: re-fit whenever value or autosize toggles.\n effect(() => {\n if (!this.autosize() || !this.isBrowser) return;\n // Read `value` to register dependency\n this.value();\n requestAnimationFrame(() => this.autofit());\n });\n }\n\n // Template handlers\n\n protected onInput(event: Event): void {\n this.value.set((event.target as HTMLTextAreaElement).value);\n }\n\n protected onBlur(): void {\n this.focused.set(false);\n this.touch.emit();\n }\n\n // Custom resize — drag the corner grip; direction comes from `effectiveResize`.\n // Pointer capture keeps move/up on the grip even when the cursor leaves it.\n protected startResize(event: PointerEvent): void {\n const el = this.native()?.nativeElement;\n if (!el) return;\n const host = this.hostEl.nativeElement;\n this.resizing = true;\n this.resizeStartY = event.clientY;\n this.resizeStartX = event.clientX;\n this.resizeStartHeight = el.offsetHeight;\n this.resizeStartWidth = host.offsetWidth;\n // Height floor = fits the current content, so shrinking never opens an\n // overflow scrollbar. Measured once, synchronously (no paint between).\n const borderY = el.offsetHeight - el.clientHeight;\n const prevHeight = el.style.height;\n el.style.height = 'auto';\n this.resizeMinHeight = el.scrollHeight + borderY;\n el.style.height = prevHeight;\n // Width ceiling = parent inner width, so horizontal drag can't overflow.\n this.resizeMaxWidth = host.parentElement?.clientWidth ?? Number.POSITIVE_INFINITY;\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n event.preventDefault();\n }\n\n protected onResize(event: PointerEvent): void {\n if (!this.resizing) return;\n const el = this.native()?.nativeElement;\n if (!el) return;\n const dir = this.effectiveResize();\n if (dir === 'vertical' || dir === 'both') {\n const h = Math.max(this.resizeMinHeight, this.resizeStartHeight + (event.clientY - this.resizeStartY));\n el.style.height = `${h}px`;\n }\n if (dir === 'horizontal' || dir === 'both') {\n const w = Math.min(\n this.resizeMaxWidth,\n Math.max(64, this.resizeStartWidth + (event.clientX - this.resizeStartX))\n );\n this.hostEl.nativeElement.style.width = `${w}px`;\n }\n }\n\n protected endResize(event: PointerEvent): void {\n if (!this.resizing) return;\n this.resizing = false;\n (event.target as HTMLElement).releasePointerCapture(event.pointerId);\n }\n\n private autofit(): void {\n const el = this.native()?.nativeElement;\n if (!el) return;\n\n el.style.height = 'auto';\n\n const maxRows = this.maxRows();\n if (maxRows && maxRows > 0) {\n const cs = getComputedStyle(el);\n const lineHeight = parseFloat(cs.lineHeight) || parseFloat(cs.fontSize) * 1.2;\n const cap = lineHeight * maxRows;\n const next = Math.min(el.scrollHeight, cap);\n el.style.height = `${next}px`;\n el.style.overflowY = el.scrollHeight > cap ? 'auto' : 'hidden';\n } else {\n el.style.height = `${el.scrollHeight}px`;\n el.style.overflowY = 'hidden';\n }\n }\n}\n","<textarea\n #native\n class=\"wr-textarea__native\"\n [placeholder]=\"placeholder()\"\n [rows]=\"rows()\"\n [readonly]=\"readonly()\"\n [disabled]=\"disabled()\"\n [value]=\"value()\"\n (input)=\"onInput($event)\"\n (focus)=\"focused.set(true)\"\n (blur)=\"onBlur()\"\n></textarea>\n\n@if (showHandle()) {\n <!-- Custom corner grip — the lucide icon + cursor follow the `resize`\n direction. Icons inlined so no icon registration is required. -->\n <span\n [class]=\"`wr-textarea__resize wr-textarea__resize--${effectiveResize()}`\"\n aria-hidden=\"true\"\n (pointerdown)=\"startResize($event)\"\n (pointermove)=\"onResize($event)\"\n (pointerup)=\"endResize($event)\"\n (pointercancel)=\"endResize($event)\"\n >\n <svg\n class=\"wr-icon__svg\"\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 @switch (effectiveResize()) {\n @case ('vertical') {\n <path d=\"M12 2v20\" />\n <path d=\"m8 18 4 4 4-4\" />\n <path d=\"m8 6 4-4 4 4\" />\n }\n @case ('horizontal') {\n <path d=\"M2 12h20\" />\n <path d=\"m18 8 4 4-4 4\" />\n <path d=\"m6 8-4 4 4 4\" />\n }\n @default {\n <path d=\"M19 13v6h-6\" />\n <path d=\"M5 11V5h6\" />\n <path d=\"m5 5 14 14\" />\n }\n }\n </svg>\n </span>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -16,6 +16,11 @@ import { WrStorage } from 'ngwr/storage';
16
16
  * Kept in sync manually with the SCSS `$base-colors` map in
17
17
  * `theme/styles/_colors.scss`. Both sources must stay aligned —
18
18
  * adding a color requires updating both this array and the SCSS map.
19
+ * Nothing enforces that, and it has already drifted once: `info` landed
20
+ * in the map without landing here, so v8.0.0 shipped every
21
+ * `--wr-color-info*` token — plus an `--info` modifier from each of the
22
+ * five stylesheets that iterate the map — while this type refused the
23
+ * value. Order matches the map so the two read as one list.
19
24
  *
20
25
  * @example
21
26
  * ```ts
@@ -25,7 +30,17 @@ import { WrStorage } from 'ngwr/storage';
25
30
  * WR_COLORS.forEach(color => console.log(color));
26
31
  * ```
27
32
  */
28
- const WR_COLORS = ['primary', 'secondary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'];
33
+ const WR_COLORS = [
34
+ 'primary',
35
+ 'secondary',
36
+ 'success',
37
+ 'warning',
38
+ 'danger',
39
+ 'info',
40
+ 'light',
41
+ 'medium',
42
+ 'dark',
43
+ ];
29
44
 
30
45
  /**
31
46
  * @license
@@ -70,7 +85,7 @@ function isThemeMode(v) {
70
85
  * theme.resolved(); // 'dark'
71
86
  * ```
72
87
  *
73
- * @see https://ngwr.dev/services/theme
88
+ * @see https://ngwr.dev/reference/services/theme
74
89
  */
75
90
  class WrTheme {
76
91
  doc = inject(DOCUMENT);
@@ -118,10 +133,10 @@ class WrTheme {
118
133
  return;
119
134
  this.storage.set(this.config.storageKey, mode);
120
135
  }
121
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTheme, deps: [], target: i0.ɵɵFactoryTarget.Service });
122
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.4", ngImport: i0, type: WrTheme });
136
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTheme, deps: [], target: i0.ɵɵFactoryTarget.Service });
137
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.0", ngImport: i0, type: WrTheme });
123
138
  }
124
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTheme, decorators: [{
139
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTheme, decorators: [{
125
140
  type: Service
126
141
  }], ctorParameters: () => [] });
127
142
 
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-theme.mjs","sources":["../../../projects/lib/theme/colors.ts","../../../projects/lib/theme/wr-theme-config.ts","../../../projects/lib/theme/services/wr-theme.ts","../../../projects/lib/theme/provide-wr-theme.ts","../../../projects/lib/theme/ngwr-theme.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\n/**\n * Built-in color variants available to NGWR components.\n *\n * Kept in sync manually with the SCSS `$base-colors` map in\n * `theme/styles/_colors.scss`. Both sources must stay aligned —\n * adding a color requires updating both this array and the SCSS map.\n *\n * @example\n * ```ts\n * import { WR_COLORS } from 'ngwr/theme';\n *\n * // Iterate all colors for demos or documentation\n * WR_COLORS.forEach(color => console.log(color));\n * ```\n */\nexport const WR_COLORS = ['primary', 'secondary', 'success', 'warning', 'danger', 'light', 'medium', 'dark'] as const;\n\n/**\n * A color variant name.\n *\n * Use as an input type on components that accept a color:\n *\n * @example\n * ```ts\n * import type { WrColor } from 'ngwr/theme';\n *\n * @Component({...})\n * export class MyComponent {\n * readonly color = input<WrColor>('primary');\n * }\n * ```\n */\nexport type WrColor = (typeof WR_COLORS)[number];\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/** Mode the user explicitly selected. `auto` follows `prefers-color-scheme`. */\nexport type WrThemeMode = 'light' | 'dark' | 'auto';\n\n/** Resolved theme — what's actually applied to the DOM. */\nexport type WrResolvedTheme = 'light' | 'dark';\n\n/** Configuration for {@link WrTheme}. */\nexport interface WrThemeConfig {\n /** Initial mode used when no persisted value is present. @default 'auto' */\n readonly defaultMode: WrThemeMode;\n /** localStorage key for persistence. Set to `null` to disable persistence. @default 'wr-theme' */\n readonly storageKey: string | null;\n /** Attribute applied to `<html>` to expose the resolved theme. @default 'data-theme' */\n readonly attribute: string;\n}\n\nexport const DEFAULT_WR_THEME_CONFIG: WrThemeConfig = {\n defaultMode: 'auto',\n storageKey: 'wr-theme',\n attribute: 'data-theme',\n};\n\nexport const WR_THEME_CONFIG = new InjectionToken<WrThemeConfig>('WR_THEME_CONFIG', {\n factory: (): WrThemeConfig => DEFAULT_WR_THEME_CONFIG,\n});\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { DOCUMENT } from '@angular/common';\nimport { Service, type Signal, computed, effect, inject, signal } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { WrStorage } from 'ngwr/storage';\n\nimport { WR_THEME_CONFIG, type WrResolvedTheme, type WrThemeMode } from '../wr-theme-config';\n\nconst VALID_MODES: readonly WrThemeMode[] = ['light', 'dark', 'auto'];\n\nfunction isThemeMode(v: unknown): v is WrThemeMode {\n return typeof v === 'string' && (VALID_MODES as readonly string[]).includes(v);\n}\n\n/**\n * Light / dark theme manager.\n *\n * - `mode` is what the user picked (`light` | `dark` | `auto`).\n * - `resolved` is what's actually applied — `auto` resolves through\n * {@link WrPlatform.prefersDark}.\n * - Writes `[data-theme]` (or your configured attribute) on `<html>`.\n * - Persists the selected mode via {@link WrStorage} (defaults to\n * `localStorage`; swap the storage engine globally to change where).\n *\n * @example\n * ```ts\n * const theme = inject(WrTheme);\n * theme.set('dark');\n * theme.toggle();\n * theme.resolved(); // 'dark'\n * ```\n *\n * @see https://ngwr.dev/services/theme\n */\n@Service()\nexport class WrTheme {\n private readonly doc = inject(DOCUMENT);\n private readonly platform = inject(WrPlatform);\n private readonly storage = inject(WrStorage);\n private readonly config = inject(WR_THEME_CONFIG);\n\n /** User-selected mode. */\n readonly mode = signal<WrThemeMode>(this.readPersisted() ?? this.config.defaultMode);\n\n /** Resolved theme actually applied to the DOM. */\n readonly resolved: Signal<WrResolvedTheme> = computed(() => {\n const m = this.mode();\n if (m === 'auto') return this.platform.prefersDark() ? 'dark' : 'light';\n return m;\n });\n\n constructor() {\n // Whenever the resolved theme changes, mirror it to the DOM + persist mode.\n effect(() => {\n const value = this.resolved();\n const html = this.doc.documentElement;\n if (html) html.setAttribute(this.config.attribute, value);\n this.persist(this.mode());\n });\n }\n\n /** Switch to a specific mode. */\n set(mode: WrThemeMode): void {\n this.mode.set(mode);\n }\n\n /** Cycle: light → dark → light (skips auto). */\n toggle(): void {\n this.mode.set(this.resolved() === 'dark' ? 'light' : 'dark');\n }\n\n // Persistence\n\n private readPersisted(): WrThemeMode | null {\n if (!this.config.storageKey) return null;\n const raw = this.storage.get<WrThemeMode>(this.config.storageKey);\n return isThemeMode(raw) ? raw : null;\n }\n\n private persist(mode: WrThemeMode): void {\n if (!this.config.storageKey) return;\n this.storage.set(this.config.storageKey, mode);\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { DEFAULT_WR_THEME_CONFIG, WR_THEME_CONFIG, type WrThemeConfig } from './wr-theme-config';\n\n/**\n * Configure {@link WrTheme}. Partial — merged with defaults.\n *\n * @example\n * ```ts\n * provideWrTheme({ defaultMode: 'dark', storageKey: 'my-app-theme' })\n * ```\n */\nexport function provideWrTheme(config: Partial<WrThemeConfig> = {}): EnvironmentProviders {\n const merged: WrThemeConfig = { ...DEFAULT_WR_THEME_CONFIG, ...config };\n return makeEnvironmentProviders([{ provide: WR_THEME_CONFIG, useValue: merged }]);\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-theme.mjs","sources":["../../../projects/lib/theme/colors.ts","../../../projects/lib/theme/wr-theme-config.ts","../../../projects/lib/theme/services/wr-theme.ts","../../../projects/lib/theme/provide-wr-theme.ts","../../../projects/lib/theme/ngwr-theme.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\n/**\n * Built-in color variants available to NGWR components.\n *\n * Kept in sync manually with the SCSS `$base-colors` map in\n * `theme/styles/_colors.scss`. Both sources must stay aligned —\n * adding a color requires updating both this array and the SCSS map.\n * Nothing enforces that, and it has already drifted once: `info` landed\n * in the map without landing here, so v8.0.0 shipped every\n * `--wr-color-info*` token — plus an `--info` modifier from each of the\n * five stylesheets that iterate the map — while this type refused the\n * value. Order matches the map so the two read as one list.\n *\n * @example\n * ```ts\n * import { WR_COLORS } from 'ngwr/theme';\n *\n * // Iterate all colors for demos or documentation\n * WR_COLORS.forEach(color => console.log(color));\n * ```\n */\nexport const WR_COLORS = [\n 'primary',\n 'secondary',\n 'success',\n 'warning',\n 'danger',\n 'info',\n 'light',\n 'medium',\n 'dark',\n] as const;\n\n/**\n * A color variant name.\n *\n * Use as an input type on components that accept a color:\n *\n * @example\n * ```ts\n * import type { WrColor } from 'ngwr/theme';\n *\n * @Component({...})\n * export class MyComponent {\n * readonly color = input<WrColor>('primary');\n * }\n * ```\n */\nexport type WrColor = (typeof WR_COLORS)[number];\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/** Mode the user explicitly selected. `auto` follows `prefers-color-scheme`. */\nexport type WrThemeMode = 'light' | 'dark' | 'auto';\n\n/** Resolved theme — what's actually applied to the DOM. */\nexport type WrResolvedTheme = 'light' | 'dark';\n\n/** Configuration for {@link WrTheme}. */\nexport interface WrThemeConfig {\n /** Initial mode used when no persisted value is present. @default 'auto' */\n readonly defaultMode: WrThemeMode;\n /** localStorage key for persistence. Set to `null` to disable persistence. @default 'wr-theme' */\n readonly storageKey: string | null;\n /** Attribute applied to `<html>` to expose the resolved theme. @default 'data-theme' */\n readonly attribute: string;\n}\n\nexport const DEFAULT_WR_THEME_CONFIG: WrThemeConfig = {\n defaultMode: 'auto',\n storageKey: 'wr-theme',\n attribute: 'data-theme',\n};\n\nexport const WR_THEME_CONFIG = new InjectionToken<WrThemeConfig>('WR_THEME_CONFIG', {\n factory: (): WrThemeConfig => DEFAULT_WR_THEME_CONFIG,\n});\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { DOCUMENT } from '@angular/common';\nimport { Service, type Signal, computed, effect, inject, signal } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { WrStorage } from 'ngwr/storage';\n\nimport { WR_THEME_CONFIG, type WrResolvedTheme, type WrThemeMode } from '../wr-theme-config';\n\nconst VALID_MODES: readonly WrThemeMode[] = ['light', 'dark', 'auto'];\n\nfunction isThemeMode(v: unknown): v is WrThemeMode {\n return typeof v === 'string' && (VALID_MODES as readonly string[]).includes(v);\n}\n\n/**\n * Light / dark theme manager.\n *\n * - `mode` is what the user picked (`light` | `dark` | `auto`).\n * - `resolved` is what's actually applied — `auto` resolves through\n * {@link WrPlatform.prefersDark}.\n * - Writes `[data-theme]` (or your configured attribute) on `<html>`.\n * - Persists the selected mode via {@link WrStorage} (defaults to\n * `localStorage`; swap the storage engine globally to change where).\n *\n * @example\n * ```ts\n * const theme = inject(WrTheme);\n * theme.set('dark');\n * theme.toggle();\n * theme.resolved(); // 'dark'\n * ```\n *\n * @see https://ngwr.dev/reference/services/theme\n */\n@Service()\nexport class WrTheme {\n private readonly doc = inject(DOCUMENT);\n private readonly platform = inject(WrPlatform);\n private readonly storage = inject(WrStorage);\n private readonly config = inject(WR_THEME_CONFIG);\n\n /** User-selected mode. */\n readonly mode = signal<WrThemeMode>(this.readPersisted() ?? this.config.defaultMode);\n\n /** Resolved theme actually applied to the DOM. */\n readonly resolved: Signal<WrResolvedTheme> = computed(() => {\n const m = this.mode();\n if (m === 'auto') return this.platform.prefersDark() ? 'dark' : 'light';\n return m;\n });\n\n constructor() {\n // Whenever the resolved theme changes, mirror it to the DOM + persist mode.\n effect(() => {\n const value = this.resolved();\n const html = this.doc.documentElement;\n if (html) html.setAttribute(this.config.attribute, value);\n this.persist(this.mode());\n });\n }\n\n /** Switch to a specific mode. */\n set(mode: WrThemeMode): void {\n this.mode.set(mode);\n }\n\n /** Cycle: light → dark → light (skips auto). */\n toggle(): void {\n this.mode.set(this.resolved() === 'dark' ? 'light' : 'dark');\n }\n\n // Persistence\n\n private readPersisted(): WrThemeMode | null {\n if (!this.config.storageKey) return null;\n const raw = this.storage.get<WrThemeMode>(this.config.storageKey);\n return isThemeMode(raw) ? raw : null;\n }\n\n private persist(mode: WrThemeMode): void {\n if (!this.config.storageKey) return;\n this.storage.set(this.config.storageKey, mode);\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { DEFAULT_WR_THEME_CONFIG, WR_THEME_CONFIG, type WrThemeConfig } from './wr-theme-config';\n\n/**\n * Configure {@link WrTheme}. Partial — merged with defaults.\n *\n * @example\n * ```ts\n * provideWrTheme({ defaultMode: 'dark', storageKey: 'my-app-theme' })\n * ```\n */\nexport function provideWrTheme(config: Partial<WrThemeConfig> = {}): EnvironmentProviders {\n const merged: WrThemeConfig = { ...DEFAULT_WR_THEME_CONFIG, ...config };\n return makeEnvironmentProviders([{ provide: WR_THEME_CONFIG, useValue: merged }]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, inject, ElementRef, NgZone, DestroyRef, Directive, ViewEncapsulation, Component } from '@angular/core';
2
+ import { input, inject, ElementRef, NgZone, DestroyRef, PLATFORM_ID, effect, Directive, ViewEncapsulation, Component } from '@angular/core';
3
3
  import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
4
+ import { isPlatformBrowser } from '@angular/common';
4
5
  import { WrPlatform } from 'ngwr/platform';
5
6
 
6
7
  /**
@@ -32,14 +33,23 @@ class WrTilt {
32
33
  zone = inject(NgZone);
33
34
  destroyRef = inject(DestroyRef);
34
35
  platform = inject(WrPlatform);
36
+ isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
37
+ glareEl = null;
35
38
  constructor() {
36
39
  const host = this.el.nativeElement;
37
40
  host.style.transformStyle = 'preserve-3d';
38
41
  host.style.transition = 'transform 0.15s ease-out';
39
- if (this.glare())
40
- this.installGlare();
42
+ // Signal inputs are not bound yet while the constructor runs, so reading
43
+ // `glare()` here would always see the default and the overlay would never
44
+ // appear. Track it instead, so toggling the input at runtime works too.
45
+ // Only in the browser: `installGlare` measures with `getComputedStyle`,
46
+ // and the server has no layout to measure.
47
+ if (this.isBrowser) {
48
+ effect(() => (this.glare() ? this.installGlare() : this.removeGlare()));
49
+ }
41
50
  this.destroyRef.onDestroy(() => {
42
51
  host.style.transform = '';
52
+ this.removeGlare();
43
53
  });
44
54
  }
45
55
  /** @internal */
@@ -66,6 +76,8 @@ class WrTilt {
66
76
  this.el.nativeElement.style.transform = '';
67
77
  }
68
78
  installGlare() {
79
+ if (this.glareEl)
80
+ return;
69
81
  const host = this.el.nativeElement;
70
82
  if (getComputedStyle(host).position === 'static')
71
83
  host.style.position = 'relative';
@@ -74,12 +86,16 @@ class WrTilt {
74
86
  glare.className = 'wr-tilt-glare';
75
87
  glare.setAttribute('aria-hidden', 'true');
76
88
  host.appendChild(glare);
77
- this.destroyRef.onDestroy(() => glare.remove());
89
+ this.glareEl = glare;
90
+ }
91
+ removeGlare() {
92
+ this.glareEl?.remove();
93
+ this.glareEl = null;
78
94
  }
79
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTilt, deps: [], target: i0.ɵɵFactoryTarget.Directive });
80
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: WrTilt, isStandalone: true, selector: "[wrTilt]", inputs: { maxTilt: { classPropertyName: "maxTilt", publicName: "maxTilt", isSignal: true, isRequired: false, transformFunction: null }, perspective: { classPropertyName: "perspective", publicName: "perspective", isSignal: true, isRequired: false, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, glare: { classPropertyName: "glare", publicName: "glare", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointermove": "onMove($event)", "pointerleave": "onLeave()" } }, ngImport: i0 });
95
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTilt, deps: [], target: i0.ɵɵFactoryTarget.Directive });
96
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: WrTilt, isStandalone: true, selector: "[wrTilt]", inputs: { maxTilt: { classPropertyName: "maxTilt", publicName: "maxTilt", isSignal: true, isRequired: false, transformFunction: null }, perspective: { classPropertyName: "perspective", publicName: "perspective", isSignal: true, isRequired: false, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, glare: { classPropertyName: "glare", publicName: "glare", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointermove": "onMove($event)", "pointerleave": "onLeave()" } }, ngImport: i0 });
81
97
  }
82
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTilt, decorators: [{
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTilt, decorators: [{
83
99
  type: Directive,
84
100
  args: [{
85
101
  selector: '[wrTilt]',
@@ -116,17 +132,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
116
132
  * ```
117
133
  */
118
134
  class WrTiltCard {
119
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTiltCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
120
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: WrTiltCard, isStandalone: true, selector: "wr-tilt-card", host: { classAttribute: "wr-tilt-card" }, hostDirectives: [{ directive: WrTilt, inputs: ["maxTilt", "maxTilt", "perspective", "perspective", "scale", "scale", "glare", "glare"] }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [".wr-tilt-card{display:block;position:relative;padding:1.5rem;border-radius:.75rem;border:1px solid var(--wr-color-light);background:var(--wr-color-white);color:var(--wr-color-dark);box-shadow:0 1px 2px rgba(var(--wr-color-backdrop-rgb),.06);transform-style:preserve-3d;transition:transform .15s ease-out}.wr-tilt-glare{position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at var(--wr-tilt-glare-x, 50%) var(--wr-tilt-glare-y, 50%),var(--wr-tilt-glare-color, rgba(var(--wr-color-dark-rgb), .12)),transparent 60%);mix-blend-mode:multiply}[data-theme=dark] .wr-tilt-glare{--wr-tilt-glare-color: rgb(255 255 255 / 25%);mix-blend-mode:overlay}\n"], encapsulation: i0.ViewEncapsulation.None });
135
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTiltCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
136
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.0", type: WrTiltCard, isStandalone: true, selector: "wr-tilt-card", host: { classAttribute: "wr-tilt-card" }, hostDirectives: [{ directive: WrTilt, inputs: ["maxTilt", "maxTilt", "perspective", "perspective", "scale", "scale", "glare", "glare"] }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [".wr-tilt-card{display:block;position:relative;padding:1.5rem;border-radius:.75rem;border:1px solid var(--wr-color-outline);background:var(--wr-color-surface);color:var(--wr-color-on-surface);box-shadow:0 1px 2px rgba(var(--wr-color-backdrop-rgb),.06);transform-style:preserve-3d;transition:transform .15s ease-out}.wr-tilt-glare{position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at var(--wr-tilt-glare-x, 50%) var(--wr-tilt-glare-y, 50%),var(--wr-tilt-glare-color, rgba(var(--wr-color-on-surface-rgb), .12)),transparent 60%);mix-blend-mode:multiply}[data-theme=dark] .wr-tilt-glare{--wr-tilt-glare-color: rgb(255 255 255 / 25%);mix-blend-mode:overlay}\n"], encapsulation: i0.ViewEncapsulation.None });
121
137
  }
122
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTiltCard, decorators: [{
138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTiltCard, decorators: [{
123
139
  type: Component,
124
140
  args: [{ selector: 'wr-tilt-card', template: '<ng-content />', encapsulation: ViewEncapsulation.None, hostDirectives: [
125
141
  {
126
142
  directive: WrTilt,
127
143
  inputs: ['maxTilt', 'perspective', 'scale', 'glare'],
128
144
  },
129
- ], host: { class: 'wr-tilt-card' }, styles: [".wr-tilt-card{display:block;position:relative;padding:1.5rem;border-radius:.75rem;border:1px solid var(--wr-color-light);background:var(--wr-color-white);color:var(--wr-color-dark);box-shadow:0 1px 2px rgba(var(--wr-color-backdrop-rgb),.06);transform-style:preserve-3d;transition:transform .15s ease-out}.wr-tilt-glare{position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at var(--wr-tilt-glare-x, 50%) var(--wr-tilt-glare-y, 50%),var(--wr-tilt-glare-color, rgba(var(--wr-color-dark-rgb), .12)),transparent 60%);mix-blend-mode:multiply}[data-theme=dark] .wr-tilt-glare{--wr-tilt-glare-color: rgb(255 255 255 / 25%);mix-blend-mode:overlay}\n"] }]
145
+ ], host: { class: 'wr-tilt-card' }, styles: [".wr-tilt-card{display:block;position:relative;padding:1.5rem;border-radius:.75rem;border:1px solid var(--wr-color-outline);background:var(--wr-color-surface);color:var(--wr-color-on-surface);box-shadow:0 1px 2px rgba(var(--wr-color-backdrop-rgb),.06);transform-style:preserve-3d;transition:transform .15s ease-out}.wr-tilt-glare{position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at var(--wr-tilt-glare-x, 50%) var(--wr-tilt-glare-y, 50%),var(--wr-tilt-glare-color, rgba(var(--wr-color-on-surface-rgb), .12)),transparent 60%);mix-blend-mode:multiply}[data-theme=dark] .wr-tilt-glare{--wr-tilt-glare-color: rgb(255 255 255 / 25%);mix-blend-mode:overlay}\n"] }]
130
146
  }] });
131
147
 
132
148
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-tilt-card.mjs","sources":["../../../projects/lib/tilt-card/tilt.ts","../../../projects/lib/tilt-card/tilt-card.ts","../../../projects/lib/tilt-card/ngwr-tilt-card.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { DestroyRef, Directive, ElementRef, NgZone, inject, input } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\n\n/**\n * 3D mouse-tilt on hover. Adds `perspective(…) rotateX(…) rotateY(…)` to\n * the host's transform tracking the cursor's position over it.\n *\n * @example\n * ```html\n * <div class=\"card\" wrTilt>…</div>\n * <div class=\"card\" wrTilt maxTilt=\"20\" [glare]=\"true\">…</div>\n * ```\n */\n@Directive({\n selector: '[wrTilt]',\n host: { '(pointermove)': 'onMove($event)', '(pointerleave)': 'onLeave()' },\n})\nexport class WrTilt {\n /** Maximum tilt in degrees. @default 12 */\n readonly maxTilt = input(12, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 12)) });\n\n /** CSS perspective in pixels. @default 800 */\n readonly perspective = input(800, {\n transform: (v: unknown): number => Math.max(100, coerceNumberProperty(v, 800)),\n });\n\n /** Scale applied while hovered. @default 1.03 */\n readonly scale = input(1.03, { transform: (v: unknown): number => Math.max(1, coerceNumberProperty(v, 1.03)) });\n\n /** Add a moving glare highlight overlay. @default false */\n readonly glare = input(false, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platform = inject(WrPlatform);\n\n constructor() {\n const host = this.el.nativeElement;\n host.style.transformStyle = 'preserve-3d';\n host.style.transition = 'transform 0.15s ease-out';\n if (this.glare()) this.installGlare();\n this.destroyRef.onDestroy(() => {\n host.style.transform = '';\n });\n }\n\n /** @internal */\n protected onMove(event: PointerEvent): void {\n // Reduced motion: no pointer-tracking tilt — the card stays flat.\n if (this.platform.prefersReducedMotion()) return;\n this.zone.runOutsideAngular(() => {\n const host = this.el.nativeElement;\n const rect = host.getBoundingClientRect();\n const px = (event.clientX - rect.left) / rect.width;\n const py = (event.clientY - rect.top) / rect.height;\n const rx = (0.5 - py) * this.maxTilt();\n const ry = (px - 0.5) * this.maxTilt();\n host.style.transform = `perspective(${this.perspective()}px) rotateX(${rx}deg) rotateY(${ry}deg) scale(${this.scale()})`;\n if (this.glare()) {\n host.style.setProperty('--wr-tilt-glare-x', `${px * 100}%`);\n host.style.setProperty('--wr-tilt-glare-y', `${py * 100}%`);\n }\n });\n }\n\n /** @internal */\n protected onLeave(): void {\n this.el.nativeElement.style.transform = '';\n }\n\n private installGlare(): void {\n const host = this.el.nativeElement;\n if (getComputedStyle(host).position === 'static') host.style.position = 'relative';\n host.style.overflow = 'hidden';\n const glare = host.ownerDocument.createElement('span');\n glare.className = 'wr-tilt-glare';\n glare.setAttribute('aria-hidden', 'true');\n host.appendChild(glare);\n this.destroyRef.onDestroy(() => glare.remove());\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation } from '@angular/core';\n\nimport { WrTilt } from './tilt';\n\n/**\n * Card wrapper that applies the `[wrTilt]` directive out-of-the-box,\n * plus a small set of card-style defaults (radius, padding, surface).\n * Pass any inputs through — they're forwarded to the hosted directive.\n *\n * For arbitrary elements that just need the tilt behaviour, use the\n * `[wrTilt]` directive directly:\n *\n * ```html\n * <img wrTilt [maxTilt]=\"10\" src=\"…\" />\n * ```\n *\n * @example\n * ```html\n * <wr-tilt-card>\n * <h3>Hello</h3>\n * <p>Move the cursor across me.</p>\n * </wr-tilt-card>\n *\n * <wr-tilt-card [maxTilt]=\"20\" [glare]=\"true\">…</wr-tilt-card>\n * ```\n */\n@Component({\n selector: 'wr-tilt-card',\n template: '<ng-content />',\n styleUrl: './tilt-card.scss',\n encapsulation: ViewEncapsulation.None,\n hostDirectives: [\n {\n directive: WrTilt,\n inputs: ['maxTilt', 'perspective', 'scale', 'glare'],\n },\n ],\n host: { class: 'wr-tilt-card' },\n})\nexport class WrTiltCard {}\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-tilt-card.mjs","sources":["../../../projects/lib/tilt-card/tilt.ts","../../../projects/lib/tilt-card/tilt-card.ts","../../../projects/lib/tilt-card/ngwr-tilt-card.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport { DestroyRef, Directive, ElementRef, NgZone, PLATFORM_ID, effect, inject, input } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\n\n/**\n * 3D mouse-tilt on hover. Adds `perspective(…) rotateX(…) rotateY(…)` to\n * the host's transform tracking the cursor's position over it.\n *\n * @example\n * ```html\n * <div class=\"card\" wrTilt>…</div>\n * <div class=\"card\" wrTilt maxTilt=\"20\" [glare]=\"true\">…</div>\n * ```\n */\n@Directive({\n selector: '[wrTilt]',\n host: { '(pointermove)': 'onMove($event)', '(pointerleave)': 'onLeave()' },\n})\nexport class WrTilt {\n /** Maximum tilt in degrees. @default 12 */\n readonly maxTilt = input(12, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 12)) });\n\n /** CSS perspective in pixels. @default 800 */\n readonly perspective = input(800, {\n transform: (v: unknown): number => Math.max(100, coerceNumberProperty(v, 800)),\n });\n\n /** Scale applied while hovered. @default 1.03 */\n readonly scale = input(1.03, { transform: (v: unknown): number => Math.max(1, coerceNumberProperty(v, 1.03)) });\n\n /** Add a moving glare highlight overlay. @default false */\n readonly glare = input(false, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private glareEl: HTMLElement | null = null;\n\n constructor() {\n const host = this.el.nativeElement;\n host.style.transformStyle = 'preserve-3d';\n host.style.transition = 'transform 0.15s ease-out';\n\n // Signal inputs are not bound yet while the constructor runs, so reading\n // `glare()` here would always see the default and the overlay would never\n // appear. Track it instead, so toggling the input at runtime works too.\n // Only in the browser: `installGlare` measures with `getComputedStyle`,\n // and the server has no layout to measure.\n if (this.isBrowser) {\n effect(() => (this.glare() ? this.installGlare() : this.removeGlare()));\n }\n\n this.destroyRef.onDestroy(() => {\n host.style.transform = '';\n this.removeGlare();\n });\n }\n\n /** @internal */\n protected onMove(event: PointerEvent): void {\n // Reduced motion: no pointer-tracking tilt — the card stays flat.\n if (this.platform.prefersReducedMotion()) return;\n this.zone.runOutsideAngular(() => {\n const host = this.el.nativeElement;\n const rect = host.getBoundingClientRect();\n const px = (event.clientX - rect.left) / rect.width;\n const py = (event.clientY - rect.top) / rect.height;\n const rx = (0.5 - py) * this.maxTilt();\n const ry = (px - 0.5) * this.maxTilt();\n host.style.transform = `perspective(${this.perspective()}px) rotateX(${rx}deg) rotateY(${ry}deg) scale(${this.scale()})`;\n if (this.glare()) {\n host.style.setProperty('--wr-tilt-glare-x', `${px * 100}%`);\n host.style.setProperty('--wr-tilt-glare-y', `${py * 100}%`);\n }\n });\n }\n\n /** @internal */\n protected onLeave(): void {\n this.el.nativeElement.style.transform = '';\n }\n\n private installGlare(): void {\n if (this.glareEl) return;\n const host = this.el.nativeElement;\n if (getComputedStyle(host).position === 'static') host.style.position = 'relative';\n host.style.overflow = 'hidden';\n const glare = host.ownerDocument.createElement('span');\n glare.className = 'wr-tilt-glare';\n glare.setAttribute('aria-hidden', 'true');\n host.appendChild(glare);\n this.glareEl = glare;\n }\n\n private removeGlare(): void {\n this.glareEl?.remove();\n this.glareEl = null;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation } from '@angular/core';\n\nimport { WrTilt } from './tilt';\n\n/**\n * Card wrapper that applies the `[wrTilt]` directive out-of-the-box,\n * plus a small set of card-style defaults (radius, padding, surface).\n * Pass any inputs through — they're forwarded to the hosted directive.\n *\n * For arbitrary elements that just need the tilt behaviour, use the\n * `[wrTilt]` directive directly:\n *\n * ```html\n * <img wrTilt [maxTilt]=\"10\" src=\"…\" />\n * ```\n *\n * @example\n * ```html\n * <wr-tilt-card>\n * <h3>Hello</h3>\n * <p>Move the cursor across me.</p>\n * </wr-tilt-card>\n *\n * <wr-tilt-card [maxTilt]=\"20\" [glare]=\"true\">…</wr-tilt-card>\n * ```\n */\n@Component({\n selector: 'wr-tilt-card',\n template: '<ng-content />',\n styleUrl: './tilt-card.scss',\n encapsulation: ViewEncapsulation.None,\n hostDirectives: [\n {\n directive: WrTilt,\n inputs: ['maxTilt', 'perspective', 'scale', 'glare'],\n },\n ],\n host: { class: 'wr-tilt-card' },\n})\nexport class WrTiltCard {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -18,17 +18,17 @@ import { input, computed, ViewEncapsulation, Component } from '@angular/core';
18
18
  * </wr-timeline>
19
19
  * ```
20
20
  *
21
- * @see https://ngwr.dev/components/timeline
21
+ * @see https://ngwr.dev/reference/components/timeline
22
22
  */
23
23
  class WrTimeline {
24
24
  orientation = input('vertical', /* @ts-ignore */
25
25
  ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
26
26
  classes = computed(() => `wr-timeline wr-timeline--${this.orientation()}`, /* @ts-ignore */
27
27
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
28
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTimeline, deps: [], target: i0.ɵɵFactoryTarget.Component });
29
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.4", type: WrTimeline, isStandalone: true, selector: "wr-timeline", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
28
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTimeline, deps: [], target: i0.ɵɵFactoryTarget.Component });
29
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: WrTimeline, isStandalone: true, selector: "wr-timeline", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
30
30
  }
31
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTimeline, decorators: [{
31
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTimeline, decorators: [{
32
32
  type: Component,
33
33
  args: [{
34
34
  selector: 'wr-timeline',
@@ -57,10 +57,10 @@ class WrTimelineItem {
57
57
  ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
58
58
  classes = computed(() => `wr-timeline-item wr-timeline-item--${this.color()}`, /* @ts-ignore */
59
59
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
60
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTimelineItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: WrTimelineItem, isStandalone: true, selector: "wr-timeline-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, time: { classPropertyName: "time", publicName: "time", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<span class=\"wr-timeline-item__dot\" aria-hidden=\"true\"></span>\n<div class=\"wr-timeline-item__body\">\n @if (time()) {\n <div class=\"wr-timeline-item__time\">{{ time() }}</div>\n }\n @if (title()) {\n <div class=\"wr-timeline-item__title\">{{ title() }}</div>\n }\n <div class=\"wr-timeline-item__content\">\n <ng-content />\n </div>\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
60
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTimelineItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: WrTimelineItem, isStandalone: true, selector: "wr-timeline-item", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, time: { classPropertyName: "time", publicName: "time", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: "<span class=\"wr-timeline-item__dot\" aria-hidden=\"true\"></span>\n<div class=\"wr-timeline-item__body\">\n @if (time()) {\n <div class=\"wr-timeline-item__time\">{{ time() }}</div>\n }\n @if (title()) {\n <div class=\"wr-timeline-item__title\">{{ title() }}</div>\n }\n <div class=\"wr-timeline-item__content\">\n <ng-content />\n </div>\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
62
62
  }
63
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: WrTimelineItem, decorators: [{
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrTimelineItem, decorators: [{
64
64
  type: Component,
65
65
  args: [{ selector: 'wr-timeline-item', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "<span class=\"wr-timeline-item__dot\" aria-hidden=\"true\"></span>\n<div class=\"wr-timeline-item__body\">\n @if (time()) {\n <div class=\"wr-timeline-item__time\">{{ time() }}</div>\n }\n @if (title()) {\n <div class=\"wr-timeline-item__title\">{{ title() }}</div>\n }\n <div class=\"wr-timeline-item__content\">\n <ng-content />\n </div>\n</div>\n" }]
66
66
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], time: [{ type: i0.Input, args: [{ isSignal: true, alias: "time", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-timeline.mjs","sources":["../../../projects/lib/timeline/timeline.ts","../../../projects/lib/timeline/timeline-item.ts","../../../projects/lib/timeline/timeline-item.html","../../../projects/lib/timeline/ngwr-timeline.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Event-list ladder. Project `<wr-timeline-item>` children.\n *\n * @example\n * ```html\n * <wr-timeline>\n * <wr-timeline-item title=\"Created\" time=\"2026-05-01\">Initial commit.</wr-timeline-item>\n * <wr-timeline-item title=\"Deployed\" time=\"2026-05-02\" color=\"success\">Live.</wr-timeline-item>\n * </wr-timeline>\n * ```\n *\n * @see https://ngwr.dev/components/timeline\n */\n@Component({\n selector: 'wr-timeline',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrTimeline {\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\n\n protected readonly classes = computed(() => `wr-timeline wr-timeline--${this.orientation()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport type { WrTimelineColor } from './interfaces';\n\n/**\n * One event in a {@link WrTimeline}. Project content for the\n * description; `title` and `time` are header inputs.\n */\n@Component({\n selector: 'wr-timeline-item',\n templateUrl: './timeline-item.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrTimelineItem {\n readonly title = input<string>('');\n readonly time = input<string>('');\n readonly color = input<WrTimelineColor>('primary');\n\n protected readonly classes = computed(() => `wr-timeline-item wr-timeline-item--${this.color()}`);\n}\n\nexport type { WrTimelineColor } from './interfaces';\n","<span class=\"wr-timeline-item__dot\" aria-hidden=\"true\"></span>\n<div class=\"wr-timeline-item__body\">\n @if (time()) {\n <div class=\"wr-timeline-item__time\">{{ time() }}</div>\n }\n @if (title()) {\n <div class=\"wr-timeline-item__title\">{{ title() }}</div>\n }\n <div class=\"wr-timeline-item__content\">\n <ng-content />\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAAA;;;;;AAKG;AAIH;;;;;;;;;;;;AAYG;MAOU,UAAU,CAAA;IACZ,WAAW,GAAG,KAAK,CAA4B,UAAU;oFAAC;IAEhD,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA,yBAAA,EAA4B,IAAI,CAAC,WAAW,EAAE,CAAA,CAAE;gFAAC;uGAHlF,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,6QAJX,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAIf,UAAU,EAAA,UAAA,EAAA,CAAA;kBANtB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,aAAa;AACvB,oBAAA,QAAQ,EAAE,gBAAgB;oBAC1B,aAAa,EAAE,iBAAiB,CAAC,IAAI;AACrC,oBAAA,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE;AACjC,iBAAA;;;AC3BD;;;;;AAKG;AAMH;;;AAGG;MAOU,cAAc,CAAA;IAChB,KAAK,GAAG,KAAK,CAAS,EAAE;8EAAC;IACzB,IAAI,GAAG,KAAK,CAAS,EAAE;6EAAC;IACxB,KAAK,GAAG,KAAK,CAAkB,SAAS;8EAAC;IAE/B,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA,mCAAA,EAAsC,IAAI,CAAC,KAAK,EAAE,CAAA,CAAE;gFAAC;uGALtF,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAd,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,6eCrB3B,8WAYA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDSa,cAAc,EAAA,UAAA,EAAA,CAAA;kBAN1B,SAAS;+BACE,kBAAkB,EAAA,aAAA,EAEb,iBAAiB,CAAC,IAAI,QAC/B,EAAE,SAAS,EAAE,WAAW,EAAE,EAAA,QAAA,EAAA,8WAAA,EAAA;;;AEnBlC;;AAEG;;;;"}
1
+ {"version":3,"file":"ngwr-timeline.mjs","sources":["../../../projects/lib/timeline/timeline.ts","../../../projects/lib/timeline/timeline-item.ts","../../../projects/lib/timeline/timeline-item.html","../../../projects/lib/timeline/ngwr-timeline.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\n/**\n * Event-list ladder. Project `<wr-timeline-item>` children.\n *\n * @example\n * ```html\n * <wr-timeline>\n * <wr-timeline-item title=\"Created\" time=\"2026-05-01\">Initial commit.</wr-timeline-item>\n * <wr-timeline-item title=\"Deployed\" time=\"2026-05-02\" color=\"success\">Live.</wr-timeline-item>\n * </wr-timeline>\n * ```\n *\n * @see https://ngwr.dev/reference/components/timeline\n */\n@Component({\n selector: 'wr-timeline',\n template: '<ng-content />',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrTimeline {\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\n\n protected readonly classes = computed(() => `wr-timeline wr-timeline--${this.orientation()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport type { WrTimelineColor } from './interfaces';\n\n/**\n * One event in a {@link WrTimeline}. Project content for the\n * description; `title` and `time` are header inputs.\n */\n@Component({\n selector: 'wr-timeline-item',\n templateUrl: './timeline-item.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrTimelineItem {\n readonly title = input<string>('');\n readonly time = input<string>('');\n readonly color = input<WrTimelineColor>('primary');\n\n protected readonly classes = computed(() => `wr-timeline-item wr-timeline-item--${this.color()}`);\n}\n\nexport type { WrTimelineColor } from './interfaces';\n","<span class=\"wr-timeline-item__dot\" aria-hidden=\"true\"></span>\n<div class=\"wr-timeline-item__body\">\n @if (time()) {\n <div class=\"wr-timeline-item__time\">{{ time() }}</div>\n }\n @if (title()) {\n <div class=\"wr-timeline-item__title\">{{ title() }}</div>\n }\n <div class=\"wr-timeline-item__content\">\n <ng-content />\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;AAAA;;;;;AAKG;AAIH;;;;;;;;;;;;AAYG;MAOU,UAAU,CAAA;IACZ,WAAW,GAAG,KAAK,CAA4B,UAAU;oFAAC;IAEhD,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA,yBAAA,EAA4B,IAAI,CAAC,WAAW,EAAE,CAAA,CAAE;gFAAC;uGAHlF,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAV,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,6QAJX,gBAAgB,EAAA,QAAA,EAAA,IAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAIf,UAAU,EAAA,UAAA,EAAA,CAAA;kBANtB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,aAAa;AACvB,oBAAA,QAAQ,EAAE,gBAAgB;oBAC1B,aAAa,EAAE,iBAAiB,CAAC,IAAI;AACrC,oBAAA,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE;AACjC,iBAAA;;;AC3BD;;;;;AAKG;AAMH;;;AAGG;MAOU,cAAc,CAAA;IAChB,KAAK,GAAG,KAAK,CAAS,EAAE;8EAAC;IACzB,IAAI,GAAG,KAAK,CAAS,EAAE;6EAAC;IACxB,KAAK,GAAG,KAAK,CAAkB,SAAS;8EAAC;IAE/B,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAA,mCAAA,EAAsC,IAAI,CAAC,KAAK,EAAE,CAAA,CAAE;gFAAC;uGALtF,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAd,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,6eCrB3B,8WAYA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDSa,cAAc,EAAA,UAAA,EAAA,CAAA;kBAN1B,SAAS;+BACE,kBAAkB,EAAA,aAAA,EAEb,iBAAiB,CAAC,IAAI,QAC/B,EAAE,SAAS,EAAE,WAAW,EAAE,EAAA,QAAA,EAAA,8WAAA,EAAA;;;AEnBlC;;AAEG;;;;"}