ngwr 7.3.0 → 8.0.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 (261) hide show
  1. package/README.md +5 -4
  2. package/alert/styles/_index.scss +44 -17
  3. package/avatar/styles/_index.scss +2 -2
  4. package/badge/styles/_index.scss +11 -7
  5. package/badge/styles/_tag.scss +1 -1
  6. package/bar-chart/styles/_index.scss +1 -2
  7. package/breadcrumbs/styles/_index.scss +4 -2
  8. package/burger/styles/_index.scss +2 -2
  9. package/button/styles/_index.scss +30 -20
  10. package/calendar/styles/_index.scss +11 -9
  11. package/calendar-heatmap/styles/_index.scss +2 -0
  12. package/card/styles/_index.scss +1 -1
  13. package/carousel/styles/_index.scss +1 -1
  14. package/cascader/styles/_index.scss +54 -14
  15. package/checkbox/styles/_index.scss +21 -4
  16. package/collapse/styles/_index.scss +1 -1
  17. package/color-picker/styles/_index.scss +11 -12
  18. package/command-palette/styles/_index.scss +3 -3
  19. package/compare/styles/_index.scss +3 -3
  20. package/context-menu/styles/_index.scss +1 -1
  21. package/date-picker/styles/_index.scss +5 -6
  22. package/density/styles/_index.scss +3 -3
  23. package/dialog/styles/_index.scss +3 -3
  24. package/divider/styles/_index.scss +1 -1
  25. package/drawer/styles/_index.scss +11 -11
  26. package/dropdown/styles/_index.scss +2 -2
  27. package/fesm2022/ngwr-affix.mjs +3 -3
  28. package/fesm2022/ngwr-alert.mjs +22 -10
  29. package/fesm2022/ngwr-alert.mjs.map +1 -1
  30. package/fesm2022/ngwr-anchor.mjs +3 -3
  31. package/fesm2022/ngwr-aurora.mjs +3 -3
  32. package/fesm2022/ngwr-avatar.mjs +3 -3
  33. package/fesm2022/ngwr-back-top.mjs +3 -3
  34. package/fesm2022/ngwr-badge.mjs +6 -6
  35. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  36. package/fesm2022/ngwr-blur-text.mjs +3 -3
  37. package/fesm2022/ngwr-border-glow.mjs +3 -3
  38. package/fesm2022/ngwr-breadcrumbs.mjs +7 -7
  39. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  40. package/fesm2022/ngwr-burger.mjs +3 -3
  41. package/fesm2022/ngwr-button.mjs +6 -6
  42. package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
  43. package/fesm2022/ngwr-calendar.mjs +4 -4
  44. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  45. package/fesm2022/ngwr-card.mjs +10 -10
  46. package/fesm2022/ngwr-card.mjs.map +1 -1
  47. package/fesm2022/ngwr-carousel.mjs +6 -6
  48. package/fesm2022/ngwr-cascader.mjs +12 -35
  49. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  50. package/fesm2022/ngwr-checkbox.mjs +13 -30
  51. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  52. package/fesm2022/ngwr-circular-text.mjs +3 -3
  53. package/fesm2022/ngwr-click-spark.mjs +25 -6
  54. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  55. package/fesm2022/ngwr-clipboard.mjs +27 -6
  56. package/fesm2022/ngwr-clipboard.mjs.map +1 -1
  57. package/fesm2022/ngwr-collapse.mjs +9 -9
  58. package/fesm2022/ngwr-color-picker.mjs +7 -7
  59. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  60. package/fesm2022/ngwr-command-palette.mjs +3 -3
  61. package/fesm2022/ngwr-compare.mjs +3 -3
  62. package/fesm2022/ngwr-confetti.mjs +3 -3
  63. package/fesm2022/ngwr-context-menu.mjs +40 -88
  64. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  65. package/fesm2022/ngwr-cookie.mjs +3 -3
  66. package/fesm2022/ngwr-counter.mjs +12 -8
  67. package/fesm2022/ngwr-counter.mjs.map +1 -1
  68. package/fesm2022/ngwr-date-adapter-fns.mjs +3 -3
  69. package/fesm2022/ngwr-date-adapter-luxon.mjs +3 -3
  70. package/fesm2022/ngwr-date-adapter.mjs +3 -3
  71. package/fesm2022/ngwr-date-picker.mjs +25 -11
  72. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  73. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  74. package/fesm2022/ngwr-density.mjs +14 -14
  75. package/fesm2022/ngwr-density.mjs.map +1 -1
  76. package/fesm2022/ngwr-descriptions.mjs +6 -6
  77. package/fesm2022/ngwr-dialog.mjs +15 -15
  78. package/fesm2022/ngwr-directives.mjs +15 -87
  79. package/fesm2022/ngwr-directives.mjs.map +1 -1
  80. package/fesm2022/ngwr-divider.mjs +3 -3
  81. package/fesm2022/ngwr-donut-chart.mjs +10 -4
  82. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  83. package/fesm2022/ngwr-drag-drop.mjs +6 -6
  84. package/fesm2022/ngwr-drawer.mjs +15 -15
  85. package/fesm2022/ngwr-dropdown.mjs +9 -9
  86. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  87. package/fesm2022/ngwr-empty.mjs +3 -3
  88. package/fesm2022/ngwr-falling-text.mjs +3 -3
  89. package/fesm2022/ngwr-file-upload.mjs +3 -3
  90. package/fesm2022/ngwr-form.mjs +9 -9
  91. package/fesm2022/ngwr-fuzzy-text.mjs +8 -7
  92. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  93. package/fesm2022/ngwr-gauge.mjs +3 -3
  94. package/fesm2022/ngwr-glitch-text.mjs +15 -7
  95. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  96. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  97. package/fesm2022/ngwr-hotkey.mjs +6 -6
  98. package/fesm2022/ngwr-i18n.mjs +9 -9
  99. package/fesm2022/ngwr-icon.mjs +3 -3
  100. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  101. package/fesm2022/ngwr-input-number.mjs +4 -4
  102. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  103. package/fesm2022/ngwr-input-otp.mjs +10 -4
  104. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  105. package/fesm2022/ngwr-input.mjs +25 -16
  106. package/fesm2022/ngwr-input.mjs.map +1 -1
  107. package/fesm2022/ngwr-keyboard.mjs +3 -3
  108. package/fesm2022/ngwr-knob.mjs +3 -3
  109. package/fesm2022/ngwr-layout.mjs +15 -15
  110. package/fesm2022/ngwr-lightbox.mjs +17 -5
  111. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  112. package/fesm2022/ngwr-line-chart.mjs +3 -3
  113. package/fesm2022/ngwr-list.mjs +7 -7
  114. package/fesm2022/ngwr-list.mjs.map +1 -1
  115. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  116. package/fesm2022/ngwr-marquee.mjs +3 -3
  117. package/fesm2022/ngwr-media.mjs +3 -3
  118. package/fesm2022/ngwr-mention.mjs +6 -6
  119. package/fesm2022/ngwr-meta.mjs +6 -6
  120. package/fesm2022/ngwr-meter-group.mjs +3 -3
  121. package/fesm2022/ngwr-overlay.mjs +3 -3
  122. package/fesm2022/ngwr-page-header.mjs +3 -3
  123. package/fesm2022/ngwr-pagination.mjs +5 -15
  124. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  125. package/fesm2022/ngwr-pipes.mjs +21 -21
  126. package/fesm2022/ngwr-platform.mjs +3 -3
  127. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  128. package/fesm2022/ngwr-popover.mjs +6 -6
  129. package/fesm2022/ngwr-progress.mjs +3 -3
  130. package/fesm2022/ngwr-qr.mjs +3 -3
  131. package/fesm2022/ngwr-radio.mjs +28 -26
  132. package/fesm2022/ngwr-radio.mjs.map +1 -1
  133. package/fesm2022/ngwr-rating.mjs +12 -23
  134. package/fesm2022/ngwr-rating.mjs.map +1 -1
  135. package/fesm2022/ngwr-result.mjs +12 -12
  136. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  137. package/fesm2022/ngwr-scroll.mjs +3 -3
  138. package/fesm2022/ngwr-segmented.mjs +10 -22
  139. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  140. package/fesm2022/ngwr-select.mjs +26 -13
  141. package/fesm2022/ngwr-select.mjs.map +1 -1
  142. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  143. package/fesm2022/ngwr-sidebar.mjs +3 -3
  144. package/fesm2022/ngwr-skeleton.mjs +3 -3
  145. package/fesm2022/ngwr-slider.mjs +3 -3
  146. package/fesm2022/ngwr-sparkline.mjs +3 -3
  147. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  148. package/fesm2022/ngwr-spinner.mjs +3 -3
  149. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  150. package/fesm2022/ngwr-split-text.mjs +3 -3
  151. package/fesm2022/ngwr-splitter.mjs +3 -3
  152. package/fesm2022/ngwr-spotlight-card.mjs +8 -8
  153. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  154. package/fesm2022/ngwr-squircle.mjs +6 -6
  155. package/fesm2022/ngwr-star-border.mjs +3 -3
  156. package/fesm2022/ngwr-statistic.mjs +79 -10
  157. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  158. package/fesm2022/ngwr-stepper.mjs +6 -6
  159. package/fesm2022/ngwr-storage.mjs +3 -3
  160. package/fesm2022/ngwr-switch.mjs +10 -14
  161. package/fesm2022/ngwr-switch.mjs.map +1 -1
  162. package/fesm2022/ngwr-table.mjs +12 -12
  163. package/fesm2022/ngwr-tabs.mjs +8 -6
  164. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  165. package/fesm2022/ngwr-textarea.mjs +84 -25
  166. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  167. package/fesm2022/ngwr-theme.mjs +3 -3
  168. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  169. package/fesm2022/ngwr-timeline.mjs +6 -6
  170. package/fesm2022/ngwr-toast.mjs +46 -24
  171. package/fesm2022/ngwr-toast.mjs.map +1 -1
  172. package/fesm2022/ngwr-toolbar.mjs +3 -3
  173. package/fesm2022/ngwr-tree.mjs +3 -3
  174. package/fesm2022/ngwr-typewriter.mjs +3 -3
  175. package/fesm2022/ngwr-typography.mjs +3 -3
  176. package/fesm2022/ngwr-validators.mjs +41 -3
  177. package/fesm2022/ngwr-validators.mjs.map +1 -1
  178. package/fesm2022/ngwr-version.mjs +1 -1
  179. package/fesm2022/ngwr-version.mjs.map +1 -1
  180. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  181. package/fesm2022/ngwr-waves.mjs +3 -3
  182. package/fesm2022/ngwr-window.mjs +12 -12
  183. package/file-upload/styles/_index.scss +3 -3
  184. package/form/styles/_index.scss +5 -5
  185. package/glitch-text/styles/_index.scss +3 -6
  186. package/image-cropper/styles/_index.scss +3 -3
  187. package/input/styles/_index.scss +26 -7
  188. package/input-otp/styles/_index.scss +23 -5
  189. package/keyboard/styles/_index.scss +6 -4
  190. package/knob/styles/_index.scss +1 -1
  191. package/lightbox/styles/_index.scss +29 -10
  192. package/list/styles/_index.scss +3 -3
  193. package/llms-full.txt +14 -19
  194. package/mention/styles/_index.scss +2 -2
  195. package/overlay/styles/_index.scss +1 -1
  196. package/package.json +1 -6
  197. package/pagination/styles/_index.scss +3 -26
  198. package/popconfirm/styles/_index.scss +1 -1
  199. package/popover/styles/_index.scss +2 -2
  200. package/radio/styles/_index.scss +20 -5
  201. package/rating/styles/_index.scss +12 -1
  202. package/schematics/migrations/v8/index.js +122 -0
  203. package/schematics/migrations.json +5 -0
  204. package/schematics/ng-add/index.js +3 -3
  205. package/schematics/ng-add/schema.json +6 -6
  206. package/schematics/provider/schema.json +1 -1
  207. package/schematics/use/symbol-map.json +11 -2
  208. package/segmented/styles/_index.scss +31 -8
  209. package/select/styles/_index.scss +73 -25
  210. package/sidebar/styles/_index.scss +3 -3
  211. package/slider/styles/_index.scss +2 -3
  212. package/speed-dial/styles/_index.scss +1 -0
  213. package/splitter/styles/_index.scss +4 -4
  214. package/spotlight-card/styles/_index.scss +8 -4
  215. package/stepper/styles/_index.scss +4 -4
  216. package/styles/_animations.scss +0 -23
  217. package/styles.scss +0 -1
  218. package/switch/styles/_index.scss +25 -6
  219. package/table/styles/_index.scss +9 -9
  220. package/tabs/styles/_index.scss +22 -3
  221. package/textarea/styles/_index.scss +59 -4
  222. package/theme/styles/_colors.scss +57 -0
  223. package/theme/styles/_dark.scss +22 -8
  224. package/theme/styles/_focus.scss +5 -0
  225. package/theme/styles/_variables.scss +24 -0
  226. package/timeline/styles/_index.scss +11 -2
  227. package/toast/styles/_index.scss +13 -5
  228. package/toolbar/styles/_index.scss +1 -1
  229. package/tree/styles/_index.scss +18 -17
  230. package/types/ngwr-alert.d.ts +16 -6
  231. package/types/ngwr-cascader.d.ts +5 -2
  232. package/types/ngwr-checkbox.d.ts +5 -2
  233. package/types/ngwr-click-spark.d.ts +13 -1
  234. package/types/ngwr-clipboard.d.ts +12 -1
  235. package/types/ngwr-context-menu.d.ts +20 -25
  236. package/types/ngwr-date-picker.d.ts +3 -0
  237. package/types/ngwr-density.d.ts +7 -7
  238. package/types/ngwr-directives.d.ts +17 -49
  239. package/types/ngwr-fuzzy-text.d.ts +1 -1
  240. package/types/ngwr-glitch-text.d.ts +9 -3
  241. package/types/ngwr-input-otp.d.ts +6 -2
  242. package/types/ngwr-input.d.ts +27 -13
  243. package/types/ngwr-lightbox.d.ts +9 -1
  244. package/types/ngwr-pagination.d.ts +3 -9
  245. package/types/ngwr-radio.d.ts +14 -3
  246. package/types/ngwr-rating.d.ts +5 -1
  247. package/types/ngwr-segmented.d.ts +5 -2
  248. package/types/ngwr-select.d.ts +6 -2
  249. package/types/ngwr-spotlight-card.d.ts +1 -1
  250. package/types/ngwr-statistic.d.ts +35 -1
  251. package/types/ngwr-switch.d.ts +5 -1
  252. package/types/ngwr-textarea.d.ts +25 -3
  253. package/types/ngwr-toast.d.ts +7 -1
  254. package/types/ngwr-validators.d.ts +3 -1
  255. package/types/ngwr-version.d.ts +1 -1
  256. package/window/styles/_index.scss +8 -8
  257. package/fesm2022/ngwr-scramble-text.mjs +0 -165
  258. package/fesm2022/ngwr-scramble-text.mjs.map +0 -1
  259. package/scramble-text/scramble-text.scss +0 -1
  260. package/scramble-text/styles/_index.scss +0 -8
  261. package/types/ngwr-scramble-text.d.ts +0 -49
