ngwr 7.1.0 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +5 -3
  3. package/alert/styles/_index.scss +2 -0
  4. package/back-top/styles/_index.scss +4 -2
  5. package/carousel/styles/_index.scss +2 -0
  6. package/cascader/styles/_index.scss +16 -0
  7. package/color-picker/styles/_index.scss +7 -0
  8. package/command-palette/styles/_index.scss +28 -0
  9. package/density/styles/_index.scss +10 -0
  10. package/descriptions/styles/_index.scss +59 -0
  11. package/dialog/styles/_index.scss +2 -0
  12. package/drawer/styles/_index.scss +2 -0
  13. package/dropdown/styles/_index.scss +1 -0
  14. package/fesm2022/ngwr-carousel.mjs +45 -4
  15. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  16. package/fesm2022/ngwr-cascader.mjs +2 -2
  17. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  18. package/fesm2022/ngwr-command-palette.mjs +17 -3
  19. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  20. package/fesm2022/ngwr-context-menu.mjs +77 -5
  21. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  22. package/fesm2022/ngwr-density.mjs +3 -3
  23. package/fesm2022/ngwr-density.mjs.map +1 -1
  24. package/fesm2022/ngwr-descriptions.mjs +11 -2
  25. package/fesm2022/ngwr-descriptions.mjs.map +1 -1
  26. package/fesm2022/ngwr-dialog.mjs +11 -4
  27. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  28. package/fesm2022/ngwr-drag-drop.mjs +13 -3
  29. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  30. package/fesm2022/ngwr-drawer.mjs +66 -5
  31. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  32. package/fesm2022/ngwr-dropdown.mjs +35 -11
  33. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  34. package/fesm2022/ngwr-lightbox.mjs +45 -2
  35. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  36. package/fesm2022/ngwr-overlay.mjs +70 -1
  37. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  38. package/fesm2022/ngwr-page-header.mjs +11 -3
  39. package/fesm2022/ngwr-page-header.mjs.map +1 -1
  40. package/fesm2022/ngwr-pagination.mjs +11 -3
  41. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  42. package/fesm2022/ngwr-popover.mjs +36 -10
  43. package/fesm2022/ngwr-popover.mjs.map +1 -1
  44. package/fesm2022/ngwr-rotating-text.mjs +15 -4
  45. package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
  46. package/fesm2022/ngwr-select.mjs +35 -14
  47. package/fesm2022/ngwr-select.mjs.map +1 -1
  48. package/fesm2022/ngwr-stepper.mjs +11 -2
  49. package/fesm2022/ngwr-stepper.mjs.map +1 -1
  50. package/fesm2022/ngwr-table.mjs +10 -4
  51. package/fesm2022/ngwr-table.mjs.map +1 -1
  52. package/fesm2022/ngwr-tabs.mjs +38 -6
  53. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  54. package/fesm2022/ngwr-toast.mjs +54 -2
  55. package/fesm2022/ngwr-toast.mjs.map +1 -1
  56. package/fesm2022/ngwr-toolbar.mjs +11 -4
  57. package/fesm2022/ngwr-toolbar.mjs.map +1 -1
  58. package/fesm2022/ngwr-version.mjs +1 -1
  59. package/fesm2022/ngwr-version.mjs.map +1 -1
  60. package/lightbox/styles/_index.scss +4 -0
  61. package/llms-full.txt +673 -0
  62. package/llms.txt +106 -0
  63. package/overlay/styles/_index.scss +31 -0
  64. package/package.json +6 -5
  65. package/page-header/styles/_index.scss +16 -0
  66. package/pagination/styles/_index.scss +34 -0
  67. package/popover/styles/_index.scss +1 -0
  68. package/select/styles/_index.scss +27 -0
  69. package/slider/styles/_index.scss +3 -0
  70. package/splitter/styles/_index.scss +3 -0
  71. package/stepper/styles/_index.scss +30 -0
  72. package/styles.scss +1 -0
  73. package/table/styles/_index.scss +61 -0
  74. package/tabs/styles/_index.scss +24 -0
  75. package/theme/styles/_mixins.scss +47 -0
  76. package/toast/styles/_index.scss +32 -1
  77. package/toolbar/styles/_index.scss +29 -0
  78. package/tree/styles/_index.scss +15 -0
  79. package/types/ngwr-carousel.d.ts +8 -1
  80. package/types/ngwr-command-palette.d.ts +13 -1
  81. package/types/ngwr-context-menu.d.ts +25 -3
  82. package/types/ngwr-density.d.ts +2 -2
  83. package/types/ngwr-descriptions.d.ts +8 -1
  84. package/types/ngwr-dialog.d.ts +7 -0
  85. package/types/ngwr-drag-drop.d.ts +13 -1
  86. package/types/ngwr-drawer.d.ts +11 -3
  87. package/types/ngwr-dropdown.d.ts +10 -1
  88. package/types/ngwr-lightbox.d.ts +5 -0
  89. package/types/ngwr-overlay.d.ts +69 -1
  90. package/types/ngwr-page-header.d.ts +8 -1
  91. package/types/ngwr-pagination.d.ts +7 -1
  92. package/types/ngwr-popover.d.ts +10 -1
  93. package/types/ngwr-rotating-text.d.ts +1 -0
  94. package/types/ngwr-select.d.ts +10 -1
  95. package/types/ngwr-stepper.d.ts +8 -1
  96. package/types/ngwr-table.d.ts +7 -1
  97. package/types/ngwr-tabs.d.ts +6 -0
  98. package/types/ngwr-toolbar.d.ts +7 -1
  99. package/types/ngwr-version.d.ts +1 -1
@@ -1,10 +1,10 @@
1
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
1
2
  import { ScrollStrategyOptions } from '@angular/cdk/overlay';
2
3
  import { TemplatePortal } from '@angular/cdk/portal';
3
4
  import * as i0 from '@angular/core';
4
5
  import { input, output, inject, ElementRef, ViewContainerRef, DestroyRef, signal, effect, Directive, viewChild, TemplateRef, ViewEncapsulation, Component, computed } from '@angular/core';
5
6
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import { WR_OVERLAY } from 'ngwr/overlay';
7
- import { coerceBooleanProperty } from '@angular/cdk/coercion';
7
+ import { WR_OVERLAY, WR_RESPONSIVE_OVERLAYS, wrPresentAsSheet } from 'ngwr/overlay';
8
8
  import { WrIcon } from 'ngwr/icon';
9
9
 
10
10
  /**
@@ -62,12 +62,20 @@ class WrDropdown {
62
62
  /** Where the menu anchors relative to the trigger. @default 'bottom-start' */
63
63
  position = input('bottom-start', /* @ts-ignore */
64
64
  ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
65
+ /**
66
+ * Present the menu as a full-width bottom-sheet on small viewports instead
67
+ * of an anchored panel. `undefined` follows the app-wide
68
+ * `provideWrResponsiveOverlays()` setting; `true`/`false` overrides it.
69
+ * @default undefined
70
+ */
71
+ responsive = input(undefined, { ...(ngDevMode ? { debugName: "responsive" } : /* istanbul ignore next */ {}), transform: (v) => (v == null ? undefined : coerceBooleanProperty(v)) });
65
72
  /** Fires after the menu opens. */
66
73
  opened = output();
67
74
  /** Fires after the menu closes. */
68
75
  closed = output();
69
76
  host = inject(ElementRef);
70
77
  overlay = inject(WR_OVERLAY);
78
+ responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);
71
79
  vcr = inject(ViewContainerRef);
72
80
  scrollStrategies = inject(ScrollStrategyOptions);
73
81
  destroyRef = inject(DestroyRef);
@@ -126,16 +134,32 @@ class WrDropdown {
126
134
  openOverlay() {
127
135
  if (this.overlayRef)
128
136
  return;
129
- const positionStrategy = this.overlay
130
- .position()
131
- .flexibleConnectedTo(this.host)
132
- .withPositions(WR_DROPDOWN_POSITIONS[this.position()])
133
- .withPush(true);
137
+ // On small viewports (when opted in) detach from the trigger and present
138
+ // the menu as a full-width slide-up sheet pinned to the bottom edge.
139
+ const asSheet = wrPresentAsSheet(this.responsive(), this.responsiveConfig);
140
+ const positionStrategy = asSheet
141
+ ? this.overlay.position().global().centerHorizontally().bottom('0')
142
+ : this.overlay
143
+ .position()
144
+ .flexibleConnectedTo(this.host)
145
+ .withPositions(WR_DROPDOWN_POSITIONS[this.position()])
146
+ .withPush(true);
134
147
  this.overlayRef = this.overlay.create({
135
148
  positionStrategy,
136
- scrollStrategy: this.scrollStrategies.reposition(),
137
- panelClass: ['wr-dropdown-overlay', `wr-dropdown-overlay--${this.position()}`],
149
+ scrollStrategy: asSheet ? this.scrollStrategies.block() : this.scrollStrategies.reposition(),
150
+ width: asSheet ? '100%' : undefined,
151
+ hasBackdrop: asSheet,
152
+ backdropClass: asSheet ? 'wr-overlay-backdrop' : undefined,
153
+ panelClass: asSheet
154
+ ? ['wr-dropdown-overlay', 'wr-overlay-sheet']
155
+ : ['wr-dropdown-overlay', `wr-dropdown-overlay--${this.position()}`],
138
156
  });
157
+ if (asSheet) {
158
+ this.overlayRef
159
+ .backdropClick()
160
+ .pipe(takeUntilDestroyed(this.destroyRef))
161
+ .subscribe(() => this.isOpen.set(false));
162
+ }
139
163
  // Wire trigger id into menu so it can render aria-labelledby.
140
164
  this.menu().triggerId.set(this.triggerId);
141
165
  const portal = new TemplatePortal(this.menu().contentTpl(), this.vcr);
@@ -236,7 +260,7 @@ class WrDropdown {
236
260
  this.isOpen.set(false);
237
261
  };
238
262
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrDropdown, deps: [], target: i0.ɵɵFactoryTarget.Directive });
239
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: WrDropdown, isStandalone: true, selector: "[wrDropdown]", inputs: { menu: { classPropertyName: "menu", publicName: "wrDropdown", isSignal: true, isRequired: true, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "click": "onClick($event)", "keydown": "onKeydown($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave($event)" }, properties: { "attr.id": "triggerId", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? menu().menuId() : null" }, classAttribute: "wr-dropdown-trigger" }, ngImport: i0 });
263
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: WrDropdown, isStandalone: true, selector: "[wrDropdown]", inputs: { menu: { classPropertyName: "menu", publicName: "wrDropdown", isSignal: true, isRequired: true, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "click": "onClick($event)", "keydown": "onKeydown($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave($event)" }, properties: { "attr.id": "triggerId", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? menu().menuId() : null" }, classAttribute: "wr-dropdown-trigger" }, ngImport: i0 });
240
264
  }
241
265
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrDropdown, decorators: [{
242
266
  type: Directive,
@@ -254,7 +278,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
254
278
  '(mouseleave)': 'onMouseLeave($event)',
255
279
  },
256
280
  }]
257
- }], ctorParameters: () => [], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrDropdown", required: true }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
281
+ }], ctorParameters: () => [], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrDropdown", required: true }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
258
282
 
