ngwr 15.1.0 → 15.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/alert/styles/_index.scss +13 -5
  2. package/bits/aurora/styles/_rules.scss +11 -0
  3. package/bits/dot-grid/styles/_rules.scss +9 -1
  4. package/bits/iridescence/iridescence.scss +1 -0
  5. package/bits/iridescence/styles/_index.scss +8 -0
  6. package/bits/iridescence/styles/_rules.scss +72 -0
  7. package/bits/marquee/styles/_rules.scss +7 -3
  8. package/bits/ripple-grid/styles/_rules.scss +10 -2
  9. package/bits/spotlight-card/styles/_rules.scss +7 -4
  10. package/bits/star-border/styles/_rules.scss +5 -2
  11. package/bits/threads/styles/_rules.scss +9 -1
  12. package/bits/waves/styles/_rules.scss +8 -1
  13. package/charts/candlestick-chart/styles/_index.scss +2 -2
  14. package/fesm2022/ngwr-affix.mjs +3 -3
  15. package/fesm2022/ngwr-alert.mjs +5 -5
  16. package/fesm2022/ngwr-alert.mjs.map +1 -1
  17. package/fesm2022/ngwr-anchor.mjs +3 -3
  18. package/fesm2022/ngwr-avatar.mjs +3 -3
  19. package/fesm2022/ngwr-back-top.mjs +3 -3
  20. package/fesm2022/ngwr-badge.mjs +6 -6
  21. package/fesm2022/ngwr-bits-aurora.mjs +30 -38
  22. package/fesm2022/ngwr-bits-aurora.mjs.map +1 -1
  23. package/fesm2022/ngwr-bits-blur-text.mjs +3 -3
  24. package/fesm2022/ngwr-bits-border-glow-testing.mjs.map +1 -1
  25. package/fesm2022/ngwr-bits-border-glow.mjs +11 -5
  26. package/fesm2022/ngwr-bits-border-glow.mjs.map +1 -1
  27. package/fesm2022/ngwr-bits-circular-text.mjs +3 -3
  28. package/fesm2022/ngwr-bits-click-spark.mjs +3 -3
  29. package/fesm2022/ngwr-bits-confetti.mjs +3 -3
  30. package/fesm2022/ngwr-bits-decrypt-text.mjs +3 -3
  31. package/fesm2022/ngwr-bits-dot-grid.mjs +12 -9
  32. package/fesm2022/ngwr-bits-dot-grid.mjs.map +1 -1
  33. package/fesm2022/ngwr-bits-falling-text.mjs +3 -3
  34. package/fesm2022/ngwr-bits-fuzzy-text.mjs +3 -3
  35. package/fesm2022/ngwr-bits-glitch-text.mjs +3 -3
  36. package/fesm2022/ngwr-bits-gradient-text.mjs +3 -3
  37. package/fesm2022/ngwr-bits-iridescence-testing.mjs +31 -0
  38. package/fesm2022/ngwr-bits-iridescence-testing.mjs.map +1 -0
  39. package/fesm2022/ngwr-bits-iridescence.mjs +591 -0
  40. package/fesm2022/ngwr-bits-iridescence.mjs.map +1 -0
  41. package/fesm2022/ngwr-bits-marquee-testing.mjs +1 -1
  42. package/fesm2022/ngwr-bits-marquee-testing.mjs.map +1 -1
  43. package/fesm2022/ngwr-bits-marquee.mjs +7 -7
  44. package/fesm2022/ngwr-bits-marquee.mjs.map +1 -1
  45. package/fesm2022/ngwr-bits-ripple-grid.mjs +8 -11
  46. package/fesm2022/ngwr-bits-ripple-grid.mjs.map +1 -1
  47. package/fesm2022/ngwr-bits-rotating-text.mjs +3 -3
  48. package/fesm2022/ngwr-bits-shiny-text.mjs +6 -6
  49. package/fesm2022/ngwr-bits-splash-cursor.mjs +3 -3
  50. package/fesm2022/ngwr-bits-split-text.mjs +3 -3
  51. package/fesm2022/ngwr-bits-spotlight-card-testing.mjs +1 -1
  52. package/fesm2022/ngwr-bits-spotlight-card-testing.mjs.map +1 -1
  53. package/fesm2022/ngwr-bits-spotlight-card.mjs +10 -10
  54. package/fesm2022/ngwr-bits-spotlight-card.mjs.map +1 -1
  55. package/fesm2022/ngwr-bits-star-border-testing.mjs +1 -1
  56. package/fesm2022/ngwr-bits-star-border-testing.mjs.map +1 -1
  57. package/fesm2022/ngwr-bits-star-border.mjs +7 -7
  58. package/fesm2022/ngwr-bits-star-border.mjs.map +1 -1
  59. package/fesm2022/ngwr-bits-threads.mjs +17 -12
  60. package/fesm2022/ngwr-bits-threads.mjs.map +1 -1
  61. package/fesm2022/ngwr-bits-tilt-card.mjs +6 -6
  62. package/fesm2022/ngwr-bits-typewriter.mjs +3 -3
  63. package/fesm2022/ngwr-bits-waves.mjs +15 -11
  64. package/fesm2022/ngwr-bits-waves.mjs.map +1 -1
  65. package/fesm2022/ngwr-breadcrumbs.mjs +24 -8
  66. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  67. package/fesm2022/ngwr-burger.mjs +3 -3
  68. package/fesm2022/ngwr-button.mjs +6 -6
  69. package/fesm2022/ngwr-calendar.mjs +3 -3
  70. package/fesm2022/ngwr-card.mjs +9 -9
  71. package/fesm2022/ngwr-carousel.mjs +6 -6
  72. package/fesm2022/ngwr-cascader.mjs +3 -3
  73. package/fesm2022/ngwr-charts-bar-chart.mjs +3 -3
  74. package/fesm2022/ngwr-charts-boxplot-chart.mjs +3 -3
  75. package/fesm2022/ngwr-charts-bullet-chart.mjs +3 -3
  76. package/fesm2022/ngwr-charts-calendar-heatmap.mjs +3 -3
  77. package/fesm2022/ngwr-charts-candlestick-chart.mjs +7 -7
  78. package/fesm2022/ngwr-charts-candlestick-chart.mjs.map +1 -1
  79. package/fesm2022/ngwr-charts-chart-legend.mjs +6 -6
  80. package/fesm2022/ngwr-charts-core.mjs +3 -3
  81. package/fesm2022/ngwr-charts-donut-chart.mjs +3 -3
  82. package/fesm2022/ngwr-charts-funnel-chart.mjs +3 -3
  83. package/fesm2022/ngwr-charts-gauge.mjs +3 -3
  84. package/fesm2022/ngwr-charts-heatmap-chart.mjs +3 -3
  85. package/fesm2022/ngwr-charts-line-chart.mjs +3 -3
  86. package/fesm2022/ngwr-charts-meter-group.mjs +3 -3
  87. package/fesm2022/ngwr-charts-radar-chart.mjs +3 -3
  88. package/fesm2022/ngwr-charts-scatter-chart.mjs +3 -3
  89. package/fesm2022/ngwr-charts-sparkline.mjs +3 -3
  90. package/fesm2022/ngwr-charts-treemap-chart.mjs +3 -3
  91. package/fesm2022/ngwr-charts-waterfall-chart.mjs +3 -3
  92. package/fesm2022/ngwr-checkbox.mjs +6 -6
  93. package/fesm2022/ngwr-clipboard.mjs +3 -3
  94. package/fesm2022/ngwr-collapse.mjs +9 -9
  95. package/fesm2022/ngwr-color-picker.mjs +6 -6
  96. package/fesm2022/ngwr-command-palette.mjs +3 -3
  97. package/fesm2022/ngwr-compare.mjs +3 -3
  98. package/fesm2022/ngwr-context-menu.mjs +12 -12
  99. package/fesm2022/ngwr-cookie.mjs +3 -3
  100. package/fesm2022/ngwr-counter.mjs +6 -6
  101. package/fesm2022/ngwr-date-picker.mjs +21 -21
  102. package/fesm2022/ngwr-date.mjs +6 -6
  103. package/fesm2022/ngwr-density.mjs +6 -6
  104. package/fesm2022/ngwr-descriptions.mjs +6 -6
  105. package/fesm2022/ngwr-dialog.mjs +15 -15
  106. package/fesm2022/ngwr-directives.mjs +12 -12
  107. package/fesm2022/ngwr-divider.mjs +3 -3
  108. package/fesm2022/ngwr-drawer.mjs +18 -18
  109. package/fesm2022/ngwr-dropdown.mjs +9 -9
  110. package/fesm2022/ngwr-editor.mjs +3 -3
  111. package/fesm2022/ngwr-empty.mjs +3 -3
  112. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  113. package/fesm2022/ngwr-file-upload.mjs +3 -3
  114. package/fesm2022/ngwr-form.mjs +9 -9
  115. package/fesm2022/ngwr-graph.mjs +6 -6
  116. package/fesm2022/ngwr-hotkey.mjs +29 -7
  117. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  118. package/fesm2022/ngwr-i18n-ar.mjs +2 -0
  119. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  120. package/fesm2022/ngwr-i18n-cs.mjs +2 -0
  121. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  122. package/fesm2022/ngwr-i18n-de.mjs +2 -0
  123. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  124. package/fesm2022/ngwr-i18n-en.mjs +2 -0
  125. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  126. package/fesm2022/ngwr-i18n-es.mjs +2 -0
  127. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  128. package/fesm2022/ngwr-i18n-fr.mjs +2 -0
  129. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  130. package/fesm2022/ngwr-i18n-he.mjs +2 -0
  131. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  132. package/fesm2022/ngwr-i18n-hi.mjs +2 -0
  133. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  134. package/fesm2022/ngwr-i18n-id.mjs +2 -0
  135. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  136. package/fesm2022/ngwr-i18n-it.mjs +2 -0
  137. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  138. package/fesm2022/ngwr-i18n-ja.mjs +2 -0
  139. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  140. package/fesm2022/ngwr-i18n-ko.mjs +2 -0
  141. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  142. package/fesm2022/ngwr-i18n-nl.mjs +2 -0
  143. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  144. package/fesm2022/ngwr-i18n-pl.mjs +2 -0
  145. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  146. package/fesm2022/ngwr-i18n-pt.mjs +2 -0
  147. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  148. package/fesm2022/ngwr-i18n-ru.mjs +2 -0
  149. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  150. package/fesm2022/ngwr-i18n-sv.mjs +2 -0
  151. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  152. package/fesm2022/ngwr-i18n-tr.mjs +2 -0
  153. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  154. package/fesm2022/ngwr-i18n-uk.mjs +2 -0
  155. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  156. package/fesm2022/ngwr-i18n-vi.mjs +2 -0
  157. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  158. package/fesm2022/ngwr-i18n-zh-tw.mjs +2 -0
  159. package/fesm2022/ngwr-i18n-zh-tw.mjs.map +1 -1
  160. package/fesm2022/ngwr-i18n-zh.mjs +2 -0
  161. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  162. package/fesm2022/ngwr-i18n.mjs +9 -9
  163. package/fesm2022/ngwr-icon.mjs +6 -6
  164. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  165. package/fesm2022/ngwr-input-number.mjs +3 -3
  166. package/fesm2022/ngwr-input-otp.mjs +3 -3
  167. package/fesm2022/ngwr-input.mjs +15 -15
  168. package/fesm2022/ngwr-keyboard.mjs +3 -3
  169. package/fesm2022/ngwr-knob.mjs +3 -3
  170. package/fesm2022/ngwr-layout.mjs +15 -15
  171. package/fesm2022/ngwr-lightbox.mjs +3 -3
  172. package/fesm2022/ngwr-list.mjs +6 -6
  173. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  174. package/fesm2022/ngwr-mention.mjs +6 -6
  175. package/fesm2022/ngwr-meta.mjs +6 -6
  176. package/fesm2022/ngwr-overlay.mjs +6 -6
  177. package/fesm2022/ngwr-page-header.mjs +3 -3
  178. package/fesm2022/ngwr-pagination.mjs +6 -3
  179. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  180. package/fesm2022/ngwr-pipes.mjs +26 -23
  181. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  182. package/fesm2022/ngwr-platform.mjs +6 -6
  183. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  184. package/fesm2022/ngwr-popover.mjs +12 -12
  185. package/fesm2022/ngwr-progress.mjs +3 -3
  186. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  187. package/fesm2022/ngwr-qr.mjs +4 -3
  188. package/fesm2022/ngwr-qr.mjs.map +1 -1
  189. package/fesm2022/ngwr-radio.mjs +6 -6
  190. package/fesm2022/ngwr-rating.mjs +3 -3
  191. package/fesm2022/ngwr-result.mjs +12 -12
  192. package/fesm2022/ngwr-schema-form.mjs +6 -3
  193. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  194. package/fesm2022/ngwr-scroll.mjs +3 -3
  195. package/fesm2022/ngwr-segmented.mjs +3 -3
  196. package/fesm2022/ngwr-select-testing.mjs +16 -0
  197. package/fesm2022/ngwr-select-testing.mjs.map +1 -1
  198. package/fesm2022/ngwr-select.mjs +230 -50
  199. package/fesm2022/ngwr-select.mjs.map +1 -1
  200. package/fesm2022/ngwr-sidebar.mjs +3 -3
  201. package/fesm2022/ngwr-skeleton.mjs +3 -3
  202. package/fesm2022/ngwr-slider.mjs +3 -3
  203. package/fesm2022/ngwr-sortable-list.mjs +9 -9
  204. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  205. package/fesm2022/ngwr-spinner.mjs +3 -3
  206. package/fesm2022/ngwr-splitter.mjs +3 -3
  207. package/fesm2022/ngwr-statistic.mjs +18 -14
  208. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  209. package/fesm2022/ngwr-stepper.mjs +6 -6
  210. package/fesm2022/ngwr-storage.mjs +3 -3
  211. package/fesm2022/ngwr-switch.mjs +3 -3
  212. package/fesm2022/ngwr-table.mjs +18 -18
  213. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  214. package/fesm2022/ngwr-tabs.mjs +6 -6
  215. package/fesm2022/ngwr-textarea.mjs +3 -3
  216. package/fesm2022/ngwr-theme.mjs +3 -3
  217. package/fesm2022/ngwr-timeline.mjs +6 -6
  218. package/fesm2022/ngwr-toast.mjs +9 -9
  219. package/fesm2022/ngwr-toolbar.mjs +3 -3
  220. package/fesm2022/ngwr-tour.mjs +6 -6
  221. package/fesm2022/ngwr-transfer.mjs +3 -3
  222. package/fesm2022/ngwr-tree.mjs +3 -3
  223. package/fesm2022/ngwr-typography.mjs +3 -3
  224. package/fesm2022/ngwr-utils.mjs +31 -1
  225. package/fesm2022/ngwr-utils.mjs.map +1 -1
  226. package/fesm2022/ngwr-version.mjs +1 -1
  227. package/fesm2022/ngwr-version.mjs.map +1 -1
  228. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  229. package/fesm2022/ngwr-window.mjs +12 -12
  230. package/i18n/ar.json +2 -0
  231. package/i18n/cs.json +2 -0
  232. package/i18n/de.json +2 -0
  233. package/i18n/en.json +2 -0
  234. package/i18n/es.json +2 -0
  235. package/i18n/fr.json +2 -0
  236. package/i18n/he.json +2 -0
  237. package/i18n/hi.json +2 -0
  238. package/i18n/id.json +2 -0
  239. package/i18n/it.json +2 -0
  240. package/i18n/ja.json +2 -0
  241. package/i18n/ko.json +2 -0
  242. package/i18n/nl.json +2 -0
  243. package/i18n/pl.json +2 -0
  244. package/i18n/pt.json +2 -0
  245. package/i18n/ru.json +2 -0
  246. package/i18n/sv.json +2 -0
  247. package/i18n/tr.json +2 -0
  248. package/i18n/uk.json +2 -0
  249. package/i18n/vi.json +2 -0
  250. package/i18n/zh-TW.json +2 -0
  251. package/i18n/zh.json +2 -0
  252. package/llms-full.txt +15 -4
  253. package/mcp/server.js +15 -1
  254. package/mcp/tools.js +3 -3
  255. package/package.json +10 -1
  256. package/schematics/ng-add/index.js +2 -2
  257. package/schematics/use/symbol-map.json +2 -0
  258. package/select/styles/_index.scss +23 -1
  259. package/skills/ngwr/SKILL.md +1 -1
  260. package/skills/ngwr/references/catalog.md +3 -1
  261. package/types/ngwr-alert.d.ts +3 -1
  262. package/types/ngwr-bits-aurora.d.ts +11 -0
  263. package/types/ngwr-bits-border-glow-testing.d.ts +5 -6
  264. package/types/ngwr-bits-border-glow.d.ts +5 -1
  265. package/types/ngwr-bits-dot-grid.d.ts +7 -2
  266. package/types/ngwr-bits-iridescence-testing.d.ts +85 -0
  267. package/types/ngwr-bits-iridescence.d.ts +244 -0
  268. package/types/ngwr-bits-ripple-grid.d.ts +4 -7
  269. package/types/ngwr-bits-splash-cursor.d.ts +0 -1
  270. package/types/ngwr-bits-spotlight-card-testing.d.ts +3 -1
  271. package/types/ngwr-bits-star-border-testing.d.ts +7 -7
  272. package/types/ngwr-bits-threads.d.ts +11 -8
  273. package/types/ngwr-bits-waves.d.ts +6 -3
  274. package/types/ngwr-breadcrumbs.d.ts +15 -0
  275. package/types/ngwr-charts-core.d.ts +0 -10
  276. package/types/ngwr-color-picker.d.ts +0 -21
  277. package/types/ngwr-dropdown.d.ts +0 -52
  278. package/types/ngwr-editor.d.ts +2 -84
  279. package/types/ngwr-hotkey.d.ts +14 -2
  280. package/types/ngwr-i18n.d.ts +0 -15
  281. package/types/ngwr-mention.d.ts +0 -13
  282. package/types/ngwr-popconfirm.d.ts +0 -33
  283. package/types/ngwr-popover.d.ts +0 -51
  284. package/types/ngwr-select-testing.d.ts +9 -0
  285. package/types/ngwr-select.d.ts +133 -2
  286. package/types/ngwr-sidebar.d.ts +1 -1
  287. package/types/ngwr-tour.d.ts +0 -2
  288. package/types/ngwr-utils.d.ts +49 -7
  289. package/types/ngwr-version.d.ts +1 -1
  290. package/types/ngwr-window.d.ts +0 -56