@@ -4,15 +4,22 @@ import * as _angular_core from '@angular/core';
4
4
  * KPI card — label + big number + optional prefix/suffix + delta. Pair
5
5
  * with a layout grid for dashboards.
6
6
  *
7
+ * When `value` is numeric the number counts up (eased) from its previous
8
+ * value to the new one on every change — see `animate`. String values and
9
+ * `prefers-reduced-motion` render instantly.
10
+ *
7
11
  * @example
8
12
  * ```html
9
13
  * <wr-statistic label="Active users" [value]="12345" suffix="users" />
10
14
  * <wr-statistic label="Revenue" [value]="9512" prefix="$" [delta]="12.4" />
15
+ * <wr-statistic label="Churn" [value]="1.8" suffix="%" [precision]="1" />
11
16
  * ```
12
17
  *
13
18
  * @see https://ngwr.dev/components/statistic
14
19
  */
15
20
  declare class WrStatistic {
21
+ private readonly platform;
22
+ private readonly locale;
16
23
  readonly label: _angular_core.InputSignal<string>;
17
24
  /** The number (or string) to display in the main slot. */
18
25
  readonly value: _angular_core.InputSignal<string | number | null>;
@@ -20,6 +27,33 @@ declare class WrStatistic {
20
27
  readonly prefix: _angular_core.InputSignal<string>;
21
28
  /** Suffix glyph / unit (e.g. `'%'`, `'kg'`). */
22
29
  readonly suffix: _angular_core.InputSignal<string>;
30
+ /** Fixed number of decimals applied to numeric values. @default 0 */
31
+ readonly precision: _angular_core.InputSignalWithTransform<number, unknown>;
32
+ /**
33
+ * Count up to a new numeric `value` instead of swapping instantly. Always
34
+ * off for string values or under `prefers-reduced-motion`. @default true
35
+ */
36
+ readonly animate: _angular_core.InputSignalWithTransform<boolean, any>;
37
+ /** Count-up duration (ms). @default 700 */
38
+ readonly duration: _angular_core.InputSignalWithTransform<number, unknown>;
39
+ /**
40
+ * The current value coerced to a finite number, or `null` when `value` is
41
+ * a non-numeric string / empty / nullish (rendered as-is).
42
+ */
43
+ protected readonly numericValue: _angular_core.Signal<number | null>;
44
+ /** Whether the value should count up (browser, numeric, opted-in, motion allowed). */
45
+ protected readonly animated: _angular_core.Signal<boolean>;
46
+ /** Animation start — the previously-rendered numeric value (0 on first paint). */
47
+ protected readonly animateFrom: _angular_core.WritableSignal<number>;
48
+ /** Bookkeeping: the last numeric value seen, fed back as the next `from`. */
49
+ private readonly lastNumeric;
50
+ constructor();
51
+ /**
52
+ * Static (non-animated) display string. Numeric values honour `precision`
53
+ * and locale grouping so they match the count-up output; everything else
54
+ * renders verbatim with an em-dash fallback.
55
+ */
56
+ protected readonly displayValue: _angular_core.Signal<string>;
23
57
  /**
24
58
  * Optional delta vs previous period — shown as `+x.x%` (or `-x.x%`).
25
59
  * Use `deltaSuffix` to change the trailing unit.
@@ -31,7 +65,7 @@ declare class WrStatistic {
31
65
  protected readonly deltaDirection: _angular_core.Signal<"up" | "down" | "flat">;
32
66
  protected readonly deltaText: _angular_core.Signal<string>;
33
67
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrStatistic, never>;
34
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrStatistic, "wr-statistic", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "delta": { "alias": "delta"; "required": false; "isSignal": true; }; "deltaSuffix": { "alias": "deltaSuffix"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
68
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrStatistic, "wr-statistic", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "precision": { "alias": "precision"; "required": false; "isSignal": true; }; "animate": { "alias": "animate"; "required": false; "isSignal": true; }; "duration": { "alias": "duration"; "required": false; "isSignal": true; }; "delta": { "alias": "delta"; "required": false; "isSignal": true; }; "deltaSuffix": { "alias": "deltaSuffix"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
35
69
  }
36
70
 
37
71
  /**
@@ -11,6 +11,7 @@ import { ControlValueAccessor } from '@angular/forms';
11
11
  *
12
12
  * @see https://ngwr.dev/components/switch
13
13
  */
14
+ type WrSwitchSize = 'sm' | 'md' | 'lg';
14
15
  declare class WrSwitch implements ControlValueAccessor {
15
16
  /** Stable id used to associate the native input with its label. */
16
17
  readonly id: _angular_core.InputSignal<string>;
@@ -20,6 +21,8 @@ declare class WrSwitch implements ControlValueAccessor {
20
21
  * @default false
21
22
  */
22
23
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
24
+ /** Control size — shares the `--wr-control-*` contract. @default 'md' */
25
+ readonly size: _angular_core.InputSignal<WrSwitchSize>;
23
26
  protected readonly checked: _angular_core.WritableSignal<boolean>;
24
27
  private readonly disabledFromCva;
25
28
  protected readonly effectiveDisabled: _angular_core.Signal<boolean>;
@@ -33,7 +36,8 @@ declare class WrSwitch implements ControlValueAccessor {
33
36
  protected onInputChange(event: Event): void;
34
37
  protected onInputBlur(): void;
35
38
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrSwitch, never>;
36
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrSwitch, "wr-switch", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
39
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrSwitch, "wr-switch", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
37
40
  }
38
41
 
39
42
  export { WrSwitch };
43
+ export type { WrSwitchSize };
@@ -16,13 +16,19 @@ import { ControlValueAccessor } from '@angular/forms';
16
16
  *
17
17
  * @see https://ngwr.dev/components/textarea
18
18
  */
19
+ type WrTextareaSize = 'sm' | 'md' | 'lg';
20
+ type WrTextareaResize = 'none' | 'vertical' | 'horizontal' | 'both';
19
21
  declare class WrTextarea implements ControlValueAccessor {
20
22
  /** Native placeholder text. @default '' */
21
23
  readonly placeholder: _angular_core.InputSignal<string>;
24
+ /** Control size — shares the `--wr-control-*` contract. @default 'md' */
25
+ readonly size: _angular_core.InputSignal<WrTextareaSize>;
22
26
  /** Visible row count. @default 3 */
23
27
  readonly rows: _angular_core.InputSignalWithTransform<number, unknown>;
24
- /** Allow user resize via the native handle. @default true */
28
+ /** Allow user resize via the corner grip. @default true */
25
29
  readonly resizable: _angular_core.InputSignalWithTransform<boolean, any>;
30
+ /** Resize direction of the corner grip (the grip icon adapts). @default 'vertical' */
31
+ readonly resize: _angular_core.InputSignal<WrTextareaResize>;
26
32
  /** Read-only state. @default false */
27
33
  readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
28
34
  /** Grow the textarea to fit its content. @default false */
@@ -40,11 +46,23 @@ declare class WrTextarea implements ControlValueAccessor {
40
46
  protected readonly focused: _angular_core.WritableSignal<boolean>;
41
47
  protected readonly effectiveDisabled: _angular_core.Signal<boolean>;
42
48
  protected readonly native: _angular_core.Signal<ElementRef<HTMLTextAreaElement>>;
49
+ /** Resize direction, gated by `resizable` (false → 'none'). */
50
+ protected readonly effectiveResize: _angular_core.Signal<WrTextareaResize>;
43
51
  protected readonly classes: _angular_core.Signal<string>;
52
+ /** Show the corner grip (hidden when direction is 'none' / autosize / disabled). */
53
+ protected readonly showHandle: _angular_core.Signal<boolean>;
44
54
  private readonly platformId;
45
55
  private readonly isBrowser;
56
+ private readonly hostEl;
46
57
  private onChange;
47
58
  private onTouched;
59
+ private resizing;
60
+ private resizeStartY;
61
+ private resizeStartX;
62
+ private resizeStartHeight;
63
+ private resizeStartWidth;
64
+ private resizeMinHeight;
65
+ private resizeMaxWidth;
48
66
  constructor();
49
67
  writeValue(value: string | null): void;
50
68
  registerOnChange(fn: (value: string) => void): void;
@@ -52,9 +70,13 @@ declare class WrTextarea implements ControlValueAccessor {
52
70
  setDisabledState(isDisabled: boolean): void;
53
71
  protected onInput(event: Event): void;
54
72
  protected onBlur(): void;
55
- private resize;
73
+ protected startResize(event: PointerEvent): void;
74
+ protected onResize(event: PointerEvent): void;
75
+ protected endResize(event: PointerEvent): void;
76
+ private autofit;
56
77
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrTextarea, never>;
57
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrTextarea, "wr-textarea", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "autosize": { "alias": "autosize"; "required": false; "isSignal": true; }; "maxRows": { "alias": "maxRows"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
78
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrTextarea, "wr-textarea", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; "resize": { "alias": "resize"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "autosize": { "alias": "autosize"; "required": false; "isSignal": true; }; "maxRows": { "alias": "maxRows"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
58
79
  }
59
80
 
60
81
  export { WrTextarea };
82
+ export type { WrTextareaResize, WrTextareaSize };
@@ -147,7 +147,11 @@ declare class WrToast {
147
147
  private currentPosition;
148
148
  private currentMode;
149
149
  private nextId;
150
+ /** Currently rendered toasts (capped at `config.maxStack`). */
150
151
  private active;
152
+ /** Overflow waiting for a free slot — promoted FIFO as actives dismiss, so
153
+ * nothing is ever silently dropped. */
154
+ private queue;
151
155
  /** Open a toast. Returns a handle you can `dismiss()` early. */
152
156
  show(options: WrToastOptions): WrToastRef;
153
157
  /** Dismiss a single toast by id. */
@@ -161,7 +165,9 @@ declare class WrToast {
161
165
  private startTimer;
162
166
  private pauseTimer;
163
167
  private ensureHost;
164
- private enforceMaxStack;
168
+ /** Fill any free stack slots from the queue (FIFO), starting each promoted
169
+ * toast's auto-dismiss timer only as it becomes visible. */
170
+ private promoteFromQueue;
165
171
  private pushToHost;
166
172
  private disposeHost;
167
173
  static ɵfac: i0.ɵɵFactoryDeclaration<WrToast, never>;
@@ -39,10 +39,12 @@ declare const WrValidators: {
39
39
  hexColor: (control: AbstractControl) => ValidationErrors | null;
40
40
  /**
41
41
  * Valid URL. Accepts any scheme by default; pass `{ protocols: ['https'] }`
42
- * to restrict.
42
+ * to restrict. A scheme is required by default; pass `{ requireProtocol: false }`
43
+ * to also accept bare domains (e.g. `ngwr.dev`), assuming `https`.
43
44
  */
44
45
  url: (options?: {
45
46
  readonly protocols?: readonly string[];
47
+ readonly requireProtocol?: boolean;
46
48
  }) => ValidatorFn;
47
49
  /** Credit card number — Luhn check + 13-19 digit length. Spaces and dashes are stripped first. */
48
50
  cardNumber: (control: AbstractControl) => ValidationErrors | null;
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
16
16
  * Distinct from `Version` exported by `@angular/core`, which reports the
17
17
  * loaded Angular runtime version (e.g. `'21.2.13'`), not ngwr's.
18
18
  */
19
- declare const NGWR_VERSION = "7.3.0";
19
+ declare const NGWR_VERSION = "8.0.0";
20
20
 
21
21
  /**
22
22
  * @license
@@ -3,12 +3,12 @@
3
3
  .wr-window {
4
4
  --wr-window-bg: var(--wr-color-white);
5
5
  --wr-window-border: var(--wr-color-light);
6
- --wr-window-chrome-bg: rgba(var(--wr-color-light-rgb), 0.4);
6
+ --wr-window-chrome-bg: var(--wr-color-hover);
7
7
  --wr-window-chrome-color: var(--wr-color-dark);
8
8
  --wr-window-radius: var(--wr-border-radius-base);
9
9
  --wr-window-handle-size: 8px;
10
10
  --wr-window-chrome-height: 2.25rem;
11
- --wr-window-title-size: 0.8125rem;
11
+ --wr-window-title-size: var(--wr-text-sm);
12
12
  --wr-window-action-size: 1.5rem;
13
13
  --wr-window-anim-duration: 0.18s;
14
14
 
@@ -45,7 +45,7 @@
45
45
  // pixel of vertical space matters.
46
46
  &--chrome-compact {
47
47
  --wr-window-chrome-height: 1.625rem;
48
- --wr-window-title-size: 0.75rem;
48
+ --wr-window-title-size: var(--wr-text-xs);
49
49
  --wr-window-action-size: 1.125rem;
50
50
  }
51
51
 
@@ -94,7 +94,7 @@
94
94
  align-items: center;
95
95
  gap: 0.375rem;
96
96
  padding-right: 0.375rem;
97
- font-size: 0.75rem;
97
+ font-size: var(--wr-text-xs);
98
98
 
99
99
  &:empty {
100
100
  display: none;
@@ -157,7 +157,7 @@
157
157
  width: 0.875rem; // 14px — bigger than the prior 12px to match native
158
158
  height: 0.875rem;
159
159
  border-radius: 50%;
160
- color: rgba(0, 0, 0, 0.55); // glyph color (revealed on hover)
160
+ color: rgba(var(--wr-color-black-rgb), 0.55); // glyph color (revealed on hover)
161
161
 
162
162
  &--close,
163
163
  &--close:hover {
@@ -223,7 +223,7 @@
223
223
  padding: 0.25rem 0.75rem;
224
224
  border-top: 1px solid var(--wr-window-border);
225
225
  background: rgba(var(--wr-color-light-rgb), 0.25);
226
- font-size: 0.75rem;
226
+ font-size: var(--wr-text-xs);
227
227
  color: var(--wr-color-medium);
228
228
 
229
229
  &:empty {
@@ -374,7 +374,7 @@
374
374
  border-radius: var(--wr-border-radius-sm);
375
375
  color: var(--wr-color-dark);
376
376
  font-family: inherit;
377
- font-size: 0.8125rem;
377
+ font-size: var(--wr-text-sm);
378
378
  line-height: 1.25rem;
379
379
  cursor: pointer;
380
380
  max-width: 12rem;
@@ -387,7 +387,7 @@
387
387
  }
388
388
 
389
389
  &:focus-visible {
390
- outline: 2px solid var(--wr-color-primary);
390
+ @include theme.focus-ring;
391
391
  outline-offset: 2px;
392
392
  }
393
393
  }
@@ -1,165 +0,0 @@
1
- import { isPlatformBrowser } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { input, inject, ElementRef, DestroyRef, PLATFORM_ID, afterNextRender, ViewEncapsulation, Component } from '@angular/core';
4
- import { WrPlatform } from 'ngwr/platform';
5
- import { numAttr } from 'ngwr/utils';
6
-
7
- /**
8
- * @license
9
- *
10
- * Use of this source code is governed by an MIT-style license that can be
11
- * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
12
- *
13
- * Angular adaptation of the ScrambledText effect by David Haz / reactbits.dev.
14
- * Original: https://www.reactbits.dev/text-animations/scrambled-text
15
- *
16
- * The reactbits version uses GSAP's paid SplitText + ScrambleTextPlugin.
17
- * This port is dependency-free — splits via vanilla DOM, scrambles via a
18
- * per-char `setInterval` loop, restores on settle.
19
- */
20
- function pickRandom(pool, exclude) {
21
- if (pool.length === 0)
22
- return exclude;
23
- if (pool.length === 1)
24
- return pool;
25
- // Avoid landing on the original mid-scramble — looks like nothing happened.
26
- let pick = pool.charAt(Math.floor(Math.random() * pool.length));
27
- for (let tries = 0; tries < 3 && pick === exclude; tries++) {
28
- pick = pool.charAt(Math.floor(Math.random() * pool.length));
29
- }
30
- return pick;
31
- }
32
- /**
33
- * Cursor-proximity scrambler. Each character inside the projected text
34
- * scrambles through `scrambleChars` whenever the pointer moves within
35
- * `radius` px of it, then settles back to the original. Closer pointer →
36
- * longer scramble.
37
- *
38
- * @example
39
- * ```html
40
- * <wr-scramble-text
41
- * [radius]="120"
42
- * [duration]="1.4"
43
- * scrambleChars="!&%*"
44
- * >
45
- * Hover this paragraph to scramble characters near the cursor.
46
- * </wr-scramble-text>
47
- * ```
48
- *
49
- * @see https://www.reactbits.dev/text-animations/scrambled-text
50
- */
51
- class WrScrambleText {
52
- /** Proximity radius in pixels. @default 100 */
53
- radius = input(100, { ...(ngDevMode ? { debugName: "radius" } : /* istanbul ignore next */ {}), transform: numAttr(100) });
54
- /** Max scramble duration in seconds (scaled by proximity — closer = longer). @default 1.2 */
55
- duration = input(1.2, { ...(ngDevMode ? { debugName: "duration" } : /* istanbul ignore next */ {}), transform: numAttr(1.2) });
56
- /** Approximate seconds between random-char swaps. Lower = faster scramble. @default 0.05 */
57
- speed = input(0.05, { ...(ngDevMode ? { debugName: "speed" } : /* istanbul ignore next */ {}), transform: numAttr(0.05) });
58
- /** Pool of glyphs to scramble through. @default '.:' */
59
- scrambleChars = input('.:', /* @ts-ignore */
60
- ...(ngDevMode ? [{ debugName: "scrambleChars" }] : /* istanbul ignore next */ []));
61
- host = inject(ElementRef);
62
- destroyRef = inject(DestroyRef);
63
- isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
64
- platform = inject(WrPlatform);
65
- /** One entry per active scramble, keyed by char span. */
66
- active = new Map();
67
- /** Cached list of char spans. Re-computed after each render. */
68
- chars = [];
69
- constructor() {
70
- if (!this.isBrowser)
71
- return;
72
- afterNextRender(() => this.split());
73
- this.destroyRef.onDestroy(() => this.clearAll());
74
- }
75
- onPointerMove(event) {
76
- if (this.chars.length === 0)
77
- return;
78
- // Reduced motion: pointer proximity stops scrambling — text stays put.
79
- if (this.platform.prefersReducedMotion())
80
- return;
81
- const radius = this.radius();
82
- const duration = this.duration() * 1000;
83
- const swapInterval = Math.max(16, this.speed() * 1000);
84
- const pool = this.scrambleChars();
85
- for (const charEl of this.chars) {
86
- const rect = charEl.getBoundingClientRect();
87
- const dx = event.clientX - (rect.left + rect.width / 2);
88
- const dy = event.clientY - (rect.top + rect.height / 2);
89
- const dist = Math.hypot(dx, dy);
90
- if (dist > radius)
91
- continue;
92
- // Cancel any in-flight scramble for this char — we're restarting.
93
- this.cancelOne(charEl);
94
- // Proximity factor: 0 at the edge, 1 at the centre.
95
- const proximity = 1 - dist / radius;
96
- const scrambleMs = duration * proximity;
97
- const original = charEl.dataset['scrambleOriginal'] ?? '';
98
- const swapId = setInterval(() => {
99
- charEl.textContent = pickRandom(pool, original);
100
- }, swapInterval);
101
- const settleId = setTimeout(() => {
102
- clearInterval(swapId);
103
- charEl.textContent = original;
104
- this.active.delete(charEl);
105
- }, scrambleMs);
106
- this.active.set(charEl, { swapId, settleId });
107
- }
108
- }
109
- /** Walk the projected text and wrap each non-whitespace character in a span. */
110
- split() {
111
- const inner = this.host.nativeElement.querySelector('.wr-scramble-text__inner');
112
- if (!inner)
113
- return;
114
- const raw = inner.textContent ?? '';
115
- if (!raw)
116
- return;
117
- const frag = document.createDocumentFragment();
118
- for (const ch of [...raw]) {
119
- if (/\s/.test(ch)) {
120
- frag.appendChild(document.createTextNode(ch));
121
- }
122
- else {
123
- const span = document.createElement('span');
124
- span.className = 'wr-scramble-text__char';
125
- span.textContent = ch;
126
- span.dataset['scrambleOriginal'] = ch;
127
- frag.appendChild(span);
128
- }
129
- }
130
- inner.replaceChildren(frag);
131
- this.chars = Array.from(inner.querySelectorAll('.wr-scramble-text__char'));
132
- }
133
- cancelOne(el) {
134
- const entry = this.active.get(el);
135
- if (!entry)
136
- return;
137
- clearInterval(entry.swapId);
138
- clearTimeout(entry.settleId);
139
- this.active.delete(el);
140
- }
141
- clearAll() {
142
- for (const [el, entry] of this.active) {
143
- clearInterval(entry.swapId);
144
- clearTimeout(entry.settleId);
145
- el.textContent = el.dataset['scrambleOriginal'] ?? '';
146
- }
147
- this.active.clear();
148
- }
149
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrScrambleText, deps: [], target: i0.ɵɵFactoryTarget.Component });
150
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.2", type: WrScrambleText, isStandalone: true, selector: "wr-scramble-text", inputs: { radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, speed: { classPropertyName: "speed", publicName: "speed", isSignal: true, isRequired: false, transformFunction: null }, scrambleChars: { classPropertyName: "scrambleChars", publicName: "scrambleChars", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointermove": "onPointerMove($event)" }, classAttribute: "wr-scramble-text" }, ngImport: i0, template: '<span class="wr-scramble-text__inner" #inner><ng-content /></span>', isInline: true, styles: [".wr-scramble-text{display:block}.wr-scramble-text__char{display:inline-block;will-change:contents}\n"], encapsulation: i0.ViewEncapsulation.None });
151
- }
152
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrScrambleText, decorators: [{
153
- type: Component,
154
- args: [{ selector: 'wr-scramble-text', template: '<span class="wr-scramble-text__inner" #inner><ng-content /></span>', encapsulation: ViewEncapsulation.None, host: {
155
- class: 'wr-scramble-text',
156
- '(pointermove)': 'onPointerMove($event)',
157
- }, styles: [".wr-scramble-text{display:block}.wr-scramble-text__char{display:inline-block;will-change:contents}\n"] }]
158
- }], ctorParameters: () => [], propDecorators: { radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], speed: [{ type: i0.Input, args: [{ isSignal: true, alias: "speed", required: false }] }], scrambleChars: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrambleChars", required: false }] }] } });
159
-
160
- /**
161
- * Generated bundle index. Do not edit.
162
- */
163
-
164
- export { WrScrambleText };
165
- //# sourceMappingURL=ngwr-scramble-text.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ngwr-scramble-text.mjs","sources":["../../../projects/lib/scramble-text/scramble-text.ts","../../../projects/lib/scramble-text/ngwr-scramble-text.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 * Angular adaptation of the ScrambledText effect by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/text-animations/scrambled-text\n *\n * The reactbits version uses GSAP's paid SplitText + ScrambleTextPlugin.\n * This port is dependency-free — splits via vanilla DOM, scrambles via a\n * per-char `setInterval` loop, restores on settle.\n */\n\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n inject,\n input,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\ninterface ActiveScramble {\n swapId: ReturnType<typeof setInterval>;\n settleId: ReturnType<typeof setTimeout>;\n}\n\nfunction pickRandom(pool: string, exclude: string): string {\n if (pool.length === 0) return exclude;\n if (pool.length === 1) return pool;\n // Avoid landing on the original mid-scramble — looks like nothing happened.\n let pick = pool.charAt(Math.floor(Math.random() * pool.length));\n for (let tries = 0; tries < 3 && pick === exclude; tries++) {\n pick = pool.charAt(Math.floor(Math.random() * pool.length));\n }\n return pick;\n}\n\n/**\n * Cursor-proximity scrambler. Each character inside the projected text\n * scrambles through `scrambleChars` whenever the pointer moves within\n * `radius` px of it, then settles back to the original. Closer pointer →\n * longer scramble.\n *\n * @example\n * ```html\n * <wr-scramble-text\n * [radius]=\"120\"\n * [duration]=\"1.4\"\n * scrambleChars=\"!&%*\"\n * >\n * Hover this paragraph to scramble characters near the cursor.\n * </wr-scramble-text>\n * ```\n *\n * @see https://www.reactbits.dev/text-animations/scrambled-text\n */\n@Component({\n selector: 'wr-scramble-text',\n template: '<span class=\"wr-scramble-text__inner\" #inner><ng-content /></span>',\n styleUrl: './scramble-text.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-scramble-text',\n '(pointermove)': 'onPointerMove($event)',\n },\n})\nexport class WrScrambleText {\n /** Proximity radius in pixels. @default 100 */\n readonly radius = input(100, { transform: numAttr(100) });\n\n /** Max scramble duration in seconds (scaled by proximity — closer = longer). @default 1.2 */\n readonly duration = input(1.2, { transform: numAttr(1.2) });\n\n /** Approximate seconds between random-char swaps. Lower = faster scramble. @default 0.05 */\n readonly speed = input(0.05, { transform: numAttr(0.05) });\n\n /** Pool of glyphs to scramble through. @default '.:' */\n readonly scrambleChars = input('.:');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly platform = inject(WrPlatform);\n\n /** One entry per active scramble, keyed by char span. */\n private readonly active = new Map<HTMLElement, ActiveScramble>();\n\n /** Cached list of char spans. Re-computed after each render. */\n private chars: readonly HTMLElement[] = [];\n\n constructor() {\n if (!this.isBrowser) return;\n afterNextRender(() => this.split());\n this.destroyRef.onDestroy(() => this.clearAll());\n }\n\n protected onPointerMove(event: PointerEvent): void {\n if (this.chars.length === 0) return;\n // Reduced motion: pointer proximity stops scrambling — text stays put.\n if (this.platform.prefersReducedMotion()) return;\n const radius = this.radius();\n const duration = this.duration() * 1000;\n const swapInterval = Math.max(16, this.speed() * 1000);\n const pool = this.scrambleChars();\n\n for (const charEl of this.chars) {\n const rect = charEl.getBoundingClientRect();\n const dx = event.clientX - (rect.left + rect.width / 2);\n const dy = event.clientY - (rect.top + rect.height / 2);\n const dist = Math.hypot(dx, dy);\n if (dist > radius) continue;\n\n // Cancel any in-flight scramble for this char — we're restarting.\n this.cancelOne(charEl);\n\n // Proximity factor: 0 at the edge, 1 at the centre.\n const proximity = 1 - dist / radius;\n const scrambleMs = duration * proximity;\n const original = charEl.dataset['scrambleOriginal'] ?? '';\n\n const swapId = setInterval(() => {\n charEl.textContent = pickRandom(pool, original);\n }, swapInterval);\n\n const settleId = setTimeout(() => {\n clearInterval(swapId);\n charEl.textContent = original;\n this.active.delete(charEl);\n }, scrambleMs);\n\n this.active.set(charEl, { swapId, settleId });\n }\n }\n\n /** Walk the projected text and wrap each non-whitespace character in a span. */\n private split(): void {\n const inner = this.host.nativeElement.querySelector<HTMLElement>('.wr-scramble-text__inner');\n if (!inner) return;\n const raw = inner.textContent ?? '';\n if (!raw) return;\n\n const frag = document.createDocumentFragment();\n for (const ch of [...raw]) {\n if (/\\s/.test(ch)) {\n frag.appendChild(document.createTextNode(ch));\n } else {\n const span = document.createElement('span');\n span.className = 'wr-scramble-text__char';\n span.textContent = ch;\n span.dataset['scrambleOriginal'] = ch;\n frag.appendChild(span);\n }\n }\n inner.replaceChildren(frag);\n this.chars = Array.from(inner.querySelectorAll<HTMLElement>('.wr-scramble-text__char'));\n }\n\n private cancelOne(el: HTMLElement): void {\n const entry = this.active.get(el);\n if (!entry) return;\n clearInterval(entry.swapId);\n clearTimeout(entry.settleId);\n this.active.delete(el);\n }\n\n private clearAll(): void {\n for (const [el, entry] of this.active) {\n clearInterval(entry.swapId);\n clearTimeout(entry.settleId);\n el.textContent = el.dataset['scrambleOriginal'] ?? '';\n }\n this.active.clear();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- @forward './styles';
@@ -1,8 +0,0 @@
1
- .wr-scramble-text {
2
- display: block;
3
-
4
- &__char {
5
- display: inline-block;
6
- will-change: contents;
7
- }
8
- }
@@ -1,49 +0,0 @@
1
- import * as _angular_core from '@angular/core';
2
-
3
- /**
4
- * Cursor-proximity scrambler. Each character inside the projected text
5
- * scrambles through `scrambleChars` whenever the pointer moves within
6
- * `radius` px of it, then settles back to the original. Closer pointer →
7
- * longer scramble.
8
- *
9
- * @example
10
- * ```html
11
- * <wr-scramble-text
12
- * [radius]="120"
13
- * [duration]="1.4"
14
- * scrambleChars="!&%*"
15
- * >
16
- * Hover this paragraph to scramble characters near the cursor.
17
- * </wr-scramble-text>
18
- * ```
19
- *
20
- * @see https://www.reactbits.dev/text-animations/scrambled-text
21
- */
22
- declare class WrScrambleText {
23
- /** Proximity radius in pixels. @default 100 */
24
- readonly radius: _angular_core.InputSignalWithTransform<number, unknown>;
25
- /** Max scramble duration in seconds (scaled by proximity — closer = longer). @default 1.2 */
26
- readonly duration: _angular_core.InputSignalWithTransform<number, unknown>;
27
- /** Approximate seconds between random-char swaps. Lower = faster scramble. @default 0.05 */
28
- readonly speed: _angular_core.InputSignalWithTransform<number, unknown>;
29
- /** Pool of glyphs to scramble through. @default '.:' */
30
- readonly scrambleChars: _angular_core.InputSignal<string>;
31
- private readonly host;
32
- private readonly destroyRef;
33
- private readonly isBrowser;
34
- private readonly platform;
35
- /** One entry per active scramble, keyed by char span. */
36
- private readonly active;
37
- /** Cached list of char spans. Re-computed after each render. */
38
- private chars;
39
- constructor();
40
- protected onPointerMove(event: PointerEvent): void;
41
- /** Walk the projected text and wrap each non-whitespace character in a span. */
42
- private split;
43
- private cancelOne;
44
- private clearAll;
45
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrScrambleText, never>;
46
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrScrambleText, "wr-scramble-text", never, { "radius": { "alias": "radius"; "required": false; "isSignal": true; }; "duration": { "alias": "duration"; "required": false; "isSignal": true; }; "speed": { "alias": "speed"; "required": false; "isSignal": true; }; "scrambleChars": { "alias": "scrambleChars"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
47
- }
48
-
49
- export { WrScrambleText };