259
283
  /**
260
284
  * @license
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-dropdown.mjs","sources":["../../../projects/lib/dropdown/interfaces/dropdown-position.ts","../../../projects/lib/dropdown/dropdown.ts","../../../projects/lib/dropdown/dropdown-menu.ts","../../../projects/lib/dropdown/dropdown-item.ts","../../../projects/lib/dropdown/dropdown-item.html","../../../projects/lib/dropdown/ngwr-dropdown.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 { ConnectedPosition } from '@angular/cdk/overlay';\n\n/**\n * Where the dropdown menu opens, relative to the trigger.\n */\nexport type WrDropdownPosition =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'right';\n\n/**\n * Maps friendly names to CDK ConnectedPosition fallback lists.\n *\n * @internal\n */\nexport const WR_DROPDOWN_POSITIONS: Record<WrDropdownPosition, ConnectedPosition[]> = {\n top: [{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom' }],\n 'top-start': [{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' }],\n 'top-end': [{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom' }],\n bottom: [{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top' }],\n 'bottom-start': [{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' }],\n 'bottom-end': [{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top' }],\n left: [{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center' }],\n right: [{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center' }],\n};\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n ViewContainerRef,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\nimport type { WrDropdownMenu } from './dropdown-menu';\nimport { WR_DROPDOWN_POSITIONS, type WrDropdownPosition, type WrDropdownTrigger } from './interfaces';\n\n/**\n * Attach to any element to open a `<wr-dropdown-menu>` as a CDK overlay.\n *\n * @example\n * ```html\n * <button [wrDropdown]=\"menu\" position=\"bottom-start\" trigger=\"click\">\n * Actions\n * </button>\n *\n * <wr-dropdown-menu #menu>\n * <wr-dropdown-item icon=\"copy\" (click)=\"copy()\">Copy</wr-dropdown-item>\n * <wr-dropdown-item icon=\"trash\" (click)=\"remove()\">Delete</wr-dropdown-item>\n * </wr-dropdown-menu>\n * ```\n *\n * @see https://ngwr.dev/components/dropdown\n */\nlet triggerUid = 0;\n\n@Directive({\n selector: '[wrDropdown]',\n host: {\n class: 'wr-dropdown-trigger',\n '[attr.id]': 'triggerId',\n '[attr.aria-haspopup]': '\"menu\"',\n '[attr.aria-expanded]': 'isOpen()',\n '[attr.aria-controls]': 'isOpen() ? menu().menuId() : null',\n '(click)': 'onClick($event)',\n '(keydown)': 'onKeydown($event)',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave($event)',\n },\n})\nexport class WrDropdown {\n /** Menu to open. Pass a `<wr-dropdown-menu>` template reference. */\n readonly menu = input.required<WrDropdownMenu>({ alias: 'wrDropdown' });\n\n /** How the menu opens. @default 'click' */\n readonly trigger = input<WrDropdownTrigger>('click');\n\n /** Where the menu anchors relative to the trigger. @default 'bottom-start' */\n readonly position = input<WrDropdownPosition>('bottom-start');\n\n /** Fires after the menu opens. */\n readonly opened = output<void>();\n\n /** Fires after the menu closes. */\n readonly closed = output<void>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n\n /** @internal Public so host bindings can read it. */\n readonly isOpen = signal(false);\n\n /** Auto-generated id for `aria-labelledby` wiring on the menu. */\n protected readonly triggerId = `wr-dropdown-trigger-${++triggerUid}`;\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n }\n\n /** Open the menu. */\n open(): void {\n this.isOpen.set(true);\n }\n\n /** Close the menu. */\n close(): void {\n this.isOpen.set(false);\n }\n\n /** Toggle the menu. */\n toggle(): void {\n this.isOpen.update(v => !v);\n }\n\n // Host listeners\n\n /** @internal */\n protected onClick(event: MouseEvent): void {\n if (this.trigger() !== 'click') return;\n event.stopPropagation();\n this.toggle();\n }\n\n /** @internal */\n protected onMouseEnter(): void {\n if (this.trigger() !== 'hover') return;\n this.isOpen.set(true);\n }\n\n /** @internal */\n protected onMouseLeave(event: MouseEvent): void {\n if (this.trigger() !== 'hover') return;\n const related = event.relatedTarget as Node | null;\n if (related && this.overlayRef?.overlayElement.contains(related)) return;\n this.isOpen.set(false);\n }\n\n // Overlay management\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(WR_DROPDOWN_POSITIONS[this.position()])\n .withPush(true);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.reposition(),\n panelClass: ['wr-dropdown-overlay', `wr-dropdown-overlay--${this.position()}`],\n });\n\n // Wire trigger id into menu so it can render aria-labelledby.\n this.menu().triggerId.set(this.triggerId);\n\n const portal = new TemplatePortal(this.menu().contentTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n // Focus the first menu item after the menu renders.\n queueMicrotask(() => this.focusItemAt(0));\n\n this.overlayRef\n .outsidePointerEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (this.host.nativeElement.contains(event.target as Node)) return;\n this.isOpen.set(false);\n });\n\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n this.handleMenuKeydown(event);\n });\n\n if (this.trigger() === 'hover') {\n this.overlayRef.overlayElement.addEventListener('mouseleave', this.onOverlayMouseLeave);\n }\n\n this.opened.emit();\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n if (this.trigger() === 'hover') {\n this.overlayRef.overlayElement.removeEventListener('mouseleave', this.onOverlayMouseLeave);\n }\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.closed.emit();\n }\n\n // Keyboard handling\n\n /** @internal Trigger keydown — ArrowDown/Up/Enter/Space open the menu. */\n protected onKeydown(event: KeyboardEvent): void {\n if (this.isOpen()) return;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.open();\n }\n }\n\n private handleMenuKeydown(event: KeyboardEvent): void {\n const items = this.getItems();\n if (items.length === 0 && event.key !== 'Escape' && event.key !== 'Tab') return;\n const current = document.activeElement as HTMLElement | null;\n const idx = current ? items.indexOf(current) : -1;\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.isOpen.set(false);\n this.host.nativeElement.focus();\n break;\n case 'Tab':\n // Let focus leave naturally; close the menu.\n this.isOpen.set(false);\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.focusItemAt(idx < items.length - 1 ? idx + 1 : 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusItemAt(idx > 0 ? idx - 1 : items.length - 1);\n break;\n case 'Home':\n event.preventDefault();\n this.focusItemAt(0);\n break;\n case 'End':\n event.preventDefault();\n this.focusItemAt(items.length - 1);\n break;\n default:\n break;\n }\n }\n\n private getItems(): readonly HTMLElement[] {\n if (!this.overlayRef) return [];\n return Array.from(\n this.overlayRef.overlayElement.querySelectorAll<HTMLElement>('.wr-dropdown-item:not(.wr-dropdown-item--disabled)')\n );\n }\n\n private focusItemAt(index: number): void {\n const items = this.getItems();\n if (items.length === 0) return;\n const clamped = ((index % items.length) + items.length) % items.length;\n items[clamped]?.focus();\n }\n\n private readonly onOverlayMouseLeave = (event: MouseEvent): void => {\n const related = event.relatedTarget as Node | null;\n if (related && this.host.nativeElement.contains(related)) return;\n this.isOpen.set(false);\n };\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, TemplateRef, ViewEncapsulation, signal, viewChild } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Holds the menu content rendered when a {@link WrDropdown} opens.\n *\n * The component itself doesn't render anywhere — the directive grabs its\n * internal `<ng-template>` and portals it into an overlay.\n *\n * @example\n * ```html\n * <button [wrDropdown]=\"menu\">Actions</button>\n * <wr-dropdown-menu #menu>\n * <wr-dropdown-item icon=\"copy\">Copy</wr-dropdown-item>\n * <wr-dropdown-item icon=\"trash\">Delete</wr-dropdown-item>\n * </wr-dropdown-menu>\n * ```\n *\n * @see https://ngwr.dev/components/dropdown\n */\n@Component({\n selector: 'wr-dropdown-menu',\n template:\n '<ng-template><div class=\"wr-dropdown-menu\" role=\"menu\" [attr.id]=\"menuId()\" [attr.aria-labelledby]=\"triggerId() || null\"><ng-content /></div></ng-template>',\n exportAs: 'wrDropdownMenu',\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrDropdownMenu {\n /** The internal template the directive portals into the overlay. @internal */\n readonly contentTpl = viewChild.required(TemplateRef);\n\n /** Stable id used on the menu element and referenced from the trigger's `aria-controls`. */\n readonly menuId = signal(`wr-dropdown-menu-${++uid}`);\n\n /** Trigger element id, set by the directive for `aria-labelledby` wiring. */\n readonly triggerId = signal<string | null>(null);\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 { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ElementRef, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\n/**\n * Single row inside a `<wr-dropdown-menu>`.\n *\n * @example\n * ```html\n * <wr-dropdown-item icon=\"copy\" (click)=\"copy()\">Copy</wr-dropdown-item>\n * <wr-dropdown-item icon=\"trash\" disabled>Delete</wr-dropdown-item>\n * ```\n */\n@Component({\n selector: 'wr-dropdown-item',\n templateUrl: './dropdown-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'menuitem',\n '[class]': 'classes()',\n '[attr.tabindex]': '-1',\n '[attr.aria-disabled]': 'disabled() ? true : null',\n '(keydown.enter)': 'activate($event)',\n '(keydown.space)': 'activate($event)',\n },\n imports: [WrIcon],\n})\nexport class WrDropdownItem {\n /** Optional leading icon name. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n /** Disable interaction (suppresses pointer + keyboard). @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-dropdown-item'];\n if (this.disabled()) parts.push('wr-dropdown-item--disabled');\n return parts.join(' ');\n });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** @internal Keyboard activation — fires the same click consumers bind to. */\n protected activate(event: Event): void {\n if (this.disabled()) return;\n event.preventDefault();\n this.host.nativeElement.click();\n }\n}\n","@if (icon(); as name) {\n <wr-icon class=\"wr-dropdown-item__icon\" [name]=\"name\" />\n}\n<span class=\"wr-dropdown-item__label\">\n <ng-content />\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-dropdown.mjs","sources":["../../../projects/lib/dropdown/interfaces/dropdown-position.ts","../../../projects/lib/dropdown/dropdown.ts","../../../projects/lib/dropdown/dropdown-menu.ts","../../../projects/lib/dropdown/dropdown-item.ts","../../../projects/lib/dropdown/dropdown-item.html","../../../projects/lib/dropdown/ngwr-dropdown.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 { ConnectedPosition } from '@angular/cdk/overlay';\n\n/**\n * Where the dropdown menu opens, relative to the trigger.\n */\nexport type WrDropdownPosition =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'right';\n\n/**\n * Maps friendly names to CDK ConnectedPosition fallback lists.\n *\n * @internal\n */\nexport const WR_DROPDOWN_POSITIONS: Record<WrDropdownPosition, ConnectedPosition[]> = {\n top: [{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom' }],\n 'top-start': [{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' }],\n 'top-end': [{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom' }],\n bottom: [{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top' }],\n 'bottom-start': [{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' }],\n 'bottom-end': [{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top' }],\n left: [{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center' }],\n right: [{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center' }],\n};\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n ViewContainerRef,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { WR_OVERLAY, WR_RESPONSIVE_OVERLAYS, wrPresentAsSheet } from 'ngwr/overlay';\n\nimport type { WrDropdownMenu } from './dropdown-menu';\nimport { WR_DROPDOWN_POSITIONS, type WrDropdownPosition, type WrDropdownTrigger } from './interfaces';\n\n/**\n * Attach to any element to open a `<wr-dropdown-menu>` as a CDK overlay.\n *\n * @example\n * ```html\n * <button [wrDropdown]=\"menu\" position=\"bottom-start\" trigger=\"click\">\n * Actions\n * </button>\n *\n * <wr-dropdown-menu #menu>\n * <wr-dropdown-item icon=\"copy\" (click)=\"copy()\">Copy</wr-dropdown-item>\n * <wr-dropdown-item icon=\"trash\" (click)=\"remove()\">Delete</wr-dropdown-item>\n * </wr-dropdown-menu>\n * ```\n *\n * @see https://ngwr.dev/components/dropdown\n */\nlet triggerUid = 0;\n\n@Directive({\n selector: '[wrDropdown]',\n host: {\n class: 'wr-dropdown-trigger',\n '[attr.id]': 'triggerId',\n '[attr.aria-haspopup]': '\"menu\"',\n '[attr.aria-expanded]': 'isOpen()',\n '[attr.aria-controls]': 'isOpen() ? menu().menuId() : null',\n '(click)': 'onClick($event)',\n '(keydown)': 'onKeydown($event)',\n '(mouseenter)': 'onMouseEnter()',\n '(mouseleave)': 'onMouseLeave($event)',\n },\n})\nexport class WrDropdown {\n /** Menu to open. Pass a `<wr-dropdown-menu>` template reference. */\n readonly menu = input.required<WrDropdownMenu>({ alias: 'wrDropdown' });\n\n /** How the menu opens. @default 'click' */\n readonly trigger = input<WrDropdownTrigger>('click');\n\n /** Where the menu anchors relative to the trigger. @default 'bottom-start' */\n readonly position = input<WrDropdownPosition>('bottom-start');\n\n /**\n * Present the menu as a full-width bottom-sheet on small viewports instead\n * of an anchored panel. `undefined` follows the app-wide\n * `provideWrResponsiveOverlays()` setting; `true`/`false` overrides it.\n * @default undefined\n */\n readonly responsive = input<boolean | undefined, BooleanInput>(undefined, {\n transform: (v: BooleanInput): boolean | undefined => (v == null ? undefined : coerceBooleanProperty(v)),\n });\n\n /** Fires after the menu opens. */\n readonly opened = output<void>();\n\n /** Fires after the menu closes. */\n readonly closed = output<void>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly destroyRef = inject(DestroyRef);\n\n /** @internal Public so host bindings can read it. */\n readonly isOpen = signal(false);\n\n /** Auto-generated id for `aria-labelledby` wiring on the menu. */\n protected readonly triggerId = `wr-dropdown-trigger-${++triggerUid}`;\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n this.openOverlay();\n } else {\n this.closeOverlay();\n }\n });\n }\n\n /** Open the menu. */\n open(): void {\n this.isOpen.set(true);\n }\n\n /** Close the menu. */\n close(): void {\n this.isOpen.set(false);\n }\n\n /** Toggle the menu. */\n toggle(): void {\n this.isOpen.update(v => !v);\n }\n\n // Host listeners\n\n /** @internal */\n protected onClick(event: MouseEvent): void {\n if (this.trigger() !== 'click') return;\n event.stopPropagation();\n this.toggle();\n }\n\n /** @internal */\n protected onMouseEnter(): void {\n if (this.trigger() !== 'hover') return;\n this.isOpen.set(true);\n }\n\n /** @internal */\n protected onMouseLeave(event: MouseEvent): void {\n if (this.trigger() !== 'hover') return;\n const related = event.relatedTarget as Node | null;\n if (related && this.overlayRef?.overlayElement.contains(related)) return;\n this.isOpen.set(false);\n }\n\n // Overlay management\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n // On small viewports (when opted in) detach from the trigger and present\n // the menu as a full-width slide-up sheet pinned to the bottom edge.\n const asSheet = wrPresentAsSheet(this.responsive(), this.responsiveConfig);\n\n const positionStrategy = asSheet\n ? this.overlay.position().global().centerHorizontally().bottom('0')\n : this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(WR_DROPDOWN_POSITIONS[this.position()])\n .withPush(true);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: asSheet ? this.scrollStrategies.block() : this.scrollStrategies.reposition(),\n width: asSheet ? '100%' : undefined,\n hasBackdrop: asSheet,\n backdropClass: asSheet ? 'wr-overlay-backdrop' : undefined,\n panelClass: asSheet\n ? ['wr-dropdown-overlay', 'wr-overlay-sheet']\n : ['wr-dropdown-overlay', `wr-dropdown-overlay--${this.position()}`],\n });\n\n if (asSheet) {\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.isOpen.set(false));\n }\n\n // Wire trigger id into menu so it can render aria-labelledby.\n this.menu().triggerId.set(this.triggerId);\n\n const portal = new TemplatePortal(this.menu().contentTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n // Focus the first menu item after the menu renders.\n queueMicrotask(() => this.focusItemAt(0));\n\n this.overlayRef\n .outsidePointerEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (this.host.nativeElement.contains(event.target as Node)) return;\n this.isOpen.set(false);\n });\n\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n this.handleMenuKeydown(event);\n });\n\n if (this.trigger() === 'hover') {\n this.overlayRef.overlayElement.addEventListener('mouseleave', this.onOverlayMouseLeave);\n }\n\n this.opened.emit();\n }\n\n private closeOverlay(): void {\n if (!this.overlayRef) return;\n if (this.trigger() === 'hover') {\n this.overlayRef.overlayElement.removeEventListener('mouseleave', this.onOverlayMouseLeave);\n }\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.closed.emit();\n }\n\n // Keyboard handling\n\n /** @internal Trigger keydown — ArrowDown/Up/Enter/Space open the menu. */\n protected onKeydown(event: KeyboardEvent): void {\n if (this.isOpen()) return;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.open();\n }\n }\n\n private handleMenuKeydown(event: KeyboardEvent): void {\n const items = this.getItems();\n if (items.length === 0 && event.key !== 'Escape' && event.key !== 'Tab') return;\n const current = document.activeElement as HTMLElement | null;\n const idx = current ? items.indexOf(current) : -1;\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.isOpen.set(false);\n this.host.nativeElement.focus();\n break;\n case 'Tab':\n // Let focus leave naturally; close the menu.\n this.isOpen.set(false);\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.focusItemAt(idx < items.length - 1 ? idx + 1 : 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusItemAt(idx > 0 ? idx - 1 : items.length - 1);\n break;\n case 'Home':\n event.preventDefault();\n this.focusItemAt(0);\n break;\n case 'End':\n event.preventDefault();\n this.focusItemAt(items.length - 1);\n break;\n default:\n break;\n }\n }\n\n private getItems(): readonly HTMLElement[] {\n if (!this.overlayRef) return [];\n return Array.from(\n this.overlayRef.overlayElement.querySelectorAll<HTMLElement>('.wr-dropdown-item:not(.wr-dropdown-item--disabled)')\n );\n }\n\n private focusItemAt(index: number): void {\n const items = this.getItems();\n if (items.length === 0) return;\n const clamped = ((index % items.length) + items.length) % items.length;\n items[clamped]?.focus();\n }\n\n private readonly onOverlayMouseLeave = (event: MouseEvent): void => {\n const related = event.relatedTarget as Node | null;\n if (related && this.host.nativeElement.contains(related)) return;\n this.isOpen.set(false);\n };\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, TemplateRef, ViewEncapsulation, signal, viewChild } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Holds the menu content rendered when a {@link WrDropdown} opens.\n *\n * The component itself doesn't render anywhere — the directive grabs its\n * internal `<ng-template>` and portals it into an overlay.\n *\n * @example\n * ```html\n * <button [wrDropdown]=\"menu\">Actions</button>\n * <wr-dropdown-menu #menu>\n * <wr-dropdown-item icon=\"copy\">Copy</wr-dropdown-item>\n * <wr-dropdown-item icon=\"trash\">Delete</wr-dropdown-item>\n * </wr-dropdown-menu>\n * ```\n *\n * @see https://ngwr.dev/components/dropdown\n */\n@Component({\n selector: 'wr-dropdown-menu',\n template:\n '<ng-template><div class=\"wr-dropdown-menu\" role=\"menu\" [attr.id]=\"menuId()\" [attr.aria-labelledby]=\"triggerId() || null\"><ng-content /></div></ng-template>',\n exportAs: 'wrDropdownMenu',\n encapsulation: ViewEncapsulation.None,\n host: { style: 'display:none' },\n})\nexport class WrDropdownMenu {\n /** The internal template the directive portals into the overlay. @internal */\n readonly contentTpl = viewChild.required(TemplateRef);\n\n /** Stable id used on the menu element and referenced from the trigger's `aria-controls`. */\n readonly menuId = signal(`wr-dropdown-menu-${++uid}`);\n\n /** Trigger element id, set by the directive for `aria-labelledby` wiring. */\n readonly triggerId = signal<string | null>(null);\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 { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ElementRef, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WrIcon, type WrIconName } from 'ngwr/icon';\n\n/**\n * Single row inside a `<wr-dropdown-menu>`.\n *\n * @example\n * ```html\n * <wr-dropdown-item icon=\"copy\" (click)=\"copy()\">Copy</wr-dropdown-item>\n * <wr-dropdown-item icon=\"trash\" disabled>Delete</wr-dropdown-item>\n * ```\n */\n@Component({\n selector: 'wr-dropdown-item',\n templateUrl: './dropdown-item.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'menuitem',\n '[class]': 'classes()',\n '[attr.tabindex]': '-1',\n '[attr.aria-disabled]': 'disabled() ? true : null',\n '(keydown.enter)': 'activate($event)',\n '(keydown.space)': 'activate($event)',\n },\n imports: [WrIcon],\n})\nexport class WrDropdownItem {\n /** Optional leading icon name. @default null */\n readonly icon = input<WrIconName | null>(null);\n\n /** Disable interaction (suppresses pointer + keyboard). @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n protected readonly classes = computed(() => {\n const parts = ['wr-dropdown-item'];\n if (this.disabled()) parts.push('wr-dropdown-item--disabled');\n return parts.join(' ');\n });\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** @internal Keyboard activation — fires the same click consumers bind to. */\n protected activate(event: Event): void {\n if (this.disabled()) return;\n event.preventDefault();\n this.host.nativeElement.click();\n }\n}\n","@if (icon(); as name) {\n <wr-icon class=\"wr-dropdown-item__icon\" [name]=\"name\" />\n}\n<span class=\"wr-dropdown-item__label\">\n <ng-content />\n</span>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -79,6 +79,49 @@ class WrLightbox {
79
79
  onClose() {
80
80
  this.open.set(false);
81
81
  }
82
+ // Swipe-down-to-dismiss on the open viewer. The image follows the finger and
83
+ // fades; releasing past ~20% of the viewer height closes it.
84
+ viewerStartY = 0;
85
+ viewerSwiping = false;
86
+ onViewerSwipeStart(event) {
87
+ const touch = event.touches[0];
88
+ if (!touch)
89
+ return;
90
+ this.viewerStartY = touch.clientY;
91
+ this.viewerSwiping = true;
92
+ }
93
+ onViewerSwipeMove(event, viewer) {
94
+ if (!this.viewerSwiping)
95
+ return;
96
+ const touch = event.touches[0];
97
+ if (!touch)
98
+ return;
99
+ const dy = touch.clientY - this.viewerStartY;
100
+ if (dy <= 0) {
101
+ viewer.style.transform = '';
102
+ viewer.style.opacity = '';
103
+ return;
104
+ }
105
+ event.preventDefault();
106
+ viewer.style.transition = 'none';
107
+ viewer.style.transform = `translateY(${dy}px)`;
108
+ viewer.style.opacity = String(Math.max(0.3, 1 - dy / (viewer.offsetHeight || 1)));
109
+ }
110
+ onViewerSwipeEnd(event, viewer) {
111
+ if (!this.viewerSwiping)
112
+ return;
113
+ this.viewerSwiping = false;
114
+ const touch = event.changedTouches[0];
115
+ const dy = touch ? touch.clientY - this.viewerStartY : 0;
116
+ if (dy > (viewer.offsetHeight || 0) * 0.2) {
117
+ this.onClose();
118
+ }
119
+ else {
120
+ viewer.style.transition = '';
121
+ viewer.style.transform = '';
122
+ viewer.style.opacity = '';
123
+ }
124
+ }
82
125
  onLoad() {
83
126
  this.loaded.set(true);
84
127
  }
@@ -116,11 +159,11 @@ class WrLightbox {
116
159
  this.overlayRef = null;
117
160
  }
118
161
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrLightbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
119
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WrLightbox, isStandalone: true, selector: "wr-lightbox", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, disablePreview: { classPropertyName: "disablePreview", publicName: "disablePreview", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["viewerTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (disablePreview()) {\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n} @else {\n <button type=\"button\" class=\"wr-lightbox__trigger\" [attr.aria-label]=\"alt() || 'Open preview'\" (click)=\"onClick()\">\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </button>\n}\n\n<ng-template #viewerTpl>\n <div class=\"wr-lightbox-viewer\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"alt() || 'Image preview'\">\n <button\n type=\"button\"\n class=\"wr-lightbox-viewer__close\"\n aria-label=\"Close preview\"\n (click)=\"onClose()\"\n (keydown.enter)=\"onClose()\"\n (keydown.space)=\"onClose()\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <img class=\"wr-lightbox-viewer__full\" [src]=\"src()\" [alt]=\"alt()\" />\n @if (caption()) {\n <div class=\"wr-lightbox-viewer__caption\">{{ caption() }}</div>\n }\n </div>\n</ng-template>\n", styles: [":root{--wr-color-white: #ffffff;--wr-color-white-rgb: 255, 255, 255;--wr-color-black: #000000;--wr-color-black-rgb: 0, 0, 0;--wr-color-backdrop-rgb: 0, 0, 0;--wr-color-primary: #3969e2;--wr-color-primary-rgb: 57, 105, 226;--wr-color-primary-contrast: #ffffff;--wr-color-primary-dark: rgb(34.7577092511, 88.1497797357, 222.7422907489);--wr-color-primary-darker: rgb(29.6387665198, 78.6960352423, 202.3612334802);--wr-color-primary-light: rgb(79.2422907489, 121.8502202643, 229.2577092511);--wr-color-primary-lighter: rgb(101.4845814978, 138.7004405286, 232.5154185022);--wr-color-secondary: #f51c6a;--wr-color-secondary-rgb: 245, 28, 106;--wr-color-secondary-contrast: #ffffff;--wr-color-secondary-dark: rgb(237.0569620253, 10.4430379747, 91.8987341772);--wr-color-secondary-darker: rgb(212.6329113924, 9.3670886076, 82.4303797468);--wr-color-secondary-light: rgb(246.0759493671, 52.4240506329, 122.0316455696);--wr-color-secondary-lighter: rgb(247.1518987342, 76.8481012658, 138.0632911392);--wr-color-success: #00a400;--wr-color-success-rgb: 0, 164, 0;--wr-color-success-contrast: #ffffff;--wr-color-success-dark: rgb(0, 138.5, 0);--wr-color-success-darker: #007100;--wr-color-success-light: rgb(0, 189.5, 0);--wr-color-success-lighter: #00d700;--wr-color-warning: #ffba00;--wr-color-warning-rgb: 255, 186, 0;--wr-color-warning-contrast: #171616;--wr-color-warning-dark: rgb(229.5, 167.4, 0);--wr-color-warning-darker: rgb(204, 148.8, 0);--wr-color-warning-light: rgb(255, 192.9, 25.5);--wr-color-warning-lighter: rgb(255, 199.8, 51);--wr-color-danger: #fa383e;--wr-color-danger-rgb: 250, 56, 62;--wr-color-danger-contrast: #ffffff;--wr-color-danger-dark: rgb(249.375, 31.125, 37.875);--wr-color-danger-darker: rgb(248.75, 6.25, 13.75);--wr-color-danger-light: rgb(250.625, 80.875, 86.125);--wr-color-danger-lighter: rgb(251.25, 105.75, 110.25);--wr-color-light: #cbd5e1;--wr-color-light-rgb: 203, 213, 225;--wr-color-light-contrast: #171616;--wr-color-light-dark: rgb(186.8292682927, 199.9390243902, 215.6707317073);--wr-color-light-darker: rgb(170.6585365854, 186.8780487805, 206.3414634146);--wr-color-light-light: rgb(219.1707317073, 226.0609756098, 234.3292682927);--wr-color-light-lighter: rgb(235.3414634146, 239.1219512195, 243.6585365854);--wr-color-medium: #8594a4;--wr-color-medium-rgb: 133, 148, 164;--wr-color-medium-contrast: #ffffff;--wr-color-medium-dark: rgb(118.3943661972, 135.1901408451, 153.1056338028);--wr-color-medium-darker: rgb(105.0985915493, 122.4225352113, 140.9014084507);--wr-color-medium-light: rgb(147.6056338028, 160.8098591549, 174.8943661972);--wr-color-medium-lighter: rgb(162.2112676056, 173.6197183099, 185.7887323944);--wr-color-dark: #0f172a;--wr-color-dark-rgb: 15, 23, 42;--wr-color-dark-contrast: #ffffff;--wr-color-dark-dark: rgb(8.2894736842, 12.7105263158, 23.2105263158);--wr-color-dark-darker: rgb(1.5789473684, 2.4210526316, 4.4210526316);--wr-color-dark-light: rgb(21.7105263158, 33.2894736842, 60.7894736842);--wr-color-dark-lighter: rgb(28.4210526316, 43.5789473684, 79.5789473684)}:root{--wr-border-radius-sm: .375rem;--wr-border-radius-base: .625rem;--wr-border-radius-lg: 1rem;--wr-border-radius-pill: 50rem;--wr-ease-linear: linear;--wr-ease-out: cubic-bezier(.16, 1, .3, 1);--wr-ease-in: cubic-bezier(.7, 0, .84, 0);--wr-ease-in-out: cubic-bezier(.65, 0, .35, 1);--wr-ease-spring: cubic-bezier(.34, 1.56, .64, 1);--wr-duration-fast: .1s;--wr-duration-base: .15s;--wr-duration-slow: .3s;--wr-duration-slower: .5s;--wr-transition-short: var(--wr-duration-fast) var(--wr-ease-out);--wr-transition-base: var(--wr-duration-base) var(--wr-ease-linear);--wr-transition-long: var(--wr-duration-slow) var(--wr-ease-out);--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 5%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 15%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 12%), 0 2px 4px rgb(0 0 0 / 6%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 18%);--wr-shadow-modal: 0 20px 48px rgb(0 0 0 / 25%);--wr-z-overlay: 1000;--wr-z-window: 1100;--wr-z-top: 9999;--wr-overlay-duration: var(--wr-duration-base);--wr-overlay-ease: var(--wr-ease-out);--wr-font-family-base: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;--wr-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--wr-text-xs: .75rem;--wr-text-sm: .875rem;--wr-text-base: 1rem;--wr-text-lg: 1.125rem;--wr-text-xl: 1.25rem;--wr-text-2xl: 1.5rem;--wr-text-3xl: 1.875rem;--wr-text-4xl: 2.25rem;--wr-text-5xl: 3rem;--wr-font-weight-thin: 200;--wr-font-weight-light: 300;--wr-font-weight-regular: 400;--wr-font-weight-medium: 500;--wr-font-weight-semibold: 600;--wr-font-weight-bold: 700;--wr-font-weight-extrabold: 800;--wr-leading-none: 1;--wr-leading-tight: 1.25;--wr-leading-snug: 1.375;--wr-leading-normal: 1.5;--wr-leading-relaxed: 1.625;--wr-leading-loose: 2;--wr-tracking-tighter: -.05em;--wr-tracking-tight: -.025em;--wr-tracking-normal: 0;--wr-tracking-wide: .025em;--wr-tracking-wider: .05em;--wr-tracking-widest: .1em}@keyframes wr-overlay-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}[data-theme=dark]{--wr-color-white: #0b1120;--wr-color-white-rgb: 11, 17, 32;--wr-color-dark: #e6ebf3;--wr-color-dark-rgb: 230, 235, 243;--wr-color-dark-contrast: #0b1120;--wr-color-white-contrast: #e6ebf3;--wr-color-light: #262f44;--wr-color-light-rgb: 38, 47, 68;--wr-color-light-contrast: #e6ebf3;--wr-color-light-lighter: #1a2236;--wr-color-light-darker: #3a4661;--wr-color-medium: #9aa6b8;--wr-color-medium-rgb: 154, 166, 184;--wr-color-primary: #5b85ff;--wr-color-primary-rgb: 91, 133, 255;--wr-color-primary-light: #7a9eff;--wr-color-primary-dark: #2f56c9;--wr-color-primary-lighter: #99b6ff;--wr-color-primary-darker: #1f3a99;--wr-color-success: #34c759;--wr-color-success-rgb: 52, 199, 89;--wr-color-warning: #ffcc33;--wr-color-warning-rgb: 255, 204, 51;--wr-color-danger: #ff5c5c;--wr-color-danger-rgb: 255, 92, 92;--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 35%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 45%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 50%), 0 2px 4px rgb(0 0 0 / 35%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 55%);--wr-shadow-modal: 0 24px 56px rgb(0 0 0 / 60%);color-scheme:dark}.wr-tabs__tab:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-sidebar__entry:focus-visible,.wr-sidebar__item:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-anchor__link:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-collapse__header:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-command-palette__option:focus-visible,.wr-command-palette__panel input:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-mention__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-segmented__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-back-top:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-stepper__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-toast__close:focus-visible,.wr-toast__copy:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-window__chrome-action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-dropdown-item:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-lightbox{display:inline-block;position:relative;overflow:hidden;border-radius:var(--wr-lightbox-radius, var(--wr-border-radius-base))}@supports (corner-shape: squircle){.wr-lightbox{corner-shape:squircle;border-radius:calc(var(--wr-lightbox-radius, var(--wr-border-radius-base)) * 1.85)}}.wr-lightbox{cursor:zoom-in;background:rgba(var(--wr-color-light-rgb),.4)}.wr-lightbox--loading:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff73,#fff0);background-size:200% 100%;animation:wr-lightbox-shimmer 1.4s linear infinite;pointer-events:none}.wr-lightbox__trigger{display:block;width:100%;height:100%;padding:0;margin:0;border:0;background:transparent;cursor:zoom-in}.wr-lightbox__trigger:focus-visible{outline:2px solid var(--wr-color-primary);outline-offset:2px}.wr-lightbox__thumb{display:block;width:100%;height:100%;object-fit:cover;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}@keyframes wr-lightbox-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.wr-lightbox-backdrop{background:rgba(var(--wr-color-backdrop-rgb),.85)}.wr-lightbox-overlay{pointer-events:auto}.wr-lightbox-viewer{display:flex;flex-direction:column;align-items:center;gap:1rem;max-width:95vw;max-height:95vh;padding:1rem;animation:wr-lightbox-viewer-in .18s ease;outline:none}.wr-lightbox-viewer__close{--wr-icon-size: 1.25rem;position:absolute;top:1rem;right:1rem;display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;border:0;border-radius:999px;background:#ffffff1f;color:#ffffffe6;cursor:pointer;transition:background .15s ease,transform .15s ease}.wr-lightbox-viewer__close:hover{background:#fff3}.wr-lightbox-viewer__close:active{transform:scale(.95)}.wr-lightbox-viewer__close:focus-visible{outline:2px solid rgba(255,255,255,.9);outline-offset:2px}.wr-lightbox-viewer__full{display:block;max-width:100%;max-height:calc(95vh - 4rem);object-fit:contain;cursor:zoom-out;border-radius:.5rem}@supports (corner-shape: squircle){.wr-lightbox-viewer__full{corner-shape:squircle;border-radius:.925rem}}.wr-lightbox-viewer__caption{color:#ffffffd9;font-family:var(--wr-font-family-base);font-size:.9375rem;text-align:center;max-width:60ch}@keyframes wr-lightbox-viewer-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}\n"], encapsulation: i0.ViewEncapsulation.None });
162
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: WrLightbox, isStandalone: true, selector: "wr-lightbox", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, disablePreview: { classPropertyName: "disablePreview", publicName: "disablePreview", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, viewQueries: [{ propertyName: "panelTpl", first: true, predicate: ["viewerTpl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (disablePreview()) {\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n} @else {\n <button type=\"button\" class=\"wr-lightbox__trigger\" [attr.aria-label]=\"alt() || 'Open preview'\" (click)=\"onClick()\">\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </button>\n}\n\n<ng-template #viewerTpl>\n <div\n #viewer\n class=\"wr-lightbox-viewer\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"alt() || 'Image preview'\"\n (touchstart)=\"onViewerSwipeStart($event)\"\n (touchmove)=\"onViewerSwipeMove($event, viewer)\"\n (touchend)=\"onViewerSwipeEnd($event, viewer)\"\n (touchcancel)=\"onViewerSwipeEnd($event, viewer)\"\n >\n <button\n type=\"button\"\n class=\"wr-lightbox-viewer__close\"\n aria-label=\"Close preview\"\n (click)=\"onClose()\"\n (keydown.enter)=\"onClose()\"\n (keydown.space)=\"onClose()\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <img class=\"wr-lightbox-viewer__full\" [src]=\"src()\" [alt]=\"alt()\" />\n @if (caption()) {\n <div class=\"wr-lightbox-viewer__caption\">{{ caption() }}</div>\n }\n </div>\n</ng-template>\n", styles: [":root{--wr-color-white: #ffffff;--wr-color-white-rgb: 255, 255, 255;--wr-color-black: #000000;--wr-color-black-rgb: 0, 0, 0;--wr-color-backdrop-rgb: 0, 0, 0;--wr-color-primary: #3969e2;--wr-color-primary-rgb: 57, 105, 226;--wr-color-primary-contrast: #ffffff;--wr-color-primary-dark: rgb(34.7577092511, 88.1497797357, 222.7422907489);--wr-color-primary-darker: rgb(29.6387665198, 78.6960352423, 202.3612334802);--wr-color-primary-light: rgb(79.2422907489, 121.8502202643, 229.2577092511);--wr-color-primary-lighter: rgb(101.4845814978, 138.7004405286, 232.5154185022);--wr-color-secondary: #f51c6a;--wr-color-secondary-rgb: 245, 28, 106;--wr-color-secondary-contrast: #ffffff;--wr-color-secondary-dark: rgb(237.0569620253, 10.4430379747, 91.8987341772);--wr-color-secondary-darker: rgb(212.6329113924, 9.3670886076, 82.4303797468);--wr-color-secondary-light: rgb(246.0759493671, 52.4240506329, 122.0316455696);--wr-color-secondary-lighter: rgb(247.1518987342, 76.8481012658, 138.0632911392);--wr-color-success: #00a400;--wr-color-success-rgb: 0, 164, 0;--wr-color-success-contrast: #ffffff;--wr-color-success-dark: rgb(0, 138.5, 0);--wr-color-success-darker: #007100;--wr-color-success-light: rgb(0, 189.5, 0);--wr-color-success-lighter: #00d700;--wr-color-warning: #ffba00;--wr-color-warning-rgb: 255, 186, 0;--wr-color-warning-contrast: #171616;--wr-color-warning-dark: rgb(229.5, 167.4, 0);--wr-color-warning-darker: rgb(204, 148.8, 0);--wr-color-warning-light: rgb(255, 192.9, 25.5);--wr-color-warning-lighter: rgb(255, 199.8, 51);--wr-color-danger: #fa383e;--wr-color-danger-rgb: 250, 56, 62;--wr-color-danger-contrast: #ffffff;--wr-color-danger-dark: rgb(249.375, 31.125, 37.875);--wr-color-danger-darker: rgb(248.75, 6.25, 13.75);--wr-color-danger-light: rgb(250.625, 80.875, 86.125);--wr-color-danger-lighter: rgb(251.25, 105.75, 110.25);--wr-color-light: #cbd5e1;--wr-color-light-rgb: 203, 213, 225;--wr-color-light-contrast: #171616;--wr-color-light-dark: rgb(186.8292682927, 199.9390243902, 215.6707317073);--wr-color-light-darker: rgb(170.6585365854, 186.8780487805, 206.3414634146);--wr-color-light-light: rgb(219.1707317073, 226.0609756098, 234.3292682927);--wr-color-light-lighter: rgb(235.3414634146, 239.1219512195, 243.6585365854);--wr-color-medium: #8594a4;--wr-color-medium-rgb: 133, 148, 164;--wr-color-medium-contrast: #ffffff;--wr-color-medium-dark: rgb(118.3943661972, 135.1901408451, 153.1056338028);--wr-color-medium-darker: rgb(105.0985915493, 122.4225352113, 140.9014084507);--wr-color-medium-light: rgb(147.6056338028, 160.8098591549, 174.8943661972);--wr-color-medium-lighter: rgb(162.2112676056, 173.6197183099, 185.7887323944);--wr-color-dark: #0f172a;--wr-color-dark-rgb: 15, 23, 42;--wr-color-dark-contrast: #ffffff;--wr-color-dark-dark: rgb(8.2894736842, 12.7105263158, 23.2105263158);--wr-color-dark-darker: rgb(1.5789473684, 2.4210526316, 4.4210526316);--wr-color-dark-light: rgb(21.7105263158, 33.2894736842, 60.7894736842);--wr-color-dark-lighter: rgb(28.4210526316, 43.5789473684, 79.5789473684)}:root{--wr-border-radius-sm: .375rem;--wr-border-radius-base: .625rem;--wr-border-radius-lg: 1rem;--wr-border-radius-pill: 50rem;--wr-ease-linear: linear;--wr-ease-out: cubic-bezier(.16, 1, .3, 1);--wr-ease-in: cubic-bezier(.7, 0, .84, 0);--wr-ease-in-out: cubic-bezier(.65, 0, .35, 1);--wr-ease-spring: cubic-bezier(.34, 1.56, .64, 1);--wr-duration-fast: .1s;--wr-duration-base: .15s;--wr-duration-slow: .3s;--wr-duration-slower: .5s;--wr-transition-short: var(--wr-duration-fast) var(--wr-ease-out);--wr-transition-base: var(--wr-duration-base) var(--wr-ease-linear);--wr-transition-long: var(--wr-duration-slow) var(--wr-ease-out);--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 5%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 15%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 12%), 0 2px 4px rgb(0 0 0 / 6%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 18%);--wr-shadow-modal: 0 20px 48px rgb(0 0 0 / 25%);--wr-z-overlay: 1000;--wr-z-window: 1100;--wr-z-top: 9999;--wr-overlay-duration: var(--wr-duration-base);--wr-overlay-ease: var(--wr-ease-out);--wr-font-family-base: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;--wr-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--wr-text-xs: .75rem;--wr-text-sm: .875rem;--wr-text-base: 1rem;--wr-text-lg: 1.125rem;--wr-text-xl: 1.25rem;--wr-text-2xl: 1.5rem;--wr-text-3xl: 1.875rem;--wr-text-4xl: 2.25rem;--wr-text-5xl: 3rem;--wr-font-weight-thin: 200;--wr-font-weight-light: 300;--wr-font-weight-regular: 400;--wr-font-weight-medium: 500;--wr-font-weight-semibold: 600;--wr-font-weight-bold: 700;--wr-font-weight-extrabold: 800;--wr-leading-none: 1;--wr-leading-tight: 1.25;--wr-leading-snug: 1.375;--wr-leading-normal: 1.5;--wr-leading-relaxed: 1.625;--wr-leading-loose: 2;--wr-tracking-tighter: -.05em;--wr-tracking-tight: -.025em;--wr-tracking-normal: 0;--wr-tracking-wide: .025em;--wr-tracking-wider: .05em;--wr-tracking-widest: .1em}@keyframes wr-overlay-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}[data-theme=dark]{--wr-color-white: #0b1120;--wr-color-white-rgb: 11, 17, 32;--wr-color-dark: #e6ebf3;--wr-color-dark-rgb: 230, 235, 243;--wr-color-dark-contrast: #0b1120;--wr-color-white-contrast: #e6ebf3;--wr-color-light: #262f44;--wr-color-light-rgb: 38, 47, 68;--wr-color-light-contrast: #e6ebf3;--wr-color-light-lighter: #1a2236;--wr-color-light-darker: #3a4661;--wr-color-medium: #9aa6b8;--wr-color-medium-rgb: 154, 166, 184;--wr-color-primary: #5b85ff;--wr-color-primary-rgb: 91, 133, 255;--wr-color-primary-light: #7a9eff;--wr-color-primary-dark: #2f56c9;--wr-color-primary-lighter: #99b6ff;--wr-color-primary-darker: #1f3a99;--wr-color-success: #34c759;--wr-color-success-rgb: 52, 199, 89;--wr-color-warning: #ffcc33;--wr-color-warning-rgb: 255, 204, 51;--wr-color-danger: #ff5c5c;--wr-color-danger-rgb: 255, 92, 92;--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 35%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 45%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 50%), 0 2px 4px rgb(0 0 0 / 35%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 55%);--wr-shadow-modal: 0 24px 56px rgb(0 0 0 / 60%);color-scheme:dark}.wr-tabs__tab:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-sidebar__entry:focus-visible,.wr-sidebar__item:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-anchor__link:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-collapse__header:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-command-palette__option:focus-visible,.wr-command-palette__panel input:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-mention__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-segmented__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-back-top:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-stepper__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-toast__close:focus-visible,.wr-toast__copy:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-window__chrome-action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-dropdown-item:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-lightbox{display:inline-block;position:relative;overflow:hidden;border-radius:var(--wr-lightbox-radius, var(--wr-border-radius-base))}@supports (corner-shape: squircle){.wr-lightbox{corner-shape:squircle;border-radius:calc(var(--wr-lightbox-radius, var(--wr-border-radius-base)) * 1.85)}}.wr-lightbox{cursor:zoom-in;background:rgba(var(--wr-color-light-rgb),.4)}.wr-lightbox--loading:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff73,#fff0);background-size:200% 100%;animation:wr-lightbox-shimmer 1.4s linear infinite;pointer-events:none}.wr-lightbox__trigger{display:block;width:100%;height:100%;padding:0;margin:0;border:0;background:transparent;cursor:zoom-in}.wr-lightbox__trigger:focus-visible{outline:2px solid var(--wr-color-primary);outline-offset:2px}.wr-lightbox__thumb{display:block;width:100%;height:100%;object-fit:cover;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}@keyframes wr-lightbox-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.wr-lightbox-backdrop{background:rgba(var(--wr-color-backdrop-rgb),.85)}.wr-lightbox-overlay{pointer-events:auto}.wr-lightbox-viewer{display:flex;flex-direction:column;align-items:center;gap:1rem;max-width:95vw;max-height:95vh;padding:1rem;animation:wr-lightbox-viewer-in .18s ease;outline:none;touch-action:none}.wr-lightbox-viewer__close{--wr-icon-size: 1.25rem;position:absolute;top:1rem;right:1rem;display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;border:0;border-radius:999px;background:#ffffff1f;color:#ffffffe6;cursor:pointer;transition:background .15s ease,transform .15s ease}@media(pointer:coarse){.wr-lightbox-viewer__close:after{content:\"\";position:absolute;top:50%;left:50%;width:100%;height:100%;min-width:44px;min-height:44px;transform:translate(-50%,-50%)}}.wr-lightbox-viewer__close:hover{background:#fff3}.wr-lightbox-viewer__close:active{transform:scale(.95)}.wr-lightbox-viewer__close:focus-visible{outline:2px solid rgba(255,255,255,.9);outline-offset:2px}.wr-lightbox-viewer__full{display:block;max-width:100%;max-height:calc(95vh - 4rem);object-fit:contain;cursor:zoom-out;border-radius:.5rem}@supports (corner-shape: squircle){.wr-lightbox-viewer__full{corner-shape:squircle;border-radius:.925rem}}.wr-lightbox-viewer__caption{color:#ffffffd9;font-family:var(--wr-font-family-base);font-size:.9375rem;text-align:center;max-width:60ch}@keyframes wr-lightbox-viewer-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}\n"], encapsulation: i0.ViewEncapsulation.None });
120
163
  }
121
164
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: WrLightbox, decorators: [{
122
165
  type: Component,
123
- args: [{ selector: 'wr-lightbox', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "@if (disablePreview()) {\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n} @else {\n <button type=\"button\" class=\"wr-lightbox__trigger\" [attr.aria-label]=\"alt() || 'Open preview'\" (click)=\"onClick()\">\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </button>\n}\n\n<ng-template #viewerTpl>\n <div class=\"wr-lightbox-viewer\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"alt() || 'Image preview'\">\n <button\n type=\"button\"\n class=\"wr-lightbox-viewer__close\"\n aria-label=\"Close preview\"\n (click)=\"onClose()\"\n (keydown.enter)=\"onClose()\"\n (keydown.space)=\"onClose()\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <img class=\"wr-lightbox-viewer__full\" [src]=\"src()\" [alt]=\"alt()\" />\n @if (caption()) {\n <div class=\"wr-lightbox-viewer__caption\">{{ caption() }}</div>\n }\n </div>\n</ng-template>\n", styles: [":root{--wr-color-white: #ffffff;--wr-color-white-rgb: 255, 255, 255;--wr-color-black: #000000;--wr-color-black-rgb: 0, 0, 0;--wr-color-backdrop-rgb: 0, 0, 0;--wr-color-primary: #3969e2;--wr-color-primary-rgb: 57, 105, 226;--wr-color-primary-contrast: #ffffff;--wr-color-primary-dark: rgb(34.7577092511, 88.1497797357, 222.7422907489);--wr-color-primary-darker: rgb(29.6387665198, 78.6960352423, 202.3612334802);--wr-color-primary-light: rgb(79.2422907489, 121.8502202643, 229.2577092511);--wr-color-primary-lighter: rgb(101.4845814978, 138.7004405286, 232.5154185022);--wr-color-secondary: #f51c6a;--wr-color-secondary-rgb: 245, 28, 106;--wr-color-secondary-contrast: #ffffff;--wr-color-secondary-dark: rgb(237.0569620253, 10.4430379747, 91.8987341772);--wr-color-secondary-darker: rgb(212.6329113924, 9.3670886076, 82.4303797468);--wr-color-secondary-light: rgb(246.0759493671, 52.4240506329, 122.0316455696);--wr-color-secondary-lighter: rgb(247.1518987342, 76.8481012658, 138.0632911392);--wr-color-success: #00a400;--wr-color-success-rgb: 0, 164, 0;--wr-color-success-contrast: #ffffff;--wr-color-success-dark: rgb(0, 138.5, 0);--wr-color-success-darker: #007100;--wr-color-success-light: rgb(0, 189.5, 0);--wr-color-success-lighter: #00d700;--wr-color-warning: #ffba00;--wr-color-warning-rgb: 255, 186, 0;--wr-color-warning-contrast: #171616;--wr-color-warning-dark: rgb(229.5, 167.4, 0);--wr-color-warning-darker: rgb(204, 148.8, 0);--wr-color-warning-light: rgb(255, 192.9, 25.5);--wr-color-warning-lighter: rgb(255, 199.8, 51);--wr-color-danger: #fa383e;--wr-color-danger-rgb: 250, 56, 62;--wr-color-danger-contrast: #ffffff;--wr-color-danger-dark: rgb(249.375, 31.125, 37.875);--wr-color-danger-darker: rgb(248.75, 6.25, 13.75);--wr-color-danger-light: rgb(250.625, 80.875, 86.125);--wr-color-danger-lighter: rgb(251.25, 105.75, 110.25);--wr-color-light: #cbd5e1;--wr-color-light-rgb: 203, 213, 225;--wr-color-light-contrast: #171616;--wr-color-light-dark: rgb(186.8292682927, 199.9390243902, 215.6707317073);--wr-color-light-darker: rgb(170.6585365854, 186.8780487805, 206.3414634146);--wr-color-light-light: rgb(219.1707317073, 226.0609756098, 234.3292682927);--wr-color-light-lighter: rgb(235.3414634146, 239.1219512195, 243.6585365854);--wr-color-medium: #8594a4;--wr-color-medium-rgb: 133, 148, 164;--wr-color-medium-contrast: #ffffff;--wr-color-medium-dark: rgb(118.3943661972, 135.1901408451, 153.1056338028);--wr-color-medium-darker: rgb(105.0985915493, 122.4225352113, 140.9014084507);--wr-color-medium-light: rgb(147.6056338028, 160.8098591549, 174.8943661972);--wr-color-medium-lighter: rgb(162.2112676056, 173.6197183099, 185.7887323944);--wr-color-dark: #0f172a;--wr-color-dark-rgb: 15, 23, 42;--wr-color-dark-contrast: #ffffff;--wr-color-dark-dark: rgb(8.2894736842, 12.7105263158, 23.2105263158);--wr-color-dark-darker: rgb(1.5789473684, 2.4210526316, 4.4210526316);--wr-color-dark-light: rgb(21.7105263158, 33.2894736842, 60.7894736842);--wr-color-dark-lighter: rgb(28.4210526316, 43.5789473684, 79.5789473684)}:root{--wr-border-radius-sm: .375rem;--wr-border-radius-base: .625rem;--wr-border-radius-lg: 1rem;--wr-border-radius-pill: 50rem;--wr-ease-linear: linear;--wr-ease-out: cubic-bezier(.16, 1, .3, 1);--wr-ease-in: cubic-bezier(.7, 0, .84, 0);--wr-ease-in-out: cubic-bezier(.65, 0, .35, 1);--wr-ease-spring: cubic-bezier(.34, 1.56, .64, 1);--wr-duration-fast: .1s;--wr-duration-base: .15s;--wr-duration-slow: .3s;--wr-duration-slower: .5s;--wr-transition-short: var(--wr-duration-fast) var(--wr-ease-out);--wr-transition-base: var(--wr-duration-base) var(--wr-ease-linear);--wr-transition-long: var(--wr-duration-slow) var(--wr-ease-out);--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 5%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 15%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 12%), 0 2px 4px rgb(0 0 0 / 6%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 18%);--wr-shadow-modal: 0 20px 48px rgb(0 0 0 / 25%);--wr-z-overlay: 1000;--wr-z-window: 1100;--wr-z-top: 9999;--wr-overlay-duration: var(--wr-duration-base);--wr-overlay-ease: var(--wr-ease-out);--wr-font-family-base: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;--wr-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--wr-text-xs: .75rem;--wr-text-sm: .875rem;--wr-text-base: 1rem;--wr-text-lg: 1.125rem;--wr-text-xl: 1.25rem;--wr-text-2xl: 1.5rem;--wr-text-3xl: 1.875rem;--wr-text-4xl: 2.25rem;--wr-text-5xl: 3rem;--wr-font-weight-thin: 200;--wr-font-weight-light: 300;--wr-font-weight-regular: 400;--wr-font-weight-medium: 500;--wr-font-weight-semibold: 600;--wr-font-weight-bold: 700;--wr-font-weight-extrabold: 800;--wr-leading-none: 1;--wr-leading-tight: 1.25;--wr-leading-snug: 1.375;--wr-leading-normal: 1.5;--wr-leading-relaxed: 1.625;--wr-leading-loose: 2;--wr-tracking-tighter: -.05em;--wr-tracking-tight: -.025em;--wr-tracking-normal: 0;--wr-tracking-wide: .025em;--wr-tracking-wider: .05em;--wr-tracking-widest: .1em}@keyframes wr-overlay-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}[data-theme=dark]{--wr-color-white: #0b1120;--wr-color-white-rgb: 11, 17, 32;--wr-color-dark: #e6ebf3;--wr-color-dark-rgb: 230, 235, 243;--wr-color-dark-contrast: #0b1120;--wr-color-white-contrast: #e6ebf3;--wr-color-light: #262f44;--wr-color-light-rgb: 38, 47, 68;--wr-color-light-contrast: #e6ebf3;--wr-color-light-lighter: #1a2236;--wr-color-light-darker: #3a4661;--wr-color-medium: #9aa6b8;--wr-color-medium-rgb: 154, 166, 184;--wr-color-primary: #5b85ff;--wr-color-primary-rgb: 91, 133, 255;--wr-color-primary-light: #7a9eff;--wr-color-primary-dark: #2f56c9;--wr-color-primary-lighter: #99b6ff;--wr-color-primary-darker: #1f3a99;--wr-color-success: #34c759;--wr-color-success-rgb: 52, 199, 89;--wr-color-warning: #ffcc33;--wr-color-warning-rgb: 255, 204, 51;--wr-color-danger: #ff5c5c;--wr-color-danger-rgb: 255, 92, 92;--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 35%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 45%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 50%), 0 2px 4px rgb(0 0 0 / 35%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 55%);--wr-shadow-modal: 0 24px 56px rgb(0 0 0 / 60%);color-scheme:dark}.wr-tabs__tab:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-sidebar__entry:focus-visible,.wr-sidebar__item:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-anchor__link:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-collapse__header:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-command-palette__option:focus-visible,.wr-command-palette__panel input:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-mention__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-segmented__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-back-top:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-stepper__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-toast__close:focus-visible,.wr-toast__copy:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-window__chrome-action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-dropdown-item:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-lightbox{display:inline-block;position:relative;overflow:hidden;border-radius:var(--wr-lightbox-radius, var(--wr-border-radius-base))}@supports (corner-shape: squircle){.wr-lightbox{corner-shape:squircle;border-radius:calc(var(--wr-lightbox-radius, var(--wr-border-radius-base)) * 1.85)}}.wr-lightbox{cursor:zoom-in;background:rgba(var(--wr-color-light-rgb),.4)}.wr-lightbox--loading:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff73,#fff0);background-size:200% 100%;animation:wr-lightbox-shimmer 1.4s linear infinite;pointer-events:none}.wr-lightbox__trigger{display:block;width:100%;height:100%;padding:0;margin:0;border:0;background:transparent;cursor:zoom-in}.wr-lightbox__trigger:focus-visible{outline:2px solid var(--wr-color-primary);outline-offset:2px}.wr-lightbox__thumb{display:block;width:100%;height:100%;object-fit:cover;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}@keyframes wr-lightbox-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.wr-lightbox-backdrop{background:rgba(var(--wr-color-backdrop-rgb),.85)}.wr-lightbox-overlay{pointer-events:auto}.wr-lightbox-viewer{display:flex;flex-direction:column;align-items:center;gap:1rem;max-width:95vw;max-height:95vh;padding:1rem;animation:wr-lightbox-viewer-in .18s ease;outline:none}.wr-lightbox-viewer__close{--wr-icon-size: 1.25rem;position:absolute;top:1rem;right:1rem;display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;border:0;border-radius:999px;background:#ffffff1f;color:#ffffffe6;cursor:pointer;transition:background .15s ease,transform .15s ease}.wr-lightbox-viewer__close:hover{background:#fff3}.wr-lightbox-viewer__close:active{transform:scale(.95)}.wr-lightbox-viewer__close:focus-visible{outline:2px solid rgba(255,255,255,.9);outline-offset:2px}.wr-lightbox-viewer__full{display:block;max-width:100%;max-height:calc(95vh - 4rem);object-fit:contain;cursor:zoom-out;border-radius:.5rem}@supports (corner-shape: squircle){.wr-lightbox-viewer__full{corner-shape:squircle;border-radius:.925rem}}.wr-lightbox-viewer__caption{color:#ffffffd9;font-family:var(--wr-font-family-base);font-size:.9375rem;text-align:center;max-width:60ch}@keyframes wr-lightbox-viewer-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}\n"] }]
166
+ args: [{ selector: 'wr-lightbox', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()' }, template: "@if (disablePreview()) {\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n} @else {\n <button type=\"button\" class=\"wr-lightbox__trigger\" [attr.aria-label]=\"alt() || 'Open preview'\" (click)=\"onClick()\">\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </button>\n}\n\n<ng-template #viewerTpl>\n <div\n #viewer\n class=\"wr-lightbox-viewer\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"alt() || 'Image preview'\"\n (touchstart)=\"onViewerSwipeStart($event)\"\n (touchmove)=\"onViewerSwipeMove($event, viewer)\"\n (touchend)=\"onViewerSwipeEnd($event, viewer)\"\n (touchcancel)=\"onViewerSwipeEnd($event, viewer)\"\n >\n <button\n type=\"button\"\n class=\"wr-lightbox-viewer__close\"\n aria-label=\"Close preview\"\n (click)=\"onClose()\"\n (keydown.enter)=\"onClose()\"\n (keydown.space)=\"onClose()\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <img class=\"wr-lightbox-viewer__full\" [src]=\"src()\" [alt]=\"alt()\" />\n @if (caption()) {\n <div class=\"wr-lightbox-viewer__caption\">{{ caption() }}</div>\n }\n </div>\n</ng-template>\n", styles: [":root{--wr-color-white: #ffffff;--wr-color-white-rgb: 255, 255, 255;--wr-color-black: #000000;--wr-color-black-rgb: 0, 0, 0;--wr-color-backdrop-rgb: 0, 0, 0;--wr-color-primary: #3969e2;--wr-color-primary-rgb: 57, 105, 226;--wr-color-primary-contrast: #ffffff;--wr-color-primary-dark: rgb(34.7577092511, 88.1497797357, 222.7422907489);--wr-color-primary-darker: rgb(29.6387665198, 78.6960352423, 202.3612334802);--wr-color-primary-light: rgb(79.2422907489, 121.8502202643, 229.2577092511);--wr-color-primary-lighter: rgb(101.4845814978, 138.7004405286, 232.5154185022);--wr-color-secondary: #f51c6a;--wr-color-secondary-rgb: 245, 28, 106;--wr-color-secondary-contrast: #ffffff;--wr-color-secondary-dark: rgb(237.0569620253, 10.4430379747, 91.8987341772);--wr-color-secondary-darker: rgb(212.6329113924, 9.3670886076, 82.4303797468);--wr-color-secondary-light: rgb(246.0759493671, 52.4240506329, 122.0316455696);--wr-color-secondary-lighter: rgb(247.1518987342, 76.8481012658, 138.0632911392);--wr-color-success: #00a400;--wr-color-success-rgb: 0, 164, 0;--wr-color-success-contrast: #ffffff;--wr-color-success-dark: rgb(0, 138.5, 0);--wr-color-success-darker: #007100;--wr-color-success-light: rgb(0, 189.5, 0);--wr-color-success-lighter: #00d700;--wr-color-warning: #ffba00;--wr-color-warning-rgb: 255, 186, 0;--wr-color-warning-contrast: #171616;--wr-color-warning-dark: rgb(229.5, 167.4, 0);--wr-color-warning-darker: rgb(204, 148.8, 0);--wr-color-warning-light: rgb(255, 192.9, 25.5);--wr-color-warning-lighter: rgb(255, 199.8, 51);--wr-color-danger: #fa383e;--wr-color-danger-rgb: 250, 56, 62;--wr-color-danger-contrast: #ffffff;--wr-color-danger-dark: rgb(249.375, 31.125, 37.875);--wr-color-danger-darker: rgb(248.75, 6.25, 13.75);--wr-color-danger-light: rgb(250.625, 80.875, 86.125);--wr-color-danger-lighter: rgb(251.25, 105.75, 110.25);--wr-color-light: #cbd5e1;--wr-color-light-rgb: 203, 213, 225;--wr-color-light-contrast: #171616;--wr-color-light-dark: rgb(186.8292682927, 199.9390243902, 215.6707317073);--wr-color-light-darker: rgb(170.6585365854, 186.8780487805, 206.3414634146);--wr-color-light-light: rgb(219.1707317073, 226.0609756098, 234.3292682927);--wr-color-light-lighter: rgb(235.3414634146, 239.1219512195, 243.6585365854);--wr-color-medium: #8594a4;--wr-color-medium-rgb: 133, 148, 164;--wr-color-medium-contrast: #ffffff;--wr-color-medium-dark: rgb(118.3943661972, 135.1901408451, 153.1056338028);--wr-color-medium-darker: rgb(105.0985915493, 122.4225352113, 140.9014084507);--wr-color-medium-light: rgb(147.6056338028, 160.8098591549, 174.8943661972);--wr-color-medium-lighter: rgb(162.2112676056, 173.6197183099, 185.7887323944);--wr-color-dark: #0f172a;--wr-color-dark-rgb: 15, 23, 42;--wr-color-dark-contrast: #ffffff;--wr-color-dark-dark: rgb(8.2894736842, 12.7105263158, 23.2105263158);--wr-color-dark-darker: rgb(1.5789473684, 2.4210526316, 4.4210526316);--wr-color-dark-light: rgb(21.7105263158, 33.2894736842, 60.7894736842);--wr-color-dark-lighter: rgb(28.4210526316, 43.5789473684, 79.5789473684)}:root{--wr-border-radius-sm: .375rem;--wr-border-radius-base: .625rem;--wr-border-radius-lg: 1rem;--wr-border-radius-pill: 50rem;--wr-ease-linear: linear;--wr-ease-out: cubic-bezier(.16, 1, .3, 1);--wr-ease-in: cubic-bezier(.7, 0, .84, 0);--wr-ease-in-out: cubic-bezier(.65, 0, .35, 1);--wr-ease-spring: cubic-bezier(.34, 1.56, .64, 1);--wr-duration-fast: .1s;--wr-duration-base: .15s;--wr-duration-slow: .3s;--wr-duration-slower: .5s;--wr-transition-short: var(--wr-duration-fast) var(--wr-ease-out);--wr-transition-base: var(--wr-duration-base) var(--wr-ease-linear);--wr-transition-long: var(--wr-duration-slow) var(--wr-ease-out);--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 5%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 15%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 12%), 0 2px 4px rgb(0 0 0 / 6%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 18%);--wr-shadow-modal: 0 20px 48px rgb(0 0 0 / 25%);--wr-z-overlay: 1000;--wr-z-window: 1100;--wr-z-top: 9999;--wr-overlay-duration: var(--wr-duration-base);--wr-overlay-ease: var(--wr-ease-out);--wr-font-family-base: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;--wr-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--wr-text-xs: .75rem;--wr-text-sm: .875rem;--wr-text-base: 1rem;--wr-text-lg: 1.125rem;--wr-text-xl: 1.25rem;--wr-text-2xl: 1.5rem;--wr-text-3xl: 1.875rem;--wr-text-4xl: 2.25rem;--wr-text-5xl: 3rem;--wr-font-weight-thin: 200;--wr-font-weight-light: 300;--wr-font-weight-regular: 400;--wr-font-weight-medium: 500;--wr-font-weight-semibold: 600;--wr-font-weight-bold: 700;--wr-font-weight-extrabold: 800;--wr-leading-none: 1;--wr-leading-tight: 1.25;--wr-leading-snug: 1.375;--wr-leading-normal: 1.5;--wr-leading-relaxed: 1.625;--wr-leading-loose: 2;--wr-tracking-tighter: -.05em;--wr-tracking-tight: -.025em;--wr-tracking-normal: 0;--wr-tracking-wide: .025em;--wr-tracking-wider: .05em;--wr-tracking-widest: .1em}@keyframes wr-overlay-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}[data-theme=dark]{--wr-color-white: #0b1120;--wr-color-white-rgb: 11, 17, 32;--wr-color-dark: #e6ebf3;--wr-color-dark-rgb: 230, 235, 243;--wr-color-dark-contrast: #0b1120;--wr-color-white-contrast: #e6ebf3;--wr-color-light: #262f44;--wr-color-light-rgb: 38, 47, 68;--wr-color-light-contrast: #e6ebf3;--wr-color-light-lighter: #1a2236;--wr-color-light-darker: #3a4661;--wr-color-medium: #9aa6b8;--wr-color-medium-rgb: 154, 166, 184;--wr-color-primary: #5b85ff;--wr-color-primary-rgb: 91, 133, 255;--wr-color-primary-light: #7a9eff;--wr-color-primary-dark: #2f56c9;--wr-color-primary-lighter: #99b6ff;--wr-color-primary-darker: #1f3a99;--wr-color-success: #34c759;--wr-color-success-rgb: 52, 199, 89;--wr-color-warning: #ffcc33;--wr-color-warning-rgb: 255, 204, 51;--wr-color-danger: #ff5c5c;--wr-color-danger-rgb: 255, 92, 92;--wr-shadow-xs: 0 1px 2px rgb(0 0 0 / 35%);--wr-shadow-sm: 0 2px 8px rgb(0 0 0 / 45%);--wr-shadow-overlay: 0 8px 24px rgb(0 0 0 / 50%), 0 2px 4px rgb(0 0 0 / 35%);--wr-shadow-float: 0 8px 24px rgb(0 0 0 / 55%);--wr-shadow-modal: 0 24px 56px rgb(0 0 0 / 60%);color-scheme:dark}.wr-tabs__tab:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-sidebar__entry:focus-visible,.wr-sidebar__item:focus-visible,.wr-sidebar__group-toggle:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-anchor__link:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-collapse__header:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-command-palette__option:focus-visible,.wr-command-palette__panel input:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-mention__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-segmented__option:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-back-top:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-carousel__nav:focus-visible,.wr-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-speed-dial__trigger:focus-visible,.wr-speed-dial__action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-stepper__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-toast__close:focus-visible,.wr-toast__copy:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-window__chrome-action:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-date-picker__trigger:focus-visible,.wr-time-picker__step:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-dropdown-item:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(var(--wr-color-primary-rgb),.25)}.wr-lightbox{display:inline-block;position:relative;overflow:hidden;border-radius:var(--wr-lightbox-radius, var(--wr-border-radius-base))}@supports (corner-shape: squircle){.wr-lightbox{corner-shape:squircle;border-radius:calc(var(--wr-lightbox-radius, var(--wr-border-radius-base)) * 1.85)}}.wr-lightbox{cursor:zoom-in;background:rgba(var(--wr-color-light-rgb),.4)}.wr-lightbox--loading:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff73,#fff0);background-size:200% 100%;animation:wr-lightbox-shimmer 1.4s linear infinite;pointer-events:none}.wr-lightbox__trigger{display:block;width:100%;height:100%;padding:0;margin:0;border:0;background:transparent;cursor:zoom-in}.wr-lightbox__trigger:focus-visible{outline:2px solid var(--wr-color-primary);outline-offset:2px}.wr-lightbox__thumb{display:block;width:100%;height:100%;object-fit:cover;-webkit-user-select:none;user-select:none;-webkit-user-drag:none}@keyframes wr-lightbox-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.wr-lightbox-backdrop{background:rgba(var(--wr-color-backdrop-rgb),.85)}.wr-lightbox-overlay{pointer-events:auto}.wr-lightbox-viewer{display:flex;flex-direction:column;align-items:center;gap:1rem;max-width:95vw;max-height:95vh;padding:1rem;animation:wr-lightbox-viewer-in .18s ease;outline:none;touch-action:none}.wr-lightbox-viewer__close{--wr-icon-size: 1.25rem;position:absolute;top:1rem;right:1rem;display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;padding:0;border:0;border-radius:999px;background:#ffffff1f;color:#ffffffe6;cursor:pointer;transition:background .15s ease,transform .15s ease}@media(pointer:coarse){.wr-lightbox-viewer__close:after{content:\"\";position:absolute;top:50%;left:50%;width:100%;height:100%;min-width:44px;min-height:44px;transform:translate(-50%,-50%)}}.wr-lightbox-viewer__close:hover{background:#fff3}.wr-lightbox-viewer__close:active{transform:scale(.95)}.wr-lightbox-viewer__close:focus-visible{outline:2px solid rgba(255,255,255,.9);outline-offset:2px}.wr-lightbox-viewer__full{display:block;max-width:100%;max-height:calc(95vh - 4rem);object-fit:contain;cursor:zoom-out;border-radius:.5rem}@supports (corner-shape: squircle){.wr-lightbox-viewer__full{corner-shape:squircle;border-radius:.925rem}}.wr-lightbox-viewer__caption{color:#ffffffd9;font-family:var(--wr-font-family-base);font-size:.9375rem;text-align:center;max-width:60ch}@keyframes wr-lightbox-viewer-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}\n"] }]
124
167
  }], ctorParameters: () => [], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: true }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], preview: [{ type: i0.Input, args: [{ isSignal: true, alias: "preview", required: false }] }], disablePreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "disablePreview", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], panelTpl: [{ type: i0.ViewChild, args: ['viewerTpl', { isSignal: true }] }] } });
