ngwr 11.1.0 → 11.2.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 (205) hide show
  1. package/circular-text/styles/_index.scss +11 -0
  2. package/command-palette/styles/_index.scss +12 -0
  3. package/fesm2022/ngwr-action-sheet-testing.mjs +313 -0
  4. package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -0
  5. package/fesm2022/ngwr-bar-chart-testing.mjs +89 -0
  6. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -0
  7. package/fesm2022/ngwr-blur-text-testing.mjs +203 -0
  8. package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -0
  9. package/fesm2022/ngwr-blur-text.mjs +15 -1
  10. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  11. package/fesm2022/ngwr-border-glow-testing.mjs +325 -0
  12. package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -0
  13. package/fesm2022/ngwr-calendar-heatmap-testing.mjs +95 -0
  14. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -0
  15. package/fesm2022/ngwr-calendar-testing.mjs +368 -0
  16. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -0
  17. package/fesm2022/ngwr-calendar.mjs +43 -3
  18. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  19. package/fesm2022/ngwr-cascader.mjs +12 -0
  20. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  21. package/fesm2022/ngwr-checkbox.mjs +8 -0
  22. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  23. package/fesm2022/ngwr-circular-text-testing.mjs +230 -0
  24. package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -0
  25. package/fesm2022/ngwr-circular-text.mjs +2 -2
  26. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  27. package/fesm2022/ngwr-color-picker-testing.mjs +432 -0
  28. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -0
  29. package/fesm2022/ngwr-color-picker.mjs +29 -3
  30. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  31. package/fesm2022/ngwr-context-menu.mjs +25 -5
  32. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  33. package/fesm2022/ngwr-date-picker-testing.mjs +10 -79
  34. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  35. package/fesm2022/ngwr-decrypt-text-testing.mjs +261 -0
  36. package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -0
  37. package/fesm2022/ngwr-decrypt-text.mjs +6 -1
  38. package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
  39. package/fesm2022/ngwr-donut-chart-testing.mjs +93 -0
  40. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -0
  41. package/fesm2022/ngwr-drawer.mjs +36 -7
  42. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  43. package/fesm2022/ngwr-dropdown.mjs +32 -2
  44. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  45. package/fesm2022/ngwr-event-calendar-testing.mjs +446 -0
  46. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -0
  47. package/fesm2022/ngwr-event-calendar.mjs +43 -18
  48. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  49. package/fesm2022/ngwr-falling-text-testing.mjs +218 -0
  50. package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -0
  51. package/fesm2022/ngwr-fuzzy-text-testing.mjs +134 -0
  52. package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -0
  53. package/fesm2022/ngwr-gauge-testing.mjs +86 -0
  54. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -0
  55. package/fesm2022/ngwr-glitch-text-testing.mjs +181 -0
  56. package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -0
  57. package/fesm2022/ngwr-gradient-text-testing.mjs +223 -0
  58. package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -0
  59. package/fesm2022/ngwr-i18n-en.mjs +14 -0
  60. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  61. package/fesm2022/ngwr-i18n-ru.mjs +14 -0
  62. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  63. package/fesm2022/ngwr-image-cropper-testing.mjs +156 -0
  64. package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -0
  65. package/fesm2022/ngwr-image-cropper.mjs +10 -3
  66. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  67. package/fesm2022/ngwr-input-number.mjs +73 -6
  68. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  69. package/fesm2022/ngwr-knob-testing.mjs +220 -0
  70. package/fesm2022/ngwr-knob-testing.mjs.map +1 -0
  71. package/fesm2022/ngwr-lightbox-testing.mjs +223 -0
  72. package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -0
  73. package/fesm2022/ngwr-lightbox.mjs +9 -2
  74. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  75. package/fesm2022/ngwr-line-chart-testing.mjs +119 -0
  76. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -0
  77. package/fesm2022/ngwr-marquee-testing.mjs +336 -0
  78. package/fesm2022/ngwr-marquee-testing.mjs.map +1 -0
  79. package/fesm2022/ngwr-meter-group-testing.mjs +80 -0
  80. package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -0
  81. package/fesm2022/ngwr-overlay.mjs +28 -1
  82. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  83. package/fesm2022/ngwr-popover.mjs +14 -0
  84. package/fesm2022/ngwr-popover.mjs.map +1 -1
  85. package/fesm2022/ngwr-rotating-text-testing.mjs +220 -0
  86. package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -0
  87. package/fesm2022/ngwr-rotating-text.mjs +2 -2
  88. package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
  89. package/fesm2022/ngwr-select.mjs +70 -11
  90. package/fesm2022/ngwr-select.mjs.map +1 -1
  91. package/fesm2022/ngwr-shiny-text-testing.mjs +237 -0
  92. package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -0
  93. package/fesm2022/ngwr-slider.mjs +44 -6
  94. package/fesm2022/ngwr-slider.mjs.map +1 -1
  95. package/fesm2022/ngwr-sparkline-testing.mjs +76 -0
  96. package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -0
  97. package/fesm2022/ngwr-speed-dial-testing.mjs +279 -0
  98. package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -0
  99. package/fesm2022/ngwr-splash-cursor-testing.mjs +89 -0
  100. package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -0
  101. package/fesm2022/ngwr-split-text-testing.mjs +224 -0
  102. package/fesm2022/ngwr-split-text-testing.mjs.map +1 -0
  103. package/fesm2022/ngwr-split-text.mjs +15 -1
  104. package/fesm2022/ngwr-split-text.mjs.map +1 -1
  105. package/fesm2022/ngwr-splitter-testing.mjs +245 -0
  106. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -0
  107. package/fesm2022/ngwr-spotlight-card-testing.mjs +368 -0
  108. package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -0
  109. package/fesm2022/ngwr-star-border-testing.mjs +172 -0
  110. package/fesm2022/ngwr-star-border-testing.mjs.map +1 -0
  111. package/fesm2022/ngwr-table.mjs +13 -3
  112. package/fesm2022/ngwr-table.mjs.map +1 -1
  113. package/fesm2022/ngwr-tabs.mjs +15 -1
  114. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  115. package/fesm2022/ngwr-tilt-card-testing.mjs +190 -0
  116. package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -0
  117. package/fesm2022/ngwr-tilt-card.mjs +19 -1
  118. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  119. package/fesm2022/ngwr-toast.mjs +36 -7
  120. package/fesm2022/ngwr-toast.mjs.map +1 -1
  121. package/fesm2022/ngwr-tour-testing.mjs +173 -0
  122. package/fesm2022/ngwr-tour-testing.mjs.map +1 -0
  123. package/fesm2022/ngwr-tour.mjs +2 -2
  124. package/fesm2022/ngwr-tour.mjs.map +1 -1
  125. package/fesm2022/ngwr-tree.mjs +10 -3
  126. package/fesm2022/ngwr-tree.mjs.map +1 -1
  127. package/fesm2022/ngwr-typewriter-testing.mjs +228 -0
  128. package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -0
  129. package/fesm2022/ngwr-version.mjs +1 -1
  130. package/fesm2022/ngwr-version.mjs.map +1 -1
  131. package/fesm2022/ngwr-waves-testing.mjs +128 -0
  132. package/fesm2022/ngwr-waves-testing.mjs.map +1 -0
  133. package/fesm2022/ngwr-window-testing.mjs +361 -0
  134. package/fesm2022/ngwr-window-testing.mjs.map +1 -0
  135. package/fesm2022/ngwr-window.mjs +84 -10
  136. package/fesm2022/ngwr-window.mjs.map +1 -1
  137. package/i18n/en.json +16 -2
  138. package/i18n/ru.json +16 -2
  139. package/llms-full.txt +147 -0
  140. package/llms.txt +27 -8
  141. package/mcp/providers.js +29 -0
  142. package/mcp/tools.js +1 -29
  143. package/package.json +145 -1
  144. package/skills/ngwr/SKILL.md +115 -0
  145. package/skills/ngwr/references/catalog.md +212 -0
  146. package/skills/ngwr/references/setup.md +73 -0
  147. package/types/ngwr-action-sheet-testing.d.ts +260 -0
  148. package/types/ngwr-bar-chart-testing.d.ts +77 -0
  149. package/types/ngwr-blur-text-testing.d.ts +180 -0
  150. package/types/ngwr-blur-text.d.ts +12 -0
  151. package/types/ngwr-border-glow-testing.d.ts +219 -0
  152. package/types/ngwr-calendar-heatmap-testing.d.ts +79 -0
  153. package/types/ngwr-calendar-testing.d.ts +277 -0
  154. package/types/ngwr-calendar.d.ts +10 -0
  155. package/types/ngwr-checkbox.d.ts +13 -0
  156. package/types/ngwr-circular-text-testing.d.ts +196 -0
  157. package/types/ngwr-color-picker-testing.d.ts +291 -0
  158. package/types/ngwr-color-picker.d.ts +13 -1
  159. package/types/ngwr-context-menu.d.ts +15 -1
  160. package/types/ngwr-date-picker-testing.d.ts +6 -66
  161. package/types/ngwr-decrypt-text-testing.d.ts +222 -0
  162. package/types/ngwr-donut-chart-testing.d.ts +79 -0
  163. package/types/ngwr-drawer.d.ts +12 -0
  164. package/types/ngwr-dropdown.d.ts +9 -0
  165. package/types/ngwr-event-calendar-testing.d.ts +301 -0
  166. package/types/ngwr-event-calendar.d.ts +9 -6
  167. package/types/ngwr-falling-text-testing.d.ts +186 -0
  168. package/types/ngwr-fuzzy-text-testing.d.ts +130 -0
  169. package/types/ngwr-gauge-testing.d.ts +71 -0
  170. package/types/ngwr-glitch-text-testing.d.ts +172 -0
  171. package/types/ngwr-gradient-text-testing.d.ts +173 -0
  172. package/types/ngwr-image-cropper-testing.d.ts +134 -0
  173. package/types/ngwr-image-cropper.d.ts +1 -0
  174. package/types/ngwr-input-number.d.ts +33 -1
  175. package/types/ngwr-knob-testing.d.ts +150 -0
  176. package/types/ngwr-lightbox-testing.d.ts +154 -0
  177. package/types/ngwr-lightbox.d.ts +6 -0
  178. package/types/ngwr-line-chart-testing.d.ts +93 -0
  179. package/types/ngwr-marquee-testing.d.ts +280 -0
  180. package/types/ngwr-meter-group-testing.d.ts +67 -0
  181. package/types/ngwr-overlay.d.ts +19 -1
  182. package/types/ngwr-rotating-text-testing.d.ts +191 -0
  183. package/types/ngwr-select.d.ts +32 -0
  184. package/types/ngwr-shiny-text-testing.d.ts +165 -0
  185. package/types/ngwr-slider.d.ts +15 -0
  186. package/types/ngwr-sparkline-testing.d.ts +69 -0
  187. package/types/ngwr-speed-dial-testing.d.ts +195 -0
  188. package/types/ngwr-splash-cursor-testing.d.ts +95 -0
  189. package/types/ngwr-split-text-testing.d.ts +209 -0
  190. package/types/ngwr-split-text.d.ts +12 -0
  191. package/types/ngwr-splitter-testing.d.ts +174 -0
  192. package/types/ngwr-spotlight-card-testing.d.ts +303 -0
  193. package/types/ngwr-star-border-testing.d.ts +135 -0
  194. package/types/ngwr-table.d.ts +10 -1
  195. package/types/ngwr-tilt-card-testing.d.ts +158 -0
  196. package/types/ngwr-tilt-card.d.ts +2 -0
  197. package/types/ngwr-toast.d.ts +14 -5
  198. package/types/ngwr-tour-testing.d.ts +143 -0
  199. package/types/ngwr-tree.d.ts +7 -0
  200. package/types/ngwr-typewriter-testing.d.ts +201 -0
  201. package/types/ngwr-version.d.ts +1 -1
  202. package/types/ngwr-waves-testing.d.ts +121 -0
  203. package/types/ngwr-window-testing.d.ts +263 -0
  204. package/types/ngwr-window.d.ts +27 -10
  205. package/window/styles/_index.scss +44 -16
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-decrypt-text.mjs","sources":["../../../projects/lib/decrypt-text/decrypt-text.ts","../../../projects/lib/decrypt-text/decrypt-text.html","../../../projects/lib/decrypt-text/ngwr-decrypt-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 DecryptedText effect by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/text-animations/decrypted-text\n *\n * The reactbits version uses `motion/react` for the wrapper. This port\n * is dependency-free — vanilla signals + `setInterval` for the tick loop.\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nimport type { WrDecryptTextAnimateOn, WrDecryptTextRevealDirection, WrDecryptTextClickMode } from './interfaces';\n\nconst DEFAULT_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+';\n\nfunction computeOrder(len: number, dir: WrDecryptTextRevealDirection): readonly number[] {\n const order: number[] = [];\n if (len <= 0) return order;\n if (dir === 'start') {\n for (let i = 0; i < len; i++) order.push(i);\n return order;\n }\n if (dir === 'end') {\n for (let i = len - 1; i >= 0; i--) order.push(i);\n return order;\n }\n const middle = Math.floor(len / 2);\n let off = 0;\n while (order.length < len) {\n if (off % 2 === 0) {\n const idx = middle + off / 2;\n if (idx >= 0 && idx < len) order.push(idx);\n } else {\n const idx = middle - Math.ceil(off / 2);\n if (idx >= 0 && idx < len) order.push(idx);\n }\n off++;\n }\n return order.slice(0, len);\n}\n\n/**\n * How many characters the animation walks — CODE POINTS, not UTF-16 units.\n *\n * Every index in this component (`revealedIndices`, the sequential order, the\n * per-character render) counts the same way `[...txt]` does. Using `txt.length`\n * for the total counted an emoji twice, so a sequential reveal spent extra ticks\n * on indices past the end of the text and the \"everything revealed\" test never\n * lined up with what was on screen.\n */\nfunction charCount(txt: string): number {\n return [...txt].length;\n}\n\nfunction fillAllIndices(len: number): Set<number> {\n const s = new Set<number>();\n for (let i = 0; i < len; i++) s.add(i);\n return s;\n}\n\nfunction removeRandomIndices(set: ReadonlySet<number>, count: number): Set<number> {\n const arr = Array.from(set);\n for (let i = 0; i < count && arr.length > 0; i++) {\n arr.splice(Math.floor(Math.random() * arr.length), 1);\n }\n return new Set(arr);\n}\n\n/**\n * Reveals a string by scrambling characters and progressively replacing\n * scramble glyphs with the originals. Supports sequential reveal in\n * three directions, or non-sequential \"settle\" after N iterations, and\n * four trigger modes (hover, click, view, in-view + hover).\n *\n * @example\n * ```html\n * <wr-decrypt-text text=\"Hello, ngwr!\" animateOn=\"hover\" />\n * <wr-decrypt-text\n * text=\"Reveal from the center\"\n * [sequential]=\"true\"\n * revealDirection=\"center\"\n * animateOn=\"view\"\n * />\n * ```\n *\n * @see https://www.reactbits.dev/text-animations/decrypted-text\n */\n@Component({\n selector: 'wr-decrypt-text',\n templateUrl: './decrypt-text.html',\n styleUrl: './decrypt-text.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-decrypt-text',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave()',\n '(click)': 'onClick()',\n },\n})\nexport class WrDecryptText {\n /** Text to reveal. Required. */\n readonly text = input.required<string>();\n\n /** Tick interval in ms. @default 50 */\n readonly speed = input(50, { transform: numAttr(50) });\n\n /** Non-sequential mode only — total scramble ticks before snapping to plain. @default 10 */\n readonly maxIterations = input(10, { transform: numAttr(10) });\n\n /** Reveal one char per tick instead of scrambling all of them. @default false */\n readonly sequential = input(false, { transform: coerceBooleanProperty });\n\n /** Order in which chars are revealed in sequential mode. @default 'start' */\n readonly revealDirection = input<WrDecryptTextRevealDirection>('start');\n\n /** Scramble using only the glyphs present in `text` (minus spaces). @default false */\n readonly useOriginalCharsOnly = input(false, { transform: coerceBooleanProperty });\n\n /** Pool of glyphs to scramble through (used when `useOriginalCharsOnly` is false). */\n readonly characters = input(DEFAULT_CHARS);\n\n /** When to start the animation. @default 'hover' */\n readonly animateOn = input<WrDecryptTextAnimateOn>('hover');\n\n /** Click behaviour. `'once'` decrypts then stops; `'toggle'` flips state on each click. @default 'once' */\n readonly clickMode = input<WrDecryptTextClickMode>('once');\n\n private readonly displayText = signal('');\n private readonly revealedIndices = signal<ReadonlySet<number>>(new Set());\n private readonly isAnimating = signal(false);\n private readonly isDecrypted = signal(true);\n private readonly direction = signal<'forward' | 'reverse'>('forward');\n\n /** Per-char render data. */\n protected readonly chars = computed(() => {\n const display = this.displayText();\n const revealed = this.revealedIndices();\n const decrypted = this.isDecrypted();\n const animating = this.isAnimating();\n return [...display].map((ch, i) => ({\n ch,\n revealed: revealed.has(i) || (!animating && decrypted),\n }));\n });\n\n /** Sequential reverse order — captured when reverse starts. */\n private reverseOrder: readonly number[] = [];\n private reversePointer = 0;\n private iterationCount = 0;\n private intervalId: ReturnType<typeof setInterval> | undefined;\n private hasAnimatedOnce = false;\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 constructor() {\n if (!this.isBrowser) {\n // SSR: render plain text.\n effect(() => this.displayText.set(this.text()));\n return;\n }\n\n // Reset state whenever `text` or `animateOn` changes.\n effect(() => {\n const txt = this.text();\n const mode = this.animateOn();\n this.stopInterval();\n if (mode === 'click') {\n this.encryptInstantly(txt);\n } else {\n this.displayText.set(txt);\n this.isDecrypted.set(true);\n }\n this.revealedIndices.set(new Set());\n this.direction.set('forward');\n this.hasAnimatedOnce = false;\n });\n\n afterNextRender(() => {\n const mode = this.animateOn();\n if (mode === 'view' || mode === 'inViewHover') this.setupIntersectionObserver();\n });\n\n this.destroyRef.onDestroy(() => this.stopInterval());\n }\n\n // Trigger handlers\n\n protected onMouseEnter(): void {\n const mode = this.animateOn();\n if (mode !== 'hover' && mode !== 'inViewHover') return;\n this.triggerHoverDecrypt();\n }\n\n protected onMouseLeave(): void {\n const mode = this.animateOn();\n if (mode !== 'hover' && mode !== 'inViewHover') return;\n this.resetToPlain();\n }\n\n protected onClick(): void {\n if (this.animateOn() !== 'click') return;\n if (this.clickMode() === 'once') {\n if (this.isDecrypted()) return;\n this.direction.set('forward');\n this.triggerDecrypt();\n return;\n }\n if (this.isDecrypted()) this.triggerReverse();\n else {\n this.direction.set('forward');\n this.triggerDecrypt();\n }\n }\n\n // Internals\n\n private setupIntersectionObserver(): void {\n const io = new IntersectionObserver(\n (entries, obs) => {\n for (const e of entries) {\n if (e.isIntersecting && !this.hasAnimatedOnce) {\n obs.disconnect();\n this.hasAnimatedOnce = true;\n this.triggerDecrypt();\n break;\n }\n }\n },\n { threshold: 0.1, rootMargin: '0px' }\n );\n io.observe(this.host.nativeElement);\n this.destroyRef.onDestroy(() => io.disconnect());\n }\n\n private triggerHoverDecrypt(): void {\n if (this.isAnimating()) return;\n this.revealedIndices.set(new Set());\n this.isDecrypted.set(false);\n this.displayText.set(this.text());\n this.direction.set('forward');\n this.startInterval();\n }\n\n private resetToPlain(): void {\n this.stopInterval();\n this.revealedIndices.set(new Set());\n this.displayText.set(this.text());\n this.isDecrypted.set(true);\n this.direction.set('forward');\n }\n\n private triggerDecrypt(): void {\n if (this.sequential()) {\n this.revealedIndices.set(new Set());\n } else {\n this.revealedIndices.set(new Set());\n }\n this.direction.set('forward');\n this.startInterval();\n }\n\n private triggerReverse(): void {\n const txt = this.text();\n if (this.sequential()) {\n this.reverseOrder = computeOrder(charCount(txt), this.revealDirection()).slice().reverse();\n this.reversePointer = 0;\n }\n const all = fillAllIndices(charCount(txt));\n this.revealedIndices.set(all);\n this.displayText.set(this.shuffle(txt, all));\n this.direction.set('reverse');\n this.startInterval();\n }\n\n private encryptInstantly(txt: string): void {\n this.revealedIndices.set(new Set());\n this.displayText.set(this.shuffle(txt, new Set()));\n this.isDecrypted.set(false);\n }\n\n private startInterval(): void {\n // Reduced motion: every trigger funnels through here — skip the\n // scramble loop and jump straight to the plain, decrypted text.\n if (this.platform.prefersReducedMotion()) {\n this.resetToPlain();\n return;\n }\n\n this.stopInterval();\n this.isAnimating.set(true);\n this.iterationCount = 0;\n this.intervalId = setInterval(() => this.tick(), this.speed());\n }\n\n private stopInterval(): void {\n if (this.intervalId !== undefined) {\n clearInterval(this.intervalId);\n this.intervalId = undefined;\n }\n this.isAnimating.set(false);\n }\n\n private tick(): void {\n const txt = this.text();\n const seq = this.sequential();\n const dir = this.direction();\n const max = this.maxIterations();\n const revealed = this.revealedIndices();\n\n if (seq && dir === 'forward') {\n if (revealed.size < charCount(txt)) {\n const nextIdx = this.nextSequentialIndex(revealed, charCount(txt));\n const next = new Set(revealed);\n next.add(nextIdx);\n this.revealedIndices.set(next);\n this.displayText.set(this.shuffle(txt, next));\n } else {\n this.stopInterval();\n this.isDecrypted.set(true);\n this.displayText.set(txt);\n }\n return;\n }\n\n if (seq && dir === 'reverse') {\n if (this.reversePointer < this.reverseOrder.length) {\n const idx = this.reverseOrder[this.reversePointer++];\n const next = new Set(revealed);\n next.delete(idx);\n this.revealedIndices.set(next);\n this.displayText.set(this.shuffle(txt, next));\n if (next.size === 0) {\n this.stopInterval();\n this.isDecrypted.set(false);\n }\n } else {\n this.stopInterval();\n this.isDecrypted.set(false);\n }\n return;\n }\n\n if (!seq && dir === 'forward') {\n this.displayText.set(this.shuffle(txt, revealed));\n this.iterationCount++;\n if (this.iterationCount >= max) {\n this.stopInterval();\n this.displayText.set(txt);\n this.isDecrypted.set(true);\n }\n return;\n }\n\n if (!seq && dir === 'reverse') {\n let current = revealed;\n if (current.size === 0) current = fillAllIndices(charCount(txt));\n const removeCount = Math.max(1, Math.ceil(charCount(txt) / Math.max(1, max)));\n const next = removeRandomIndices(current, removeCount);\n this.revealedIndices.set(next);\n this.displayText.set(this.shuffle(txt, next));\n this.iterationCount++;\n if (next.size === 0 || this.iterationCount >= max) {\n this.stopInterval();\n this.isDecrypted.set(false);\n this.displayText.set(this.shuffle(txt, new Set()));\n this.revealedIndices.set(new Set());\n }\n }\n }\n\n private nextSequentialIndex(revealed: ReadonlySet<number>, len: number): number {\n switch (this.revealDirection()) {\n case 'end':\n return len - 1 - revealed.size;\n case 'center': {\n const middle = Math.floor(len / 2);\n const offset = Math.floor(revealed.size / 2);\n const candidate = revealed.size % 2 === 0 ? middle + offset : middle - offset - 1;\n if (candidate >= 0 && candidate < len && !revealed.has(candidate)) return candidate;\n for (let i = 0; i < len; i++) if (!revealed.has(i)) return i;\n return 0;\n }\n case 'start':\n default:\n return revealed.size;\n }\n }\n\n private shuffle(txt: string, revealed: ReadonlySet<number>): string {\n // Every index here counts CODE POINTS, because that is what `[...txt]`\n // produces and what `revealed` was built against. `split('')` counts UTF-16\n // units instead, so an emoji in the text (or in a custom alphabet) put half a\n // surrogate pair in the pool; and reading the revealed character back as\n // `txt[i]` mixed the two index spaces, so every character after the first\n // astral one revealed as the WRONG one.\n const pool = this.useOriginalCharsOnly()\n ? Array.from(new Set([...txt])).filter(ch => ch !== ' ')\n : [...this.characters()];\n if (pool.length === 0) return txt;\n return [...txt]\n .map((ch, i) => {\n if (ch === ' ') return ' ';\n if (revealed.has(i)) return ch;\n return pool[Math.floor(Math.random() * pool.length)];\n })\n .join('');\n }\n}\n\nexport type { WrDecryptTextAnimateOn, WrDecryptTextRevealDirection, WrDecryptTextClickMode } from './interfaces';\n","<span class=\"wr-decrypt-text__sr-only\">{{ text() }}</span>\n<span aria-hidden=\"true\">\n @for (c of chars(); track $index) {\n <span [class]=\"c.revealed ? 'wr-decrypt-text__char' : 'wr-decrypt-text__char wr-decrypt-text__char--encrypted'\">{{\n c.ch\n }}</span>\n }\n</span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-decrypt-text.mjs","sources":["../../../projects/lib/decrypt-text/decrypt-text.ts","../../../projects/lib/decrypt-text/decrypt-text.html","../../../projects/lib/decrypt-text/ngwr-decrypt-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 DecryptedText effect by David Haz / reactbits.dev.\n * Original: https://www.reactbits.dev/text-animations/decrypted-text\n *\n * The reactbits version uses `motion/react` for the wrapper. This port\n * is dependency-free — vanilla signals + `setInterval` for the tick loop.\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n PLATFORM_ID,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nimport type { WrDecryptTextAnimateOn, WrDecryptTextRevealDirection, WrDecryptTextClickMode } from './interfaces';\n\nconst DEFAULT_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+';\n\nfunction computeOrder(len: number, dir: WrDecryptTextRevealDirection): readonly number[] {\n const order: number[] = [];\n if (len <= 0) return order;\n if (dir === 'start') {\n for (let i = 0; i < len; i++) order.push(i);\n return order;\n }\n if (dir === 'end') {\n for (let i = len - 1; i >= 0; i--) order.push(i);\n return order;\n }\n const middle = Math.floor(len / 2);\n let off = 0;\n while (order.length < len) {\n if (off % 2 === 0) {\n const idx = middle + off / 2;\n if (idx >= 0 && idx < len) order.push(idx);\n } else {\n const idx = middle - Math.ceil(off / 2);\n if (idx >= 0 && idx < len) order.push(idx);\n }\n off++;\n }\n return order.slice(0, len);\n}\n\n/**\n * How many characters the animation walks — CODE POINTS, not UTF-16 units.\n *\n * Every index in this component (`revealedIndices`, the sequential order, the\n * per-character render) counts the same way `[...txt]` does. Using `txt.length`\n * for the total counted an emoji twice, so a sequential reveal spent extra ticks\n * on indices past the end of the text and the \"everything revealed\" test never\n * lined up with what was on screen.\n */\nfunction charCount(txt: string): number {\n return [...txt].length;\n}\n\nfunction fillAllIndices(len: number): Set<number> {\n const s = new Set<number>();\n for (let i = 0; i < len; i++) s.add(i);\n return s;\n}\n\nfunction removeRandomIndices(set: ReadonlySet<number>, count: number): Set<number> {\n const arr = Array.from(set);\n for (let i = 0; i < count && arr.length > 0; i++) {\n arr.splice(Math.floor(Math.random() * arr.length), 1);\n }\n return new Set(arr);\n}\n\n/**\n * Reveals a string by scrambling characters and progressively replacing\n * scramble glyphs with the originals. Supports sequential reveal in\n * three directions, or non-sequential \"settle\" after N iterations, and\n * four trigger modes (hover, click, view, in-view + hover).\n *\n * @example\n * ```html\n * <wr-decrypt-text text=\"Hello, ngwr!\" animateOn=\"hover\" />\n * <wr-decrypt-text\n * text=\"Reveal from the center\"\n * [sequential]=\"true\"\n * revealDirection=\"center\"\n * animateOn=\"view\"\n * />\n * ```\n *\n * @see https://www.reactbits.dev/text-animations/decrypted-text\n */\n@Component({\n selector: 'wr-decrypt-text',\n templateUrl: './decrypt-text.html',\n styleUrl: './decrypt-text.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-decrypt-text',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave()',\n '(click)': 'onClick()',\n },\n})\nexport class WrDecryptText {\n /** Text to reveal. Required. */\n readonly text = input.required<string>();\n\n /** Tick interval in ms. @default 50 */\n readonly speed = input(50, { transform: numAttr(50) });\n\n /** Non-sequential mode only — total scramble ticks before snapping to plain. @default 10 */\n readonly maxIterations = input(10, { transform: numAttr(10) });\n\n /** Reveal one char per tick instead of scrambling all of them. @default false */\n readonly sequential = input(false, { transform: coerceBooleanProperty });\n\n /** Order in which chars are revealed in sequential mode. @default 'start' */\n readonly revealDirection = input<WrDecryptTextRevealDirection>('start');\n\n /** Scramble using only the glyphs present in `text` (minus spaces). @default false */\n readonly useOriginalCharsOnly = input(false, { transform: coerceBooleanProperty });\n\n /** Pool of glyphs to scramble through (used when `useOriginalCharsOnly` is false). */\n readonly characters = input(DEFAULT_CHARS);\n\n /** When to start the animation. @default 'hover' */\n readonly animateOn = input<WrDecryptTextAnimateOn>('hover');\n\n /** Click behaviour. `'once'` decrypts then stops; `'toggle'` flips state on each click. @default 'once' */\n readonly clickMode = input<WrDecryptTextClickMode>('once');\n\n private readonly displayText = signal('');\n private readonly revealedIndices = signal<ReadonlySet<number>>(new Set());\n private readonly isAnimating = signal(false);\n private readonly isDecrypted = signal(true);\n private readonly direction = signal<'forward' | 'reverse'>('forward');\n\n /** Per-char render data. */\n protected readonly chars = computed(() => {\n const display = this.displayText();\n const revealed = this.revealedIndices();\n const decrypted = this.isDecrypted();\n const animating = this.isAnimating();\n return [...display].map((ch, i) => ({\n ch,\n revealed: revealed.has(i) || (!animating && decrypted),\n }));\n });\n\n /** Sequential reverse order — captured when reverse starts. */\n private reverseOrder: readonly number[] = [];\n private reversePointer = 0;\n private iterationCount = 0;\n private intervalId: ReturnType<typeof setInterval> | undefined;\n private hasAnimatedOnce = false;\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 constructor() {\n if (!this.isBrowser) {\n // SSR: render plain text.\n effect(() => this.displayText.set(this.text()));\n return;\n }\n\n // Reset state whenever `text` or `animateOn` changes.\n effect(() => {\n const txt = this.text();\n const mode = this.animateOn();\n this.stopInterval();\n // The resting state of `click` mode is the scramble — but not for someone who\n // asked for less motion. `startInterval` short-circuits every TRIGGER to the\n // plain text, and this is the one path that never reaches it, so a reduced-\n // motion reader was left staring at permanently scrambled glyphs with no\n // pointer-free way to undo them.\n if (mode === 'click' && !this.platform.prefersReducedMotion()) {\n this.encryptInstantly(txt);\n } else {\n this.displayText.set(txt);\n this.isDecrypted.set(true);\n }\n this.revealedIndices.set(new Set());\n this.direction.set('forward');\n this.hasAnimatedOnce = false;\n });\n\n afterNextRender(() => {\n const mode = this.animateOn();\n if (mode === 'view' || mode === 'inViewHover') this.setupIntersectionObserver();\n });\n\n this.destroyRef.onDestroy(() => this.stopInterval());\n }\n\n // Trigger handlers\n\n protected onMouseEnter(): void {\n const mode = this.animateOn();\n if (mode !== 'hover' && mode !== 'inViewHover') return;\n this.triggerHoverDecrypt();\n }\n\n protected onMouseLeave(): void {\n const mode = this.animateOn();\n if (mode !== 'hover' && mode !== 'inViewHover') return;\n this.resetToPlain();\n }\n\n protected onClick(): void {\n if (this.animateOn() !== 'click') return;\n if (this.clickMode() === 'once') {\n if (this.isDecrypted()) return;\n this.direction.set('forward');\n this.triggerDecrypt();\n return;\n }\n if (this.isDecrypted()) this.triggerReverse();\n else {\n this.direction.set('forward');\n this.triggerDecrypt();\n }\n }\n\n // Internals\n\n private setupIntersectionObserver(): void {\n const io = new IntersectionObserver(\n (entries, obs) => {\n for (const e of entries) {\n if (e.isIntersecting && !this.hasAnimatedOnce) {\n obs.disconnect();\n this.hasAnimatedOnce = true;\n this.triggerDecrypt();\n break;\n }\n }\n },\n { threshold: 0.1, rootMargin: '0px' }\n );\n io.observe(this.host.nativeElement);\n this.destroyRef.onDestroy(() => io.disconnect());\n }\n\n private triggerHoverDecrypt(): void {\n if (this.isAnimating()) return;\n this.revealedIndices.set(new Set());\n this.isDecrypted.set(false);\n this.displayText.set(this.text());\n this.direction.set('forward');\n this.startInterval();\n }\n\n private resetToPlain(): void {\n this.stopInterval();\n this.revealedIndices.set(new Set());\n this.displayText.set(this.text());\n this.isDecrypted.set(true);\n this.direction.set('forward');\n }\n\n private triggerDecrypt(): void {\n if (this.sequential()) {\n this.revealedIndices.set(new Set());\n } else {\n this.revealedIndices.set(new Set());\n }\n this.direction.set('forward');\n this.startInterval();\n }\n\n private triggerReverse(): void {\n const txt = this.text();\n if (this.sequential()) {\n this.reverseOrder = computeOrder(charCount(txt), this.revealDirection()).slice().reverse();\n this.reversePointer = 0;\n }\n const all = fillAllIndices(charCount(txt));\n this.revealedIndices.set(all);\n this.displayText.set(this.shuffle(txt, all));\n this.direction.set('reverse');\n this.startInterval();\n }\n\n private encryptInstantly(txt: string): void {\n this.revealedIndices.set(new Set());\n this.displayText.set(this.shuffle(txt, new Set()));\n this.isDecrypted.set(false);\n }\n\n private startInterval(): void {\n // Reduced motion: every trigger funnels through here — skip the\n // scramble loop and jump straight to the plain, decrypted text.\n if (this.platform.prefersReducedMotion()) {\n this.resetToPlain();\n return;\n }\n\n this.stopInterval();\n this.isAnimating.set(true);\n this.iterationCount = 0;\n this.intervalId = setInterval(() => this.tick(), this.speed());\n }\n\n private stopInterval(): void {\n if (this.intervalId !== undefined) {\n clearInterval(this.intervalId);\n this.intervalId = undefined;\n }\n this.isAnimating.set(false);\n }\n\n private tick(): void {\n const txt = this.text();\n const seq = this.sequential();\n const dir = this.direction();\n const max = this.maxIterations();\n const revealed = this.revealedIndices();\n\n if (seq && dir === 'forward') {\n if (revealed.size < charCount(txt)) {\n const nextIdx = this.nextSequentialIndex(revealed, charCount(txt));\n const next = new Set(revealed);\n next.add(nextIdx);\n this.revealedIndices.set(next);\n this.displayText.set(this.shuffle(txt, next));\n } else {\n this.stopInterval();\n this.isDecrypted.set(true);\n this.displayText.set(txt);\n }\n return;\n }\n\n if (seq && dir === 'reverse') {\n if (this.reversePointer < this.reverseOrder.length) {\n const idx = this.reverseOrder[this.reversePointer++];\n const next = new Set(revealed);\n next.delete(idx);\n this.revealedIndices.set(next);\n this.displayText.set(this.shuffle(txt, next));\n if (next.size === 0) {\n this.stopInterval();\n this.isDecrypted.set(false);\n }\n } else {\n this.stopInterval();\n this.isDecrypted.set(false);\n }\n return;\n }\n\n if (!seq && dir === 'forward') {\n this.displayText.set(this.shuffle(txt, revealed));\n this.iterationCount++;\n if (this.iterationCount >= max) {\n this.stopInterval();\n this.displayText.set(txt);\n this.isDecrypted.set(true);\n }\n return;\n }\n\n if (!seq && dir === 'reverse') {\n let current = revealed;\n if (current.size === 0) current = fillAllIndices(charCount(txt));\n const removeCount = Math.max(1, Math.ceil(charCount(txt) / Math.max(1, max)));\n const next = removeRandomIndices(current, removeCount);\n this.revealedIndices.set(next);\n this.displayText.set(this.shuffle(txt, next));\n this.iterationCount++;\n if (next.size === 0 || this.iterationCount >= max) {\n this.stopInterval();\n this.isDecrypted.set(false);\n this.displayText.set(this.shuffle(txt, new Set()));\n this.revealedIndices.set(new Set());\n }\n }\n }\n\n private nextSequentialIndex(revealed: ReadonlySet<number>, len: number): number {\n switch (this.revealDirection()) {\n case 'end':\n return len - 1 - revealed.size;\n case 'center': {\n const middle = Math.floor(len / 2);\n const offset = Math.floor(revealed.size / 2);\n const candidate = revealed.size % 2 === 0 ? middle + offset : middle - offset - 1;\n if (candidate >= 0 && candidate < len && !revealed.has(candidate)) return candidate;\n for (let i = 0; i < len; i++) if (!revealed.has(i)) return i;\n return 0;\n }\n case 'start':\n default:\n return revealed.size;\n }\n }\n\n private shuffle(txt: string, revealed: ReadonlySet<number>): string {\n // Every index here counts CODE POINTS, because that is what `[...txt]`\n // produces and what `revealed` was built against. `split('')` counts UTF-16\n // units instead, so an emoji in the text (or in a custom alphabet) put half a\n // surrogate pair in the pool; and reading the revealed character back as\n // `txt[i]` mixed the two index spaces, so every character after the first\n // astral one revealed as the WRONG one.\n const pool = this.useOriginalCharsOnly()\n ? Array.from(new Set([...txt])).filter(ch => ch !== ' ')\n : [...this.characters()];\n if (pool.length === 0) return txt;\n return [...txt]\n .map((ch, i) => {\n if (ch === ' ') return ' ';\n if (revealed.has(i)) return ch;\n return pool[Math.floor(Math.random() * pool.length)];\n })\n .join('');\n }\n}\n\nexport type { WrDecryptTextAnimateOn, WrDecryptTextRevealDirection, WrDecryptTextClickMode } from './interfaces';\n","<span class=\"wr-decrypt-text__sr-only\">{{ text() }}</span>\n<span aria-hidden=\"true\">\n @for (c of chars(); track $index) {\n <span [class]=\"c.revealed ? 'wr-decrypt-text__char' : 'wr-decrypt-text__char wr-decrypt-text__char--encrypted'\">{{\n c.ch\n }}</span>\n }\n</span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
2
+
3
+ /**
4
+ * @license
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
8
+ */
9
+ /**
10
+ * Test harness for `<wr-donut-chart>`.
11
+ *
12
+ * **The ring itself is unreadable, and that is by design.** The slices are SVG
13
+ * paths inside an `aria-hidden` drawing: a screen reader is given the chart's
14
+ * `aria-label` and nothing else, and a spec cannot get a label or a value off a
15
+ * path's `d`. {@link getLegend} is where the numbers are — which is also the
16
+ * argument for keeping `showLegend` on, since with it off the chart's data has no
17
+ * textual form at all.
18
+ *
19
+ * {@link getSliceCount} is therefore the one thing the ring answers: how many
20
+ * wedges were drawn. Compare it with the legend's length to catch a slice that was
21
+ * filtered out of one and not the other.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const chart = await loader.getHarness(WrDonutChartHarness);
26
+ *
27
+ * expect(await chart.getSliceCount()).toBe(3);
28
+ * expect(await chart.getLegend()).toEqual([
29
+ * { label: 'Direct', value: '48' },
30
+ * { label: 'Search', value: '32' },
31
+ * { label: 'Social', value: '20' },
32
+ * ]);
33
+ * ```
34
+ *
35
+ * @see https://ngwr.dev/guides/testing
36
+ */
37
+ class WrDonutChartHarness extends ComponentHarness {
38
+ static hostSelector = 'wr-donut-chart';
39
+ /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
40
+ static with(options = {}) {
41
+ return new HarnessPredicate(WrDonutChartHarness, options)
42
+ .addOption('ariaLabel', options.ariaLabel, (harness, label) => HarnessPredicate.stringMatches(harness.getAccessibleName(), label))
43
+ .addOption('sliceLabel', options.sliceLabel, async (harness, label) => {
44
+ for (const entry of await harness.getLegend()) {
45
+ if (await HarnessPredicate.stringMatches(entry.label, label))
46
+ return true;
47
+ }
48
+ return false;
49
+ });
50
+ }
51
+ /** The name the ring announces — the whole chart's, since the slices announce nothing. */
52
+ async getAccessibleName() {
53
+ return (await this.locatorFor('.wr-donut-chart__surface')()).getAttribute('aria-label');
54
+ }
55
+ /** How many wedges were drawn. */
56
+ async getSliceCount() {
57
+ return (await this.locatorForAll('.wr-donut-chart__surface path')()).length;
58
+ }
59
+ /** Whether the legend is rendered (`showLegend`, and at least one slice). */
60
+ async hasLegend() {
61
+ return (await this.locatorForOptional('.wr-donut-chart__legend')()) !== null;
62
+ }
63
+ /** The legend rows in order — the only textual form the data has. */
64
+ async getLegend() {
65
+ const labels = await this.locatorForAll('.wr-donut-chart__legend-label')();
66
+ const values = await this.locatorForAll('.wr-donut-chart__legend-value')();
67
+ return Promise.all(labels.map(async (label, index) => ({
68
+ label: await label.text(),
69
+ value: (await values[index]?.text()) ?? '',
70
+ })));
71
+ }
72
+ /** The big number in the middle, or `null` when the chart has none. */
73
+ async getCenterValue() {
74
+ const center = await this.locatorForOptional('.wr-donut-chart__center-value')();
75
+ return center ? center.text() : null;
76
+ }
77
+ /** The caption under the centre value, or `null`. */
78
+ async getCenterLabel() {
79
+ const center = await this.locatorForOptional('.wr-donut-chart__center-label')();
80
+ return center ? center.text() : null;
81
+ }
82
+ /** The ring's diameter in pixels, as the component writes it inline. */
83
+ async getSize() {
84
+ return Number.parseFloat(await (await this.locatorFor('.wr-donut-chart__surface')()).getCssValue('width'));
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Generated bundle index. Do not edit.
90
+ */
91
+
92
+ export { WrDonutChartHarness };
93
+ //# sourceMappingURL=ngwr-donut-chart-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngwr-donut-chart-testing.mjs","sources":["../../../projects/lib/donut-chart/testing/wr-donut-chart-harness.ts","../../../projects/lib/donut-chart/testing/ngwr-donut-chart-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport type { WrDonutChartHarnessFilters, WrDonutChartLegendEntry } from './interfaces';\n\n/**\n * Test harness for `<wr-donut-chart>`.\n *\n * **The ring itself is unreadable, and that is by design.** The slices are SVG\n * paths inside an `aria-hidden` drawing: a screen reader is given the chart's\n * `aria-label` and nothing else, and a spec cannot get a label or a value off a\n * path's `d`. {@link getLegend} is where the numbers are — which is also the\n * argument for keeping `showLegend` on, since with it off the chart's data has no\n * textual form at all.\n *\n * {@link getSliceCount} is therefore the one thing the ring answers: how many\n * wedges were drawn. Compare it with the legend's length to catch a slice that was\n * filtered out of one and not the other.\n *\n * @example\n * ```ts\n * const chart = await loader.getHarness(WrDonutChartHarness);\n *\n * expect(await chart.getSliceCount()).toBe(3);\n * expect(await chart.getLegend()).toEqual([\n * { label: 'Direct', value: '48' },\n * { label: 'Search', value: '32' },\n * { label: 'Social', value: '20' },\n * ]);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrDonutChartHarness extends ComponentHarness {\n static hostSelector = 'wr-donut-chart';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrDonutChartHarnessFilters = {}): HarnessPredicate<WrDonutChartHarness> {\n return new HarnessPredicate(WrDonutChartHarness, options)\n .addOption('ariaLabel', options.ariaLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n )\n .addOption('sliceLabel', options.sliceLabel, async (harness, label) => {\n for (const entry of await harness.getLegend()) {\n if (await HarnessPredicate.stringMatches(entry.label, label)) return true;\n }\n return false;\n });\n }\n\n /** The name the ring announces — the whole chart's, since the slices announce nothing. */\n async getAccessibleName(): Promise<string | null> {\n return (await this.locatorFor('.wr-donut-chart__surface')()).getAttribute('aria-label');\n }\n\n /** How many wedges were drawn. */\n async getSliceCount(): Promise<number> {\n return (await this.locatorForAll('.wr-donut-chart__surface path')()).length;\n }\n\n /** Whether the legend is rendered (`showLegend`, and at least one slice). */\n async hasLegend(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-donut-chart__legend')()) !== null;\n }\n\n /** The legend rows in order — the only textual form the data has. */\n async getLegend(): Promise<WrDonutChartLegendEntry[]> {\n const labels = await this.locatorForAll('.wr-donut-chart__legend-label')();\n const values = await this.locatorForAll('.wr-donut-chart__legend-value')();\n\n return Promise.all(\n labels.map(async (label, index) => ({\n label: await label.text(),\n value: (await values[index]?.text()) ?? '',\n }))\n );\n }\n\n /** The big number in the middle, or `null` when the chart has none. */\n async getCenterValue(): Promise<string | null> {\n const center = await this.locatorForOptional('.wr-donut-chart__center-value')();\n return center ? center.text() : null;\n }\n\n /** The caption under the centre value, or `null`. */\n async getCenterLabel(): Promise<string | null> {\n const center = await this.locatorForOptional('.wr-donut-chart__center-label')();\n return center ? center.text() : null;\n }\n\n /** The ring's diameter in pixels, as the component writes it inline. */\n async getSize(): Promise<number> {\n return Number.parseFloat(await (await this.locatorFor('.wr-donut-chart__surface')()).getCssValue('width'));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;AACG,MAAO,mBAAoB,SAAQ,gBAAgB,CAAA;AACvD,IAAA,OAAO,YAAY,GAAG,gBAAgB;;AAGtC,IAAA,OAAO,IAAI,CAAC,OAAA,GAAsC,EAAE,EAAA;AAClD,QAAA,OAAO,IAAI,gBAAgB,CAAC,mBAAmB,EAAE,OAAO;aACrD,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,KAAK,KACxD,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,KAAK,CAAC;AAEnE,aAAA,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,OAAO,EAAE,KAAK,KAAI;YACpE,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE;gBAC7C,IAAI,MAAM,gBAAgB,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC;AAAE,oBAAA,OAAO,IAAI;YAC3E;AACA,YAAA,OAAO,KAAK;AACd,QAAA,CAAC,CAAC;IACN;;AAGA,IAAA,MAAM,iBAAiB,GAAA;AACrB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,0BAA0B,CAAC,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC;IACzF;;AAGA,IAAA,MAAM,aAAa,GAAA;AACjB,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,+BAA+B,CAAC,EAAE,EAAE,MAAM;IAC7E;;AAGA,IAAA,MAAM,SAAS,GAAA;AACb,QAAA,OAAO,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,yBAAyB,CAAC,EAAE,MAAM,IAAI;IAC9E;;AAGA,IAAA,MAAM,SAAS,GAAA;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,+BAA+B,CAAC,EAAE;QAC1E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,+BAA+B,CAAC,EAAE;AAE1E,QAAA,OAAO,OAAO,CAAC,GAAG,CAChB,MAAM,CAAC,GAAG,CAAC,OAAO,KAAK,EAAE,KAAK,MAAM;AAClC,YAAA,KAAK,EAAE,MAAM,KAAK,CAAC,IAAI,EAAE;AACzB,YAAA,KAAK,EAAE,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE;SAC3C,CAAC,CAAC,CACJ;IACH;;AAGA,IAAA,MAAM,cAAc,GAAA;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,+BAA+B,CAAC,EAAE;AAC/E,QAAA,OAAO,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI;IACtC;;AAGA,IAAA,MAAM,cAAc,GAAA;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,+BAA+B,CAAC,EAAE;AAC/E,QAAA,OAAO,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI;IACtC;;AAGA,IAAA,MAAM,OAAO,GAAA;QACX,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,0BAA0B,CAAC,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5G;;;ACnGF;;AAEG;;;;"}
@@ -3,7 +3,7 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
3
3
  import { TemplatePortal, ComponentPortal } from '@angular/cdk/portal';
4
4
  import { isPlatformBrowser } from '@angular/common';
5
5
  import * as i0 from '@angular/core';
6
- import { model, input, viewChild, TemplateRef, inject, ViewContainerRef, DestroyRef, PLATFORM_ID, effect, ViewEncapsulation, Component, InjectionToken, EnvironmentInjector, Injector, afterNextRender, Service, Directive, computed } from '@angular/core';
6
+ import { model, input, viewChild, TemplateRef, inject, ViewContainerRef, DestroyRef, PLATFORM_ID, effect, afterEveryRender, ViewEncapsulation, Component, InjectionToken, EnvironmentInjector, Injector, Service, Directive, computed } from '@angular/core';
7
7
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
8
  import { useI18nText, WrI18n } from 'ngwr/i18n';
9
9
  import { WR_OVERLAY, wrAppendOverlayClose } from 'ngwr/overlay';
@@ -179,8 +179,30 @@ class WrDrawer {
179
179
  this.closeOverlay();
180
180
  }
181
181
  });
182
+ afterEveryRender(() => this.syncLabel());
182
183
  this.destroyRef.onDestroy(() => this.closeOverlay());
183
184
  }
185
+ /**
186
+ * Point the panel's `aria-labelledby` at the CURRENT `[wrDrawerTitle]`.
187
+ *
188
+ * Re-resolved after every render rather than once when the drawer opens,
189
+ * because the title element is projected content and can come and go while
190
+ * the drawer stays open — an `@if` around it, or a heading that only exists
191
+ * once the data arrives. A one-shot lookup leaves the attribute naming an
192
+ * element that has been removed or replaced, and a dangling reference is not
193
+ * a name: the dialog is announced as unnamed, with nothing on screen to say
194
+ * so. A missing title clears the attribute for the same reason.
195
+ */
196
+ syncLabel() {
197
+ const host = this.overlayRef?.overlayElement;
198
+ if (!host)
199
+ return;
200
+ const titleEl = host.querySelector('[wrDrawerTitle], [wr-drawer-title]');
201
+ if (titleEl?.id)
202
+ host.setAttribute('aria-labelledby', titleEl.id);
203
+ else
204
+ host.removeAttribute('aria-labelledby');
205
+ }
184
206
  openOverlay() {
185
207
  if (this.overlayRef)
186
208
  return;
@@ -214,11 +236,6 @@ class WrDrawer {
214
236
  const host = this.overlayRef.overlayElement;
215
237
  host.setAttribute('role', 'dialog');
216
238
  host.setAttribute('aria-modal', 'true');
217
- queueMicrotask(() => {
218
- const titleEl = host.querySelector('[wrDrawerTitle], [wr-drawer-title]');
219
- if (titleEl?.id)
220
- host.setAttribute('aria-labelledby', titleEl.id);
221
- });
222
239
  this.focusTrap = this.focusTrapFactory.create(host);
223
240
  void this.focusTrap.focusInitialElementWhenReady();
224
241
  }
@@ -546,11 +563,23 @@ class WrDrawerManager {
546
563
  // Has to wait for a render, not a microtask: attaching the portal only
547
564
  // schedules change detection, so under zoneless CD a microtask runs while
548
565
  // the content is still an empty view and the title id doesn't exist yet.
549
- afterNextRender(() => {
566
+ //
567
+ // And after EVERY render, not just the next one: the title belongs to the
568
+ // caller's component, so an `@if` or a late-arriving heading can replace
569
+ // or remove the element the attribute names. A reference to a node that is
570
+ // no longer there is not a name — the dialog announces as unnamed — so a
571
+ // missing title clears the attribute rather than leaving it dangling.
572
+ const labelSync = afterEveryRender(() => {
550
573
  const titleEl = host.querySelector('[wrDrawerTitle], [wr-drawer-title]');
551
574
  if (titleEl?.id)
552
575
  host.setAttribute('aria-labelledby', titleEl.id);
576
+ else
577
+ host.removeAttribute('aria-labelledby');
553
578
  }, { injector: this.parentInjector });
579
+ // The hook is bound to the root injector, so it outlives the drawer unless
580
+ // it is torn down with it. `detachments()` fires on dispose, which is the
581
+ // one path every dismissal goes through.
582
+ overlayRef.detachments().subscribe(() => labelSync.destroy());
554
583
  // Trap focus inside the drawer and move initial focus in.
555
584
  const trap = this.focusTrapFactory.create(host);
556
585
  drawerRef.focusTrap = trap;
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-drawer.mjs","sources":["../../../projects/lib/drawer/drawer.ts","../../../projects/lib/drawer/drawer.html","../../../projects/lib/drawer/drawer-ref.ts","../../../projects/lib/drawer/tokens/drawer-data.token.ts","../../../projects/lib/drawer/tokens/drawer-ref.token.ts","../../../projects/lib/drawer/drawer-manager.ts","../../../projects/lib/drawer/directives/drawer-title.ts","../../../projects/lib/drawer/directives/drawer-content.ts","../../../projects/lib/drawer/directives/drawer-footer.ts","../../../projects/lib/drawer/directives/drawer-close.ts","../../../projects/lib/drawer/ngwr-drawer.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n PLATFORM_ID,\n TemplateRef,\n ViewContainerRef,\n ViewEncapsulation,\n effect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\nimport type { WrDrawerPosition } from './interfaces';\n\n/**\n * Side panel that slides in from an edge of the viewport. Two-way binds\n * `open` and renders into a CDK overlay so it sits above page content.\n *\n * Compose the body with `<wrDrawerTitle>`, `<wrDrawerContent>`, and\n * `<wrDrawerFooter>` directives.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"settingsOpen\" position=\"right\" width=\"24rem\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>...</div>\n * <div wrDrawerFooter>\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * </div>\n * </wr-drawer>\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Component({\n selector: 'wr-drawer',\n templateUrl: './drawer.html',\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrDrawer {\n /** Two-way bindable open state. */\n readonly open = model<boolean>(false);\n\n /** Side the drawer slides in from. @default 'right' */\n readonly position = input<WrDrawerPosition>('right');\n\n /** Width when position is left/right. Any CSS length. @default '20rem' */\n readonly width = input<string>('20rem');\n\n /** Height when position is top/bottom. Any CSS length. @default '16rem' */\n readonly height = input<string>('16rem');\n\n /**\n * Upper cap on height (top/bottom positions). Useful for bottom sheets\n * that should grow with content up to a viewport-relative max.\n * Any CSS length. @default null (no cap)\n */\n readonly maxHeight = input<string | null>(null);\n\n /**\n * Round the leading corners — the edge facing the viewport interior.\n * Common bottom-sheet styling. @default false\n */\n readonly rounded = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Render a grab handle at the leading edge and enable swipe-to-dismiss:\n * drag the handle toward the drawer's edge (down for `bottom`, left for\n * `left`, …) and release past ~30% of the panel to close. @default false\n */\n readonly showHandle = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Pad the trailing edge with `env(safe-area-inset-*)` so content\n * doesn't sit under the iOS home indicator. @default false\n */\n readonly safeArea = input(false, { transform: coerceBooleanProperty });\n\n /** Show the dimming backdrop. @default true */\n readonly hasBackdrop = input(true, { transform: coerceBooleanProperty });\n\n /** Close when the backdrop is clicked. @default true */\n readonly closeOnBackdropClick = input(true, { transform: coerceBooleanProperty });\n\n /** Close on Escape. @default true */\n readonly closeOnEscape = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Show a dismiss (×) button in the panel's top-right corner. Set `false` when\n * the projected content supplies its own close affordance. @default true\n */\n readonly closable = input(true, { transform: coerceBooleanProperty });\n\n /** Accessible name for the dismiss button. Falls back to `drawer.close`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'drawer.close', 'Close drawer');\n\n protected readonly panelTpl = viewChild.required(TemplateRef);\n\n protected panelClass(): string {\n const parts = ['wr-drawer__panel', `wr-drawer__panel--${this.position()}`];\n if (this.rounded()) parts.push('wr-drawer__panel--rounded');\n if (this.safeArea()) parts.push('wr-drawer__panel--safe-area');\n if (this.closable()) parts.push('wr-drawer__panel--closable');\n return parts.join(' ');\n }\n\n // Swipe-to-dismiss — gated to the grab handle, so it never fights the\n // panel's own scrolling. The panel follows the finger toward the closing\n // edge and closes past ~30% of its size, otherwise snaps back.\n\n private swipeStartX = 0;\n private swipeStartY = 0;\n private swiping = false;\n\n // Pointer, not Touch. The handle has always advertised itself to a mouse with\n // `cursor: grab`, but the gesture was bound to touch events only, so on a\n // desktop it could not be dragged at all. Pointer Events cover touch, mouse and\n // pen through one path — the same idiom `wr-splitter` already uses.\n\n protected onSwipeStart(event: PointerEvent): void {\n // Ignore secondary contacts of a multi-touch gesture.\n if (!event.isPrimary) return;\n this.swipeStartX = event.clientX;\n this.swipeStartY = event.clientY;\n this.swiping = true;\n // Capture, so the drag keeps reporting once the cursor leaves the 2.5rem\n // grabber — without it a mouse drag dies the moment it slips off the handle.\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n }\n\n protected onSwipeMove(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n // Only follow the pointer when dragging toward the closing edge.\n if (delta * sign <= 0) {\n panel.style.transform = '';\n return;\n }\n panel.style.transition = 'none';\n panel.style.transform = axis === 'y' ? `translateY(${delta}px)` : `translateX(${delta}px)`;\n }\n\n protected onSwipeEnd(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n this.swiping = false;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n const panelSize = axis === 'y' ? panel.offsetHeight : panel.offsetWidth;\n if (delta * sign > panelSize * 0.3) {\n this.open.set(false); // keep the dragged offset as the overlay disposes\n } else {\n panel.style.transition = '';\n panel.style.transform = '';\n }\n }\n\n /** Axis + sign of the closing direction for the current position. */\n private closeAxis(): { axis: 'x' | 'y'; sign: number } {\n switch (this.position()) {\n case 'bottom':\n return { axis: 'y', sign: 1 };\n case 'top':\n return { axis: 'y', sign: -1 };\n case 'left':\n return { axis: 'x', sign: -1 };\n case 'right':\n default:\n return { axis: 'x', sign: 1 };\n }\n }\n\n private readonly overlay = inject(WR_OVERLAY);\n private readonly vcr = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private overlayRef: OverlayRef | null = null;\n private focusTrap: ConfigurableFocusTrap | null = null;\n private previouslyFocused: HTMLElement | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n this.destroyRef.onDestroy(() => this.closeOverlay());\n }\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n const pos = this.position();\n const isHorizontal = pos === 'left' || pos === 'right';\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [pos === 'left' ? 'left' : pos === 'right' ? 'right' : 'centerHorizontally']();\n\n if (pos === 'top') positionStrategy.top();\n else if (pos === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = this.maxHeight();\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n hasBackdrop: this.hasBackdrop(),\n backdropClass: 'wr-drawer-backdrop',\n panelClass: ['wr-drawer-overlay', `wr-drawer-overlay--${pos}`],\n scrollStrategy: this.overlay.scrollStrategies.block(),\n width: isHorizontal ? this.width() : '100vw',\n height: isHorizontal ? undefined : this.height(),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n this.previouslyFocused = active instanceof HTMLElement ? active : null;\n const host = this.overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n queueMicrotask(() => {\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n });\n this.focusTrap = this.focusTrapFactory.create(host);\n void this.focusTrap.focusInitialElementWhenReady();\n }\n\n if (this.closeOnBackdropClick()) {\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.open.set(false));\n }\n\n if (this.closeOnEscape()) {\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n }\n });\n }\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n}\n","<ng-template>\n <div #panel [class]=\"panelClass()\">\n @if (showHandle()) {\n <div\n class=\"wr-drawer__handle\"\n aria-hidden=\"true\"\n (pointerdown)=\"onSwipeStart($event)\"\n (pointermove)=\"onSwipeMove($event, panel)\"\n (pointerup)=\"onSwipeEnd($event, panel)\"\n (pointercancel)=\"onSwipeEnd($event, panel)\"\n >\n <span class=\"wr-drawer__grabber\"></span>\n </div>\n }\n @if (closable()) {\n <button type=\"button\" class=\"wr-drawer__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"open.set(false)\">\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 <ng-content />\n </div>\n</ng-template>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDrawerManager.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the drawer's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDrawerClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = drawers.open<ChatComponent, boolean>(ChatComponent, { position: 'right' });\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the drawer closes itself.\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject(WrDrawerRef);\n *\n * send(): void {\n * this.store.send(this.draft());\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDrawerRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated drawer component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDrawerRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the drawer, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the drawer is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDrawerManager.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * readonly data = inject<ChatData>(WR_DRAWER_DATA);\n * }\n * ```\n */\nexport const WR_DRAWER_DATA = new InjectionToken<unknown>('WR_DRAWER_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDrawerRef } from '../drawer-ref';\n\n/**\n * Token exposing the open drawer's `WrDrawerRef` to components and\n * directives rendered inside it (e.g. `[wrDrawerClose]`).\n *\n * **Prefer `inject(WrDrawerRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDrawerRef, { optional: true })`\n * works for content that also renders outside a drawer, and\n * `inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef)` types the generics\n * without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDrawerClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef);\n *\n * dismiss(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DRAWER_REF = new InjectionToken<WrDrawerRef<unknown, unknown>>('WR_DRAWER_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Injector, PLATFORM_ID, Service, afterNextRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, wrAppendOverlayClose } from 'ngwr/overlay';\n\nimport { WrDrawerRef } from './drawer-ref';\nimport type { WrDrawerOptions, WrDrawerPosition } from './interfaces';\nimport { WR_DRAWER_DATA, WR_DRAWER_REF } from './tokens';\n\nconst DEFAULT_POSITION: WrDrawerPosition = 'right';\nconst DEFAULT_WIDTH = '20rem';\nconst DEFAULT_HEIGHT = '16rem';\nconst BACKDROP_CLASS = 'wr-drawer-backdrop';\n\n/**\n * Opens drawer components in an isolated NGWR overlay — the programmatic\n * counterpart to `<wr-drawer [(open)]=\"…\">`.\n *\n * Use the component when the drawer is part of a template and its open state\n * is a signal you already own; use this service when the caller doesn't own\n * the markup (opening a chat panel from a toolbar action, from an effect, from\n * a route guard) or when you need the close result.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — drawers render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * `showHandle` / swipe-to-dismiss is component-only: it needs the drawer's own\n * wrapper markup, which the service path replaces with your component.\n *\n * @example\n * ```ts\n * const drawers = inject(WrDrawerManager);\n *\n * const ref = drawers.open(ChatComponent, {\n * data: { threadId },\n * position: 'right',\n * width: '28rem',\n * });\n *\n * await ref.awaitClose();\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Service()\nexport class WrDrawerManager {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly i18n = inject(WrI18n);\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDrawerOptions<D> = {}): WrDrawerRef<C, R> {\n const position = options.position ?? DEFAULT_POSITION;\n const isHorizontal = position === 'left' || position === 'right';\n\n // The content component is attached straight into the overlay pane, so the\n // panel styles land on the pane rather than on an inner wrapper.\n const panelClasses = [\n 'wr-drawer-overlay',\n `wr-drawer-overlay--${position}`,\n 'wr-drawer__panel',\n `wr-drawer__panel--${position}`,\n ];\n if (options.rounded) panelClasses.push('wr-drawer__panel--rounded');\n if (options.safeArea) panelClasses.push('wr-drawer__panel--safe-area');\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [position === 'left' ? 'left' : position === 'right' ? 'right' : 'centerHorizontally']();\n\n if (position === 'top') positionStrategy.top();\n else if (position === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = options.maxHeight ?? null;\n\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: options.hasBackdrop !== false,\n backdropClass: BACKDROP_CLASS,\n panelClass: panelClasses,\n width: isHorizontal ? (options.width ?? DEFAULT_WIDTH) : '100vw',\n height: isHorizontal ? undefined : (options.height ?? DEFAULT_HEIGHT),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const drawerRef = new WrDrawerRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n drawerRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DRAWER_DATA, useValue: options.data },\n { provide: WR_DRAWER_REF, useValue: drawerRef },\n // Provided as its own token as well, so drawer content can reach for\n // the familiar `inject(WrDrawerRef)` and close itself.\n { provide: WrDrawerRef, useValue: drawerRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n drawerRef.componentRef = overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss, same contract as WrDialog's `closable`.\n if (options.closable !== false) {\n host.classList.add('wr-drawer__panel--closable');\n const label = options.closeLabel ?? this.closeLabel();\n wrAppendOverlayClose(host, 'wr-drawer__close', label, () => drawerRef.close());\n }\n // Wire aria-labelledby to wrDrawerTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n afterNextRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n },\n { injector: this.parentInjector }\n );\n // Trap focus inside the drawer and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n drawerRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n // Overlay subscriptions complete when the overlay is disposed, so no\n // explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => drawerRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n drawerRef.close();\n }\n });\n }\n\n return drawerRef;\n }\n\n /**\n * The dismiss button's accessible name.\n *\n * Resolved per open, not once at injection: this is a root service, so a\n * `readI18nText` field — which is what `WrDialog` uses — would be evaluated\n * before an async catalog had loaded and then freeze that answer for the life\n * of the app.\n *\n * The miss check is the point. `t()` hands back the KEY when the catalog has\n * no entry, and `WrI18n` is root-provided with an empty catalog by default —\n * so an app that never configured i18n got a button announced as\n * \"drawer.close, button\". A name WAS present, which is exactly why the axe\n * gate could not see it.\n */\n private closeLabel(): string {\n const resolved = this.i18n.t('drawer.close');\n return resolved === 'drawer.close' ? 'Close drawer' : resolved;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Marks an element as the drawer's title row. Applies the `wr-drawer__title`\n * class so the drawer's stylesheet can lay it out alongside content and\n * footer slots. Auto-assigns an `id` so the drawer panel references it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"open\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>…</div>\n * </wr-drawer>\n * ```\n */\n@Directive({\n selector: '[wrDrawerTitle]',\n host: { class: 'wr-drawer__title', '[attr.id]': 'id' },\n})\nexport class WrDrawerTitle {\n /** Generated id used by the drawer panel for `aria-labelledby`. */\n readonly id = `wr-drawer-title-${++uid}`;\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\n/**\n * Marks the scrollable body of the drawer. Applies the `wr-drawer__content`\n * class so the panel's flex layout can stretch it between the title and the\n * footer.\n */\n@Directive({\n selector: '[wrDrawerContent]',\n host: { class: 'wr-drawer__content' },\n})\nexport class WrDrawerContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Marks the action row pinned to the bottom of the drawer. Adds the\n * `wr-drawer__footer` class plus an alignment modifier so action buttons\n * can sit at the start, center, or end of the row.\n *\n * @example\n * ```html\n * <div wrDrawerFooter align=\"end\">\n * <wr-btn wrDrawerClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" (click)=\"save()\">Save</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDrawerFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDrawerFooter {\n /** Horizontal alignment of footer content. @default 'end' */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-drawer__footer wr-drawer__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport { WrDrawer } from '../drawer';\nimport type { WrDrawerRef } from '../drawer-ref';\nimport { WR_DRAWER_REF } from '../tokens';\n\n/**\n * Closes the parent drawer on click. Attach to any clickable element.\n *\n * Works for both drawer flavours: inside `<wr-drawer>` it clears the\n * component's `open` model, and inside a `WrDrawerManager.open()` drawer it\n * closes the ref — optionally passing a `[wrDrawerClose]` value as the close\n * result (the component flavour has no result to carry, so the value is\n * ignored there).\n *\n * @example\n * ```html\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * <wr-btn color=\"primary\" [wrDrawerClose]=\"true\">Save</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDrawerClose]',\n host: { '(click)': 'close()' },\n})\nexport class WrDrawerClose<R = unknown> {\n /**\n * Value to pass to `close()` for service-opened drawers. When unset — or\n * used as a bare attribute — the drawer closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDrawerClose',\n // A bare `wrDrawerClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly drawer = inject(WrDrawer, { optional: true });\n private readonly ref = inject<WrDrawerRef<unknown, R>>(WR_DRAWER_REF, { optional: true });\n\n protected close(): void {\n // Element injectors win, so a surrounding `<wr-drawer>` is the nearer\n // owner even when a service-opened drawer sits further up the tree.\n if (this.drawer) {\n this.drawer.open.set(false);\n return;\n }\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-drawer.mjs","sources":["../../../projects/lib/drawer/drawer.ts","../../../projects/lib/drawer/drawer.html","../../../projects/lib/drawer/drawer-ref.ts","../../../projects/lib/drawer/tokens/drawer-data.token.ts","../../../projects/lib/drawer/tokens/drawer-ref.token.ts","../../../projects/lib/drawer/drawer-manager.ts","../../../projects/lib/drawer/directives/drawer-title.ts","../../../projects/lib/drawer/directives/drawer-content.ts","../../../projects/lib/drawer/directives/drawer-footer.ts","../../../projects/lib/drawer/directives/drawer-close.ts","../../../projects/lib/drawer/ngwr-drawer.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n PLATFORM_ID,\n TemplateRef,\n ViewContainerRef,\n ViewEncapsulation,\n afterEveryRender,\n effect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\nimport type { WrDrawerPosition } from './interfaces';\n\n/**\n * Side panel that slides in from an edge of the viewport. Two-way binds\n * `open` and renders into a CDK overlay so it sits above page content.\n *\n * Compose the body with `<wrDrawerTitle>`, `<wrDrawerContent>`, and\n * `<wrDrawerFooter>` directives.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"settingsOpen\" position=\"right\" width=\"24rem\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>...</div>\n * <div wrDrawerFooter>\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * </div>\n * </wr-drawer>\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Component({\n selector: 'wr-drawer',\n templateUrl: './drawer.html',\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrDrawer {\n /** Two-way bindable open state. */\n readonly open = model<boolean>(false);\n\n /** Side the drawer slides in from. @default 'right' */\n readonly position = input<WrDrawerPosition>('right');\n\n /** Width when position is left/right. Any CSS length. @default '20rem' */\n readonly width = input<string>('20rem');\n\n /** Height when position is top/bottom. Any CSS length. @default '16rem' */\n readonly height = input<string>('16rem');\n\n /**\n * Upper cap on height (top/bottom positions). Useful for bottom sheets\n * that should grow with content up to a viewport-relative max.\n * Any CSS length. @default null (no cap)\n */\n readonly maxHeight = input<string | null>(null);\n\n /**\n * Round the leading corners — the edge facing the viewport interior.\n * Common bottom-sheet styling. @default false\n */\n readonly rounded = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Render a grab handle at the leading edge and enable swipe-to-dismiss:\n * drag the handle toward the drawer's edge (down for `bottom`, left for\n * `left`, …) and release past ~30% of the panel to close. @default false\n */\n readonly showHandle = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Pad the trailing edge with `env(safe-area-inset-*)` so content\n * doesn't sit under the iOS home indicator. @default false\n */\n readonly safeArea = input(false, { transform: coerceBooleanProperty });\n\n /** Show the dimming backdrop. @default true */\n readonly hasBackdrop = input(true, { transform: coerceBooleanProperty });\n\n /** Close when the backdrop is clicked. @default true */\n readonly closeOnBackdropClick = input(true, { transform: coerceBooleanProperty });\n\n /** Close on Escape. @default true */\n readonly closeOnEscape = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Show a dismiss (×) button in the panel's top-right corner. Set `false` when\n * the projected content supplies its own close affordance. @default true\n */\n readonly closable = input(true, { transform: coerceBooleanProperty });\n\n /** Accessible name for the dismiss button. Falls back to `drawer.close`. */\n readonly closeLabel = input<string | null>(null);\n\n protected readonly resolvedCloseLabel = useI18nText(this.closeLabel, 'drawer.close', 'Close drawer');\n\n protected readonly panelTpl = viewChild.required(TemplateRef);\n\n protected panelClass(): string {\n const parts = ['wr-drawer__panel', `wr-drawer__panel--${this.position()}`];\n if (this.rounded()) parts.push('wr-drawer__panel--rounded');\n if (this.safeArea()) parts.push('wr-drawer__panel--safe-area');\n if (this.closable()) parts.push('wr-drawer__panel--closable');\n return parts.join(' ');\n }\n\n // Swipe-to-dismiss — gated to the grab handle, so it never fights the\n // panel's own scrolling. The panel follows the finger toward the closing\n // edge and closes past ~30% of its size, otherwise snaps back.\n\n private swipeStartX = 0;\n private swipeStartY = 0;\n private swiping = false;\n\n // Pointer, not Touch. The handle has always advertised itself to a mouse with\n // `cursor: grab`, but the gesture was bound to touch events only, so on a\n // desktop it could not be dragged at all. Pointer Events cover touch, mouse and\n // pen through one path — the same idiom `wr-splitter` already uses.\n\n protected onSwipeStart(event: PointerEvent): void {\n // Ignore secondary contacts of a multi-touch gesture.\n if (!event.isPrimary) return;\n this.swipeStartX = event.clientX;\n this.swipeStartY = event.clientY;\n this.swiping = true;\n // Capture, so the drag keeps reporting once the cursor leaves the 2.5rem\n // grabber — without it a mouse drag dies the moment it slips off the handle.\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n }\n\n protected onSwipeMove(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n // Only follow the pointer when dragging toward the closing edge.\n if (delta * sign <= 0) {\n panel.style.transform = '';\n return;\n }\n panel.style.transition = 'none';\n panel.style.transform = axis === 'y' ? `translateY(${delta}px)` : `translateX(${delta}px)`;\n }\n\n protected onSwipeEnd(event: PointerEvent, panel: HTMLElement): void {\n if (!this.swiping) return;\n this.swiping = false;\n const { axis, sign } = this.closeAxis();\n const delta = axis === 'y' ? event.clientY - this.swipeStartY : event.clientX - this.swipeStartX;\n const panelSize = axis === 'y' ? panel.offsetHeight : panel.offsetWidth;\n if (delta * sign > panelSize * 0.3) {\n this.open.set(false); // keep the dragged offset as the overlay disposes\n } else {\n panel.style.transition = '';\n panel.style.transform = '';\n }\n }\n\n /** Axis + sign of the closing direction for the current position. */\n private closeAxis(): { axis: 'x' | 'y'; sign: number } {\n switch (this.position()) {\n case 'bottom':\n return { axis: 'y', sign: 1 };\n case 'top':\n return { axis: 'y', sign: -1 };\n case 'left':\n return { axis: 'x', sign: -1 };\n case 'right':\n default:\n return { axis: 'x', sign: 1 };\n }\n }\n\n private readonly overlay = inject(WR_OVERLAY);\n private readonly vcr = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private overlayRef: OverlayRef | null = null;\n private focusTrap: ConfigurableFocusTrap | null = null;\n private previouslyFocused: HTMLElement | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n afterEveryRender(() => this.syncLabel());\n this.destroyRef.onDestroy(() => this.closeOverlay());\n }\n\n /**\n * Point the panel's `aria-labelledby` at the CURRENT `[wrDrawerTitle]`.\n *\n * Re-resolved after every render rather than once when the drawer opens,\n * because the title element is projected content and can come and go while\n * the drawer stays open — an `@if` around it, or a heading that only exists\n * once the data arrives. A one-shot lookup leaves the attribute naming an\n * element that has been removed or replaced, and a dangling reference is not\n * a name: the dialog is announced as unnamed, with nothing on screen to say\n * so. A missing title clears the attribute for the same reason.\n */\n private syncLabel(): void {\n const host = this.overlayRef?.overlayElement;\n if (!host) return;\n\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n }\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n const pos = this.position();\n const isHorizontal = pos === 'left' || pos === 'right';\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [pos === 'left' ? 'left' : pos === 'right' ? 'right' : 'centerHorizontally']();\n\n if (pos === 'top') positionStrategy.top();\n else if (pos === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = this.maxHeight();\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n hasBackdrop: this.hasBackdrop(),\n backdropClass: 'wr-drawer-backdrop',\n panelClass: ['wr-drawer-overlay', `wr-drawer-overlay--${pos}`],\n scrollStrategy: this.overlay.scrollStrategies.block(),\n width: isHorizontal ? this.width() : '100vw',\n height: isHorizontal ? undefined : this.height(),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n this.previouslyFocused = active instanceof HTMLElement ? active : null;\n const host = this.overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n this.focusTrap = this.focusTrapFactory.create(host);\n void this.focusTrap.focusInitialElementWhenReady();\n }\n\n if (this.closeOnBackdropClick()) {\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.open.set(false));\n }\n\n if (this.closeOnEscape()) {\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.open.set(false);\n }\n });\n }\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n}\n","<ng-template>\n <div #panel [class]=\"panelClass()\">\n @if (showHandle()) {\n <div\n class=\"wr-drawer__handle\"\n aria-hidden=\"true\"\n (pointerdown)=\"onSwipeStart($event)\"\n (pointermove)=\"onSwipeMove($event, panel)\"\n (pointerup)=\"onSwipeEnd($event, panel)\"\n (pointercancel)=\"onSwipeEnd($event, panel)\"\n >\n <span class=\"wr-drawer__grabber\"></span>\n </div>\n }\n @if (closable()) {\n <button type=\"button\" class=\"wr-drawer__close\" [attr.aria-label]=\"resolvedCloseLabel()\" (click)=\"open.set(false)\">\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 <ng-content />\n </div>\n</ng-template>\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDrawerManager.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the drawer's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDrawerClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = drawers.open<ChatComponent, boolean>(ChatComponent, { position: 'right' });\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the drawer closes itself.\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject(WrDrawerRef);\n *\n * send(): void {\n * this.store.send(this.draft());\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDrawerRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated drawer component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDrawerRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the drawer, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the drawer is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDrawerManager.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * readonly data = inject<ChatData>(WR_DRAWER_DATA);\n * }\n * ```\n */\nexport const WR_DRAWER_DATA = new InjectionToken<unknown>('WR_DRAWER_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDrawerRef } from '../drawer-ref';\n\n/**\n * Token exposing the open drawer's `WrDrawerRef` to components and\n * directives rendered inside it (e.g. `[wrDrawerClose]`).\n *\n * **Prefer `inject(WrDrawerRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDrawerRef, { optional: true })`\n * works for content that also renders outside a drawer, and\n * `inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef)` types the generics\n * without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDrawerClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ChatComponent {\n * private readonly ref = inject<WrDrawerRef<ChatComponent, boolean>>(WrDrawerRef);\n *\n * dismiss(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DRAWER_REF = new InjectionToken<WrDrawerRef<unknown, unknown>>('WR_DRAWER_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Injector, PLATFORM_ID, Service, afterEveryRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, wrAppendOverlayClose } from 'ngwr/overlay';\n\nimport { WrDrawerRef } from './drawer-ref';\nimport type { WrDrawerOptions, WrDrawerPosition } from './interfaces';\nimport { WR_DRAWER_DATA, WR_DRAWER_REF } from './tokens';\n\nconst DEFAULT_POSITION: WrDrawerPosition = 'right';\nconst DEFAULT_WIDTH = '20rem';\nconst DEFAULT_HEIGHT = '16rem';\nconst BACKDROP_CLASS = 'wr-drawer-backdrop';\n\n/**\n * Opens drawer components in an isolated NGWR overlay — the programmatic\n * counterpart to `<wr-drawer [(open)]=\"…\">`.\n *\n * Use the component when the drawer is part of a template and its open state\n * is a signal you already own; use this service when the caller doesn't own\n * the markup (opening a chat panel from a toolbar action, from an effect, from\n * a route guard) or when you need the close result.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — drawers render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * `showHandle` / swipe-to-dismiss is component-only: it needs the drawer's own\n * wrapper markup, which the service path replaces with your component.\n *\n * @example\n * ```ts\n * const drawers = inject(WrDrawerManager);\n *\n * const ref = drawers.open(ChatComponent, {\n * data: { threadId },\n * position: 'right',\n * width: '28rem',\n * });\n *\n * await ref.awaitClose();\n * ```\n *\n * @see https://ngwr.dev/reference/components/drawer\n */\n@Service()\nexport class WrDrawerManager {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly i18n = inject(WrI18n);\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDrawerOptions<D> = {}): WrDrawerRef<C, R> {\n const position = options.position ?? DEFAULT_POSITION;\n const isHorizontal = position === 'left' || position === 'right';\n\n // The content component is attached straight into the overlay pane, so the\n // panel styles land on the pane rather than on an inner wrapper.\n const panelClasses = [\n 'wr-drawer-overlay',\n `wr-drawer-overlay--${position}`,\n 'wr-drawer__panel',\n `wr-drawer__panel--${position}`,\n ];\n if (options.rounded) panelClasses.push('wr-drawer__panel--rounded');\n if (options.safeArea) panelClasses.push('wr-drawer__panel--safe-area');\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n const positionStrategy = this.overlay\n .position()\n .global()\n [position === 'left' ? 'left' : position === 'right' ? 'right' : 'centerHorizontally']();\n\n if (position === 'top') positionStrategy.top();\n else if (position === 'bottom') positionStrategy.bottom();\n else positionStrategy.centerVertically();\n\n const cap = options.maxHeight ?? null;\n\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: options.hasBackdrop !== false,\n backdropClass: BACKDROP_CLASS,\n panelClass: panelClasses,\n width: isHorizontal ? (options.width ?? DEFAULT_WIDTH) : '100vw',\n height: isHorizontal ? undefined : (options.height ?? DEFAULT_HEIGHT),\n maxHeight: isHorizontal ? undefined : (cap ?? undefined),\n });\n\n const drawerRef = new WrDrawerRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n drawerRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DRAWER_DATA, useValue: options.data },\n { provide: WR_DRAWER_REF, useValue: drawerRef },\n // Provided as its own token as well, so drawer content can reach for\n // the familiar `inject(WrDrawerRef)` and close itself.\n { provide: WrDrawerRef, useValue: drawerRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n drawerRef.componentRef = overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss, same contract as WrDialog's `closable`.\n if (options.closable !== false) {\n host.classList.add('wr-drawer__panel--closable');\n const label = options.closeLabel ?? this.closeLabel();\n wrAppendOverlayClose(host, 'wr-drawer__close', label, () => drawerRef.close());\n }\n // Wire aria-labelledby to wrDrawerTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n //\n // And after EVERY render, not just the next one: the title belongs to the\n // caller's component, so an `@if` or a late-arriving heading can replace\n // or remove the element the attribute names. A reference to a node that is\n // no longer there is not a name — the dialog announces as unnamed — so a\n // missing title clears the attribute rather than leaving it dangling.\n const labelSync = afterEveryRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDrawerTitle], [wr-drawer-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n else host.removeAttribute('aria-labelledby');\n },\n { injector: this.parentInjector }\n );\n // The hook is bound to the root injector, so it outlives the drawer unless\n // it is torn down with it. `detachments()` fires on dispose, which is the\n // one path every dismissal goes through.\n overlayRef.detachments().subscribe(() => labelSync.destroy());\n // Trap focus inside the drawer and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n drawerRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n // Overlay subscriptions complete when the overlay is disposed, so no\n // explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => drawerRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n drawerRef.close();\n }\n });\n }\n\n return drawerRef;\n }\n\n /**\n * The dismiss button's accessible name.\n *\n * Resolved per open, not once at injection: this is a root service, so a\n * `readI18nText` field — which is what `WrDialog` uses — would be evaluated\n * before an async catalog had loaded and then freeze that answer for the life\n * of the app.\n *\n * The miss check is the point. `t()` hands back the KEY when the catalog has\n * no entry, and `WrI18n` is root-provided with an empty catalog by default —\n * so an app that never configured i18n got a button announced as\n * \"drawer.close, button\". A name WAS present, which is exactly why the axe\n * gate could not see it.\n */\n private closeLabel(): string {\n const resolved = this.i18n.t('drawer.close');\n return resolved === 'drawer.close' ? 'Close drawer' : resolved;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Marks an element as the drawer's title row. Applies the `wr-drawer__title`\n * class so the drawer's stylesheet can lay it out alongside content and\n * footer slots. Auto-assigns an `id` so the drawer panel references it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <wr-drawer [(open)]=\"open\">\n * <h2 wrDrawerTitle>Settings</h2>\n * <div wrDrawerContent>…</div>\n * </wr-drawer>\n * ```\n */\n@Directive({\n selector: '[wrDrawerTitle]',\n host: { class: 'wr-drawer__title', '[attr.id]': 'id' },\n})\nexport class WrDrawerTitle {\n /** Generated id used by the drawer panel for `aria-labelledby`. */\n readonly id = `wr-drawer-title-${++uid}`;\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\n/**\n * Marks the scrollable body of the drawer. Applies the `wr-drawer__content`\n * class so the panel's flex layout can stretch it between the title and the\n * footer.\n */\n@Directive({\n selector: '[wrDrawerContent]',\n host: { class: 'wr-drawer__content' },\n})\nexport class WrDrawerContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Marks the action row pinned to the bottom of the drawer. Adds the\n * `wr-drawer__footer` class plus an alignment modifier so action buttons\n * can sit at the start, center, or end of the row.\n *\n * @example\n * ```html\n * <div wrDrawerFooter align=\"end\">\n * <wr-btn wrDrawerClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" (click)=\"save()\">Save</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDrawerFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDrawerFooter {\n /** Horizontal alignment of footer content. @default 'end' */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-drawer__footer wr-drawer__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport { WrDrawer } from '../drawer';\nimport type { WrDrawerRef } from '../drawer-ref';\nimport { WR_DRAWER_REF } from '../tokens';\n\n/**\n * Closes the parent drawer on click. Attach to any clickable element.\n *\n * Works for both drawer flavours: inside `<wr-drawer>` it clears the\n * component's `open` model, and inside a `WrDrawerManager.open()` drawer it\n * closes the ref — optionally passing a `[wrDrawerClose]` value as the close\n * result (the component flavour has no result to carry, so the value is\n * ignored there).\n *\n * @example\n * ```html\n * <wr-btn wrDrawerClose>Close</wr-btn>\n * <wr-btn color=\"primary\" [wrDrawerClose]=\"true\">Save</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDrawerClose]',\n host: { '(click)': 'close()' },\n})\nexport class WrDrawerClose<R = unknown> {\n /**\n * Value to pass to `close()` for service-opened drawers. When unset — or\n * used as a bare attribute — the drawer closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDrawerClose',\n // A bare `wrDrawerClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly drawer = inject(WrDrawer, { optional: true });\n private readonly ref = inject<WrDrawerRef<unknown, R>>(WR_DRAWER_REF, { optional: true });\n\n protected close(): void {\n // Element injectors win, so a surrounding `<wr-drawer>` is the nearer\n // owner even when a service-opened drawer sits further up the tree.\n if (this.drawer) {\n this.drawer.open.set(false);\n return;\n }\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}