ngwr 13.0.0 → 13.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/fesm2022/ngwr-border-glow.mjs +12 -3
  2. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  3. package/fesm2022/ngwr-breadcrumbs.mjs +14 -3
  4. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  5. package/fesm2022/ngwr-context-menu.mjs +6 -2
  6. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  7. package/fesm2022/ngwr-dialog.mjs +22 -16
  8. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  9. package/fesm2022/ngwr-directives.mjs +5 -2
  10. package/fesm2022/ngwr-directives.mjs.map +1 -1
  11. package/fesm2022/ngwr-drawer.mjs +24 -18
  12. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  13. package/fesm2022/ngwr-dropdown.mjs +6 -2
  14. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  15. package/fesm2022/ngwr-fuzzy-text.mjs +21 -4
  16. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  17. package/fesm2022/ngwr-gradient-text.mjs +9 -2
  18. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  19. package/fesm2022/ngwr-icon-adapters-feather.mjs +11 -0
  20. package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
  21. package/fesm2022/ngwr-icon-adapters-lucide.mjs +22 -2
  22. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  23. package/fesm2022/ngwr-icon.mjs +474 -37
  24. package/fesm2022/ngwr-icon.mjs.map +1 -1
  25. package/fesm2022/ngwr-markdown.mjs +63 -11
  26. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  27. package/fesm2022/ngwr-overlay.mjs +36 -7
  28. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  29. package/fesm2022/ngwr-qr.mjs +38 -1
  30. package/fesm2022/ngwr-qr.mjs.map +1 -1
  31. package/fesm2022/ngwr-shiny-text.mjs +10 -3
  32. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  33. package/fesm2022/ngwr-tabs.mjs +6 -2
  34. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  35. package/fesm2022/ngwr-utils.mjs +107 -1
  36. package/fesm2022/ngwr-utils.mjs.map +1 -1
  37. package/fesm2022/ngwr-version.mjs +1 -1
  38. package/fesm2022/ngwr-version.mjs.map +1 -1
  39. package/llms-full.txt +1 -1
  40. package/package.json +3 -3
  41. package/types/ngwr-breadcrumbs.d.ts +1 -0
  42. package/types/ngwr-fuzzy-text.d.ts +5 -0
  43. package/types/ngwr-icon-adapters-feather.d.ts +11 -0
  44. package/types/ngwr-icon.d.ts +42 -1
  45. package/types/ngwr-shiny-text.d.ts +1 -0
  46. package/types/ngwr-utils.d.ts +47 -1
  47. package/types/ngwr-version.d.ts +1 -1
@@ -3,7 +3,7 @@ import { isPlatformBrowser } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { input, inject, ElementRef, PLATFORM_ID, computed, effect, ViewEncapsulation, Component } from '@angular/core';
5
5
  import { WrPlatform } from 'ngwr/platform';
6
- import { numAttr } from 'ngwr/utils';
6
+ import { isSafeCssValue, numAttr } from 'ngwr/utils';
7
7
 