125
168
 
126
169
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-lightbox.mjs","sources":["../../../projects/lib/lightbox/lightbox.ts","../../../projects/lib/lightbox/lightbox.html","../../../projects/lib/lightbox/ngwr-lightbox.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport type { TemplateRef } from '@angular/core';\nimport {\n Component,\n DestroyRef,\n ViewContainerRef,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\n/**\n * Image with click-to-zoom lightbox. The thumbnail is a plain `<img>`\n * with whatever sizing/`object-fit` you give it; clicking opens a CDK\n * overlay showing the full image, with Escape + close button + backdrop\n * to dismiss.\n *\n * @example\n * ```html\n * <wr-lightbox\n * src=\"/photo.jpg\"\n * alt=\"Mountain\"\n * style=\"width: 16rem; height: 10rem; object-fit: cover\"\n * />\n * ```\n *\n * @see https://ngwr.dev/components/lightbox\n */\n@Component({\n selector: 'wr-lightbox',\n templateUrl: './lightbox.html',\n styleUrl: './lightbox.scss',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrLightbox {\n /** Image source. */\n readonly src = input.required<string>();\n\n /** Alt text. Required for a11y; falls back to an empty string. @default '' */\n readonly alt = input<string>('');\n\n /** Optional preview src — shown until the full image loads. */\n readonly preview = input<string | null>(null);\n\n /** Disable the click-to-zoom lightbox. @default false */\n readonly disablePreview = input(false, { transform: coerceBooleanProperty });\n\n /** Caption shown under the full image in the lightbox. */\n readonly caption = input<string>('');\n\n protected readonly open = signal(false);\n protected readonly loaded = signal(false);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-lightbox'];\n if (this.open()) parts.push('wr-lightbox--open');\n if (!this.loaded()) parts.push('wr-lightbox--loading');\n return parts.join(' ');\n });\n\n // Query by name — `@if` blocks register their own TemplateRefs, so an\n // unqualified TemplateRef query would grab the thumbnail branch instead.\n protected readonly panelTpl = viewChild.required<TemplateRef<unknown>>('viewerTpl');\n\n private readonly overlay = inject(WR_OVERLAY);\n private readonly vcr = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) this.openOverlay();\n else this.closeOverlay();\n });\n }\n\n protected onClick(): void {\n if (this.disablePreview()) return;\n this.open.set(true);\n }\n\n protected onClose(): void {\n this.open.set(false);\n }\n\n protected onLoad(): void {\n this.loaded.set(true);\n }\n\n // Overlay\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n this.overlayRef = this.overlay.create({\n hasBackdrop: true,\n backdropClass: 'wr-lightbox-backdrop',\n positionStrategy: this.overlay.position().global().centerHorizontally().centerVertically(),\n scrollStrategy: this.overlay.scrollStrategies.block(),\n panelClass: 'wr-lightbox-overlay',\n });\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.open.set(false));\n\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 private closeOverlay(): void {\n if (!this.overlayRef) return;\n this.overlayRef.dispose();\n this.overlayRef = null;\n }\n}\n","@if (disablePreview()) {\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n} @else {\n <button type=\"button\" class=\"wr-lightbox__trigger\" [attr.aria-label]=\"alt() || 'Open preview'\" (click)=\"onClick()\">\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </button>\n}\n\n<ng-template #viewerTpl>\n <div class=\"wr-lightbox-viewer\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"alt() || 'Image preview'\">\n <button\n type=\"button\"\n class=\"wr-lightbox-viewer__close\"\n aria-label=\"Close preview\"\n (click)=\"onClose()\"\n (keydown.enter)=\"onClose()\"\n (keydown.space)=\"onClose()\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <img class=\"wr-lightbox-viewer__full\" [src]=\"src()\" [alt]=\"alt()\" />\n @if (caption()) {\n <div class=\"wr-lightbox-viewer__caption\">{{ caption() }}</div>\n }\n </div>\n</ng-template>\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-lightbox.mjs","sources":["../../../projects/lib/lightbox/lightbox.ts","../../../projects/lib/lightbox/lightbox.html","../../../projects/lib/lightbox/ngwr-lightbox.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport type { TemplateRef } from '@angular/core';\nimport {\n Component,\n DestroyRef,\n ViewContainerRef,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { WR_OVERLAY } from 'ngwr/overlay';\n\n/**\n * Image with click-to-zoom lightbox. The thumbnail is a plain `<img>`\n * with whatever sizing/`object-fit` you give it; clicking opens a CDK\n * overlay showing the full image, with Escape + close button + backdrop\n * to dismiss.\n *\n * @example\n * ```html\n * <wr-lightbox\n * src=\"/photo.jpg\"\n * alt=\"Mountain\"\n * style=\"width: 16rem; height: 10rem; object-fit: cover\"\n * />\n * ```\n *\n * @see https://ngwr.dev/components/lightbox\n */\n@Component({\n selector: 'wr-lightbox',\n templateUrl: './lightbox.html',\n styleUrl: './lightbox.scss',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()' },\n})\nexport class WrLightbox {\n /** Image source. */\n readonly src = input.required<string>();\n\n /** Alt text. Required for a11y; falls back to an empty string. @default '' */\n readonly alt = input<string>('');\n\n /** Optional preview src — shown until the full image loads. */\n readonly preview = input<string | null>(null);\n\n /** Disable the click-to-zoom lightbox. @default false */\n readonly disablePreview = input(false, { transform: coerceBooleanProperty });\n\n /** Caption shown under the full image in the lightbox. */\n readonly caption = input<string>('');\n\n protected readonly open = signal(false);\n protected readonly loaded = signal(false);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-lightbox'];\n if (this.open()) parts.push('wr-lightbox--open');\n if (!this.loaded()) parts.push('wr-lightbox--loading');\n return parts.join(' ');\n });\n\n // Query by name — `@if` blocks register their own TemplateRefs, so an\n // unqualified TemplateRef query would grab the thumbnail branch instead.\n protected readonly panelTpl = viewChild.required<TemplateRef<unknown>>('viewerTpl');\n\n private readonly overlay = inject(WR_OVERLAY);\n private readonly vcr = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) this.openOverlay();\n else this.closeOverlay();\n });\n }\n\n protected onClick(): void {\n if (this.disablePreview()) return;\n this.open.set(true);\n }\n\n protected onClose(): void {\n this.open.set(false);\n }\n\n // Swipe-down-to-dismiss on the open viewer. The image follows the finger and\n // fades; releasing past ~20% of the viewer height closes it.\n private viewerStartY = 0;\n private viewerSwiping = false;\n\n protected onViewerSwipeStart(event: TouchEvent): void {\n const touch = event.touches[0];\n if (!touch) return;\n this.viewerStartY = touch.clientY;\n this.viewerSwiping = true;\n }\n\n protected onViewerSwipeMove(event: TouchEvent, viewer: HTMLElement): void {\n if (!this.viewerSwiping) return;\n const touch = event.touches[0];\n if (!touch) return;\n const dy = touch.clientY - this.viewerStartY;\n if (dy <= 0) {\n viewer.style.transform = '';\n viewer.style.opacity = '';\n return;\n }\n event.preventDefault();\n viewer.style.transition = 'none';\n viewer.style.transform = `translateY(${dy}px)`;\n viewer.style.opacity = String(Math.max(0.3, 1 - dy / (viewer.offsetHeight || 1)));\n }\n\n protected onViewerSwipeEnd(event: TouchEvent, viewer: HTMLElement): void {\n if (!this.viewerSwiping) return;\n this.viewerSwiping = false;\n const touch = event.changedTouches[0];\n const dy = touch ? touch.clientY - this.viewerStartY : 0;\n if (dy > (viewer.offsetHeight || 0) * 0.2) {\n this.onClose();\n } else {\n viewer.style.transition = '';\n viewer.style.transform = '';\n viewer.style.opacity = '';\n }\n }\n\n protected onLoad(): void {\n this.loaded.set(true);\n }\n\n // Overlay\n\n private openOverlay(): void {\n if (this.overlayRef) return;\n\n this.overlayRef = this.overlay.create({\n hasBackdrop: true,\n backdropClass: 'wr-lightbox-backdrop',\n positionStrategy: this.overlay.position().global().centerHorizontally().centerVertically(),\n scrollStrategy: this.overlay.scrollStrategies.block(),\n panelClass: 'wr-lightbox-overlay',\n });\n\n const portal = new TemplatePortal(this.panelTpl(), this.vcr);\n this.overlayRef.attach(portal);\n\n this.overlayRef\n .backdropClick()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.open.set(false));\n\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 private closeOverlay(): void {\n if (!this.overlayRef) return;\n this.overlayRef.dispose();\n this.overlayRef = null;\n }\n}\n","@if (disablePreview()) {\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n} @else {\n <button type=\"button\" class=\"wr-lightbox__trigger\" [attr.aria-label]=\"alt() || 'Open preview'\" (click)=\"onClick()\">\n <img\n class=\"wr-lightbox__thumb\"\n [src]=\"preview() || src()\"\n [alt]=\"alt()\"\n (load)=\"onLoad()\"\n loading=\"lazy\"\n decoding=\"async\"\n />\n </button>\n}\n\n<ng-template #viewerTpl>\n <div\n #viewer\n class=\"wr-lightbox-viewer\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"alt() || 'Image preview'\"\n (touchstart)=\"onViewerSwipeStart($event)\"\n (touchmove)=\"onViewerSwipeMove($event, viewer)\"\n (touchend)=\"onViewerSwipeEnd($event, viewer)\"\n (touchcancel)=\"onViewerSwipeEnd($event, viewer)\"\n >\n <button\n type=\"button\"\n class=\"wr-lightbox-viewer__close\"\n aria-label=\"Close preview\"\n (click)=\"onClose()\"\n (keydown.enter)=\"onClose()\"\n (keydown.space)=\"onClose()\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n <img class=\"wr-lightbox-viewer__full\" [src]=\"src()\" [alt]=\"alt()\" />\n @if (caption()) {\n <div class=\"wr-lightbox-viewer__caption\">{{ caption() }}</div>\n }\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -79,6 +79,44 @@ const WR_OVERLAY_CONTAINER = new InjectionToken('WR_OVERLAY_CONTAINER', {
79
79
  factory: () => inject(OverlayContainer),
80
80
  });