@@ -108,7 +108,10 @@ $alert-colors: (
108
108
  line-height: var(--wr-alert-title-line-height);
109
109
  }
110
110
 
111
- &__message {
111
+ // Projected content reads as the message does. Hidden while empty, so an alert
112
+ // with nothing inside keeps the body's gap to what it had.
113
+ &__message,
114
+ &__content {
112
115
  margin: 0;
113
116
  color: var(--wr-alert-message);
114
117
  font-family: var(--wr-alert-font-family);
@@ -116,6 +119,10 @@ $alert-colors: (
116
119
  line-height: var(--wr-alert-message-line-height);
117
120
  }
118
121
 
122
+ &__content:empty {
123
+ display: none;
124
+ }
125
+
119
126
  &__close {
120
127
  flex: 0 0 auto;
121
128
  appearance: none;
@@ -136,11 +143,12 @@ $alert-colors: (
136
143
  // `font: inherit`. Inheriting the size makes `1em` the alert's own text in
137
144
  // every app. `--wr-icon-size` cannot do this job — only a `<wr-icon>` host
138
145
  // reads it, and the rule here used to set it for nothing. The SIZE only,
139
- // never the `font` shorthand, which would bring the line-height with it; and
140
- // no `line-height` of its own either, the way `wr-dialog` needs one — the
141
- // alert stretches its row, so this box is the alert's height whatever the
142
- // strut says.
146
+ // never the `font` shorthand, which would bring the line-height with it.
143
147
  font-size: inherit;
148
+ // Top of the row, by the title, rather than stretched to the alert's height:
149
+ // with projected content under the message, a stretched button put the ✕
150
+ // halfway down the alert and painted its hover tint as a full-height strip.
151
+ align-self: flex-start;
144
152
 
145
153
  @include theme.touch-target; // glyph -> 44px tap area on touch
146
154
 
@@ -22,4 +22,15 @@
22
22
  width: 100%;
23
23
  height: 100%;
24
24
  }
25
+
26
+ // Under forced colours the ribbon would cover the palette's own ground, which forced
27
+ // text and marks are chosen against. The adjust inherits to the colour probe inside
28
+ // the canvas, which would otherwise read the forced colour, so a frame drawn in this
29
+ // mode is still right when it ends.
30
+ @media (forced-colors: active) {
31
+ &__canvas {
32
+ display: none;
33
+ forced-color-adjust: none;
34
+ }
35
+ }
25
36
  }
@@ -28,7 +28,7 @@
28
28
  // so the handover moves nothing.
29
29
  background-image: radial-gradient(
30
30
  circle,
31
- var(--wr-dot-grid-dot-color) calc(var(--wr-dot-grid-dot-size) / 2 - 0.25px),
31
+ var(--wr-dot-grid-input-dot-color, var(--wr-dot-grid-dot-color)) calc(var(--wr-dot-grid-dot-size) / 2 - 0.25px),
32
32
  transparent calc(var(--wr-dot-grid-dot-size) / 2 + 0.25px)
33
33
  );
34
34
  background-position: center;
@@ -43,4 +43,12 @@
43
43
  width: 100%;
44
44
  height: 100%;
45
45
  }
46
+
47
+ // The adjust inherits to the colour probe inside the canvas, which would otherwise
48
+ // read the forced colour. A still frame drawn then keeps it after the mode ends.
49
+ @media (forced-colors: active) {
50
+ &__canvas {
51
+ forced-color-adjust: none;
52
+ }
53
+ }
46
54
  }
