ngwr 14.7.0 → 14.8.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 (152) hide show
  1. package/bar-chart/styles/_index.scss +1 -0
  2. package/calendar-heatmap/styles/_index.scss +1 -0
  3. package/cascader/styles/_rules.scss +86 -14
  4. package/date-picker/styles/_index.scss +30 -0
  5. package/density/styles/_index.scss +4 -2
  6. package/donut-chart/styles/_index.scss +10 -0
  7. package/dropdown/styles/_index.scss +67 -5
  8. package/event-calendar/styles/_index.scss +209 -35
  9. package/fesm2022/ngwr-bar-chart.mjs +29 -4
  10. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  11. package/fesm2022/ngwr-calendar-heatmap.mjs +59 -4
  12. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  13. package/fesm2022/ngwr-cascader.mjs +2 -2
  14. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  15. package/fesm2022/ngwr-checkbox.mjs +12 -2
  16. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  17. package/fesm2022/ngwr-date-picker.mjs +705 -46
  18. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  19. package/fesm2022/ngwr-donut-chart.mjs +46 -4
  20. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  21. package/fesm2022/ngwr-dropdown.mjs +166 -17
  22. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  23. package/fesm2022/ngwr-event-calendar.mjs +9 -2
  24. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  25. package/fesm2022/ngwr-form.mjs +52 -1
  26. package/fesm2022/ngwr-form.mjs.map +1 -1
  27. package/fesm2022/ngwr-gauge.mjs +33 -4
  28. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  29. package/fesm2022/ngwr-i18n-ar.mjs +2 -0
  30. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  31. package/fesm2022/ngwr-i18n-cs.mjs +2 -0
  32. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  33. package/fesm2022/ngwr-i18n-de.mjs +2 -0
  34. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  35. package/fesm2022/ngwr-i18n-en.mjs +5 -0
  36. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  37. package/fesm2022/ngwr-i18n-es.mjs +2 -0
  38. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  39. package/fesm2022/ngwr-i18n-fr.mjs +2 -0
  40. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  41. package/fesm2022/ngwr-i18n-he.mjs +2 -0
  42. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  43. package/fesm2022/ngwr-i18n-hi.mjs +2 -0
  44. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  45. package/fesm2022/ngwr-i18n-id.mjs +2 -0
  46. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  47. package/fesm2022/ngwr-i18n-it.mjs +2 -0
  48. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  49. package/fesm2022/ngwr-i18n-ja.mjs +2 -0
  50. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  51. package/fesm2022/ngwr-i18n-ko.mjs +2 -0
  52. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  53. package/fesm2022/ngwr-i18n-nl.mjs +2 -0
  54. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  55. package/fesm2022/ngwr-i18n-pl.mjs +2 -0
  56. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  57. package/fesm2022/ngwr-i18n-pt.mjs +2 -0
  58. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  59. package/fesm2022/ngwr-i18n-ru.mjs +2 -0
  60. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  61. package/fesm2022/ngwr-i18n-sv.mjs +2 -0
  62. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  63. package/fesm2022/ngwr-i18n-tr.mjs +2 -0
  64. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  65. package/fesm2022/ngwr-i18n-uk.mjs +2 -0
  66. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  67. package/fesm2022/ngwr-i18n-vi.mjs +2 -0
  68. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  69. package/fesm2022/ngwr-i18n-zh-TW.mjs +2 -0
  70. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  71. package/fesm2022/ngwr-i18n-zh.mjs +2 -0
  72. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  73. package/fesm2022/ngwr-input-number.mjs +12 -0
  74. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  75. package/fesm2022/ngwr-line-chart.mjs +16 -5
  76. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  77. package/fesm2022/ngwr-meter-group-testing.mjs +7 -3
  78. package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
  79. package/fesm2022/ngwr-meter-group.mjs +24 -4
  80. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  81. package/fesm2022/ngwr-page-header.mjs +10 -2
  82. package/fesm2022/ngwr-page-header.mjs.map +1 -1
  83. package/fesm2022/ngwr-popover.mjs +569 -7
  84. package/fesm2022/ngwr-popover.mjs.map +1 -1
  85. package/fesm2022/ngwr-sidebar.mjs +7 -0
  86. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  87. package/fesm2022/ngwr-sparkline.mjs +82 -8
  88. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  89. package/fesm2022/ngwr-table.mjs +1 -1
  90. package/fesm2022/ngwr-table.mjs.map +1 -1
  91. package/fesm2022/ngwr-toolbar.mjs +7 -0
  92. package/fesm2022/ngwr-toolbar.mjs.map +1 -1
  93. package/fesm2022/ngwr-version.mjs +1 -1
  94. package/fesm2022/ngwr-version.mjs.map +1 -1
  95. package/form/styles/_index.scss +11 -1
  96. package/gauge/styles/_index.scss +1 -0
  97. package/i18n/ar.json +3 -1
  98. package/i18n/cs.json +3 -1
  99. package/i18n/de.json +3 -1
  100. package/i18n/en.json +3 -1
  101. package/i18n/es.json +3 -1
  102. package/i18n/fr.json +3 -1
  103. package/i18n/he.json +3 -1
  104. package/i18n/hi.json +3 -1
  105. package/i18n/id.json +3 -1
  106. package/i18n/it.json +3 -1
  107. package/i18n/ja.json +3 -1
  108. package/i18n/ko.json +3 -1
  109. package/i18n/nl.json +3 -1
  110. package/i18n/pl.json +3 -1
  111. package/i18n/pt.json +3 -1
  112. package/i18n/ru.json +3 -1
  113. package/i18n/sv.json +3 -1
  114. package/i18n/tr.json +3 -1
  115. package/i18n/uk.json +3 -1
  116. package/i18n/vi.json +3 -1
  117. package/i18n/zh-TW.json +3 -1
  118. package/i18n/zh.json +3 -1
  119. package/input/styles/_index.scss +19 -0
  120. package/input-number/styles/_index.scss +69 -0
  121. package/line-chart/styles/_index.scss +30 -2
  122. package/llms-full.txt +3 -3
  123. package/meter-group/styles/_index.scss +1 -0
  124. package/overlay/styles/_arrow.scss +27 -2
  125. package/package.json +1 -1
  126. package/page-header/styles/_index.scss +37 -1
  127. package/pagination/styles/_index.scss +9 -5
  128. package/popover/styles/_index.scss +73 -5
  129. package/select/styles/_index.scss +48 -9
  130. package/sidebar/styles/_index.scss +34 -2
  131. package/sparkline/styles/_index.scss +19 -0
  132. package/toolbar/styles/_index.scss +35 -1
  133. package/tree/styles/_index.scss +45 -6
  134. package/types/ngwr-bar-chart.d.ts +19 -1
  135. package/types/ngwr-calendar-heatmap.d.ts +29 -1
  136. package/types/ngwr-checkbox.d.ts +2 -0
  137. package/types/ngwr-date-picker.d.ts +308 -43
  138. package/types/ngwr-donut-chart.d.ts +24 -1
  139. package/types/ngwr-dropdown.d.ts +22 -2
  140. package/types/ngwr-event-calendar.d.ts +8 -0
  141. package/types/ngwr-form.d.ts +35 -5
  142. package/types/ngwr-gauge.d.ts +20 -1
  143. package/types/ngwr-input-number.d.ts +7 -0
  144. package/types/ngwr-line-chart.d.ts +9 -1
  145. package/types/ngwr-meter-group-testing.d.ts +3 -2
  146. package/types/ngwr-meter-group.d.ts +14 -1
  147. package/types/ngwr-page-header.d.ts +10 -2
  148. package/types/ngwr-popover.d.ts +154 -3
  149. package/types/ngwr-sidebar.d.ts +7 -0
  150. package/types/ngwr-sparkline.d.ts +43 -1
  151. package/types/ngwr-toolbar.d.ts +7 -0
  152. package/types/ngwr-version.d.ts +1 -1