81
81
 
82
+ /**
83
+ * @license
84
+ *
85
+ * Use of this source code is governed by an MIT-style license that can be
86
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
87
+ */
88
+ /**
89
+ * When set, overlay services (dialog, select, dropdown, …) present as a
90
+ * slide-up bottom-sheet on viewports at or below `breakpoint`. `null`
91
+ * (the default) keeps every overlay floating. Configure via
92
+ * {@link provideWrResponsiveOverlays}; override per call with a
93
+ * component's `responsive` option.
94
+ *
95
+ * @internal
96
+ */
97
+ const WR_RESPONSIVE_OVERLAYS = new InjectionToken('WR_RESPONSIVE_OVERLAYS', {
98
+ factory: () => null,
99
+ });
100
+ /**
101
+ * Decide whether an overlay should present as a bottom-sheet for the
102
+ * current viewport.
103
+ *
104
+ * - `responsive === true` — sheet on small viewports regardless of config.
105
+ * - `responsive === false` — never a sheet.
106
+ * - `responsive === undefined` — follow the global config (sheet when
107
+ * {@link provideWrResponsiveOverlays} is configured).
108
+ *
109
+ * SSR-safe: returns `false` when there's no `window`.
110
+ *
111
+ * @internal
112
+ */
113
+ function wrPresentAsSheet(responsive, config) {
114
+ const enabled = responsive ?? config !== null;
115
+ if (!enabled || typeof window === 'undefined')
116
+ return false;
117
+ return window.innerWidth <= (config?.breakpoint ?? 640);
118
+ }
119
+
82
120
  /**
83
121
  * @license
84
122
  *
@@ -137,9 +175,40 @@ function provideWrOverlay() {
137
175
  ]);
138
176
  }
139
177
 
178
+ /**
179
+ * @license
180
+ *
181
+ * Use of this source code is governed by an MIT-style license that can be
182
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
183
+ */
184
+ /**
185
+ * Opt every NGWR overlay into responsive presentation — on viewports at or
186
+ * below `breakpoint`, dialogs / selects / dropdowns and friends slide up as
187
+ * a full-width bottom-sheet instead of a floating panel. Built on the same
188
+ * overlay plumbing, so focus-trap, backdrop and scroll-blocking carry over.
189
+ *
190
+ * Individual components can still opt out (or in) per instance via their
191
+ * `responsive` option.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * bootstrapApplication(AppComponent, {
196
+ * providers: [provideWrOverlay(), provideWrResponsiveOverlays()],
197
+ * });
198
+ *
199
+ * // Custom breakpoint:
200
+ * provideWrResponsiveOverlays({ breakpoint: 768 });
201
+ * ```
202
+ */
203
+ function provideWrResponsiveOverlays(config) {
204
+ return makeEnvironmentProviders([
205
+ { provide: WR_RESPONSIVE_OVERLAYS, useValue: { breakpoint: config?.breakpoint ?? 640 } },
206
+ ]);
207
+ }
208
+
140
209
  /**
141
210
  * Generated bundle index. Do not edit.
142
211
  */