@@ -0,0 +1 @@
1
+ @forward './styles/rules';
@@ -0,0 +1,8 @@
1
+ // Public Sass entry for `@use 'ngwr/bits/iridescence'`.
2
+ //
3
+ // `iridescence.scss` — the component's `styleUrl` — forwards `_rules` and
4
+ // nothing else, so the compiled component styles carry this component's own
5
+ // CSS and no second copy of the theme layer.
6
+ @use '../../../theme/styles';
7
+
8
+ @forward 'rules';
@@ -0,0 +1,72 @@
1
+ // Iridescence background. A WebGL2 canvas fills the nearest positioned ancestor
2
+ // and the picture lives in the fragment shader. A uniform reads neither a `var()`
3
+ // nor a `light-dark()`, so `iridescence.ts` resolves the colour through
4
+ // `resolveCssColorChannels` before it reaches one.
5
+
6
+ .wr-iridescence {
7
+ // Multiplied over the picture, so white leaves it as it is.
8
+ --wr-iridescence-color: light-dark(#ffffff, #5c669e);
9
+
10
+ position: absolute;
11
+ inset: 0;
12
+ z-index: 0;
13
+ display: block;
14
+ overflow: hidden;
15
+ // The pointer is followed on the parent, so the layer itself never takes a
16
+ // click or a hover from what sits behind or around it.
17
+ pointer-events: none;
18
+
19
+ // Stand-in, shown before hydration, on a machine with no WebGL2 and after a
20
+ // lost context, so the box is never empty and text placed on it keeps its
21
+ // ground. The colours are sampled from the shader's own output at a white tint,
22
+ // and the bands run along its drape axis: 329deg is the direction across the
23
+ // folds, `(-0.51, 0.86)` in GL. `multiply` is what `uColor` does to the shader,
24
+ // so an opaque tint lands on both the same way, and the second layer shades the
25
+ // far corners so the first does not read as plain stripes.
26
+ background-color: var(--wr-iridescence-input-color, var(--wr-iridescence-color));
27
+ background-image:
28
+ linear-gradient(59deg, #e6dcf0 0%, transparent 35%, transparent 65%, #d6d0ea 100%),
29
+ linear-gradient(
30
+ 329deg,
31
+ #e9dbef 0%,
32
+ #c49cd1 16%,
33
+ #f2e6f3 32%,
34
+ #b2bcde 48%,
35
+ #7387b2 60%,
36
+ #d5c7e7 74%,
37
+ #c6bce4 86%,
38
+ #ebddf0 100%
39
+ );
40
+ background-blend-mode: multiply;
41
+
42
+ &__canvas {
43
+ display: block;
44
+ width: 100%;
45
+ height: 100%;
46
+ opacity: 0;
47
+ transition: opacity var(--wr-duration-slower) var(--wr-ease-in-out);
48
+ }
49
+
50
+ // The stand-in stays under it and is not retired. It is an approximation and
51
+ // not the same picture, so swapping one for the other would pop.
52
+ &--painted &__canvas {
53
+ opacity: 1;
54
+ }
55
+
56
+ @media (prefers-reduced-motion: reduce) {
57
+ &__canvas {
58
+ transition: none;
59
+ }
60
+ }
61
+
62
+ // The browser has already taken the stand-in down to the palette's own ground,
63
+ // which forced text and marks are chosen against, and the silk would cover it. The
64
+ // adjust inherits to the colour probe inside the canvas, which would otherwise read
65
+ // the forced colour, so a frame drawn in this mode is still right when it ends.
66
+ @media (forced-colors: active) {
67
+ &__canvas {
68
+ display: none;
69
+ forced-color-adjust: none;
70
+ }
71
+ }
72
+ }
@@ -2,7 +2,8 @@
2
2
  // Vars driven from component inputs:
3
3
  // --wr-marquee-gap gap between items (px)
4
4
  // --wr-marquee-height item height (px)
5
- // --wr-marquee-fade-color edge fade colour (falls back to page bg)
5
+ // --wr-marquee-input-fade-color edge fade colour (falls back to
6
+ // --wr-marquee-fade-color, then the page bg)
6
7
 
7
8
  .wr-marquee {
8
9
  --wr-marquee-gap: 32px;
@@ -10,6 +11,9 @@
10
11
  // Default to the lib's surface colour; consumers can override via
11
12
  // `[fadeOutColor]` or by setting `--wr-marquee-fade-color` directly.
12
13
  --wr-marquee-fade-color-auto: var(--wr-color-surface, #ffffff);
14
+ // What `[fadeOutColor]` writes on the host, which the inline value beats. Unset here so
15
+ // a marquee rendered inside another one does not inherit its colour.
16
+ --wr-marquee-input-fade-color: initial;
13
17
 
14
18
  position: relative;
15
19
  display: block;
@@ -138,7 +142,7 @@
138
142
  left: 0;
139
143
  background: linear-gradient(
140
144
  to right,
141
- var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto)) 0%,
145
+ var(--wr-marquee-input-fade-color, var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto))) 0%,
142
146
  rgba(0, 0, 0, 0) 100%
143
147
  );