@@ -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' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | '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 { Directionality } from '@angular/cdk/bidi';\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 Injector,\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, WrOutsideClick, wrFollowDirection, 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/reference/components/dropdown\n */\nlet triggerUid = 0;\n\n@Directive({\n selector: '[wrDropdown]',\n exportAs: '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 /**\n * The reading direction the open menu has to keep up with.\n *\n * Optional inject: `Directionality` is root-provided, so this is never null in\n * an app — but a bare `TestBed` that provides nothing should still get a menu\n * that opens, with simply nothing ambient to follow.\n */\n private readonly dir = inject(Directionality, { optional: true });\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n /** @internal Public so host bindings can read it. */\n readonly isOpen = signal(false);\n\n /** The id used only when the consumer's element carries none of its own. */\n private readonly fallbackId = `wr-dropdown-trigger-${++triggerUid}`;\n\n /**\n * Id the menu names itself after. The trigger is the CONSUMER's own element, so\n * an `id` they already put there wins: overwriting it broke `<label for>`,\n * `document.getElementById` and any `aria-labelledby` aimed at that button from\n * elsewhere in their app. The generated one is only a fallback so the menu has\n * something to reference.\n *\n * A GETTER, read fresh by the host binding on every pass, rather than a field\n * resolved in the constructor. A static `id=\"…\"` is on the element before a\n * directive is instantiated and so was already honoured; a BOUND `[id]` is\n * not — it lands with the rest of the template's bindings, which run before\n * host bindings but after construction, so the constructor read an empty\n * string, fell through to the fallback, and the host binding then wrote that\n * fallback over the value the template had just set. Everything bound was\n * lost — `[id]`, `[attr.id]` and an interpolated `id=\"dd-{{ n }}\"` alike —\n * while the static form survived, which is the shape that makes it look like\n * a naming convention rather than a defect.\n *\n * `.id` rather than `getAttribute`: it is always a string, and an empty one is\n * no id at all, so it falls through to the fallback.\n */\n protected get triggerId(): string {\n return this.host.nativeElement.id || this.fallbackId;\n }\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n // The host view carrying `[wrDropdown]` can be destroyed while the menu is\n // open — a route change, or an `@if` around the trigger. The overlay lives\n // in the CDK container, not in that view, so nothing removes it unless we do.\n this.destroyRef.onDestroy(() => this.closeOverlay(false));\n\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 /**\n * Whether the pointer, rather than the keyboard, opened the current menu.\n *\n * A hover-opened menu must not take focus — the APG shows a menu on hover and\n * leaves the caret where it was — while a keyboard-opened one must. The\n * trigger MODE cannot answer that on its own: a `trigger=\"hover\"` menu is\n * still openable with Enter, and that open should focus the first item.\n */\n private openedByPointer = false;\n\n protected onClick(event: MouseEvent): void {\n if (this.trigger() !== 'click') return;\n event.stopPropagation();\n this.openedByPointer = false;\n this.toggle();\n }\n\n /** @internal */\n protected onMouseEnter(): void {\n if (this.trigger() !== 'hover') return;\n // A POINTER opened this, so the menu must not take the keyboard with it —\n // see `openedByPointer`.\n this.openedByPointer = true;\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 // `create()` above froze the direction into the ref as a string, and nothing\n // in the CDK ever revisits it. This menu is where it shows first: the docs\n // site keeps its own LTR/RTL switch INSIDE a dropdown, so the flip is made\n // from within the one panel that has to answer it.\n //\n // No callback — `WR_DROPDOWN_POSITIONS` anchors on `start` / `end` and\n // carries no `offsetX`, so letting the CDK re-resolve those against the new\n // direction is the whole job; the sheet has no anchor at all and only needs\n // the `dir` on its host.\n wrFollowDirection(this.overlayRef, this.dir, this.injector);\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 — unless a POINTER\n // opened it. This used to be unconditional, so merely sweeping the cursor\n // over a `trigger=\"hover\"` menu yanked the caret out of whatever the user\n // was typing; the APG's own rule is that hover shows a menu and does not\n // move focus into it. A keyboard open (Enter / Space / ArrowDown) still\n // focuses the first item, on a hover trigger too.\n if (!this.openedByPointer) queueMicrotask(() => this.focusItemAt(0));\n\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\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 /**\n * Tear the overlay down, and tell the host — unless the host is going away\n * with it.\n *\n * `notify: false` is the DESTROY path, and it is not a nicety. An `output()`\n * belongs to the view that declares it, so emitting from `onDestroy` is\n * refused: Angular logs `NG0953: Unexpected emit for destroyed OutputRef` and\n * the listener never runs. Measured — a `(closed)` handler on a dropdown whose\n * host view is removed while the menu is open fired zero times and left a\n * console error behind. There is nobody to notify at that point, because the\n * consumer's own view is being torn down in the same pass; `wr-popconfirm`\n * already disposes without emitting, and this brings the other two into line.\n *\n * The focus hand-back is skipped for the same reason — the host element is on\n * its way out of the document.\n */\n private closeOverlay(notify = true): void {\n if (!this.overlayRef) return;\n if (this.trigger() === 'hover') {\n this.overlayRef.overlayElement.removeEventListener('mouseleave', this.onOverlayMouseLeave);\n }\n // Take the focus back before the pane goes, or it lands on `<body>` and the\n // next Tab starts from the top of the document. Only when focus is actually\n // inside the menu: closing a menu nobody was in must not steal the caret\n // from wherever the user has since moved.\n const active = document.activeElement;\n const focusWasInside = active instanceof Node && this.overlayRef.overlayElement.contains(active);\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (notify) {\n if (focusWasInside) this.host.nativeElement.focus();\n this.closed.emit();\n }\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 // Opened from the keyboard — including on a `hover` trigger, which stays\n // keyboard-operable — so the first item SHOULD take focus.\n this.openedByPointer = false;\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 // CDK's keyboard dispatcher feeds this overlay EVERY document keydown, not\n // just the ones typed into it — and a `trigger=\"hover\"` menu is open with\n // the caret deliberately left wherever the user was (see `openedByPointer`).\n // So ownership is checked here rather than assumed: without it, ArrowDown /\n // ArrowUp / Home / End pressed in an unrelated field were `preventDefault`ed\n // and yanked focus into the menu. The trigger counts as ours — a hover menu\n // that the user has tabbed back to should still open to the keyboard.\n const typedIn = event.target;\n const ours =\n typedIn instanceof Node &&\n (this.host.nativeElement.contains(typedIn) || (this.overlayRef?.overlayElement.contains(typedIn) ?? false));\n // Escape (and Tab) still close from anywhere — routing to the topmost\n // overlay regardless of focus is the dispatcher's whole job. Escape just\n // must not drag the caret onto the trigger from a field the user is in.\n if (!ours && event.key !== 'Escape' && event.key !== 'Tab') return;\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.isOpen.set(false);\n if (ours) 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/reference/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 // A BOUND display rather than a static `style` attribute: Angular writes a\n // binding through `style.setProperty`, which no CSP governs, while a real\n // `style=\"…\"` attribute is refused under `style-src 'self'` — and this host\n // would then lay out an empty box in the middle of the content.\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' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'right';\n\n/**\n * The CDK geometry for each placement — one position, no fallbacks.\n *\n * No `offsetX` / `offsetY`, unlike `wr-popover`'s table: the gap between the\n * trigger and the menu is PADDING on the pane (`.wr-dropdown-overlay--<placement>`),\n * so the pointer crossing it is still over the overlay and a `trigger=\"hover\"`\n * menu does not close on the way in. It also means nothing here is\n * direction-dependent, which is why the directive needs no `wrMirrorOffsets`.\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/**\n * What each placement is allowed to flip to when it does not fit, best first.\n * The requested placement always leads, so a menu that fits never moves.\n *\n * The same chains as `wr-popover`'s, restricted to the eight placements a\n * dropdown offers — which needs no editing, since every link in those eight\n * chains is itself one of the eight. Alignment is kept down the chain, a\n * block-axis placement only flips to its opposite, and a side placement may\n * also fall below or above, because on a phone neither side of a mid-page\n * trigger has the room. Once it has, the directive drops the side links for as\n * long as the menu stays open — the gap changes axis with the placement, so a\n * pane is only measured correctly against links on one axis at a time.\n *\n * Each list used to hold ONE position. With `withPush(true)` and nothing to\n * fall back to, a menu that did not fit below its trigger was pushed back up\n * over it instead — measured in Chromium at 1280×700 with a `bottom-start`\n * trigger 40px above the fold: the menu's top landed at 626, inside the\n * trigger's 630–660 box, covering the control that opened it.\n *\n * @internal\n */\nexport const WR_DROPDOWN_FALLBACKS: Record<WrDropdownPosition, readonly WrDropdownPosition[]> = {\n top: ['top', 'bottom'],\n 'top-start': ['top-start', 'bottom-start'],\n 'top-end': ['top-end', 'bottom-end'],\n bottom: ['bottom', 'top'],\n 'bottom-start': ['bottom-start', 'top-start'],\n 'bottom-end': ['bottom-end', 'top-end'],\n left: ['left', 'right', 'bottom', 'top'],\n right: ['right', 'left', 'bottom', 'top'],\n};\n\n/**\n * The list `withPositions()` wants — the chain in `WR_DROPDOWN_FALLBACKS` order,\n * as fresh objects, so the directive can tell which link the CDK landed on by\n * the IDENTITY of the position it reports back.\n *\n * Deliberately untagged, and this is where the dropdown parts from `wr-popover`,\n * which puts each placement's class in the position's own `panelClass`. The CDK\n * takes those classes off the pane BEFORE it measures it for fit, and here the\n * class carries the gap, as padding — so a tagged list is measured without its\n * gap. A menu with less room than that gap was judged to fit and the flexible\n * bounding box squeezed it instead: measured in Chromium at 1280×700 with 2px to\n * spare below the trigger, the menu's box shrank from 74px to 68px and its last\n * row ran through the bottom border. The directive writes the class itself, which\n * the CDK leaves alone, so the pane is measured with the gap it will render with.\n *\n * @internal\n */\nexport function wrDropdownPositions(position: WrDropdownPosition): ConnectedPosition[] {\n return WR_DROPDOWN_FALLBACKS[position].map(name => ({ ...WR_DROPDOWN_POSITIONS[name] }));\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 { Directionality } from '@angular/cdk/bidi';\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 Injector,\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, WrOutsideClick, wrFollowDirection, wrPresentAsSheet } from 'ngwr/overlay';\n\nimport type { WrDropdownMenu } from './dropdown-menu';\nimport {\n WR_DROPDOWN_FALLBACKS,\n WR_DROPDOWN_POSITIONS,\n type WrDropdownPosition,\n type WrDropdownTrigger,\n wrDropdownPositions,\n} from './interfaces';\n\n/** Whether a placement puts the menu BESIDE its trigger, where the gap is inline padding. */\nconst isSidePlacement = (name: WrDropdownPosition): boolean => name === 'left' || name === 'right';\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/reference/components/dropdown\n */\nlet triggerUid = 0;\n\n@Directive({\n selector: '[wrDropdown]',\n exportAs: '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 /**\n * Where the menu anchors relative to the trigger. A placement that does not\n * fit flips to the opposite side (a `left` / `right` menu may also drop below\n * or above, and then stays there until it closes), and the pane's\n * `wr-dropdown-overlay--<placement>` class names the side it actually took.\n * @default 'bottom-start'\n */\n readonly position = input<WrDropdownPosition>('bottom-start');\n\n /**\n * Draw a small arrow on the menu's edge, pointing at the trigger — the one\n * `wr-popover` and `wr-popconfirm` draw, from the same shared rule. It follows\n * the placement the menu actually took, so a flipped menu points the right\n * way, and it widens the gap to the trigger from 0.25rem to popover's 0.5rem\n * so the tip does not touch the control.\n *\n * Never drawn on a bottom sheet (`responsive`), which is anchored to nothing.\n * Turn it off on a menu with no padding of its own (`--wr-dropdown-padding: 0`)\n * or one that clips its overflow: the square reaches about 3px inside the\n * menu's border, over the first row, and `overflow` cuts its tip off.\n * Read when the menu opens. @default true\n */\n readonly arrow = input(true, { transform: coerceBooleanProperty });\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 /**\n * The reading direction the open menu has to keep up with.\n *\n * Optional inject: `Directionality` is root-provided, so this is never null in\n * an app — but a bare `TestBed` that provides nothing should still get a menu\n * that opens, with simply nothing ambient to follow.\n */\n private readonly dir = inject(Directionality, { optional: true });\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n /** @internal Public so host bindings can read it. */\n readonly isOpen = signal(false);\n\n /** The id used only when the consumer's element carries none of its own. */\n private readonly fallbackId = `wr-dropdown-trigger-${++triggerUid}`;\n\n /**\n * Id the menu names itself after. The trigger is the CONSUMER's own element, so\n * an `id` they already put there wins: overwriting it broke `<label for>`,\n * `document.getElementById` and any `aria-labelledby` aimed at that button from\n * elsewhere in their app. The generated one is only a fallback so the menu has\n * something to reference.\n *\n * A GETTER, read fresh by the host binding on every pass, rather than a field\n * resolved in the constructor. A static `id=\"…\"` is on the element before a\n * directive is instantiated and so was already honoured; a BOUND `[id]` is\n * not — it lands with the rest of the template's bindings, which run before\n * host bindings but after construction, so the constructor read an empty\n * string, fell through to the fallback, and the host binding then wrote that\n * fallback over the value the template had just set. Everything bound was\n * lost — `[id]`, `[attr.id]` and an interpolated `id=\"dd-{{ n }}\"` alike —\n * while the static form survived, which is the shape that makes it look like\n * a naming convention rather than a defect.\n *\n * `.id` rather than `getAttribute`: it is always a string, and an empty one is\n * no id at all, so it falls through to the fallback.\n */\n protected get triggerId(): string {\n return this.host.nativeElement.id || this.fallbackId;\n }\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n // The host view carrying `[wrDropdown]` can be destroyed while the menu is\n // open — a route change, or an `@if` around the trigger. The overlay lives\n // in the CDK container, not in that view, so nothing removes it unless we do.\n this.destroyRef.onDestroy(() => this.closeOverlay(false));\n\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 /**\n * Whether the pointer, rather than the keyboard, opened the current menu.\n *\n * A hover-opened menu must not take focus — the APG shows a menu on hover and\n * leaves the caret where it was — while a keyboard-opened one must. The\n * trigger MODE cannot answer that on its own: a `trigger=\"hover\"` menu is\n * still openable with Enter, and that open should focus the first item.\n */\n private openedByPointer = false;\n\n protected onClick(event: MouseEvent): void {\n if (this.trigger() !== 'click') return;\n event.stopPropagation();\n this.openedByPointer = false;\n this.toggle();\n }\n\n /** @internal */\n protected onMouseEnter(): void {\n if (this.trigger() !== 'hover') return;\n // A POINTER opened this, so the menu must not take the keyboard with it —\n // see `openedByPointer`.\n this.openedByPointer = true;\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 const requested = this.position();\n // A list of fresh objects, kept: the CDK reports the link it landed on by\n // handing that same object back, which is how the pane learns its placement.\n const positions = wrDropdownPositions(requested);\n\n // `withGrowAfterOpen`: past the first pass the CDK never gives the pane a box\n // larger than the last one it gave it. A menu measured with the wrong gap\n // (see the `positionChanges` handler below) is laid out once in a box sized\n // for the placement it is about to leave, and without this the pass that\n // corrects it inherits that box — a `right` menu with 70px below its trigger\n // moved above it into a 70px box and was squeezed all the same. The menu's\n // content does not change while it is open, so the box only ever grows back\n // to what the menu already needs.\n const connected = asSheet\n ? null\n : this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(positions)\n .withPush(true)\n .withGrowAfterOpen(true);\n\n const positionStrategy = connected ?? this.overlay.position().global().centerHorizontally().bottom('0');\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 // A sheet is anchored to nothing, so it gets neither a placement nor an\n // arrow. A floating menu starts on the placement it asked for, which is\n // what the CDK measures it with — see `wrDropdownPositions` for why that\n // class must already be on the pane rather than arrive with the position.\n panelClass: asSheet\n ? ['wr-dropdown-overlay', 'wr-overlay-sheet']\n : [\n 'wr-dropdown-overlay',\n `wr-dropdown-overlay--${requested}`,\n ...(this.arrow() ? ['wr-dropdown-overlay--arrow'] : []),\n ],\n });\n\n // When the menu flips, the pane has to name the side it actually took: the\n // gap padding belongs on the edge facing the trigger and the arrow hangs off\n // that same edge, and both key off this class. The CDK emits synchronously\n // from inside its own `apply()`, so the swap lands in the same frame as the\n // move, and the next measurement (a scroll, a resize) sees the new gap.\n if (connected) {\n const ref = this.overlayRef;\n const pane = ref.overlayElement;\n // Index-aligned: `links[i]` is the object the CDK hands back for `chain[i]`.\n let chain = WR_DROPDOWN_FALLBACKS[requested];\n let links = positions;\n connected.positionChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ connectionPair }) => {\n const landed = chain[links.indexOf(connectionPair)];\n if (!landed) return;\n for (const name of Object.keys(WR_DROPDOWN_POSITIONS)) {\n pane.classList.toggle(`wr-dropdown-overlay--${name}`, name === landed);\n }\n\n // A `left` / `right` menu that fell below or above was tested for fit\n // with the WRONG gap. The CDK measures the pane once per pass, for every\n // link, with the class on it at the time — the side placement's, whose\n // gap is inline padding — so the block link was judged by a box one gap\n // shorter than the one the swap above has just given it, and a menu with\n // less room than that gap was squeezed instead of flipped. Measured in\n // Chromium at 375×700, `right` with 76px below the trigger: the menu shrank\n // from 74px to 68px and its last row ran through the bottom border.\n //\n // So the sides are dropped for as long as this menu stays open and the\n // pane is measured again, now carrying the block gap, against block links\n // only. Not re-admitted afterwards: measured with a block gap, a side link\n // looks one gap narrower than it renders, which is the same mistake the\n // other way round and a menu that would flap between the two. Deferred to\n // a microtask because this runs INSIDE the CDK's `apply()`, which records\n // the link it landed on after this returns — a nested pass would have that\n // record overwritten by the outer one. A microtask still lands before the\n // frame is painted.\n if (isSidePlacement(landed) || !chain.some(isSidePlacement)) return;\n const kept = chain.flatMap((name, i) => (isSidePlacement(name) ? [] : [i]));\n chain = kept.map(i => chain[i]);\n links = kept.map(i => links[i]);\n connected.withPositions(links);\n queueMicrotask(() => {\n if (this.overlayRef === ref) ref.updatePosition();\n });\n });\n }\n\n // `create()` above froze the direction into the ref as a string, and nothing\n // in the CDK ever revisits it. This menu is where it shows first: the docs\n // site keeps its own LTR/RTL switch INSIDE a dropdown, so the flip is made\n // from within the one panel that has to answer it.\n //\n // No callback — `WR_DROPDOWN_POSITIONS` anchors on `start` / `end` and\n // carries no `offsetX`, so letting the CDK re-resolve those against the new\n // direction is the whole job; the sheet has no anchor at all and only needs\n // the `dir` on its host.\n wrFollowDirection(this.overlayRef, this.dir, this.injector);\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 — unless a POINTER\n // opened it. This used to be unconditional, so merely sweeping the cursor\n // over a `trigger=\"hover\"` menu yanked the caret out of whatever the user\n // was typing; the APG's own rule is that hover shows a menu and does not\n // move focus into it. A keyboard open (Enter / Space / ArrowDown) still\n // focuses the first item, on a hover trigger too.\n if (!this.openedByPointer) queueMicrotask(() => this.focusItemAt(0));\n\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\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 /**\n * Tear the overlay down, and tell the host — unless the host is going away\n * with it.\n *\n * `notify: false` is the DESTROY path, and it is not a nicety. An `output()`\n * belongs to the view that declares it, so emitting from `onDestroy` is\n * refused: Angular logs `NG0953: Unexpected emit for destroyed OutputRef` and\n * the listener never runs. Measured — a `(closed)` handler on a dropdown whose\n * host view is removed while the menu is open fired zero times and left a\n * console error behind. There is nobody to notify at that point, because the\n * consumer's own view is being torn down in the same pass; `wr-popconfirm`\n * already disposes without emitting, and this brings the other two into line.\n *\n * The focus hand-back is skipped for the same reason — the host element is on\n * its way out of the document.\n */\n private closeOverlay(notify = true): void {\n if (!this.overlayRef) return;\n if (this.trigger() === 'hover') {\n this.overlayRef.overlayElement.removeEventListener('mouseleave', this.onOverlayMouseLeave);\n }\n // Take the focus back before the pane goes, or it lands on `<body>` and the\n // next Tab starts from the top of the document. Only when focus is actually\n // inside the menu: closing a menu nobody was in must not steal the caret\n // from wherever the user has since moved.\n const active = document.activeElement;\n const focusWasInside = active instanceof Node && this.overlayRef.overlayElement.contains(active);\n this.overlayRef.dispose();\n this.overlayRef = null;\n if (notify) {\n if (focusWasInside) this.host.nativeElement.focus();\n this.closed.emit();\n }\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 // Opened from the keyboard — including on a `hover` trigger, which stays\n // keyboard-operable — so the first item SHOULD take focus.\n this.openedByPointer = false;\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 // CDK's keyboard dispatcher feeds this overlay EVERY document keydown, not\n // just the ones typed into it — and a `trigger=\"hover\"` menu is open with\n // the caret deliberately left wherever the user was (see `openedByPointer`).\n // So ownership is checked here rather than assumed: without it, ArrowDown /\n // ArrowUp / Home / End pressed in an unrelated field were `preventDefault`ed\n // and yanked focus into the menu. The trigger counts as ours — a hover menu\n // that the user has tabbed back to should still open to the keyboard.\n const typedIn = event.target;\n const ours =\n typedIn instanceof Node &&\n (this.host.nativeElement.contains(typedIn) || (this.overlayRef?.overlayElement.contains(typedIn) ?? false));\n // Escape (and Tab) still close from anywhere — routing to the topmost\n // overlay regardless of focus is the dispatcher's whole job. Escape just\n // must not drag the caret onto the trigger from a field the user is in.\n if (!ours && event.key !== 'Escape' && event.key !== 'Tab') return;\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.isOpen.set(false);\n if (ours) 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/reference/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 // A BOUND display rather than a static `style` attribute: Angular writes a\n // binding through `style.setProperty`, which no CSP governs, while a real\n // `style=\"…\"` attribute is refused under `style-src 'self'` — and this host\n // would then lay out an empty box in the middle of the content.\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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"}
@@ -280,6 +280,7 @@ class WrEventCalendar {
280
280
  const { chips, hidden } = this.bandLayout(events, row, this.maxLanes());
281
281
  weeks.push({
282
282
  key: this.iso(row[0]),
283
+ lanes: this.laneCount(chips),
283
284
  days: row.map((date, col) => ({
284
285
  date,
285
286
  key: this.iso(date),
@@ -331,6 +332,9 @@ class WrEventCalendar {
331
332
  ...(ngDevMode ? [{ debugName: "allDayCells" }] : /* istanbul ignore next */ []));
332
333
  hasAllDay = computed(() => this.allDayBands().length > 0, /* @ts-ignore */
333
334
  ...(ngDevMode ? [{ debugName: "hasAllDay" }] : /* istanbul ignore next */ []));
335
+ /** Lanes the all-day band fills — it has no `maxLanes` cap, so its row has to grow instead. */
336
+ allDayLanes = computed(() => this.laneCount(this.allDayBands()), /* @ts-ignore */
337
+ ...(ngDevMode ? [{ debugName: "allDayLanes" }] : /* istanbul ignore next */ []));
334
338
  rows = computed(() => {
335
339
  const slot = Math.max(5, this.slotMinutes());
336
340
  const from = Math.max(0, Math.min(23, this.dayStartHour())) * 60;
@@ -637,6 +641,9 @@ class WrEventCalendar {
637
641
  }
638
642
  return { chips, hidden };
639
643
  }
644
+ laneCount(chips) {
645
+ return chips.reduce((count, chip) => Math.max(count, chip.lane + 1), 0);
646
+ }
640
647
  /**
641
648
  * Column layout inside one day: events that overlap in time share the width.
642
649
  * Clusters are built by a running high-water mark — a new cluster starts the
@@ -799,7 +806,7 @@ class WrEventCalendar {
799
806
  return key;
800
807
  }
801
808
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrEventCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
802
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrEventCalendar, isStandalone: true, selector: "wr-event-calendar", inputs: { events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, slotMinutes: { classPropertyName: "slotMinutes", publicName: "slotMinutes", isSignal: true, isRequired: false, transformFunction: null }, dayStartHour: { classPropertyName: "dayStartHour", publicName: "dayStartHour", isSignal: true, isRequired: false, transformFunction: null }, dayEndHour: { classPropertyName: "dayEndHour", publicName: "dayEndHour", isSignal: true, isRequired: false, transformFunction: null }, maxLanes: { classPropertyName: "maxLanes", publicName: "maxLanes", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { view: "viewChange", date: "dateChange", eventClick: "eventClick", slotClick: "slotClick", eventChange: "eventChange" }, host: { listeners: { "pointerup": "onPointerUp($event)", "pointercancel": "drag.set(null)" }, properties: { "class": "classes()" } }, queries: [{ propertyName: "chipTpl", first: true, predicate: WrCalendarEventTemplate, descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n Two grids, one rule: a chip always lives inside the `role=\"gridcell\"` where it\n STARTS, and reaches out from there \u2014 `calc()` widths for day-spanning bands,\n percentage heights for timed chips. A floating events layer would read better\n in the template and would leave `role=\"row\"` owning something other than\n cells, which is exactly what the axe gate rejects.\n-->\n@if (!hideHeader()) {\n <div class=\"wr-event-calendar__header\">\n <div class=\"wr-event-calendar__nav\">\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--prev\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"step(-1)\"\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=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button wr-btn type=\"button\" size=\"sm\" outlined class=\"wr-event-calendar__today\" (click)=\"goToday()\">\n {{ todayLabel() }}\n </button>\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--next\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"step(1)\"\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=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n </div>\n\n <h2 class=\"wr-event-calendar__title\">{{ title() }}</h2>\n\n @if (switcher().length > 1) {\n <wr-btn-group>\n @for (item of switcher(); track item.view) {\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n class=\"wr-event-calendar__view\"\n [outlined]=\"view() !== item.view\"\n [color]=\"view() === item.view ? 'primary' : null\"\n [attr.aria-pressed]=\"view() === item.view\"\n (click)=\"setView(item.view)\"\n >\n {{ item.label }}\n </button>\n }\n </wr-btn-group>\n }\n </div>\n}\n\n@if (view() === 'month') {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--month\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n @for (name of weekdayNames(); track $index) {\n <div role=\"columnheader\" class=\"wr-event-calendar__weekday\">{{ name }}</div>\n }\n </div>\n\n @for (week of weeks(); track week.key; let w = $index) {\n <div role=\"row\" class=\"wr-event-calendar__row\">\n @for (cell of week.days; track cell.key; let c = $index) {\n @let index = w * 7 + c;\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--day\"\n [class.wr-event-calendar__cell--muted]=\"!cell.inMonth\"\n [class.wr-event-calendar__cell--today]=\"cell.isToday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(index, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${index}:-1`\"\n (focusin)=\"onCellFocus(index, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n <span class=\"wr-event-calendar__daynum\" aria-hidden=\"true\">{{ cell.day }}</span>\n\n @for (chip of cell.bands; track chip.key) {\n <ng-container\n [ngTemplateOutlet]=\"band\"\n [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '1.75rem' }\"\n />\n }\n\n @if (cell.hidden > 0) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__more\"\n [style.--wr-event-calendar-lane]=\"maxLanes()\"\n (click)=\"openDay(cell.date); $event.stopPropagation()\"\n >\n {{ moreLabel({ count: cell.hidden }) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n} @else {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--time\"\n [style.--wr-event-calendar-cols]=\"columns().length\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n <div role=\"columnheader\" class=\"wr-event-calendar__gutter\" [attr.aria-label]=\"timeLabel()\"></div>\n @for (column of columns(); track column.key) {\n <div\n role=\"columnheader\"\n class=\"wr-event-calendar__colhead\"\n [class.wr-event-calendar__colhead--today]=\"column.isToday\"\n >\n <span class=\"wr-event-calendar__colhead-weekday\">{{ column.weekday }}</span>\n <span class=\"wr-event-calendar__colhead-day\">{{ column.day }}</span>\n </div>\n }\n </div>\n\n @if (hasAllDay()) {\n <div role=\"row\" class=\"wr-event-calendar__row wr-event-calendar__row--allday\">\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ allDayLabel() }}</div>\n @for (cell of allDayCells(); track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--allday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${c}:-1`\"\n (focusin)=\"onCellFocus(c, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.bands; track chip.key) {\n <ng-container [ngTemplateOutlet]=\"band\" [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '0rem' }\" />\n }\n </div>\n }\n </div>\n }\n\n @for (row of rows(); track row.key) {\n <div role=\"row\" class=\"wr-event-calendar__row\" [class.wr-event-calendar__row--major]=\"row.major\">\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ row.label }}</div>\n @for (cell of row.cells; track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--slot\"\n [class.wr-event-calendar__cell--major]=\"row.major\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, row.minutes) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"row.minutes\"\n [attr.data-cell-index]=\"`${c}:${row.minutes}`\"\n (focusin)=\"onCellFocus(c, row.minutes)\"\n (click)=\"onCellClick(cell.date, row.minutes)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.chips; track chip.key) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--time\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.top.%]=\"chip.top\"\n [style.height.%]=\"chip.height\"\n [style.inset-inline-start.%]=\"chip.inlineStart\"\n [style.width.%]=\"chip.width\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n <span class=\"wr-event-calendar__chip-time\" aria-hidden=\"true\">{{ chipTime(chip.event) }}</span>\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n\n @if (canDrag(chip.event) && !chip.continuesAfter) {\n <!--\n A grab area, not a control: the same resize is on the keyboard as\n `Alt` + `Shift` + arrows on the chip itself, so exposing a second\n focusable thing here would add a tab stop that leads nowhere.\n -->\n <span\n class=\"wr-event-calendar__resize\"\n aria-hidden=\"true\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'resize')\"\n ></span>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n\n<!-- One chip shape for both day-spanning cases: month cells and the all-day band. -->\n<ng-template #band let-chip let-offset=\"offset\">\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--band\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.--wr-event-calendar-span]=\"chip.span\"\n [style.--wr-event-calendar-lane]=\"chip.lane\"\n [style.--wr-event-calendar-offset]=\"offset\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n </button>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: WrButton, selector: "wr-btn, button[wr-btn], a[wr-btn]", inputs: ["color", "size", "shape", "icon", "iconPosition", "disabled", "outlined", "block", "loading", "disabledWhenLoading"] }, { kind: "component", type: WrButtonGroup, selector: "wr-btn-group", inputs: ["shape"] }], encapsulation: i0.ViewEncapsulation.None });
809
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrEventCalendar, isStandalone: true, selector: "wr-event-calendar", inputs: { events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, slotMinutes: { classPropertyName: "slotMinutes", publicName: "slotMinutes", isSignal: true, isRequired: false, transformFunction: null }, dayStartHour: { classPropertyName: "dayStartHour", publicName: "dayStartHour", isSignal: true, isRequired: false, transformFunction: null }, dayEndHour: { classPropertyName: "dayEndHour", publicName: "dayEndHour", isSignal: true, isRequired: false, transformFunction: null }, maxLanes: { classPropertyName: "maxLanes", publicName: "maxLanes", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { view: "viewChange", date: "dateChange", eventClick: "eventClick", slotClick: "slotClick", eventChange: "eventChange" }, host: { listeners: { "pointerup": "onPointerUp($event)", "pointercancel": "drag.set(null)" }, properties: { "class": "classes()" } }, queries: [{ propertyName: "chipTpl", first: true, predicate: WrCalendarEventTemplate, descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n Two grids, one rule: a chip always lives inside the `role=\"gridcell\"` where it\n STARTS, and reaches out from there \u2014 `calc()` widths for day-spanning bands,\n percentage heights for timed chips. A floating events layer would read better\n in the template and would leave `role=\"row\"` owning something other than\n cells, which is exactly what the axe gate rejects.\n-->\n@if (!hideHeader()) {\n <div class=\"wr-event-calendar__header\">\n <div class=\"wr-event-calendar__nav\">\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--prev\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"step(-1)\"\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=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button wr-btn type=\"button\" size=\"sm\" outlined class=\"wr-event-calendar__today\" (click)=\"goToday()\">\n {{ todayLabel() }}\n </button>\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--next\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"step(1)\"\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=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n </div>\n\n <h2 class=\"wr-event-calendar__title\">{{ title() }}</h2>\n\n @if (switcher().length > 1) {\n <wr-btn-group>\n @for (item of switcher(); track item.view) {\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n class=\"wr-event-calendar__view\"\n [outlined]=\"view() !== item.view\"\n [color]=\"view() === item.view ? 'primary' : null\"\n [attr.aria-pressed]=\"view() === item.view\"\n (click)=\"setView(item.view)\"\n >\n {{ item.label }}\n </button>\n }\n </wr-btn-group>\n }\n </div>\n}\n\n@if (view() === 'month') {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--month\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n @for (name of weekdayNames(); track $index) {\n <div role=\"columnheader\" class=\"wr-event-calendar__weekday\">{{ name }}</div>\n }\n </div>\n\n @for (week of weeks(); track week.key; let w = $index) {\n <div role=\"row\" class=\"wr-event-calendar__row\" [style.--wr-event-calendar-lanes]=\"week.lanes\">\n @for (cell of week.days; track cell.key; let c = $index) {\n @let index = w * 7 + c;\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--day\"\n [class.wr-event-calendar__cell--muted]=\"!cell.inMonth\"\n [class.wr-event-calendar__cell--today]=\"cell.isToday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(index, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${index}:-1`\"\n (focusin)=\"onCellFocus(index, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n <span class=\"wr-event-calendar__daynum\" aria-hidden=\"true\">{{ cell.day }}</span>\n\n @for (chip of cell.bands; track chip.key) {\n <ng-container\n [ngTemplateOutlet]=\"band\"\n [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '1.75rem' }\"\n />\n }\n\n @if (cell.hidden > 0) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__more\"\n [style.--wr-event-calendar-lane]=\"maxLanes()\"\n (click)=\"openDay(cell.date); $event.stopPropagation()\"\n >\n {{ moreLabel({ count: cell.hidden }) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n} @else {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--time\"\n [style.--wr-event-calendar-cols]=\"columns().length\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n <div role=\"columnheader\" class=\"wr-event-calendar__gutter\" [attr.aria-label]=\"timeLabel()\"></div>\n @for (column of columns(); track column.key) {\n <div\n role=\"columnheader\"\n class=\"wr-event-calendar__colhead\"\n [class.wr-event-calendar__colhead--today]=\"column.isToday\"\n >\n <span class=\"wr-event-calendar__colhead-weekday\">{{ column.weekday }}</span>\n <span class=\"wr-event-calendar__colhead-day\">{{ column.day }}</span>\n </div>\n }\n </div>\n\n @if (hasAllDay()) {\n <div\n role=\"row\"\n class=\"wr-event-calendar__row wr-event-calendar__row--allday\"\n [style.--wr-event-calendar-lanes]=\"allDayLanes()\"\n >\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ allDayLabel() }}</div>\n @for (cell of allDayCells(); track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--allday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${c}:-1`\"\n (focusin)=\"onCellFocus(c, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.bands; track chip.key) {\n <ng-container [ngTemplateOutlet]=\"band\" [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '0rem' }\" />\n }\n </div>\n }\n </div>\n }\n\n @for (row of rows(); track row.key) {\n <div role=\"row\" class=\"wr-event-calendar__row\" [class.wr-event-calendar__row--major]=\"row.major\">\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ row.label }}</div>\n @for (cell of row.cells; track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--slot\"\n [class.wr-event-calendar__cell--major]=\"row.major\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, row.minutes) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"row.minutes\"\n [attr.data-cell-index]=\"`${c}:${row.minutes}`\"\n (focusin)=\"onCellFocus(c, row.minutes)\"\n (click)=\"onCellClick(cell.date, row.minutes)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.chips; track chip.key) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--time\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.top.%]=\"chip.top\"\n [style.--wr-event-calendar-block-size.%]=\"chip.height\"\n [style.--wr-event-calendar-inline-start.%]=\"chip.inlineStart\"\n [style.--wr-event-calendar-inline-size.%]=\"chip.width\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n <span class=\"wr-event-calendar__chip-time\" aria-hidden=\"true\">{{ chipTime(chip.event) }}</span>\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n\n @if (canDrag(chip.event) && !chip.continuesAfter) {\n <!--\n A grab area, not a control: the same resize is on the keyboard as\n `Alt` + `Shift` + arrows on the chip itself, so exposing a second\n focusable thing here would add a tab stop that leads nowhere.\n -->\n <span\n class=\"wr-event-calendar__resize\"\n aria-hidden=\"true\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'resize')\"\n ></span>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n\n<!-- One chip shape for both day-spanning cases: month cells and the all-day band. -->\n<ng-template #band let-chip let-offset=\"offset\">\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--band\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.--wr-event-calendar-span]=\"chip.span\"\n [style.--wr-event-calendar-lane]=\"chip.lane\"\n [style.--wr-event-calendar-offset]=\"offset\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n </button>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: WrButton, selector: "wr-btn, button[wr-btn], a[wr-btn]", inputs: ["color", "size", "shape", "icon", "iconPosition", "disabled", "outlined", "block", "loading", "disabledWhenLoading"] }, { kind: "component", type: WrButtonGroup, selector: "wr-btn-group", inputs: ["shape"] }], encapsulation: i0.ViewEncapsulation.None });
803
810
  }
804
811
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrEventCalendar, decorators: [{
805
812
  type: Component,
@@ -809,7 +816,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
809
816
  // chip it started on — so the host owns the release, not the chip.
810
817
  '(pointerup)': 'onPointerUp($event)',
811
818
  '(pointercancel)': 'drag.set(null)',
812
- }, imports: [NgTemplateOutlet, WrButton, WrButtonGroup], template: "<!--\n Two grids, one rule: a chip always lives inside the `role=\"gridcell\"` where it\n STARTS, and reaches out from there \u2014 `calc()` widths for day-spanning bands,\n percentage heights for timed chips. A floating events layer would read better\n in the template and would leave `role=\"row\"` owning something other than\n cells, which is exactly what the axe gate rejects.\n-->\n@if (!hideHeader()) {\n <div class=\"wr-event-calendar__header\">\n <div class=\"wr-event-calendar__nav\">\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--prev\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"step(-1)\"\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=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button wr-btn type=\"button\" size=\"sm\" outlined class=\"wr-event-calendar__today\" (click)=\"goToday()\">\n {{ todayLabel() }}\n </button>\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--next\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"step(1)\"\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=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n </div>\n\n <h2 class=\"wr-event-calendar__title\">{{ title() }}</h2>\n\n @if (switcher().length > 1) {\n <wr-btn-group>\n @for (item of switcher(); track item.view) {\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n class=\"wr-event-calendar__view\"\n [outlined]=\"view() !== item.view\"\n [color]=\"view() === item.view ? 'primary' : null\"\n [attr.aria-pressed]=\"view() === item.view\"\n (click)=\"setView(item.view)\"\n >\n {{ item.label }}\n </button>\n }\n </wr-btn-group>\n }\n </div>\n}\n\n@if (view() === 'month') {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--month\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n @for (name of weekdayNames(); track $index) {\n <div role=\"columnheader\" class=\"wr-event-calendar__weekday\">{{ name }}</div>\n }\n </div>\n\n @for (week of weeks(); track week.key; let w = $index) {\n <div role=\"row\" class=\"wr-event-calendar__row\">\n @for (cell of week.days; track cell.key; let c = $index) {\n @let index = w * 7 + c;\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--day\"\n [class.wr-event-calendar__cell--muted]=\"!cell.inMonth\"\n [class.wr-event-calendar__cell--today]=\"cell.isToday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(index, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${index}:-1`\"\n (focusin)=\"onCellFocus(index, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n <span class=\"wr-event-calendar__daynum\" aria-hidden=\"true\">{{ cell.day }}</span>\n\n @for (chip of cell.bands; track chip.key) {\n <ng-container\n [ngTemplateOutlet]=\"band\"\n [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '1.75rem' }\"\n />\n }\n\n @if (cell.hidden > 0) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__more\"\n [style.--wr-event-calendar-lane]=\"maxLanes()\"\n (click)=\"openDay(cell.date); $event.stopPropagation()\"\n >\n {{ moreLabel({ count: cell.hidden }) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n} @else {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--time\"\n [style.--wr-event-calendar-cols]=\"columns().length\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n <div role=\"columnheader\" class=\"wr-event-calendar__gutter\" [attr.aria-label]=\"timeLabel()\"></div>\n @for (column of columns(); track column.key) {\n <div\n role=\"columnheader\"\n class=\"wr-event-calendar__colhead\"\n [class.wr-event-calendar__colhead--today]=\"column.isToday\"\n >\n <span class=\"wr-event-calendar__colhead-weekday\">{{ column.weekday }}</span>\n <span class=\"wr-event-calendar__colhead-day\">{{ column.day }}</span>\n </div>\n }\n </div>\n\n @if (hasAllDay()) {\n <div role=\"row\" class=\"wr-event-calendar__row wr-event-calendar__row--allday\">\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ allDayLabel() }}</div>\n @for (cell of allDayCells(); track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--allday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${c}:-1`\"\n (focusin)=\"onCellFocus(c, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.bands; track chip.key) {\n <ng-container [ngTemplateOutlet]=\"band\" [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '0rem' }\" />\n }\n </div>\n }\n </div>\n }\n\n @for (row of rows(); track row.key) {\n <div role=\"row\" class=\"wr-event-calendar__row\" [class.wr-event-calendar__row--major]=\"row.major\">\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ row.label }}</div>\n @for (cell of row.cells; track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--slot\"\n [class.wr-event-calendar__cell--major]=\"row.major\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, row.minutes) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"row.minutes\"\n [attr.data-cell-index]=\"`${c}:${row.minutes}`\"\n (focusin)=\"onCellFocus(c, row.minutes)\"\n (click)=\"onCellClick(cell.date, row.minutes)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.chips; track chip.key) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--time\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.top.%]=\"chip.top\"\n [style.height.%]=\"chip.height\"\n [style.inset-inline-start.%]=\"chip.inlineStart\"\n [style.width.%]=\"chip.width\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n <span class=\"wr-event-calendar__chip-time\" aria-hidden=\"true\">{{ chipTime(chip.event) }}</span>\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n\n @if (canDrag(chip.event) && !chip.continuesAfter) {\n <!--\n A grab area, not a control: the same resize is on the keyboard as\n `Alt` + `Shift` + arrows on the chip itself, so exposing a second\n focusable thing here would add a tab stop that leads nowhere.\n -->\n <span\n class=\"wr-event-calendar__resize\"\n aria-hidden=\"true\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'resize')\"\n ></span>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n\n<!-- One chip shape for both day-spanning cases: month cells and the all-day band. -->\n<ng-template #band let-chip let-offset=\"offset\">\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--band\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.--wr-event-calendar-span]=\"chip.span\"\n [style.--wr-event-calendar-lane]=\"chip.lane\"\n [style.--wr-event-calendar-offset]=\"offset\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n </button>\n</ng-template>\n" }]
819
+ }, imports: [NgTemplateOutlet, WrButton, WrButtonGroup], template: "<!--\n Two grids, one rule: a chip always lives inside the `role=\"gridcell\"` where it\n STARTS, and reaches out from there \u2014 `calc()` widths for day-spanning bands,\n percentage heights for timed chips. A floating events layer would read better\n in the template and would leave `role=\"row\"` owning something other than\n cells, which is exactly what the axe gate rejects.\n-->\n@if (!hideHeader()) {\n <div class=\"wr-event-calendar__header\">\n <div class=\"wr-event-calendar__nav\">\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--prev\"\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"step(-1)\"\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=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button wr-btn type=\"button\" size=\"sm\" outlined class=\"wr-event-calendar__today\" (click)=\"goToday()\">\n {{ todayLabel() }}\n </button>\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n outlined\n class=\"wr-event-calendar__step wr-event-calendar__step--next\"\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"step(1)\"\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=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n </div>\n\n <h2 class=\"wr-event-calendar__title\">{{ title() }}</h2>\n\n @if (switcher().length > 1) {\n <wr-btn-group>\n @for (item of switcher(); track item.view) {\n <button\n wr-btn\n type=\"button\"\n size=\"sm\"\n class=\"wr-event-calendar__view\"\n [outlined]=\"view() !== item.view\"\n [color]=\"view() === item.view ? 'primary' : null\"\n [attr.aria-pressed]=\"view() === item.view\"\n (click)=\"setView(item.view)\"\n >\n {{ item.label }}\n </button>\n }\n </wr-btn-group>\n }\n </div>\n}\n\n@if (view() === 'month') {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--month\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n @for (name of weekdayNames(); track $index) {\n <div role=\"columnheader\" class=\"wr-event-calendar__weekday\">{{ name }}</div>\n }\n </div>\n\n @for (week of weeks(); track week.key; let w = $index) {\n <div role=\"row\" class=\"wr-event-calendar__row\" [style.--wr-event-calendar-lanes]=\"week.lanes\">\n @for (cell of week.days; track cell.key; let c = $index) {\n @let index = w * 7 + c;\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--day\"\n [class.wr-event-calendar__cell--muted]=\"!cell.inMonth\"\n [class.wr-event-calendar__cell--today]=\"cell.isToday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(index, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${index}:-1`\"\n (focusin)=\"onCellFocus(index, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n <span class=\"wr-event-calendar__daynum\" aria-hidden=\"true\">{{ cell.day }}</span>\n\n @for (chip of cell.bands; track chip.key) {\n <ng-container\n [ngTemplateOutlet]=\"band\"\n [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '1.75rem' }\"\n />\n }\n\n @if (cell.hidden > 0) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__more\"\n [style.--wr-event-calendar-lane]=\"maxLanes()\"\n (click)=\"openDay(cell.date); $event.stopPropagation()\"\n >\n {{ moreLabel({ count: cell.hidden }) }}\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n} @else {\n <div\n role=\"grid\"\n class=\"wr-event-calendar__grid wr-event-calendar__grid--time\"\n [style.--wr-event-calendar-cols]=\"columns().length\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n >\n <div role=\"row\" class=\"wr-event-calendar__row\">\n <div role=\"columnheader\" class=\"wr-event-calendar__gutter\" [attr.aria-label]=\"timeLabel()\"></div>\n @for (column of columns(); track column.key) {\n <div\n role=\"columnheader\"\n class=\"wr-event-calendar__colhead\"\n [class.wr-event-calendar__colhead--today]=\"column.isToday\"\n >\n <span class=\"wr-event-calendar__colhead-weekday\">{{ column.weekday }}</span>\n <span class=\"wr-event-calendar__colhead-day\">{{ column.day }}</span>\n </div>\n }\n </div>\n\n @if (hasAllDay()) {\n <div\n role=\"row\"\n class=\"wr-event-calendar__row wr-event-calendar__row--allday\"\n [style.--wr-event-calendar-lanes]=\"allDayLanes()\"\n >\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ allDayLabel() }}</div>\n @for (cell of allDayCells(); track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--allday\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, -1) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"-1\"\n [attr.data-cell-index]=\"`${c}:-1`\"\n (focusin)=\"onCellFocus(c, -1)\"\n (click)=\"onCellClick(cell.date, -1)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.bands; track chip.key) {\n <ng-container [ngTemplateOutlet]=\"band\" [ngTemplateOutletContext]=\"{ $implicit: chip, offset: '0rem' }\" />\n }\n </div>\n }\n </div>\n }\n\n @for (row of rows(); track row.key) {\n <div role=\"row\" class=\"wr-event-calendar__row\" [class.wr-event-calendar__row--major]=\"row.major\">\n <div role=\"rowheader\" class=\"wr-event-calendar__gutter\">{{ row.label }}</div>\n @for (cell of row.cells; track cell.key; let c = $index) {\n <div\n role=\"gridcell\"\n class=\"wr-event-calendar__cell wr-event-calendar__cell--slot\"\n [class.wr-event-calendar__cell--major]=\"row.major\"\n [attr.aria-label]=\"cell.label\"\n [attr.tabindex]=\"isCursor(c, row.minutes) ? 0 : -1\"\n [attr.data-cell-date]=\"stamp(cell.date)\"\n [attr.data-cell-minutes]=\"row.minutes\"\n [attr.data-cell-index]=\"`${c}:${row.minutes}`\"\n (focusin)=\"onCellFocus(c, row.minutes)\"\n (click)=\"onCellClick(cell.date, row.minutes)\"\n (keydown)=\"onGridKeyDown($event)\"\n >\n @for (chip of cell.chips; track chip.key) {\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--time\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.top.%]=\"chip.top\"\n [style.--wr-event-calendar-block-size.%]=\"chip.height\"\n [style.--wr-event-calendar-inline-start.%]=\"chip.inlineStart\"\n [style.--wr-event-calendar-inline-size.%]=\"chip.width\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n <span class=\"wr-event-calendar__chip-time\" aria-hidden=\"true\">{{ chipTime(chip.event) }}</span>\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n\n @if (canDrag(chip.event) && !chip.continuesAfter) {\n <!--\n A grab area, not a control: the same resize is on the keyboard as\n `Alt` + `Shift` + arrows on the chip itself, so exposing a second\n focusable thing here would add a tab stop that leads nowhere.\n -->\n <span\n class=\"wr-event-calendar__resize\"\n aria-hidden=\"true\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'resize')\"\n ></span>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n\n<!-- One chip shape for both day-spanning cases: month cells and the all-day band. -->\n<ng-template #band let-chip let-offset=\"offset\">\n <button\n type=\"button\"\n class=\"wr-event-calendar__chip wr-event-calendar__chip--band\"\n [class.wr-event-calendar__chip--dragging]=\"dragging() === chip.event.id\"\n [class.wr-event-calendar__chip--continues-before]=\"chip.continuesBefore\"\n [class.wr-event-calendar__chip--continues-after]=\"chip.continuesAfter\"\n [style.--wr-event-calendar-color]=\"`var(--wr-color-${chip.event.color ?? 'primary'})`\"\n [style.--wr-event-calendar-span]=\"chip.span\"\n [style.--wr-event-calendar-lane]=\"chip.lane\"\n [style.--wr-event-calendar-offset]=\"offset\"\n [attr.aria-label]=\"chipLabel(chip.event)\"\n (click)=\"onChipClick(chip.event); $event.stopPropagation()\"\n (keydown)=\"onChipKeyDown($event, chip.event)\"\n (pointerdown)=\"onChipPointerDown($event, chip.event, 'move')\"\n >\n @if (chipTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"{ $implicit: chip.event }\" />\n } @else {\n <span class=\"wr-event-calendar__chip-title\" aria-hidden=\"true\">{{ chip.event.title }}</span>\n }\n </button>\n</ng-template>\n" }]
813
820
  }], propDecorators: { events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }, { type: i0.Output, args: ["dateChange"] }], views: [{ type: i0.Input, args: [{ isSignal: true, alias: "views", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], slotMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "slotMinutes", required: false }] }], dayStartHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "dayStartHour", required: false }] }], dayEndHour: [{ type: i0.Input, args: [{ isSignal: true, alias: "dayEndHour", required: false }] }], maxLanes: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLanes", required: false }] }], hideHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideHeader", required: false }] }], eventClick: [{ type: i0.Output, args: ["eventClick"] }], slotClick: [{ type: i0.Output, args: ["slotClick"] }], eventChange: [{ type: i0.Output, args: ["eventChange"] }], chipTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => WrCalendarEventTemplate), { isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
814
821
 
815
822
  /**