143
212
 
144
- export { WR_OVERLAY, WR_OVERLAY_CONTAINER, WrOverlayContainer, provideWrOverlay };
213
+ export { WR_OVERLAY, WR_OVERLAY_CONTAINER, WR_RESPONSIVE_OVERLAYS, WrOverlayContainer, provideWrOverlay, provideWrResponsiveOverlays, wrPresentAsSheet };
145
214
  //# sourceMappingURL=ngwr-overlay.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-overlay.mjs","sources":["../../../projects/lib/overlay/wr-overlay-container.ts","../../../projects/lib/overlay/tokens/wr-overlay.token.ts","../../../projects/lib/overlay/tokens/wr-overlay-container.token.ts","../../../projects/lib/overlay/provide-wr-overlay.ts","../../../projects/lib/overlay/ngwr-overlay.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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { Service } from '@angular/core';\n\n/**\n * Custom CDK `OverlayContainer` subclass that tags its DOM element with\n * `.wr-overlay-container` in addition to CDK's own `.cdk-overlay-container`.\n *\n * Why: CDK uses a single overlay container per app — every CDK consumer\n * (this lib, Angular Material, NG-ZORRO, etc.) puts its overlays in the\n * same root element. With this class applied you can scope NGWR-specific\n * overlay styles via the tag, e.g.:\n *\n * ```scss\n * .wr-overlay-container .cdk-overlay-pane { z-index: 1100; }\n * ```\n *\n * It does **not** isolate two libraries that both subclass OverlayContainer\n * — the last provider wins. It does give NGWR overlays a stable CSS hook.\n */\n@Service()\nexport class WrOverlayContainer extends OverlayContainer {\n protected override _createContainer(): void {\n super._createContainer();\n this._containerElement?.classList.add('wr-overlay-container');\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 { Overlay } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the CDK `Overlay` service NGWR components should\n * use to open panels.\n *\n * Defaults to CDK's root `Overlay` (shared with every other CDK consumer\n * in the app). Call `provideWrOverlay()` to bind it to an isolated\n * `Overlay` instance backed by a separate `OverlayContainer` — that way\n * NGWR overlays don't share the same DOM root with other libraries.\n *\n * @internal — directives/services inside the lib inject this instead of\n * CDK's `Overlay` directly.\n */\nexport const WR_OVERLAY = new InjectionToken<Overlay>('WR_OVERLAY', {\n providedIn: 'root',\n factory: () => inject(Overlay),\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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the overlay container NGWR components should use.\n *\n * Defaults to CDK's `OverlayContainer` — i.e. the same root element every\n * CDK consumer shares. Call `provideWrOverlay()` to replace it with an\n * isolated instance so NGWR overlays don't collide with other libraries.\n *\n * @internal\n */\nexport const WR_OVERLAY_CONTAINER = new InjectionToken<OverlayContainer>('WR_OVERLAY_CONTAINER', {\n providedIn: 'root',\n factory: () => inject(OverlayContainer),\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 { Overlay, OverlayContainer } from '@angular/cdk/overlay';\nimport {\n EnvironmentInjector,\n Injector,\n type EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n} from '@angular/core';\n\nimport { WR_OVERLAY, WR_OVERLAY_CONTAINER } from './tokens';\nimport { WrOverlayContainer } from './wr-overlay-container';\n\n/**\n * Isolates NGWR overlays from other CDK consumers in the app.\n *\n * Without this call, NGWR overlays use CDK's root `Overlay` — they\n * render into the same `.cdk-overlay-container` element as Angular\n * Material, NG-ZORRO, etc. With it, NGWR gets its own `OverlayContainer`\n * (marked `.wr-overlay-container`) **and** its own `Overlay` service\n * instance — so styles, z-index, and lifecycle never collide.\n *\n * It does this by replacing two injection tokens:\n * - `WR_OVERLAY_CONTAINER` → custom `WrOverlayContainer` subclass\n * - `WR_OVERLAY` → a fresh `Overlay` instance built in a child injector\n * that resolves `OverlayContainer` to the custom subclass\n *\n * CDK's own root `Overlay` / `OverlayContainer` are left untouched, so\n * other libraries keep working with their original container.\n *\n * @example\n * ```ts\n * import { provideWrOverlay } from 'ngwr/overlay';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrOverlay(),\n * ],\n * });\n * ```\n */\nexport function provideWrOverlay(): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: WR_OVERLAY_CONTAINER, useClass: WrOverlayContainer },\n {\n provide: WR_OVERLAY,\n useFactory: (): Overlay => {\n const parent = inject(EnvironmentInjector);\n const container = inject(WR_OVERLAY_CONTAINER);\n\n // Child injector resolves `OverlayContainer` to our subclass and\n // creates a fresh `Overlay` instance bound to it. CDK's own root\n // `Overlay` and `OverlayContainer` are untouched in the parent.\n const child = Injector.create({\n parent,\n providers: [\n { provide: OverlayContainer, useValue: container },\n { provide: Overlay, useClass: Overlay },\n ],\n });\n\n return child.get(Overlay);\n },\n },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAKH;;;;;;;;;;;;;;;AAeG;AAEG,MAAO,kBAAmB,SAAQ,gBAAgB,CAAA;IACnC,gBAAgB,GAAA;QACjC,KAAK,CAAC,gBAAgB,EAAE;QACxB,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAC/D;uGAJW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,OAAA,EAAA,CAAA;wGAAlB,kBAAkB,EAAA,CAAA;;2FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B;;;AC1BD;;;;;AAKG;AAKH;;;;;;;;;;;AAWG;MACU,UAAU,GAAG,IAAI,cAAc,CAAU,YAAY,EAAE;AAClE,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,MAAM,CAAC,OAAO,CAAC;AAC/B,CAAA;;ACzBD;;;;;AAKG;AAKH;;;;;;;;AAQG;MACU,oBAAoB,GAAG,IAAI,cAAc,CAAmB,sBAAsB,EAAE;AAC/F,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,MAAM,CAAC,gBAAgB,CAAC;AACxC,CAAA;;ACtBD;;;;;AAKG;AAcH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;SACa,gBAAgB,GAAA;AAC9B,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,EAAE,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;AAC/D,QAAA;AACE,YAAA,OAAO,EAAE,UAAU;YACnB,UAAU,EAAE,MAAc;AACxB,gBAAA,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC1C,gBAAA,MAAM,SAAS,GAAG,MAAM,CAAC,oBAAoB,CAAC;;;;AAK9C,gBAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;oBAC5B,MAAM;AACN,oBAAA,SAAS,EAAE;AACT,wBAAA,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE;AAClD,wBAAA,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE;AACxC,qBAAA;AACF,iBAAA,CAAC;AAEF,gBAAA,OAAO,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;YAC3B,CAAC;AACF,SAAA;AACF,KAAA,CAAC;AACJ;;ACvEA;;AAEG;;;;"}