144
148
  }
@@ -148,7 +152,7 @@
148
152
  right: 0;
149
153
  background: linear-gradient(
150
154
  to left,
151
- var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto)) 0%,
155
+ var(--wr-marquee-input-fade-color, var(--wr-marquee-fade-color, var(--wr-marquee-fade-color-auto))) 0%,
152
156
  rgba(0, 0, 0, 0) 100%
153
157
  );
154
158
  }
@@ -32,12 +32,12 @@
32
32
  background-image:
33
33
  linear-gradient(
34
34
  to right,
35
- var(--wr-ripple-grid-line-color) var(--wr-ripple-grid-line-width),
35
+ var(--wr-ripple-grid-input-line-color, var(--wr-ripple-grid-line-color)) var(--wr-ripple-grid-line-width),
36
36
  transparent var(--wr-ripple-grid-line-width)
37
37
  ),
38
38
  linear-gradient(
39
39
  to bottom,
40
- var(--wr-ripple-grid-line-color) var(--wr-ripple-grid-line-width),
40
+ var(--wr-ripple-grid-input-line-color, var(--wr-ripple-grid-line-color)) var(--wr-ripple-grid-line-width),
41
41
  transparent var(--wr-ripple-grid-line-width)
42
42
  );
43
43
  background-position: calc(50% - var(--wr-ripple-grid-line-width) / 2) calc(50% - var(--wr-ripple-grid-line-width) / 2);