8
8
  /**
9
9
  * @license
@@ -48,7 +48,11 @@ function buildGlowVars(glowColor, intensity) {
48
48
  }
49
49
  function buildGradientVars(colors) {
50
50
  const out = {};
51
- const palette = colors.length > 0 ? colors : DEFAULT_COLORS;
51
+ // Each entry is INTERPOLATED into the `radial-gradient()` below, so a value
52
+ // that balances the parens around it escapes into a sibling layer and can add
53
+ // a `url()` the browser fetches. One unsafe entry discards the palette — the
54
+ // same all-or-nothing rule `wr-gradient-text` follows, for the same reason.
55
+ const palette = colors.length > 0 && colors.every(color => isSafeCssValue(color)) ? colors : DEFAULT_COLORS;
52
56
  for (let i = 0; i < GRADIENT_VAR_NAMES.length; i++) {
53
57
  const colour = palette[Math.min(GRADIENT_COLOR_INDEX[i], palette.length - 1)];
54
58
  out[GRADIENT_VAR_NAMES[i]] = `radial-gradient(at ${GRADIENT_POSITIONS[i]}, ${colour} 0px, transparent 50%)`;
@@ -150,8 +154,13 @@ class WrBorderGlow {
150
154
  Object.assign(vars, buildGradientVars(colors));
151
155
  // Colour vars are written only when set — otherwise the stylesheet's
152
156
  // per-theme defaults (light vs dark) take over.
157
+ // Composed, not passed through: `_rules.scss` reads this var inside a
158
+ // `linear-gradient()` and again in a `background` shorthand, where a `url()`
159
+ // is valid and fetches. An audit bound `url("…")` here and recorded the
160
+ // request. Validated like its `colors` sibling on this same component —
161
+ // leaving one of the two unchecked is two rules inside one component.
153
162
  const bg = this.backgroundColor();
154
- if (bg !== null)
163
+ if (bg !== null && isSafeCssValue(bg))
155
164
  vars['--wr-border-glow-bg'] = bg;
156
165
  const glow = this.glowColor();
157
166
  if (glow !== null)
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-border-glow.mjs","sources":["../../../projects/lib/border-glow/border-glow.ts","../../../projects/lib/border-glow/border-glow.html","../../../projects/lib/border-glow/ngwr-border-glow.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 * Port of the reactbits.dev BorderGlow effect — a cursor-tracked cone of\n * mesh-gradient light that follows the pointer along the card's perimeter,\n * with an outer halo and optional auto-sweep on mount.\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Component, ElementRef, PLATFORM_ID, ViewEncapsulation, computed, effect, inject, input } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { numAttr } from 'ngwr/utils';\n\nconst RADIANS_TO_DEG = 180 / Math.PI;\n\ninterface ParsedHsl {\n readonly h: number;\n readonly s: number;\n readonly l: number;\n}\n\nfunction parseHsl(input: string): ParsedHsl {\n const match = /([\\d.]+)\\s*([\\d.]+)%?\\s*([\\d.]+)%?/.exec(input);\n if (!match) return { h: 40, s: 80, l: 80 };\n return { h: Number.parseFloat(match[1]), s: Number.parseFloat(match[2]), l: Number.parseFloat(match[3]) };\n}\n\nconst GLOW_OPACITY_STEPS = [100, 60, 50, 40, 30, 20, 10] as const;\nconst GLOW_VAR_SUFFIXES = ['', '-60', '-50', '-40', '-30', '-20', '-10'] as const;\n\nconst GRADIENT_POSITIONS = ['80% 55%', '69% 34%', '8% 6%', '41% 38%', '86% 85%', '82% 18%', '51% 4%'] as const;\nconst GRADIENT_VAR_NAMES = [\n '--wr-border-glow-gradient-one',\n '--wr-border-glow-gradient-two',\n '--wr-border-glow-gradient-three',\n '--wr-border-glow-gradient-four',\n '--wr-border-glow-gradient-five',\n '--wr-border-glow-gradient-six',\n '--wr-border-glow-gradient-seven',\n] as const;\nconst GRADIENT_COLOR_INDEX = [0, 1, 2, 0, 1, 2, 1] as const;\n\nconst DEFAULT_COLORS: readonly string[] = ['#c084fc', '#f472b6', '#38bdf8'];\n\nfunction buildGlowVars(glowColor: string, intensity: number): Record<string, string> {\n const { h, s, l } = parseHsl(glowColor);\n const base = `${h}deg ${s}% ${l}%`;\n const out: Record<string, string> = {};\n for (let i = 0; i < GLOW_OPACITY_STEPS.length; i++) {\n const alpha = Math.min(GLOW_OPACITY_STEPS[i] * intensity, 100);\n out[`--wr-border-glow-color${GLOW_VAR_SUFFIXES[i]}`] = `hsl(${base} / ${alpha}%)`;\n }\n return out;\n}\n\nfunction buildGradientVars(colors: readonly string[]): Record<string, string> {\n const out: Record<string, string> = {};\n const palette = colors.length > 0 ? colors : DEFAULT_COLORS;\n for (let i = 0; i < GRADIENT_VAR_NAMES.length; i++) {\n const colour = palette[Math.min(GRADIENT_COLOR_INDEX[i], palette.length - 1)];\n out[GRADIENT_VAR_NAMES[i]] = `radial-gradient(at ${GRADIENT_POSITIONS[i]}, ${colour} 0px, transparent 50%)`;\n }\n out['--wr-border-glow-gradient-base'] = `linear-gradient(${palette[0]} 0 100%)`;\n return out;\n}\n\ninterface AnimateOptions {\n readonly start?: number;\n readonly end?: number;\n readonly duration?: number;\n readonly delay?: number;\n readonly ease?: (t: number) => number;\n readonly onUpdate: (v: number) => void;\n readonly onEnd?: () => void;\n}\n\n/** Tiny rAF-driven tweener. Returns a cancel function so callers can clean up on destroy. */\nfunction animateValue(opts: AnimateOptions): () => void {\n const { start = 0, end = 100, duration = 1000, delay = 0, ease = (t: number): number => t, onUpdate, onEnd } = opts;\n let raf = 0;\n let cancelled = false;\n\n const startAt = performance.now() + delay;\n const tick = (): void => {\n if (cancelled) return;\n const elapsed = performance.now() - startAt;\n const t = Math.min(Math.max(elapsed / duration, 0), 1);\n onUpdate(start + (end - start) * ease(t));\n if (t < 1) raf = requestAnimationFrame(tick);\n else if (onEnd) onEnd();\n };\n\n const timer = setTimeout(() => {\n raf = requestAnimationFrame(tick);\n }, delay);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n cancelAnimationFrame(raf);\n };\n}\n\n/**\n * Cursor-tracked glowing border card. A cone of light follows the pointer\n * along the card's perimeter, brightening as the cursor approaches an edge.\n *\n * - Outer halo via stacked `box-shadow` on an inner `.edge-light` element.\n * - Inner \"soft bloom\" via `mix-blend-mode: soft-light` for content near the\n * edges (subtle; control via `[fillOpacity]`).\n * - Optional `[animated]` mode performs a one-shot sweep on mount, useful\n * for drawing attention to a freshly-rendered card.\n *\n * @example\n * ```html\n * <wr-border-glow [animated]=\"true\" [colors]=\"['#c084fc', '#f472b6', '#38bdf8']\">\n * <h3>Hover me</h3>\n * <p>The border lights up where the cursor is.</p>\n * </wr-border-glow>\n * ```\n *\n * @see https://www.reactbits.dev/components/border-glow (visual reference)\n */\n@Component({\n selector: 'wr-border-glow',\n templateUrl: './border-glow.html',\n styleUrl: './border-glow.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-border-glow',\n '(pointermove)': 'onPointerMove($event)',\n },\n})\nexport class WrBorderGlow {\n /** Card background fill. When unset, uses the theme surface token. */\n readonly backgroundColor = input<string | null>(null);\n\n /** Corner radius in pixels. @default 28 */\n readonly borderRadius = input(28, { transform: numAttr(28) });\n\n /** Halo extent in pixels — how far the outer glow reaches past the card edge. @default 40 */\n readonly glowRadius = input(40, { transform: numAttr(40) });\n\n /** Halo opacity multiplier (1 = full strength). @default 1 */\n readonly glowIntensity = input(1, { transform: numAttr(1) });\n\n /** Width of the lit cone as a percentage of the perimeter. @default 25 */\n readonly coneSpread = input(25, { transform: numAttr(25) });\n\n /** How sharply the halo fades as the cursor leaves the edge. Lower = wider falloff. @default 30 */\n readonly edgeSensitivity = input(30, { transform: numAttr(30) });\n\n /** Strength of the soft-light interior fill near edges. @default 0.5 */\n readonly fillOpacity = input(0.5, { transform: numAttr(0.5) });\n\n /**\n * Halo colour as `'H S L'` (HSL parts, no commas). When unset, the theme\n * decides: a deep amber on light surfaces, pale amber on dark. Note\n * `glowIntensity` only applies alongside an explicit `glowColor`.\n */\n readonly glowColor = input<string | null>(null);\n\n /**\n * Mesh-gradient palette for the colored border slice. When unset, the\n * theme decides: deep tones on light, pastels on dark.\n */\n readonly colors = input<readonly string[] | null>(null);\n\n /** Play a one-shot perimeter sweep on mount, then fade out. @default false */\n readonly animated = input(false, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Inline CSS variable bag — recomputed when colour / radius / sensitivity inputs change. */\n protected readonly cssVars = computed<Record<string, string>>(() => {\n const vars: Record<string, string> = {\n '--wr-border-glow-radius': `${this.borderRadius()}px`,\n '--wr-border-glow-padding': `${this.glowRadius()}px`,\n '--wr-border-glow-cone-spread': String(this.coneSpread()),\n '--wr-border-glow-edge-sensitivity': String(this.edgeSensitivity()),\n '--wr-border-glow-fill-opacity': String(this.fillOpacity()),\n };\n const colors = this.colors();\n if (colors !== null) Object.assign(vars, buildGradientVars(colors));\n // Colour vars are written only when set — otherwise the stylesheet's\n // per-theme defaults (light vs dark) take over.\n const bg = this.backgroundColor();\n if (bg !== null) vars['--wr-border-glow-bg'] = bg;\n const glow = this.glowColor();\n if (glow !== null) Object.assign(vars, buildGlowVars(glow, this.glowIntensity()));\n return vars;\n });\n\n constructor() {\n // Apply the variable bag to the host on every input change. Bind in an\n // effect rather than `host: { '[style.--foo]': '...' }` so a single\n // `setProperty` loop handles the lot.\n effect(() => {\n const host = this.el.nativeElement;\n const vars = this.cssVars();\n for (const [k, v] of Object.entries(vars)) host.style.setProperty(k, v);\n });\n\n if (!this.isBrowser) return;\n\n // Auto-sweep on mount — fires once when `animated` is true.\n effect(onCleanup => {\n if (!this.animated()) return;\n onCleanup(this.runAutoSweep());\n });\n }\n\n /** Pointer-driven update of `--wr-border-glow-angle` + `--wr-border-glow-edge-proximity`. */\n protected onPointerMove(event: PointerEvent): void {\n const host = this.el.nativeElement;\n const rect = host.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n\n const dx = x - cx;\n const dy = y - cy;\n\n // `edge-proximity`: 0 at centre, 1 at the perimeter (whichever axis hits first).\n let edge = 0;\n if (dx !== 0 || dy !== 0) {\n const kx = dx === 0 ? Infinity : cx / Math.abs(dx);\n const ky = dy === 0 ? Infinity : cy / Math.abs(dy);\n edge = Math.min(Math.max(1 / Math.min(kx, ky), 0), 1);\n }\n\n // `cursor-angle`: 0deg = top, increases clockwise.\n let angle = 0;\n if (dx !== 0 || dy !== 0) {\n angle = Math.atan2(dy, dx) * RADIANS_TO_DEG + 90;\n if (angle < 0) angle += 360;\n }\n\n host.style.setProperty('--wr-border-glow-edge-proximity', (edge * 100).toFixed(3));\n host.style.setProperty('--wr-border-glow-angle', `${angle.toFixed(3)}deg`);\n }\n\n /** One-shot perimeter sweep: in → around → out, mirroring the reactbits behaviour. */\n private runAutoSweep(): () => void {\n // Reduced motion: skip the decorative mount sweep. The pointer-driven\n // glow stays — it maps 1:1 to the cursor with no autonomous motion.\n if (this.platform.prefersReducedMotion()) return () => undefined;\n const host = this.el.nativeElement;\n const ANGLE_START = 110;\n const ANGLE_END = 465;\n host.classList.add('wr-border-glow--sweeping');\n host.style.setProperty('--wr-border-glow-angle', `${ANGLE_START}deg`);\n\n const easeOutCubic = (t: number): number => 1 - (1 - t) ** 3;\n const easeInCubic = (t: number): number => t * t * t;\n const lerpAngle = (v: number): string => `${(ANGLE_END - ANGLE_START) * (v / 100) + ANGLE_START}deg`;\n\n // 1. Ramp edge-proximity up to 100 quickly.\n const cancelA = animateValue({\n duration: 500,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n });\n // 2. Sweep angle first half (ease-in).\n const cancelB = animateValue({\n duration: 1500,\n end: 50,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 3. Sweep angle second half (ease-out).\n const cancelC = animateValue({\n delay: 1500,\n duration: 2250,\n start: 50,\n end: 100,\n ease: easeOutCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 4. Fade proximity back to 0.\n const cancelD = animateValue({\n delay: 2500,\n duration: 1500,\n start: 100,\n end: 0,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n onEnd: () => host.classList.remove('wr-border-glow--sweeping'),\n });\n\n // Returned rather than registered on `destroyRef`: this method runs from an\n // effect, so registering there stacked one more teardown per re-run and none\n // of them fired until the component died. The caller ties it to the effect's\n // own cleanup instead.\n return () => {\n cancelA();\n cancelB();\n cancelC();\n cancelD();\n host.classList.remove('wr-border-glow--sweeping');\n };\n }\n}\n","<span class=\"wr-border-glow__edge\" aria-hidden=\"true\"></span>\n<div class=\"wr-border-glow__inner\">\n <ng-content />\n</div>\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-border-glow.mjs","sources":["../../../projects/lib/border-glow/border-glow.ts","../../../projects/lib/border-glow/border-glow.html","../../../projects/lib/border-glow/ngwr-border-glow.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 * Port of the reactbits.dev BorderGlow effect — a cursor-tracked cone of\n * mesh-gradient light that follows the pointer along the card's perimeter,\n * with an outer halo and optional auto-sweep on mount.\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Component, ElementRef, PLATFORM_ID, ViewEncapsulation, computed, effect, inject, input } from '@angular/core';\n\nimport { WrPlatform } from 'ngwr/platform';\nimport { isSafeCssValue, numAttr } from 'ngwr/utils';\n\nconst RADIANS_TO_DEG = 180 / Math.PI;\n\ninterface ParsedHsl {\n readonly h: number;\n readonly s: number;\n readonly l: number;\n}\n\nfunction parseHsl(input: string): ParsedHsl {\n const match = /([\\d.]+)\\s*([\\d.]+)%?\\s*([\\d.]+)%?/.exec(input);\n if (!match) return { h: 40, s: 80, l: 80 };\n return { h: Number.parseFloat(match[1]), s: Number.parseFloat(match[2]), l: Number.parseFloat(match[3]) };\n}\n\nconst GLOW_OPACITY_STEPS = [100, 60, 50, 40, 30, 20, 10] as const;\nconst GLOW_VAR_SUFFIXES = ['', '-60', '-50', '-40', '-30', '-20', '-10'] as const;\n\nconst GRADIENT_POSITIONS = ['80% 55%', '69% 34%', '8% 6%', '41% 38%', '86% 85%', '82% 18%', '51% 4%'] as const;\nconst GRADIENT_VAR_NAMES = [\n '--wr-border-glow-gradient-one',\n '--wr-border-glow-gradient-two',\n '--wr-border-glow-gradient-three',\n '--wr-border-glow-gradient-four',\n '--wr-border-glow-gradient-five',\n '--wr-border-glow-gradient-six',\n '--wr-border-glow-gradient-seven',\n] as const;\nconst GRADIENT_COLOR_INDEX = [0, 1, 2, 0, 1, 2, 1] as const;\n\nconst DEFAULT_COLORS: readonly string[] = ['#c084fc', '#f472b6', '#38bdf8'];\n\nfunction buildGlowVars(glowColor: string, intensity: number): Record<string, string> {\n const { h, s, l } = parseHsl(glowColor);\n const base = `${h}deg ${s}% ${l}%`;\n const out: Record<string, string> = {};\n for (let i = 0; i < GLOW_OPACITY_STEPS.length; i++) {\n const alpha = Math.min(GLOW_OPACITY_STEPS[i] * intensity, 100);\n out[`--wr-border-glow-color${GLOW_VAR_SUFFIXES[i]}`] = `hsl(${base} / ${alpha}%)`;\n }\n return out;\n}\n\nfunction buildGradientVars(colors: readonly string[]): Record<string, string> {\n const out: Record<string, string> = {};\n // Each entry is INTERPOLATED into the `radial-gradient()` below, so a value\n // that balances the parens around it escapes into a sibling layer and can add\n // a `url()` the browser fetches. One unsafe entry discards the palette — the\n // same all-or-nothing rule `wr-gradient-text` follows, for the same reason.\n const palette = colors.length > 0 && colors.every(color => isSafeCssValue(color)) ? colors : DEFAULT_COLORS;\n for (let i = 0; i < GRADIENT_VAR_NAMES.length; i++) {\n const colour = palette[Math.min(GRADIENT_COLOR_INDEX[i], palette.length - 1)];\n out[GRADIENT_VAR_NAMES[i]] = `radial-gradient(at ${GRADIENT_POSITIONS[i]}, ${colour} 0px, transparent 50%)`;\n }\n out['--wr-border-glow-gradient-base'] = `linear-gradient(${palette[0]} 0 100%)`;\n return out;\n}\n\ninterface AnimateOptions {\n readonly start?: number;\n readonly end?: number;\n readonly duration?: number;\n readonly delay?: number;\n readonly ease?: (t: number) => number;\n readonly onUpdate: (v: number) => void;\n readonly onEnd?: () => void;\n}\n\n/** Tiny rAF-driven tweener. Returns a cancel function so callers can clean up on destroy. */\nfunction animateValue(opts: AnimateOptions): () => void {\n const { start = 0, end = 100, duration = 1000, delay = 0, ease = (t: number): number => t, onUpdate, onEnd } = opts;\n let raf = 0;\n let cancelled = false;\n\n const startAt = performance.now() + delay;\n const tick = (): void => {\n if (cancelled) return;\n const elapsed = performance.now() - startAt;\n const t = Math.min(Math.max(elapsed / duration, 0), 1);\n onUpdate(start + (end - start) * ease(t));\n if (t < 1) raf = requestAnimationFrame(tick);\n else if (onEnd) onEnd();\n };\n\n const timer = setTimeout(() => {\n raf = requestAnimationFrame(tick);\n }, delay);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n cancelAnimationFrame(raf);\n };\n}\n\n/**\n * Cursor-tracked glowing border card. A cone of light follows the pointer\n * along the card's perimeter, brightening as the cursor approaches an edge.\n *\n * - Outer halo via stacked `box-shadow` on an inner `.edge-light` element.\n * - Inner \"soft bloom\" via `mix-blend-mode: soft-light` for content near the\n * edges (subtle; control via `[fillOpacity]`).\n * - Optional `[animated]` mode performs a one-shot sweep on mount, useful\n * for drawing attention to a freshly-rendered card.\n *\n * @example\n * ```html\n * <wr-border-glow [animated]=\"true\" [colors]=\"['#c084fc', '#f472b6', '#38bdf8']\">\n * <h3>Hover me</h3>\n * <p>The border lights up where the cursor is.</p>\n * </wr-border-glow>\n * ```\n *\n * @see https://www.reactbits.dev/components/border-glow (visual reference)\n */\n@Component({\n selector: 'wr-border-glow',\n templateUrl: './border-glow.html',\n styleUrl: './border-glow.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-border-glow',\n '(pointermove)': 'onPointerMove($event)',\n },\n})\nexport class WrBorderGlow {\n /** Card background fill. When unset, uses the theme surface token. */\n readonly backgroundColor = input<string | null>(null);\n\n /** Corner radius in pixels. @default 28 */\n readonly borderRadius = input(28, { transform: numAttr(28) });\n\n /** Halo extent in pixels — how far the outer glow reaches past the card edge. @default 40 */\n readonly glowRadius = input(40, { transform: numAttr(40) });\n\n /** Halo opacity multiplier (1 = full strength). @default 1 */\n readonly glowIntensity = input(1, { transform: numAttr(1) });\n\n /** Width of the lit cone as a percentage of the perimeter. @default 25 */\n readonly coneSpread = input(25, { transform: numAttr(25) });\n\n /** How sharply the halo fades as the cursor leaves the edge. Lower = wider falloff. @default 30 */\n readonly edgeSensitivity = input(30, { transform: numAttr(30) });\n\n /** Strength of the soft-light interior fill near edges. @default 0.5 */\n readonly fillOpacity = input(0.5, { transform: numAttr(0.5) });\n\n /**\n * Halo colour as `'H S L'` (HSL parts, no commas). When unset, the theme\n * decides: a deep amber on light surfaces, pale amber on dark. Note\n * `glowIntensity` only applies alongside an explicit `glowColor`.\n */\n readonly glowColor = input<string | null>(null);\n\n /**\n * Mesh-gradient palette for the colored border slice. When unset, the\n * theme decides: deep tones on light, pastels on dark.\n */\n readonly colors = input<readonly string[] | null>(null);\n\n /** Play a one-shot perimeter sweep on mount, then fade out. @default false */\n readonly animated = input(false, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly platform = inject(WrPlatform);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** Inline CSS variable bag — recomputed when colour / radius / sensitivity inputs change. */\n protected readonly cssVars = computed<Record<string, string>>(() => {\n const vars: Record<string, string> = {\n '--wr-border-glow-radius': `${this.borderRadius()}px`,\n '--wr-border-glow-padding': `${this.glowRadius()}px`,\n '--wr-border-glow-cone-spread': String(this.coneSpread()),\n '--wr-border-glow-edge-sensitivity': String(this.edgeSensitivity()),\n '--wr-border-glow-fill-opacity': String(this.fillOpacity()),\n };\n const colors = this.colors();\n if (colors !== null) Object.assign(vars, buildGradientVars(colors));\n // Colour vars are written only when set — otherwise the stylesheet's\n // per-theme defaults (light vs dark) take over.\n // Composed, not passed through: `_rules.scss` reads this var inside a\n // `linear-gradient()` and again in a `background` shorthand, where a `url()`\n // is valid and fetches. An audit bound `url(\"…\")` here and recorded the\n // request. Validated like its `colors` sibling on this same component —\n // leaving one of the two unchecked is two rules inside one component.\n const bg = this.backgroundColor();\n if (bg !== null && isSafeCssValue(bg)) vars['--wr-border-glow-bg'] = bg;\n const glow = this.glowColor();\n if (glow !== null) Object.assign(vars, buildGlowVars(glow, this.glowIntensity()));\n return vars;\n });\n\n constructor() {\n // Apply the variable bag to the host on every input change. Bind in an\n // effect rather than `host: { '[style.--foo]': '...' }` so a single\n // `setProperty` loop handles the lot.\n effect(() => {\n const host = this.el.nativeElement;\n const vars = this.cssVars();\n for (const [k, v] of Object.entries(vars)) host.style.setProperty(k, v);\n });\n\n if (!this.isBrowser) return;\n\n // Auto-sweep on mount — fires once when `animated` is true.\n effect(onCleanup => {\n if (!this.animated()) return;\n onCleanup(this.runAutoSweep());\n });\n }\n\n /** Pointer-driven update of `--wr-border-glow-angle` + `--wr-border-glow-edge-proximity`. */\n protected onPointerMove(event: PointerEvent): void {\n const host = this.el.nativeElement;\n const rect = host.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n\n const dx = x - cx;\n const dy = y - cy;\n\n // `edge-proximity`: 0 at centre, 1 at the perimeter (whichever axis hits first).\n let edge = 0;\n if (dx !== 0 || dy !== 0) {\n const kx = dx === 0 ? Infinity : cx / Math.abs(dx);\n const ky = dy === 0 ? Infinity : cy / Math.abs(dy);\n edge = Math.min(Math.max(1 / Math.min(kx, ky), 0), 1);\n }\n\n // `cursor-angle`: 0deg = top, increases clockwise.\n let angle = 0;\n if (dx !== 0 || dy !== 0) {\n angle = Math.atan2(dy, dx) * RADIANS_TO_DEG + 90;\n if (angle < 0) angle += 360;\n }\n\n host.style.setProperty('--wr-border-glow-edge-proximity', (edge * 100).toFixed(3));\n host.style.setProperty('--wr-border-glow-angle', `${angle.toFixed(3)}deg`);\n }\n\n /** One-shot perimeter sweep: in → around → out, mirroring the reactbits behaviour. */\n private runAutoSweep(): () => void {\n // Reduced motion: skip the decorative mount sweep. The pointer-driven\n // glow stays — it maps 1:1 to the cursor with no autonomous motion.\n if (this.platform.prefersReducedMotion()) return () => undefined;\n const host = this.el.nativeElement;\n const ANGLE_START = 110;\n const ANGLE_END = 465;\n host.classList.add('wr-border-glow--sweeping');\n host.style.setProperty('--wr-border-glow-angle', `${ANGLE_START}deg`);\n\n const easeOutCubic = (t: number): number => 1 - (1 - t) ** 3;\n const easeInCubic = (t: number): number => t * t * t;\n const lerpAngle = (v: number): string => `${(ANGLE_END - ANGLE_START) * (v / 100) + ANGLE_START}deg`;\n\n // 1. Ramp edge-proximity up to 100 quickly.\n const cancelA = animateValue({\n duration: 500,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n });\n // 2. Sweep angle first half (ease-in).\n const cancelB = animateValue({\n duration: 1500,\n end: 50,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 3. Sweep angle second half (ease-out).\n const cancelC = animateValue({\n delay: 1500,\n duration: 2250,\n start: 50,\n end: 100,\n ease: easeOutCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-angle', lerpAngle(v)),\n });\n // 4. Fade proximity back to 0.\n const cancelD = animateValue({\n delay: 2500,\n duration: 1500,\n start: 100,\n end: 0,\n ease: easeInCubic,\n onUpdate: v => host.style.setProperty('--wr-border-glow-edge-proximity', `${v}`),\n onEnd: () => host.classList.remove('wr-border-glow--sweeping'),\n });\n\n // Returned rather than registered on `destroyRef`: this method runs from an\n // effect, so registering there stacked one more teardown per re-run and none\n // of them fired until the component died. The caller ties it to the effect's\n // own cleanup instead.\n return () => {\n cancelA();\n cancelB();\n cancelC();\n cancelD();\n host.classList.remove('wr-border-glow--sweeping');\n };\n }\n}\n","<span class=\"wr-border-glow__edge\" aria-hidden=\"true\"></span>\n<div class=\"wr-border-glow__inner\">\n <ng-content />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, ViewEncapsulation, Component, computed } from '@angular/core';
2
+ import { input, computed, ViewEncapsulation, Component } from '@angular/core';
3
3
  import { useI18nText } from 'ngwr/i18n';
4
4
  import { NgTemplateOutlet } from '@angular/common';
5
5
  import { RouterLink } from '@angular/router';
@@ -11,6 +11,10 @@ import { WrIcon } from 'ngwr/icon';
11
11
  * Use of this source code is governed by an MIT-style license that can be
12
12
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
13
13
  */
14
+ /** Escape a string for use inside a double-quoted CSS `<string>`. */
15
+ function cssString(value) {
16
+ return value.replace(/[\\"]/g, '\\$&').replace(/[\n\r\f]/g, char => `\\${char.codePointAt(0).toString(16)} `);
17
+ }
14
18
  /**
15
19
  * Breadcrumb navigation. Project `<wr-breadcrumbs-item>` children — each keeps
16
20
  * its own element and takes `role="listitem"` inside the `<ol>` rather than
@@ -46,14 +50,21 @@ class WrBreadcrumbs {
46
50
  // announced in Russian on the same page while this one stayed "Breadcrumbs", and
47
51
  // the only escape was restating `[ariaLabel]` on every trail.
48
52
  resolvedAriaLabel = useI18nText(this.ariaLabel, 'breadcrumbs.label', 'Breadcrumbs');
53
+ // The glyph is WRAPPED in quotes here and unwrapped by `content:` in the
54
+ // stylesheet, so an unescaped `"` inside it closes the library's own string
55
+ // and the rest of the value is parsed as CSS — `/" url("…") "` computes to
56
+ // `content: "/" url("…") ""`, an image the browser fetches. Escaping is the
57
+ // whole fix, and it is lossless: a separator that IS a quote still renders.
58
+ separatorValue = computed(() => `"${cssString(this.separator())}"`, /* @ts-ignore */
59
+ ...(ngDevMode ? [{ debugName: "separatorValue" }] : /* istanbul ignore next */ []));
49
60
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrBreadcrumbs, deps: [], target: i0.ɵɵFactoryTarget.Component });
50
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: WrBreadcrumbs, isStandalone: true, selector: "wr-breadcrumbs", inputs: { separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--wr-breadcrumbs-separator": "'\"' + separator() + '\"'" }, classAttribute: "wr-breadcrumbs" }, ngImport: i0, template: "<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\n", styles: [".wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible,.wr-command-palette__panel input:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-breadcrumbs{--wr-breadcrumbs-separator: \"/\";--wr-breadcrumbs-gap: .5rem;--wr-breadcrumbs-color: rgba(var(--wr-color-on-surface-rgb), .6);--wr-breadcrumbs-current-color: var(--wr-color-on-surface);--wr-breadcrumbs-link-color: var(--wr-color-primary-ink);--wr-breadcrumbs-separator-color: rgba(var(--wr-color-on-surface-rgb), .3);display:block;font-family:var(--wr-font-family-base);font-size:var(--wr-text-sm);color:var(--wr-breadcrumbs-color)}.wr-breadcrumbs__nav{display:block}.wr-breadcrumbs__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wr-breadcrumbs-gap);margin:0;padding:0;list-style:none}.wr-breadcrumbs__item{display:inline-flex;align-items:center;gap:var(--wr-breadcrumbs-gap)}.wr-breadcrumbs__item:not(:first-child):before{content:var(--wr-breadcrumbs-separator);color:var(--wr-breadcrumbs-separator-color);-webkit-user-select:none;user-select:none}.wr-breadcrumbs__link{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-link-color);text-decoration:none;border-radius:var(--wr-border-radius-sm);transition:color .15s ease}.wr-breadcrumbs__link:hover{text-decoration:underline}.wr-breadcrumbs__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:2px}.wr-breadcrumbs__current{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-current-color);font-weight:600}.wr-breadcrumbs__icon{--wr-icon-size: 1rem;flex:0 0 auto}\n"], encapsulation: i0.ViewEncapsulation.None });
61
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: WrBreadcrumbs, isStandalone: true, selector: "wr-breadcrumbs", inputs: { separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--wr-breadcrumbs-separator": "separatorValue()" }, classAttribute: "wr-breadcrumbs" }, ngImport: i0, template: "<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\n", styles: [".wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible,.wr-command-palette__panel input:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-breadcrumbs{--wr-breadcrumbs-separator: \"/\";--wr-breadcrumbs-gap: .5rem;--wr-breadcrumbs-color: rgba(var(--wr-color-on-surface-rgb), .6);--wr-breadcrumbs-current-color: var(--wr-color-on-surface);--wr-breadcrumbs-link-color: var(--wr-color-primary-ink);--wr-breadcrumbs-separator-color: rgba(var(--wr-color-on-surface-rgb), .3);display:block;font-family:var(--wr-font-family-base);font-size:var(--wr-text-sm);color:var(--wr-breadcrumbs-color)}.wr-breadcrumbs__nav{display:block}.wr-breadcrumbs__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wr-breadcrumbs-gap);margin:0;padding:0;list-style:none}.wr-breadcrumbs__item{display:inline-flex;align-items:center;gap:var(--wr-breadcrumbs-gap)}.wr-breadcrumbs__item:not(:first-child):before{content:var(--wr-breadcrumbs-separator);color:var(--wr-breadcrumbs-separator-color);-webkit-user-select:none;user-select:none}.wr-breadcrumbs__link{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-link-color);text-decoration:none;border-radius:var(--wr-border-radius-sm);transition:color .15s ease}.wr-breadcrumbs__link:hover{text-decoration:underline}.wr-breadcrumbs__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:2px}.wr-breadcrumbs__current{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-current-color);font-weight:600}.wr-breadcrumbs__icon{--wr-icon-size: 1rem;flex:0 0 auto}\n"], encapsulation: i0.ViewEncapsulation.None });
51
62
  }