1
+ {"version":3,"file":"ngwr-overlay.mjs","sources":["../../../projects/lib/overlay/wr-overlay-container.ts","../../../projects/lib/overlay/tokens/wr-overlay.token.ts","../../../projects/lib/overlay/tokens/wr-overlay-container.token.ts","../../../projects/lib/overlay/tokens/wr-responsive-overlays.token.ts","../../../projects/lib/overlay/provide-wr-overlay.ts","../../../projects/lib/overlay/provide-wr-responsive-overlays.ts","../../../projects/lib/overlay/ngwr-overlay.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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { Service } from '@angular/core';\n\n/**\n * Custom CDK `OverlayContainer` subclass that tags its DOM element with\n * `.wr-overlay-container` in addition to CDK's own `.cdk-overlay-container`.\n *\n * Why: CDK uses a single overlay container per app — every CDK consumer\n * (this lib, Angular Material, NG-ZORRO, etc.) puts its overlays in the\n * same root element. With this class applied you can scope NGWR-specific\n * overlay styles via the tag, e.g.:\n *\n * ```scss\n * .wr-overlay-container .cdk-overlay-pane { z-index: 1100; }\n * ```\n *\n * It does **not** isolate two libraries that both subclass OverlayContainer\n * — the last provider wins. It does give NGWR overlays a stable CSS hook.\n */\n@Service()\nexport class WrOverlayContainer extends OverlayContainer {\n protected override _createContainer(): void {\n super._createContainer();\n this._containerElement?.classList.add('wr-overlay-container');\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 { Overlay } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the CDK `Overlay` service NGWR components should\n * use to open panels.\n *\n * Defaults to CDK's root `Overlay` (shared with every other CDK consumer\n * in the app). Call `provideWrOverlay()` to bind it to an isolated\n * `Overlay` instance backed by a separate `OverlayContainer` — that way\n * NGWR overlays don't share the same DOM root with other libraries.\n *\n * @internal — directives/services inside the lib inject this instead of\n * CDK's `Overlay` directly.\n */\nexport const WR_OVERLAY = new InjectionToken<Overlay>('WR_OVERLAY', {\n providedIn: 'root',\n factory: () => inject(Overlay),\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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the overlay container NGWR components should use.\n *\n * Defaults to CDK's `OverlayContainer` — i.e. the same root element every\n * CDK consumer shares. Call `provideWrOverlay()` to replace it with an\n * isolated instance so NGWR overlays don't collide with other libraries.\n *\n * @internal\n */\nexport const WR_OVERLAY_CONTAINER = new InjectionToken<OverlayContainer>('WR_OVERLAY_CONTAINER', {\n providedIn: 'root',\n factory: () => inject(OverlayContainer),\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/** Configuration for responsive (bottom-sheet) overlay presentation. */\ninterface WrResponsiveOverlaysConfig {\n /**\n * Viewport width (CSS px) at or below which overlays present as a\n * bottom-sheet instead of a floating panel. @default 640\n */\n readonly breakpoint: number;\n}\n\n/**\n * When set, overlay services (dialog, select, dropdown, …) present as a\n * slide-up bottom-sheet on viewports at or below `breakpoint`. `null`\n * (the default) keeps every overlay floating. Configure via\n * {@link provideWrResponsiveOverlays}; override per call with a\n * component's `responsive` option.\n *\n * @internal\n */\nconst WR_RESPONSIVE_OVERLAYS = new InjectionToken<WrResponsiveOverlaysConfig | null>('WR_RESPONSIVE_OVERLAYS', {\n factory: () => null,\n});\n\n/**\n * Decide whether an overlay should present as a bottom-sheet for the\n * current viewport.\n *\n * - `responsive === true` — sheet on small viewports regardless of config.\n * - `responsive === false` — never a sheet.\n * - `responsive === undefined` — follow the global config (sheet when\n * {@link provideWrResponsiveOverlays} is configured).\n *\n * SSR-safe: returns `false` when there's no `window`.\n *\n * @internal\n */\nfunction wrPresentAsSheet(responsive: boolean | undefined, config: WrResponsiveOverlaysConfig | null): boolean {\n const enabled = responsive ?? config !== null;\n if (!enabled || typeof window === 'undefined') return false;\n return window.innerWidth <= (config?.breakpoint ?? 640);\n}\n\nexport { WR_RESPONSIVE_OVERLAYS, wrPresentAsSheet };\nexport type { WrResponsiveOverlaysConfig };\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 { Overlay, OverlayContainer } from '@angular/cdk/overlay';\nimport {\n EnvironmentInjector,\n Injector,\n type EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n} from '@angular/core';\n\nimport { WR_OVERLAY, WR_OVERLAY_CONTAINER } from './tokens';\nimport { WrOverlayContainer } from './wr-overlay-container';\n\n/**\n * Isolates NGWR overlays from other CDK consumers in the app.\n *\n * Without this call, NGWR overlays use CDK's root `Overlay` — they\n * render into the same `.cdk-overlay-container` element as Angular\n * Material, NG-ZORRO, etc. With it, NGWR gets its own `OverlayContainer`\n * (marked `.wr-overlay-container`) **and** its own `Overlay` service\n * instance — so styles, z-index, and lifecycle never collide.\n *\n * It does this by replacing two injection tokens:\n * - `WR_OVERLAY_CONTAINER` → custom `WrOverlayContainer` subclass\n * - `WR_OVERLAY` → a fresh `Overlay` instance built in a child injector\n * that resolves `OverlayContainer` to the custom subclass\n *\n * CDK's own root `Overlay` / `OverlayContainer` are left untouched, so\n * other libraries keep working with their original container.\n *\n * @example\n * ```ts\n * import { provideWrOverlay } from 'ngwr/overlay';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrOverlay(),\n * ],\n * });\n * ```\n */\nexport function provideWrOverlay(): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: WR_OVERLAY_CONTAINER, useClass: WrOverlayContainer },\n {\n provide: WR_OVERLAY,\n useFactory: (): Overlay => {\n const parent = inject(EnvironmentInjector);\n const container = inject(WR_OVERLAY_CONTAINER);\n\n // Child injector resolves `OverlayContainer` to our subclass and\n // creates a fresh `Overlay` instance bound to it. CDK's own root\n // `Overlay` and `OverlayContainer` are untouched in the parent.\n const child = Injector.create({\n parent,\n providers: [\n { provide: OverlayContainer, useValue: container },\n { provide: Overlay, useClass: Overlay },\n ],\n });\n\n return child.get(Overlay);\n },\n },\n ]);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { WR_RESPONSIVE_OVERLAYS, type WrResponsiveOverlaysConfig } from './tokens/wr-responsive-overlays.token';\n\n/**\n * Opt every NGWR overlay into responsive presentation — on viewports at or\n * below `breakpoint`, dialogs / selects / dropdowns and friends slide up as\n * a full-width bottom-sheet instead of a floating panel. Built on the same\n * overlay plumbing, so focus-trap, backdrop and scroll-blocking carry over.\n *\n * Individual components can still opt out (or in) per instance via their\n * `responsive` option.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideWrOverlay(), provideWrResponsiveOverlays()],\n * });\n *\n * // Custom breakpoint:\n * provideWrResponsiveOverlays({ breakpoint: 768 });\n * ```\n */\nexport function provideWrResponsiveOverlays(config?: Partial<WrResponsiveOverlaysConfig>): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: WR_RESPONSIVE_OVERLAYS, useValue: { breakpoint: config?.breakpoint ?? 640 } },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAKH;;;;;;;;;;;;;;;AAeG;AAEG,MAAO,kBAAmB,SAAQ,gBAAgB,CAAA;IACnC,gBAAgB,GAAA;QACjC,KAAK,CAAC,gBAAgB,EAAE;QACxB,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAC/D;uGAJW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,OAAA,EAAA,CAAA;wGAAlB,kBAAkB,EAAA,CAAA;;2FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAD9B;;;AC1BD;;;;;AAKG;AAKH;;;;;;;;;;;AAWG;MACU,UAAU,GAAG,IAAI,cAAc,CAAU,YAAY,EAAE;AAClE,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,MAAM,CAAC,OAAO,CAAC;AAC/B,CAAA;;ACzBD;;;;;AAKG;AAKH;;;;;;;;AAQG;MACU,oBAAoB,GAAG,IAAI,cAAc,CAAmB,sBAAsB,EAAE;AAC/F,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,MAAM,CAAC,gBAAgB,CAAC;AACxC,CAAA;;ACtBD;;;;;AAKG;AAaH;;;;;;;;AAQG;AACH,MAAM,sBAAsB,GAAG,IAAI,cAAc,CAAoC,wBAAwB,EAAE;AAC7G,IAAA,OAAO,EAAE,MAAM,IAAI;AACpB,CAAA;AAED;;;;;;;;;;;;AAYG;AACH,SAAS,gBAAgB,CAAC,UAA+B,EAAE,MAAyC,EAAA;AAClG,IAAA,MAAM,OAAO,GAAG,UAAU,IAAI,MAAM,KAAK,IAAI;AAC7C,IAAA,IAAI,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW;AAAE,QAAA,OAAO,KAAK;IAC3D,OAAO,MAAM,CAAC,UAAU,KAAK,MAAM,EAAE,UAAU,IAAI,GAAG,CAAC;AACzD;;AChDA;;;;;AAKG;AAcH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;SACa,gBAAgB,GAAA;AAC9B,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,EAAE,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,kBAAkB,EAAE;AAC/D,QAAA;AACE,YAAA,OAAO,EAAE,UAAU;YACnB,UAAU,EAAE,MAAc;AACxB,gBAAA,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC1C,gBAAA,MAAM,SAAS,GAAG,MAAM,CAAC,oBAAoB,CAAC;;;;AAK9C,gBAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;oBAC5B,MAAM;AACN,oBAAA,SAAS,EAAE;AACT,wBAAA,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE;AAClD,wBAAA,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE;AACxC,qBAAA;AACF,iBAAA,CAAC;AAEF,gBAAA,OAAO,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;YAC3B,CAAC;AACF,SAAA;AACF,KAAA,CAAC;AACJ;;ACvEA;;;;;AAKG;AAMH;;;;;;;;;;;;;;;;;;AAkBG;AACG,SAAU,2BAA2B,CAAC,MAA4C,EAAA;AACtF,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,IAAI,GAAG,EAAE,EAAE;AACzF,KAAA,CAAC;AACJ;;AClCA;;AAEG;;;;"}