@@ -52,4 +52,12 @@
52
52
  width: 100%;
53
53
  height: 100%;
54
54
  }
55
+
56
+ // The adjust inherits to the colour probe inside the canvas, which would otherwise
57
+ // read the forced colour. A still frame drawn then keeps it after the mode ends.
58
+ @media (forced-colors: active) {
59
+ &__canvas {
60
+ forced-color-adjust: none;
61
+ }
62
+ }
55
63
  }
@@ -1,7 +1,7 @@
1
1
  // Cursor-tracked spotlight card (reactbits port). The `--wr-spotlight-x/y`
2
- // vars come from the host's mousemove handler; `--wr-spotlight-color` is
3
- // set inline from the `[spotlightColor]` input when provided — otherwise
4
- // the theme picks the default below. `--wr-color-on-surface` flips between
2
+ // vars come from the host's mousemove handler; `--wr-spotlight-input-color`
3
+ // is set inline from the `[spotlightColor]` input when provided — otherwise
4
+ // `--wr-spotlight-color` below decides. `--wr-color-on-surface` flips between
5
5
  // schemes (dark on light surfaces, light on dark), so one tint reads as a
6
6
  // dark-ish glow in light mode and a light beam in dark mode; the dark side
7
7
  // takes a touch more alpha so the beam reads as bright as the classic
@@ -10,6 +10,9 @@
10
10
  .wr-spotlight-card {
11
11
  --wr-spotlight-x: 50%;
12
12
  --wr-spotlight-y: 50%;
13
+ // What `[spotlightColor]` writes on the host, which the inline value beats. Unset here
14
+ // so a card projected inside another one does not inherit its colour.
15
+ --wr-spotlight-input-color: initial;
13
16
  --wr-spotlight-color: light-dark(
14
17
  color-mix(in srgb, var(--wr-color-on-surface) 15%, transparent),
15
18
  color-mix(in srgb, var(--wr-color-on-surface) 22%, transparent)
@@ -33,7 +36,7 @@
33
36
  inset: 0;
34
37
  background: radial-gradient(
35
38
  circle at var(--wr-spotlight-x) var(--wr-spotlight-y),
36
- var(--wr-spotlight-color),
39
+ var(--wr-spotlight-input-color, var(--wr-spotlight-color)),
37
40
  transparent var(--wr-spotlight-radius, 80%)
38
41
  );
39
42
  opacity: 0;
@@ -6,6 +6,9 @@
6
6
  // Light surfaces get a primary comet; dark flips to the classic white.
7
7
  // `[color]` overrides both inline.
8
8
  --wr-star-border-color: light-dark(var(--wr-color-primary), #ffffff);
9
+ // What `[color]` writes on the host, which the inline value beats. Unset here so an
10
+ // instance projected inside another one does not inherit its colour.
11
+ --wr-star-border-input-color: initial;
9
12
  --wr-star-border-speed: 6s;
10
13
  --wr-star-border-radius: 20px;
11
14
  --wr-star-border-opacity: 1;
@@ -33,8 +36,8 @@
33
36
  // there, so each scheme draws the gradient it drew as its own stop.
34
37
  background: radial-gradient(
35
38
  circle,
36
- var(--wr-star-border-color),
37
- light-dark(color-mix(in srgb, var(--wr-star-border-color) 37.5%, transparent), transparent) 10%,
39
+ var(--wr-star-border-input-color, var(--wr-star-border-color)),
40
+ light-dark(color-mix(in srgb, var(--wr-star-border-input-color, var(--wr-star-border-color)) 37.5%, transparent), transparent) 10%,
38
41
  transparent 16%
39
42
  );
40
43
  animation: wr-star-border-bottom var(--wr-star-border-speed) linear infinite alternate;
@@ -43,7 +43,7 @@
43
43
  inset: 0;
44
44
  background-image: repeating-linear-gradient(
45
45
  to bottom,
46
- var(--wr-threads-color) 0 var(--wr-threads-line-width),
46
+ var(--wr-threads-input-color, var(--wr-threads-color)) 0 var(--wr-threads-line-width),
47
47
  transparent var(--wr-threads-line-width)
48
48
  calc((100% - var(--wr-threads-line-width)) / max(1, var(--wr-threads-count) - 1))
49
49
  );
@@ -65,4 +65,12 @@
65
65
  width: 100%;
66
66
  height: 100%;
67
67
  }
68
+
69
+ // The adjust inherits to the colour probe inside the canvas, which would otherwise
70
+ // read the forced colour. A still frame drawn then keeps it after the mode ends.
71
+ @media (forced-colors: active) {
72
+ &__canvas {
73
+ forced-color-adjust: none;
74
+ }
75
+ }
68
76
  }
@@ -43,5 +43,12 @@
43
43
  width: 100%;
44
44
  height: 100%;
45
45
  }
46
- }
47
46
 
47
+ // The adjust inherits to the colour probe inside the canvas, which would otherwise
48
+ // read the forced colour. A still frame drawn then keeps it after the mode ends.
49
+ @media (forced-colors: active) {
50
+ &__canvas {
51
+ forced-color-adjust: none;
52
+ }
53
+ }
54
+ }
@@ -160,11 +160,11 @@ $-body: calc(100% - $-upper - $-lower);
160
160
  pointer-events: none;