52
63
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrBreadcrumbs, decorators: [{
53
64
  type: Component,
54
65
  args: [{ selector: 'wr-breadcrumbs', encapsulation: ViewEncapsulation.None, host: {
55
66
  class: 'wr-breadcrumbs',
56
- '[style.--wr-breadcrumbs-separator]': "'\"' + separator() + '\"'",
67
+ '[style.--wr-breadcrumbs-separator]': 'separatorValue()',
57
68
  }, template: "<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\n", styles: [".wr-tabs__tab:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-sidebar__entry:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-sidebar__item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-anchor__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-collapse__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:-2px}.wr-command-palette__option:focus-visible,.wr-command-palette__panel input:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-mention-panel__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-segmented__option:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-back-top:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-stepper__header:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-window__chrome-action:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-dropdown-item:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-alert__close:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo)}.wr-breadcrumbs{--wr-breadcrumbs-separator: \"/\";--wr-breadcrumbs-gap: .5rem;--wr-breadcrumbs-color: rgba(var(--wr-color-on-surface-rgb), .6);--wr-breadcrumbs-current-color: var(--wr-color-on-surface);--wr-breadcrumbs-link-color: var(--wr-color-primary-ink);--wr-breadcrumbs-separator-color: rgba(var(--wr-color-on-surface-rgb), .3);display:block;font-family:var(--wr-font-family-base);font-size:var(--wr-text-sm);color:var(--wr-breadcrumbs-color)}.wr-breadcrumbs__nav{display:block}.wr-breadcrumbs__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--wr-breadcrumbs-gap);margin:0;padding:0;list-style:none}.wr-breadcrumbs__item{display:inline-flex;align-items:center;gap:var(--wr-breadcrumbs-gap)}.wr-breadcrumbs__item:not(:first-child):before{content:var(--wr-breadcrumbs-separator);color:var(--wr-breadcrumbs-separator-color);-webkit-user-select:none;user-select:none}.wr-breadcrumbs__link{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-link-color);text-decoration:none;border-radius:var(--wr-border-radius-sm);transition:color .15s ease}.wr-breadcrumbs__link:hover{text-decoration:underline}.wr-breadcrumbs__link:focus-visible{outline:var(--wr-focus-ring-width) solid var(--wr-focus-ring-color);outline-offset:var(--wr-focus-ring-offset);box-shadow:0 0 0 var(--wr-focus-ring-offset) var(--wr-focus-ring-halo);outline-offset:2px}.wr-breadcrumbs__current{display:inline-flex;align-items:center;gap:.375rem;color:var(--wr-breadcrumbs-current-color);font-weight:600}.wr-breadcrumbs__icon{--wr-icon-size: 1rem;flex:0 0 auto}\n"] }]
58
69
  }], propDecorators: { separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
59
70
 
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-breadcrumbs.mjs","sources":["../../../projects/lib/breadcrumbs/breadcrumbs.ts","../../../projects/lib/breadcrumbs/breadcrumbs.html","../../../projects/lib/breadcrumbs/breadcrumbs-item.ts","../../../projects/lib/breadcrumbs/breadcrumbs-item.html","../../../projects/lib/breadcrumbs/ngwr-breadcrumbs.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\n/**\n * Breadcrumb navigation. Project `<wr-breadcrumbs-item>` children — each keeps\n * its own element and takes `role=\"listitem\"` inside the `<ol>` rather than\n * rendering an `<li>`, separated by the configured glyph (default `/`). The\n * container exposes the `nav[aria-label]` landmark required by WCAG.\n *\n * @example\n * ```html\n * <wr-breadcrumbs>\n * <wr-breadcrumbs-item routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item routerLink=\"/docs\">Docs</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current</wr-breadcrumbs-item>\n * </wr-breadcrumbs>\n *\n * <!-- Custom separator -->\n * <wr-breadcrumbs separator=\"›\">…</wr-breadcrumbs>\n * ```\n *\n * @see https://ngwr.dev/reference/components/breadcrumbs\n */\n@Component({\n selector: 'wr-breadcrumbs',\n templateUrl: './breadcrumbs.html',\n styleUrl: './breadcrumbs.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-breadcrumbs',\n '[style.--wr-breadcrumbs-separator]': \"'\\\"' + separator() + '\\\"'\",\n },\n})\nexport class WrBreadcrumbs {\n /** Separator glyph between items. Any short string. @default '/' */\n readonly separator = input('/');\n\n /**\n * Accessible label for the `nav` landmark. Falls back to `breadcrumbs.label`,\n * then `'Breadcrumbs'`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n // The English default used to live on the input itself, which made this the one\n // landmark in the library a catalog could not reach: `wr-anchor` and `wr-sidebar`\n // announced in Russian on the same page while this one stayed \"Breadcrumbs\", and\n // the only escape was restating `[ariaLabel]` on every trail.\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'breadcrumbs.label', 'Breadcrumbs');\n}\n","<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\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 { NgTemplateOutlet } from '@angular/common';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\n/**\n * One row inside `<wr-breadcrumbs>`. The host itself is the row — a\n * `<wr-breadcrumbs-item role=\"listitem\" class=\"wr-breadcrumbs__item\">`\n * inside the parent's `<ol>` — and it contains either a real\n * `<a class=\"wr-breadcrumbs__link\">` (when `[href]` or `[routerLink]` is\n * set) or, for the current crumb, a non-interactive\n * `<a class=\"wr-breadcrumbs__current\" role=\"text\" tabindex=\"-1\"\n * aria-current=\"page\">` (when neither is set — typically the last crumb).\n *\n * @example\n * ```html\n * <wr-breadcrumbs-item icon=\"home\" routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item href=\"https://ngwr.dev\">External</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current page</wr-breadcrumbs-item>\n * ```\n */\n@Component({\n selector: 'wr-breadcrumbs-item',\n templateUrl: './breadcrumbs-item.html',\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, RouterLink, WrIcon],\n host: { class: 'wr-breadcrumbs__item', role: 'listitem' },\n})\nexport class WrBreadcrumbsItem {\n /** Plain anchor href. Overridden by `routerLink` when both are set. */\n readonly href = input<string | null>(null);\n\n /** Angular router target. Anything `RouterLink` accepts (string or `any[]`). */\n readonly routerLink = input<string | readonly unknown[] | null>(null);\n\n /** Open external `href` in a new tab. Ignored when `routerLink` is set. @default false */\n readonly external = input(false);\n\n /** Optional leading icon rendered inline before the label. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n protected readonly isLink = computed(() => this.href() != null || this.routerLink() != null);\n protected readonly isRouter = computed(() => this.routerLink() != null);\n\n protected readonly rootClass = computed(() => (this.isLink() ? 'wr-breadcrumbs__link' : 'wr-breadcrumbs__current'));\n}\n","<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\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-breadcrumbs.mjs","sources":["../../../projects/lib/breadcrumbs/breadcrumbs.ts","../../../projects/lib/breadcrumbs/breadcrumbs.html","../../../projects/lib/breadcrumbs/breadcrumbs-item.ts","../../../projects/lib/breadcrumbs/breadcrumbs-item.html","../../../projects/lib/breadcrumbs/ngwr-breadcrumbs.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\n/** Escape a string for use inside a double-quoted CSS `<string>`. */\nfunction cssString(value: string): string {\n return value.replace(/[\\\\\"]/g, '\\\\$&').replace(/[\\n\\r\\f]/g, char => `\\\\${char.codePointAt(0)!.toString(16)} `);\n}\n\n/**\n * Breadcrumb navigation. Project `<wr-breadcrumbs-item>` children — each keeps\n * its own element and takes `role=\"listitem\"` inside the `<ol>` rather than\n * rendering an `<li>`, separated by the configured glyph (default `/`). The\n * container exposes the `nav[aria-label]` landmark required by WCAG.\n *\n * @example\n * ```html\n * <wr-breadcrumbs>\n * <wr-breadcrumbs-item routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item routerLink=\"/docs\">Docs</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current</wr-breadcrumbs-item>\n * </wr-breadcrumbs>\n *\n * <!-- Custom separator -->\n * <wr-breadcrumbs separator=\"›\">…</wr-breadcrumbs>\n * ```\n *\n * @see https://ngwr.dev/reference/components/breadcrumbs\n */\n@Component({\n selector: 'wr-breadcrumbs',\n templateUrl: './breadcrumbs.html',\n styleUrl: './breadcrumbs.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'wr-breadcrumbs',\n '[style.--wr-breadcrumbs-separator]': 'separatorValue()',\n },\n})\nexport class WrBreadcrumbs {\n /** Separator glyph between items. Any short string. @default '/' */\n readonly separator = input('/');\n\n /**\n * Accessible label for the `nav` landmark. Falls back to `breadcrumbs.label`,\n * then `'Breadcrumbs'`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n // The English default used to live on the input itself, which made this the one\n // landmark in the library a catalog could not reach: `wr-anchor` and `wr-sidebar`\n // announced in Russian on the same page while this one stayed \"Breadcrumbs\", and\n // the only escape was restating `[ariaLabel]` on every trail.\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'breadcrumbs.label', 'Breadcrumbs');\n\n // The glyph is WRAPPED in quotes here and unwrapped by `content:` in the\n // stylesheet, so an unescaped `\"` inside it closes the library's own string\n // and the rest of the value is parsed as CSS — `/\" url(\"…\") \"` computes to\n // `content: \"/\" url(\"…\") \"\"`, an image the browser fetches. Escaping is the\n // whole fix, and it is lossless: a separator that IS a quote still renders.\n protected readonly separatorValue = computed(() => `\"${cssString(this.separator())}\"`);\n}\n","<nav class=\"wr-breadcrumbs__nav\" [attr.aria-label]=\"resolvedAriaLabel()\">\n <ol class=\"wr-breadcrumbs__list\">\n <ng-content />\n </ol>\n</nav>\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 { NgTemplateOutlet } from '@angular/common';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\n/**\n * One row inside `<wr-breadcrumbs>`. The host itself is the row — a\n * `<wr-breadcrumbs-item role=\"listitem\" class=\"wr-breadcrumbs__item\">`\n * inside the parent's `<ol>` — and it contains either a real\n * `<a class=\"wr-breadcrumbs__link\">` (when `[href]` or `[routerLink]` is\n * set) or, for the current crumb, a non-interactive\n * `<a class=\"wr-breadcrumbs__current\" role=\"text\" tabindex=\"-1\"\n * aria-current=\"page\">` (when neither is set — typically the last crumb).\n *\n * @example\n * ```html\n * <wr-breadcrumbs-item icon=\"home\" routerLink=\"/\">Home</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item href=\"https://ngwr.dev\">External</wr-breadcrumbs-item>\n * <wr-breadcrumbs-item>Current page</wr-breadcrumbs-item>\n * ```\n */\n@Component({\n selector: 'wr-breadcrumbs-item',\n templateUrl: './breadcrumbs-item.html',\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, RouterLink, WrIcon],\n host: { class: 'wr-breadcrumbs__item', role: 'listitem' },\n})\nexport class WrBreadcrumbsItem {\n /** Plain anchor href. Overridden by `routerLink` when both are set. */\n readonly href = input<string | null>(null);\n\n /** Angular router target. Anything `RouterLink` accepts (string or `any[]`). */\n readonly routerLink = input<string | readonly unknown[] | null>(null);\n\n /** Open external `href` in a new tab. Ignored when `routerLink` is set. @default false */\n readonly external = input(false);\n\n /** Optional leading icon rendered inline before the label. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n protected readonly isLink = computed(() => this.href() != null || this.routerLink() != null);\n protected readonly isRouter = computed(() => this.routerLink() != null);\n\n protected readonly rootClass = computed(() => (this.isLink() ? 'wr-breadcrumbs__link' : 'wr-breadcrumbs__current'));\n}\n","<!--\n The label lives in a template rather than inside each branch below. A default\n `<ng-content />` written into two `@if` branches fills only ONE of them — the\n last in static order — and the other renders empty, with no template error and\n nothing in the console. This component has been broken exactly that way\n before; stamping one template from either branch keeps two anchors and one\n projection.\n-->\n<ng-template #label>\n @if (icon(); as i) {\n <wr-icon class=\"wr-breadcrumbs__icon\" [name]=\"i\" />\n }\n <ng-content />\n</ng-template>\n\n@if (isRouter()) {\n <!--\n Only ROUTER crumbs get `RouterLink`. Applied unconditionally it owns the\n anchor's `href` and writes null into it whenever `routerLink` is null —\n which silently turned every `href`-based crumb, a documented input, into\n text that navigates nowhere.\n -->\n <a [class]=\"rootClass()\" [routerLink]=\"routerLink()\">\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n} @else {\n <a\n [class]=\"rootClass()\"\n [attr.href]=\"href()\"\n [attr.aria-current]=\"isLink() ? null : 'page'\"\n [attr.role]=\"isLink() ? null : 'text'\"\n [attr.tabindex]=\"isLink() ? null : -1\"\n [attr.target]=\"external() ? '_blank' : null\"\n [attr.rel]=\"external() ? 'noreferrer noopener' : null\"\n >\n <ng-container [ngTemplateOutlet]=\"label\" />\n </a>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;AAAA;;;;;AAKG;AAMH;AACA,SAAS,SAAS,CAAC,KAAa,EAAA;AAC9B,IAAA,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,IAAI,CAAA,EAAA,EAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA,CAAA,CAAG,CAAC;AAChH;AAEA;;;;;;;;;;;;;;;;;;;AAmBG;MAWU,aAAa,CAAA;;IAEf,SAAS,GAAG,KAAK,CAAC,GAAG;kFAAC;AAE/B;;;AAGG;IACM,SAAS,GAAG,KAAK,CAAgB,IAAI;kFAAC;;;;;IAM5B,iBAAiB,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,EAAE,aAAa,CAAC;;;;;;AAOnF,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAA,CAAA,EAAI,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA,CAAA,CAAG;uFAAC;uGArB3E,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,aAAa,kdC9C1B,6JAKA,EAAA,MAAA,EAAA,CAAA,mqKAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDyCa,aAAa,EAAA,UAAA,EAAA,CAAA;kBAVzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,aAAA,EAGX,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B;AACJ,wBAAA,KAAK,EAAE,gBAAgB;AACvB,wBAAA,oCAAoC,EAAE,kBAAkB;AACzD,qBAAA,EAAA,QAAA,EAAA,6JAAA,EAAA,MAAA,EAAA,CAAA,mqKAAA,CAAA,EAAA;;;AE5CH;;;;;AAKG;AAQH;;;;;;;;;;;;;;;AAeG;MAQU,iBAAiB,CAAA;;IAEnB,IAAI,GAAG,KAAK,CAAgB,IAAI;6EAAC;;IAGjC,UAAU,GAAG,KAAK,CAAqC,IAAI;mFAAC;;IAG5D,QAAQ,GAAG,KAAK,CAAC,KAAK;iFAAC;;IAGvB,IAAI,GAAG,KAAK,CAAoB,IAAI;6EAAC;AAE3B,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI;+EAAC;IACzE,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI;iFAAC;AAEpD,IAAA,SAAS,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,sBAAsB,GAAG,yBAAyB,CAAC;kFAAC;uGAhBxG,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,iBAAiB,mqBCpC9B,m4CAsCA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDLY,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,UAAU,kPAAE,MAAM,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FAGnC,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAP7B,SAAS;+BACE,qBAAqB,EAAA,aAAA,EAEhB,iBAAiB,CAAC,IAAI,WAC5B,CAAC,gBAAgB,EAAE,UAAU,EAAE,MAAM,CAAC,EAAA,IAAA,EACzC,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,UAAU,EAAE,EAAA,QAAA,EAAA,m4CAAA,EAAA;;;AElC3D;;AAEG;;;;"}
@@ -1084,7 +1084,7 @@ class WrContextMenuPanel {
1084
1084
  contentTpl = viewChild.required(TemplateRef, /* @ts-ignore */
1085
1085
  ...(ngDevMode ? [{ debugName: "contentTpl" }] : /* istanbul ignore next */ []));
1086
1086
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrContextMenuPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
1087
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.4", type: WrContextMenuPanel, isStandalone: true, selector: "wr-context-menu", host: { styleAttribute: "display:none" }, viewQueries: [{ propertyName: "contentTpl", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], exportAs: ["wrContextMenu"], ngImport: i0, template: '<ng-template><div class="wr-context-menu" role="menu"><ng-content /></div></ng-template>', isInline: true, encapsulation: i0.ViewEncapsulation.None });
1087
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.4", type: WrContextMenuPanel, isStandalone: true, selector: "wr-context-menu", host: { properties: { "style.display": "'none'" } }, viewQueries: [{ propertyName: "contentTpl", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], exportAs: ["wrContextMenu"], ngImport: i0, template: '<ng-template><div class="wr-context-menu" role="menu"><ng-content /></div></ng-template>', isInline: true, encapsulation: i0.ViewEncapsulation.None });
1088
1088
  }
1089
1089
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrContextMenuPanel, decorators: [{
1090
1090
  type: Component,
@@ -1093,7 +1093,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
1093
1093
  template: '<ng-template><div class="wr-context-menu" role="menu"><ng-content /></div></ng-template>',
1094
1094
  exportAs: 'wrContextMenu',
1095
1095
  encapsulation: ViewEncapsulation.None,
1096
- host: { style: 'display:none' },
1096
+ // A BOUND display rather than a static `style` attribute: Angular writes a
1097
+ // binding through `style.setProperty`, which no CSP governs, while a real
1098
+ // `style="…"` attribute is refused under `style-src 'self'` — and this host
1099
+ // would then lay out an empty box in the middle of the content.
1100
+ host: { '[style.display]': "'none'" },
1097
1101
  }]
1098
1102
  }], propDecorators: { contentTpl: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
1099
1103