161
161
 
162
162
  &--increase {
163
- color: var(--wr-candlestick-chart-increase-color);
163
+ color: var(--wr-candlestick-chart-input-increase-color, var(--wr-candlestick-chart-increase-color));
164
164
  }
165
165
 
166
166
  &--decrease {
167
- color: var(--wr-candlestick-chart-decrease-color);
167
+ color: var(--wr-candlestick-chart-input-decrease-color, var(--wr-candlestick-chart-decrease-color));
168
168
  }
169
169
 
170
170
  // The wicks: above the body and below it, never through it, so a hollow body is
@@ -129,7 +129,7 @@ var WrAffix = class WrAffix {
129
129
  }
130
130
  static ɵfac = i0.ɵɵngDeclareFactory({
131
131
  minVersion: "12.0.0",
132
- version: "22.2.3",
132
+ version: "22.2.4",
133
133
  ngImport: i0,
134
134
  type: WrAffix,
135
135
  deps: [],
@@ -137,7 +137,7 @@ var WrAffix = class WrAffix {
137
137
  });
138
138
  static ɵdir = i0.ɵɵngDeclareDirective({
139
139
  minVersion: "17.1.0",
140
- version: "22.2.3",
140
+ version: "22.2.4",
141
141
  type: WrAffix,
142
142
  isStandalone: true,
143
143
  selector: "[wrAffix]",
@@ -161,7 +161,7 @@ var WrAffix = class WrAffix {
161
161
  };
162
162
  i0.ɵɵngDeclareClassMetadata({
163
163
  minVersion: "12.0.0",
164
- version: "22.2.3",
164
+ version: "22.2.4",
165
165
  ngImport: i0,
166
166
  type: WrAffix,
167
167
  decorators: [{
@@ -54,7 +54,7 @@ var WrAlert = class WrAlert {
54
54
  }
55
55
  static ɵfac = i0.ɵɵngDeclareFactory({
56
56
  minVersion: "12.0.0",
57
- version: "22.2.3",
57
+ version: "22.2.4",
58
58
  ngImport: i0,
59
59
  type: WrAlert,
60
60
  deps: [],
@@ -62,7 +62,7 @@ var WrAlert = class WrAlert {
62
62
  });
63
63
  static ɵcmp = i0.ɵɵngDeclareComponent({
64
64
  minVersion: "17.0.0",
65
- version: "22.2.3",
65
+ version: "22.2.4",
66
66
  type: WrAlert,
67
67
  isStandalone: true,
68
68
  selector: "wr-alert",
@@ -125,7 +125,7 @@ var WrAlert = class WrAlert {
125
125
  "attr.aria-live": "liveLevel()"
126
126
  } },
127
127
  ngImport: i0,
128
- template: "@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\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 <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n",
128
+ template: "@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n <div class=\"wr-alert__content\"><ng-content /></div>\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\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 <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n",
129
129
  dependencies: [{
130
130
  kind: "component",
131
131
  type: WrIcon,
@@ -137,7 +137,7 @@ var WrAlert = class WrAlert {
137
137
  };
138
138
  i0.ɵɵngDeclareClassMetadata({
139
139
  minVersion: "12.0.0",
140
- version: "22.2.3",
140
+ version: "22.2.4",
141
141
  ngImport: i0,
142
142
  type: WrAlert,
143
143
  decorators: [{
@@ -152,7 +152,7 @@ i0.ɵɵngDeclareClassMetadata({
152
152
  "[attr.role]": "liveRole()",
153
153
  "[attr.aria-live]": "liveLevel()"
154
154
  },
155
- template: "@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\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 <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n"
155
+ template: "@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n <div class=\"wr-alert__content\"><ng-content /></div>\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\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 <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n"
156
156
  }]
157
157
  }],
158
158
  propDecorators: {
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-alert.mjs","names":[],"sources":["../../../projects/lib/alert/alert.ts","../../../projects/lib/alert/alert.html"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { getFocusableElements } from 'ngwr/utils';\n\nimport type { WrAlertType } from './types';\n\n/**\n * Inline status banner. Use for feedback messages — saved/failed/notice etc.\n *\n * @example\n * ```html\n * <wr-alert title=\"Saved\" message=\"Your changes are live.\" type=\"success\" />\n * <wr-alert title=\"Failed\" type=\"danger\" closable (closed)=\"onClose()\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/alert\n */\n@Component({\n selector: 'wr-alert',\n templateUrl: './alert.html',\n imports: [WrIcon],\n encapsulation: ViewEncapsulation.None,\n host: {\n // `title` is an input, and a static attribute that feeds an input is ALSO\n // written onto the host — where the browser shows it as a native tooltip\n // over the whole component, and where it feeds the accessible name of any\n // element that has a role. `<wr-alert title=\"Heads up\">` is the documented\n // spelling, so every page writing it shipped both. A bound `[title]` never\n // did this, which is why the two forms behaved differently for no reason a\n // reader could see.\n '[attr.title]': 'null',\n '[class]': 'classes()',\n '[attr.role]': 'liveRole()',\n '[attr.aria-live]': 'liveLevel()',\n },\n})\nexport class WrAlert {\n /** Accessible name. Falls back to `alert.close`, then `'Close alert'`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'alert.close', 'Close alert');\n\n /**\n * Optional headline shown at the top of the alert.\n *\n * @default null\n */\n readonly title = input<string | null>(null);\n\n /**\n * Visual variant.\n *\n * @default 'info'\n */\n readonly type = input<WrAlertType>('info');\n\n /**\n * Override the default per-type icon with any ngwr icon name.\n *\n * @default null\n */\n readonly iconName = input<WrIconName | null>(null);\n\n /**\n * Optional secondary message rendered below the title.\n *\n * @default null\n */\n readonly message = input<string | null>(null);\n\n /**\n * When `true`, renders a leading status icon matching the `type`.\n * Pass `false` to hide. Ignored when `iconName` is set.\n *\n * @default true\n */\n readonly icon = input(true, { transform: coerceBooleanProperty });\n\n /**\n * When `true`, renders a close button.\n *\n * @default false\n */\n readonly closable = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Emitted when the user dismisses the alert via the close button. If the close\n * button had focus, focus moves on to the next focusable element after the alert\n * (or the one before it, when nothing follows) — unless a `(closed)` handler has\n * placed it somewhere itself.\n */\n readonly closed = output<void>();\n\n protected readonly dismissed = signal(false);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-alert', `wr-alert--${this.type()}`];\n if (this.dismissed()) parts.push('wr-alert--dismissed');\n return parts.join(' ');\n });\n\n /** Escalate role/aria-live for danger/warning alerts. */\n protected readonly liveRole = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' ? 'alert' : 'status'\n );\n protected readonly liveLevel = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' || this.type() === 'warning' ? 'assertive' : 'polite'\n );\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n protected onClose(): void {\n const host = this.host.nativeElement;\n const hadFocus = host.contains(host.ownerDocument.activeElement);\n this.dismissed.set(true);\n this.closed.emit();\n if (hadFocus) afterNextRender(() => this.handOnFocus(), { injector: this.injector });\n }\n\n /**\n * The close button is removed with the rest of the content, and a focused element\n * that leaves the DOM drops the caret on `<body>`: a keyboard user's next Tab, and\n * a screen reader's reading position, started over from the top of the page. Run\n * after the render that removed it, so a `(closed)` handler that moved focus on\n * purpose is seen and left alone.\n */\n private handOnFocus(): void {\n const host = this.host.nativeElement;\n const doc = host.ownerDocument;\n const active = doc.activeElement;\n if (active && active !== doc.body) return;\n // Tab stops only: a roving composite parks its other items at -1. The host has\n // nothing focusable left inside it, so every stop is either before or after it.\n const stops = getFocusableElements(doc.body).filter(el => el.tabIndex >= 0);\n // eslint-disable-next-line no-bitwise -- compareDocumentPosition answers with a bitmask\n const after = stops.findIndex(el => (host.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0);\n (after >= 0 ? stops[after] : stops.at(-1))?.focus();\n }\n}\n","@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\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 <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-alert.mjs","names":[],"sources":["../../../projects/lib/alert/alert.ts","../../../projects/lib/alert/alert.html"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport {\n Component,\n ElementRef,\n Injector,\n ViewEncapsulation,\n afterNextRender,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\nimport { getFocusableElements } from 'ngwr/utils';\n\nimport type { WrAlertType } from './types';\n\n/**\n * Inline status banner. Use for feedback messages — saved/failed/notice etc.\n * Content placed inside renders below the message, in `.wr-alert__content`.\n *\n * @example\n * ```html\n * <wr-alert title=\"Saved\" message=\"Your changes are live.\" type=\"success\" />\n * <wr-alert title=\"Failed\" type=\"danger\" closable (closed)=\"onClose()\" />\n * <wr-alert title=\"Sync failed\" type=\"danger\">Request <code>8f2c41</code> timed out.</wr-alert>\n * ```\n *\n * @see https://ngwr.dev/reference/components/alert\n */\n@Component({\n selector: 'wr-alert',\n templateUrl: './alert.html',\n imports: [WrIcon],\n encapsulation: ViewEncapsulation.None,\n host: {\n // `title` is an input, and a static attribute that feeds an input is ALSO\n // written onto the host — where the browser shows it as a native tooltip\n // over the whole component, and where it feeds the accessible name of any\n // element that has a role. `<wr-alert title=\"Heads up\">` is the documented\n // spelling, so every page writing it shipped both. A bound `[title]` never\n // did this, which is why the two forms behaved differently for no reason a\n // reader could see.\n '[attr.title]': 'null',\n '[class]': 'classes()',\n '[attr.role]': 'liveRole()',\n '[attr.aria-live]': 'liveLevel()',\n },\n})\nexport class WrAlert {\n /** Accessible name. Falls back to `alert.close`, then `'Close alert'`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'alert.close', 'Close alert');\n\n /**\n * Optional headline shown at the top of the alert.\n *\n * @default null\n */\n readonly title = input<string | null>(null);\n\n /**\n * Visual variant.\n *\n * @default 'info'\n */\n readonly type = input<WrAlertType>('info');\n\n /**\n * Override the default per-type icon with any ngwr icon name.\n *\n * @default null\n */\n readonly iconName = input<WrIconName | null>(null);\n\n /**\n * Optional secondary message rendered below the title.\n *\n * @default null\n */\n readonly message = input<string | null>(null);\n\n /**\n * When `true`, renders a leading status icon matching the `type`.\n * Pass `false` to hide. Ignored when `iconName` is set.\n *\n * @default true\n */\n readonly icon = input(true, { transform: coerceBooleanProperty });\n\n /**\n * When `true`, renders a close button.\n *\n * @default false\n */\n readonly closable = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Emitted when the user dismisses the alert via the close button. If the close\n * button had focus, focus moves on to the next focusable element after the alert\n * (or the one before it, when nothing follows) — unless a `(closed)` handler has\n * placed it somewhere itself.\n */\n readonly closed = output<void>();\n\n protected readonly dismissed = signal(false);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-alert', `wr-alert--${this.type()}`];\n if (this.dismissed()) parts.push('wr-alert--dismissed');\n return parts.join(' ');\n });\n\n /** Escalate role/aria-live for danger/warning alerts. */\n protected readonly liveRole = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' ? 'alert' : 'status'\n );\n protected readonly liveLevel = computed(() =>\n this.dismissed() ? null : this.type() === 'danger' || this.type() === 'warning' ? 'assertive' : 'polite'\n );\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n\n protected onClose(): void {\n const host = this.host.nativeElement;\n const hadFocus = host.contains(host.ownerDocument.activeElement);\n this.dismissed.set(true);\n this.closed.emit();\n if (hadFocus) afterNextRender(() => this.handOnFocus(), { injector: this.injector });\n }\n\n /**\n * The close button is removed with the rest of the content, and a focused element\n * that leaves the DOM drops the caret on `<body>`: a keyboard user's next Tab, and\n * a screen reader's reading position, started over from the top of the page. Run\n * after the render that removed it, so a `(closed)` handler that moved focus on\n * purpose is seen and left alone.\n */\n private handOnFocus(): void {\n const host = this.host.nativeElement;\n const doc = host.ownerDocument;\n const active = doc.activeElement;\n if (active && active !== doc.body) return;\n // Tab stops only: a roving composite parks its other items at -1. The host has\n // nothing focusable left inside it, so every stop is either before or after it.\n const stops = getFocusableElements(doc.body).filter(el => el.tabIndex >= 0);\n // eslint-disable-next-line no-bitwise -- compareDocumentPosition answers with a bitmask\n const after = stops.findIndex(el => (host.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0);\n (after >= 0 ? stops[after] : stops.at(-1))?.focus();\n }\n}\n","@if (!dismissed()) {\n @if (iconName(); as n) {\n <wr-icon class=\"wr-alert__icon\" [name]=\"n\" />\n } @else if (icon()) {\n <svg\n class=\"wr-alert__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n @switch (type()) {\n @case ('success') {\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n }\n @case ('warning') {\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n }\n <!-- An OCTAGON, and the shape is the point. `danger` used to be a\n circle holding a bar over a dot, which is the vertical mirror of\n the `i` the @default branch draws — at the rendered 18px the two\n differ only by where a 1.5px gap sits. The stop-sign silhouette\n reads at that size and survives greyscale, which a mirrored gap\n does not. -->\n @case ('danger') {\n <path\n d=\"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z\"\n />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n <!-- A bar, not the exclamation mark `danger` used to carry: `neutral`\n emitted that glyph byte for byte. The icon is the whole difference\n between these two, because what the component actually paints —\n `danger-ink` #a32a33 (L 0.0968) against `on-surface-muted` #5f6c7d\n (L 0.1464) on tints 1.036:1 apart — is a hue difference and little\n else. -->\n @case ('neutral') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M8 12h8\" />\n }\n @case ('offline') {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.9 4.9 14.2 14.2\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n }\n }\n </svg>\n }\n\n <div class=\"wr-alert__body\">\n @if (title(); as t) {\n <p class=\"wr-alert__title\">{{ t }}</p>\n @if (message(); as m) {\n <p class=\"wr-alert__message\">{{ m }}</p>\n }\n } @else if (message(); as m) {\n <p class=\"wr-alert__title\">{{ m }}</p>\n }\n <div class=\"wr-alert__content\"><ng-content /></div>\n </div>\n\n @if (closable()) {\n <button type=\"button\" class=\"wr-alert__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"onClose()\">\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 <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n }\n}\n"],"mappings":"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"}
@@ -84,7 +84,7 @@ var WrAnchor = class WrAnchor {
84
84
  }
85
85
  static ɵfac = i0.ɵɵngDeclareFactory({
86
86
  minVersion: "12.0.0",
87
- version: "22.2.3",
87
+ version: "22.2.4",
88
88
  ngImport: i0,
89
89
  type: WrAnchor,
90
90
  deps: [],
@@ -92,7 +92,7 @@ var WrAnchor = class WrAnchor {
92
92
  });
93
93
  static ɵcmp = i0.ɵɵngDeclareComponent({
94
94
  minVersion: "17.0.0",
95
- version: "22.2.3",
95
+ version: "22.2.4",
96
96
  type: WrAnchor,
97
97
  isStandalone: true,
98
98
  selector: "wr-anchor",
@@ -138,7 +138,7 @@ var WrAnchor = class WrAnchor {
138
138
  };
139
139
  i0.ɵɵngDeclareClassMetadata({
140
140
  minVersion: "12.0.0",
141
- version: "22.2.3",
141
+ version: "22.2.4",
142
142
  ngImport: i0,
143
143
  type: WrAnchor,
144
144
  decorators: [{
@@ -64,7 +64,7 @@ var WrAvatar = class WrAvatar {
64
64
  }
65
65
  static ɵfac = i0.ɵɵngDeclareFactory({
66
66
  minVersion: "12.0.0",
67
- version: "22.2.3",
67
+ version: "22.2.4",
68
68
  ngImport: i0,
69
69
  type: WrAvatar,
70
70
  deps: [],
@@ -72,7 +72,7 @@ var WrAvatar = class WrAvatar {
72
72
  });
73
73
  static ɵcmp = i0.ɵɵngDeclareComponent({
74
74
  minVersion: "17.0.0",
75
- version: "22.2.3",
75
+ version: "22.2.4",
76
76
  type: WrAvatar,
77
77
  isStandalone: true,
78
78
  selector: "wr-avatar",
@@ -132,7 +132,7 @@ var WrAvatar = class WrAvatar {
132
132
  };
133
133
  i0.ɵɵngDeclareClassMetadata({
134
134
  minVersion: "12.0.0",
135
- version: "22.2.3",
135
+ version: "22.2.4",
136
136
  ngImport: i0,
137
137
  type: WrAvatar,
138
138
  decorators: [{
@@ -46,7 +46,7 @@ var WrBackTop = class WrBackTop {
46
46
  }
47
47
  static ɵfac = i0.ɵɵngDeclareFactory({
48
48
  minVersion: "12.0.0",
49
- version: "22.2.3",
49
+ version: "22.2.4",
50
50
  ngImport: i0,
51
51
  type: WrBackTop,
52
52
  deps: [],
@@ -54,7 +54,7 @@ var WrBackTop = class WrBackTop {
54
54
  });
55
55
  static ɵcmp = i0.ɵɵngDeclareComponent({
56
56
  minVersion: "17.1.0",
57
- version: "22.2.3",
57
+ version: "22.2.4",
58
58
  type: WrBackTop,
59
59
  isStandalone: true,
60
60
  selector: "wr-back-top",
@@ -93,7 +93,7 @@ var WrBackTop = class WrBackTop {
93
93
  };
94
94
  i0.ɵɵngDeclareClassMetadata({
95
95
  minVersion: "12.0.0",
96
- version: "22.2.3",
96
+ version: "22.2.4",
97
97
  ngImport: i0,
98
98
  type: WrBackTop,
99
99
  decorators: [{
@@ -30,7 +30,7 @@ var WrBadge = class WrBadge {
30
30
  }, ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
31
31
  static ɵfac = i0.ɵɵngDeclareFactory({
32
32
  minVersion: "12.0.0",
33
- version: "22.2.3",
33
+ version: "22.2.4",
34
34
  ngImport: i0,
35
35
  type: WrBadge,
36
36
  deps: [],
@@ -38,7 +38,7 @@ var WrBadge = class WrBadge {
38
38
  });
39
39
  static ɵcmp = i0.ɵɵngDeclareComponent({
40
40
  minVersion: "17.1.0",
41
- version: "22.2.3",
41
+ version: "22.2.4",
42
42
  type: WrBadge,
43
43
  isStandalone: true,
44
44
  selector: "wr-badge",
@@ -81,7 +81,7 @@ var WrBadge = class WrBadge {
81
81
  };
82
82
  i0.ɵɵngDeclareClassMetadata({
83
83
  minVersion: "12.0.0",
84
- version: "22.2.3",
84
+ version: "22.2.4",
85
85
  ngImport: i0,
86
86
  type: WrBadge,
87
87
  decorators: [{
@@ -172,7 +172,7 @@ var WrTag = class WrTag {
172
172
  }, ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
173
173
  static ɵfac = i0.ɵɵngDeclareFactory({
174
174
  minVersion: "12.0.0",
175
- version: "22.2.3",
175
+ version: "22.2.4",
176
176
  ngImport: i0,
177
177
  type: WrTag,
178
178
  deps: [],
@@ -180,7 +180,7 @@ var WrTag = class WrTag {
180
180
  });
181
181
  static ɵcmp = i0.ɵɵngDeclareComponent({
182
182
  minVersion: "17.0.0",
183
- version: "22.2.3",
183
+ version: "22.2.4",
184
184
  type: WrTag,
185
185
  isStandalone: true,
186
186
  selector: "wr-tag",
@@ -261,7 +261,7 @@ var WrTag = class WrTag {
261
261
  };
262
262
  i0.ɵɵngDeclareClassMetadata({
263
263
  minVersion: "12.0.0",
264
- version: "22.2.3",
264
+ version: "22.2.4",
265
265
  ngImport: i0,
266
266
  type: WrTag,
267
267
  decorators: [{