@agorapulse/ui-components 22.1.7 → 22.1.8

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 (42) hide show
  1. package/agorapulse-ui-components-22.1.8.tgz +0 -0
  2. package/fesm2022/agorapulse-ui-components-action-dropdown.mjs +29 -61
  3. package/fesm2022/agorapulse-ui-components-action-dropdown.mjs.map +1 -1
  4. package/fesm2022/agorapulse-ui-components-button.mjs +8 -4
  5. package/fesm2022/agorapulse-ui-components-button.mjs.map +1 -1
  6. package/fesm2022/agorapulse-ui-components-checkbox.mjs +16 -4
  7. package/fesm2022/agorapulse-ui-components-checkbox.mjs.map +1 -1
  8. package/fesm2022/agorapulse-ui-components-directives.mjs +5 -2
  9. package/fesm2022/agorapulse-ui-components-directives.mjs.map +1 -1
  10. package/fesm2022/agorapulse-ui-components-dropdown-base.mjs +69 -2
  11. package/fesm2022/agorapulse-ui-components-dropdown-base.mjs.map +1 -1
  12. package/fesm2022/agorapulse-ui-components-dropdown-panel.mjs +44 -2
  13. package/fesm2022/agorapulse-ui-components-dropdown-panel.mjs.map +1 -1
  14. package/fesm2022/agorapulse-ui-components-filter-dropdown.mjs +27 -8
  15. package/fesm2022/agorapulse-ui-components-filter-dropdown.mjs.map +1 -1
  16. package/fesm2022/agorapulse-ui-components-input-search.mjs +10 -4
  17. package/fesm2022/agorapulse-ui-components-input-search.mjs.map +1 -1
  18. package/fesm2022/agorapulse-ui-components-labels-selector.mjs +1 -1
  19. package/fesm2022/agorapulse-ui-components-labels-selector.mjs.map +1 -1
  20. package/fesm2022/agorapulse-ui-components-legacy-select.mjs +1 -1
  21. package/fesm2022/agorapulse-ui-components-legacy-select.mjs.map +1 -1
  22. package/fesm2022/agorapulse-ui-components-nav-selector.mjs +3 -3
  23. package/fesm2022/agorapulse-ui-components-nav-selector.mjs.map +1 -1
  24. package/fesm2022/agorapulse-ui-components-select.mjs +11 -6
  25. package/fesm2022/agorapulse-ui-components-select.mjs.map +1 -1
  26. package/fesm2022/agorapulse-ui-components-selection-dropdown.mjs +160 -16
  27. package/fesm2022/agorapulse-ui-components-selection-dropdown.mjs.map +1 -1
  28. package/fesm2022/agorapulse-ui-components.mjs +1 -1
  29. package/fesm2022/agorapulse-ui-components.mjs.map +1 -1
  30. package/package.json +1 -1
  31. package/types/agorapulse-ui-components-action-dropdown.d.ts +6 -4
  32. package/types/agorapulse-ui-components-button.d.ts +4 -2
  33. package/types/agorapulse-ui-components-checkbox.d.ts +7 -1
  34. package/types/agorapulse-ui-components-directives.d.ts +13 -2
  35. package/types/agorapulse-ui-components-dropdown-base.d.ts +40 -1
  36. package/types/agorapulse-ui-components-dropdown-panel.d.ts +13 -0
  37. package/types/agorapulse-ui-components-filter-dropdown.d.ts +3 -1
  38. package/types/agorapulse-ui-components-input-search.d.ts +5 -1
  39. package/types/agorapulse-ui-components-select.d.ts +4 -1
  40. package/types/agorapulse-ui-components-selection-dropdown.d.ts +68 -5
  41. package/types/agorapulse-ui-components.d.ts +1 -1
  42. package/agorapulse-ui-components-22.1.7.tgz +0 -0
@@ -1,7 +1,54 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, input, HostListener, Directive } from '@angular/core';
2
+ import { inject, ElementRef, input, Directive, HostListener } from '@angular/core';
3
3
  import { createFloatingOverlay } from '@agorapulse/ui-components/floating';
4
4
 
5
+ /** Set on the active option by `ActiveDescendantKeyManager`, where focus stays in a search field. */
6
+ const DROPDOWN_OPTION_ACTIVE_CLASS = 'ap-dropdown-option--active';
7
+ /**
8
+ * Marks an element a `ListKeyManager` can drive. It satisfies both managers, because the right one
9
+ * depends on the role: `FocusKeyManager` moves real focus through a menu or a plain listbox,
10
+ * `ActiveDescendantKeyManager` leaves focus in a combobox's input and only marks the active option.
11
+ *
12
+ * The panel is role-agnostic, so the host says which of its children are options.
13
+ */
14
+ class DropdownOptionDirective {
15
+ element = inject(ElementRef);
16
+ label = input('', { ...(ngDevMode ? { debugName: "label" } : /* istanbul ignore next */ {}), alias: 'apDropdownOption' });
17
+ isDisabled = input(false, { ...(ngDevMode ? { debugName: "isDisabled" } : /* istanbul ignore next */ {}), alias: 'apDropdownOptionDisabled' });
18
+ /** `ListKeyManager` skips disabled options on its own; a disabled button is unfocusable anyway. */
19
+ get disabled() {
20
+ return this.isDisabled();
21
+ }
22
+ /** The id `aria-activedescendant` points at. Only meaningful under the active-descendant manager. */
23
+ get id() {
24
+ return this.element.nativeElement.id;
25
+ }
26
+ focus() {
27
+ this.element.nativeElement.focus();
28
+ }
29
+ /** Clicks the option, for a combobox where focus stays in the input and Enter must still reach it. */
30
+ activate() {
31
+ this.element.nativeElement.click();
32
+ }
33
+ getLabel() {
34
+ return this.label();
35
+ }
36
+ setActiveStyles() {
37
+ this.element.nativeElement.classList.add(DROPDOWN_OPTION_ACTIVE_CLASS);
38
+ // Optional: jsdom has no such method, and keeping the active option in view is a browser nicety.
39
+ this.element.nativeElement.scrollIntoView?.({ block: 'nearest' });
40
+ }
41
+ setInactiveStyles() {
42
+ this.element.nativeElement.classList.remove(DROPDOWN_OPTION_ACTIVE_CLASS);
43
+ }
44
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DropdownOptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
45
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: DropdownOptionDirective, isStandalone: true, selector: "[apDropdownOption]", inputs: { label: { classPropertyName: "label", publicName: "apDropdownOption", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "apDropdownOptionDisabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DropdownOptionDirective, decorators: [{
48
+ type: Directive,
49
+ args: [{ selector: '[apDropdownOption]' }]
50
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "apDropdownOption", required: false }] }], isDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "apDropdownOptionDisabled", required: false }] }] } });
51
+
5
52
  /**
6
53
  * Generic directive that turns any element into a trigger for a dropdown component
7
54
  * implementing the DropdownOverlay interface.
@@ -50,6 +97,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
50
97
  args: ['keydown', ['$event']]
51
98
  }] } });
52
99
 
100
+ /** Natively interactive, or made focusable on purpose. `[tabindex]` includes `-1`: still a focus target. */
101
+ const INTERACTIVE = 'button, [href], input, select, textarea, [tabindex]';
102
+ /** What to fall back to inside a wrapper. Here `-1` is excluded: it is a target, not an entry point. */
103
+ const FOCUSABLE_INSIDE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
104
+ /**
105
+ * The element a trigger really exposes — what takes focus and carries `aria-expanded`.
106
+ *
107
+ * `apDropdownTrigger` usually sits on a component host, and `<ap-button>` is not a button: it wraps
108
+ * one, so writing on the host would be inert.
109
+ *
110
+ * @param declared what the host component provides through `AP_INTERACTIVE_ELEMENT`, if any.
111
+ */
112
+ function interactiveTriggerElement(host, declared) {
113
+ if (declared)
114
+ return declared.interactiveElement();
115
+ if (host.matches(INTERACTIVE))
116
+ return host;
117
+ return host.querySelector(FOCUSABLE_INSIDE) ?? host;
118
+ }
119
+
53
120
  /**
54
121
  * Thin adapter over `createFloatingOverlay()`. Keeps the dropdown's name, lifecycle and default
55
122
  * backdrop; delegates all positioning to the shared floating primitive. Must be called within an
@@ -73,5 +140,5 @@ function createDropdownOverlay() {
73
140
  * Generated bundle index. Do not edit.
74
141
  */
75
142
 
76
- export { DropdownTriggerDirective, createDropdownOverlay };
143
+ export { DROPDOWN_OPTION_ACTIVE_CLASS, DropdownOptionDirective, DropdownTriggerDirective, createDropdownOverlay, interactiveTriggerElement };
77
144
  //# sourceMappingURL=agorapulse-ui-components-dropdown-base.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agorapulse-ui-components-dropdown-base.mjs","sources":["../../../libs/ui-components/dropdown-base/src/dropdown-trigger.directive.ts","../../../libs/ui-components/dropdown-base/src/dropdown-overlay.helper.ts","../../../libs/ui-components/dropdown-base/src/agorapulse-ui-components-dropdown-base.ts"],"sourcesContent":["import { Directive, ElementRef, HostListener, inject, input } from '@angular/core';\nimport { DropdownOverlay } from './dropdown-overlay.interface';\n\n/**\n * Generic directive that turns any element into a trigger for a dropdown component\n * implementing the DropdownOverlay interface.\n * Handles click and keyboard interactions to open/close the dropdown.\n */\n@Directive({\n selector: '[apDropdownTrigger]',\n})\nexport class DropdownTriggerDirective {\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n\n /** Reference to the dropdown component that this trigger controls */\n apDropdownTrigger = input.required<DropdownOverlay>();\n\n /** Handles click events to toggle the dropdown */\n @HostListener('click', ['$event'])\n onClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n this.apDropdownTrigger().toggle(this.elementRef.nativeElement);\n }\n\n /** Handles keyboard events for accessibility (Enter, Space, Arrow Down, Escape) */\n @HostListener('keydown', ['$event'])\n onKeyDown(event: KeyboardEvent): void {\n const dropdown = this.apDropdownTrigger();\n\n switch (event.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n event.preventDefault();\n dropdown.open(this.elementRef.nativeElement);\n break;\n\n case 'Escape':\n event.preventDefault();\n dropdown.close();\n break;\n }\n }\n}\n","import { createFloatingOverlay, FloatingAnchorMode, FloatingPlacement } from '@agorapulse/ui-components/floating';\nimport { TemplateRef } from '@angular/core';\n\nexport interface DropdownOverlayConfig {\n /** Defaults to `true` — the dropdown keeps its click catcher, unlike the primitive. */\n showBackdrop?: boolean;\n /** Panel placement. Unset means derived from `anchor`, i.e. `bottom-start`. */\n placement?: FloatingPlacement;\n /** What the panel connects to. Defaults to `'trigger'`. */\n anchor?: FloatingAnchorMode;\n /** Opt-in, and not offered by any existing panel's public API. */\n arrow?: boolean;\n /** What the tip points at. Defaults to `'anchor'`. */\n arrowTarget?: 'anchor' | 'pointer';\n /** Extra class(es) set on the overlay pane, so a consumer can scope global styles to its own dropdown. */\n panelClass?: string | string[];\n /** Called when the overlay is closed via outside click or Escape key. Typically routes to the component's own close() method. */\n onClose?: () => void;\n}\n\n/**\n * Thin adapter over `createFloatingOverlay()`. Keeps the dropdown's name, lifecycle and default\n * backdrop; delegates all positioning to the shared floating primitive. Must be called within an\n * Angular injection context (e.g., in a component constructor or field initializer).\n */\nexport function createDropdownOverlay() {\n const floating = createFloatingOverlay();\n\n return {\n get overlayRef() {\n return floating.overlayRef;\n },\n isOpen: floating.isOpen,\n close: floating.close,\n open(template: TemplateRef<unknown>, triggerElement?: HTMLElement, config?: DropdownOverlayConfig, event?: MouseEvent): void {\n floating.open(template, triggerElement, { ...config, showBackdrop: config?.showBackdrop ?? true }, event);\n },\n };\n}\n\nexport type DropdownOverlayInstance = ReturnType<typeof createDropdownOverlay>;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAGA;;;;AAIG;MAIU,wBAAwB,CAAA;AAChB,IAAA,UAAU,GAAG,MAAM,EAAC,UAAuB,EAAC;;IAG7D,iBAAiB,GAAG,KAAK,CAAC,QAAQ;0FAAmB;;AAIrD,IAAA,OAAO,CAAC,KAAiB,EAAA;QACrB,KAAK,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,eAAe,EAAE;AAEvB,QAAA,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;IAClE;;AAIA,IAAA,SAAS,CAAC,KAAoB,EAAA;AAC1B,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE;AAEzC,QAAA,QAAQ,KAAK,CAAC,GAAG;AACb,YAAA,KAAK,OAAO;AACZ,YAAA,KAAK,GAAG;AACR,YAAA,KAAK,WAAW;gBACZ,KAAK,CAAC,cAAc,EAAE;gBACtB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;gBAC5C;AAEJ,YAAA,KAAK,QAAQ;gBACT,KAAK,CAAC,cAAc,EAAE;gBACtB,QAAQ,CAAC,KAAK,EAAE;gBAChB;;IAEZ;uGAjCS,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,mBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAHpC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACP,oBAAA,QAAQ,EAAE,qBAAqB;AAClC,iBAAA;;sBAQI,YAAY;uBAAC,OAAO,EAAE,CAAC,QAAQ,CAAC;;sBAShC,YAAY;uBAAC,SAAS,EAAE,CAAC,QAAQ,CAAC;;;ACPvC;;;;AAIG;SACa,qBAAqB,GAAA;AACjC,IAAA,MAAM,QAAQ,GAAG,qBAAqB,EAAE;IAExC,OAAO;AACH,QAAA,IAAI,UAAU,GAAA;YACV,OAAO,QAAQ,CAAC,UAAU;QAC9B,CAAC;QACD,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,KAAK,EAAE,QAAQ,CAAC,KAAK;AACrB,QAAA,IAAI,CAAC,QAA8B,EAAE,cAA4B,EAAE,MAA8B,EAAE,KAAkB,EAAA;YACjH,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC;QAC7G,CAAC;KACJ;AACL;;ACtCA;;AAEG;;;;"}
1
+ {"version":3,"file":"agorapulse-ui-components-dropdown-base.mjs","sources":["../../../libs/ui-components/dropdown-base/src/dropdown-option.directive.ts","../../../libs/ui-components/dropdown-base/src/dropdown-trigger.directive.ts","../../../libs/ui-components/dropdown-base/src/trigger-element.ts","../../../libs/ui-components/dropdown-base/src/dropdown-overlay.helper.ts","../../../libs/ui-components/dropdown-base/src/agorapulse-ui-components-dropdown-base.ts"],"sourcesContent":["import { FocusableOption, Highlightable } from '@angular/cdk/a11y';\nimport { Directive, ElementRef, inject, input } from '@angular/core';\n\n/** Set on the active option by `ActiveDescendantKeyManager`, where focus stays in a search field. */\nexport const DROPDOWN_OPTION_ACTIVE_CLASS = 'ap-dropdown-option--active';\n\n/**\n * Marks an element a `ListKeyManager` can drive. It satisfies both managers, because the right one\n * depends on the role: `FocusKeyManager` moves real focus through a menu or a plain listbox,\n * `ActiveDescendantKeyManager` leaves focus in a combobox's input and only marks the active option.\n *\n * The panel is role-agnostic, so the host says which of its children are options.\n */\n@Directive({ selector: '[apDropdownOption]' })\nexport class DropdownOptionDirective implements FocusableOption, Highlightable {\n private readonly element = inject<ElementRef<HTMLElement>>(ElementRef);\n\n readonly label = input('', { alias: 'apDropdownOption' });\n\n readonly isDisabled = input(false, { alias: 'apDropdownOptionDisabled' });\n\n /** `ListKeyManager` skips disabled options on its own; a disabled button is unfocusable anyway. */\n get disabled(): boolean {\n return this.isDisabled();\n }\n\n /** The id `aria-activedescendant` points at. Only meaningful under the active-descendant manager. */\n get id(): string {\n return this.element.nativeElement.id;\n }\n\n focus(): void {\n this.element.nativeElement.focus();\n }\n\n /** Clicks the option, for a combobox where focus stays in the input and Enter must still reach it. */\n activate(): void {\n this.element.nativeElement.click();\n }\n\n getLabel(): string {\n return this.label();\n }\n\n setActiveStyles(): void {\n this.element.nativeElement.classList.add(DROPDOWN_OPTION_ACTIVE_CLASS);\n // Optional: jsdom has no such method, and keeping the active option in view is a browser nicety.\n this.element.nativeElement.scrollIntoView?.({ block: 'nearest' });\n }\n\n setInactiveStyles(): void {\n this.element.nativeElement.classList.remove(DROPDOWN_OPTION_ACTIVE_CLASS);\n }\n}\n","import { Directive, ElementRef, HostListener, inject, input } from '@angular/core';\nimport { DropdownOverlay } from './dropdown-overlay.interface';\n\n/**\n * Generic directive that turns any element into a trigger for a dropdown component\n * implementing the DropdownOverlay interface.\n * Handles click and keyboard interactions to open/close the dropdown.\n */\n@Directive({\n selector: '[apDropdownTrigger]',\n})\nexport class DropdownTriggerDirective {\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n\n /** Reference to the dropdown component that this trigger controls */\n apDropdownTrigger = input.required<DropdownOverlay>();\n\n /** Handles click events to toggle the dropdown */\n @HostListener('click', ['$event'])\n onClick(event: MouseEvent): void {\n event.preventDefault();\n event.stopPropagation();\n\n this.apDropdownTrigger().toggle(this.elementRef.nativeElement);\n }\n\n /** Handles keyboard events for accessibility (Enter, Space, Arrow Down, Escape) */\n @HostListener('keydown', ['$event'])\n onKeyDown(event: KeyboardEvent): void {\n const dropdown = this.apDropdownTrigger();\n\n switch (event.key) {\n case 'Enter':\n case ' ':\n case 'ArrowDown':\n event.preventDefault();\n dropdown.open(this.elementRef.nativeElement);\n break;\n\n case 'Escape':\n event.preventDefault();\n dropdown.close();\n break;\n }\n }\n}\n","import type { ApInteractiveElement } from '@agorapulse/ui-components/directives';\n\n/** Natively interactive, or made focusable on purpose. `[tabindex]` includes `-1`: still a focus target. */\nconst INTERACTIVE = 'button, [href], input, select, textarea, [tabindex]';\n\n/** What to fall back to inside a wrapper. Here `-1` is excluded: it is a target, not an entry point. */\nconst FOCUSABLE_INSIDE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * The element a trigger really exposes — what takes focus and carries `aria-expanded`.\n *\n * `apDropdownTrigger` usually sits on a component host, and `<ap-button>` is not a button: it wraps\n * one, so writing on the host would be inert.\n *\n * @param declared what the host component provides through `AP_INTERACTIVE_ELEMENT`, if any.\n */\nexport function interactiveTriggerElement(host: HTMLElement, declared?: ApInteractiveElement | null): HTMLElement {\n if (declared) return declared.interactiveElement();\n if (host.matches(INTERACTIVE)) return host;\n\n return host.querySelector<HTMLElement>(FOCUSABLE_INSIDE) ?? host;\n}\n","import { createFloatingOverlay, FloatingAnchorMode, FloatingPlacement } from '@agorapulse/ui-components/floating';\nimport { TemplateRef } from '@angular/core';\n\nexport interface DropdownOverlayConfig {\n /** Defaults to `true` — the dropdown keeps its click catcher, unlike the primitive. */\n showBackdrop?: boolean;\n /** Panel placement. Unset means derived from `anchor`, i.e. `bottom-start`. */\n placement?: FloatingPlacement;\n /** What the panel connects to. Defaults to `'trigger'`. */\n anchor?: FloatingAnchorMode;\n /** Opt-in, and not offered by any existing panel's public API. */\n arrow?: boolean;\n /** What the tip points at. Defaults to `'anchor'`. */\n arrowTarget?: 'anchor' | 'pointer';\n /** Extra class(es) set on the overlay pane, so a consumer can scope global styles to its own dropdown. */\n panelClass?: string | string[];\n /** Called when the overlay is closed via outside click or Escape key. Typically routes to the component's own close() method. */\n onClose?: () => void;\n}\n\n/**\n * Thin adapter over `createFloatingOverlay()`. Keeps the dropdown's name, lifecycle and default\n * backdrop; delegates all positioning to the shared floating primitive. Must be called within an\n * Angular injection context (e.g., in a component constructor or field initializer).\n */\nexport function createDropdownOverlay() {\n const floating = createFloatingOverlay();\n\n return {\n get overlayRef() {\n return floating.overlayRef;\n },\n isOpen: floating.isOpen,\n close: floating.close,\n open(template: TemplateRef<unknown>, triggerElement?: HTMLElement, config?: DropdownOverlayConfig, event?: MouseEvent): void {\n floating.open(template, triggerElement, { ...config, showBackdrop: config?.showBackdrop ?? true }, event);\n },\n };\n}\n\nexport type DropdownOverlayInstance = ReturnType<typeof createDropdownOverlay>;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { inject, TemplateRef, Directive, contentChild, viewChild, input, output, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { createFloatingOverlay } from '@agorapulse/ui-components/floating';
4
4
  import { NgTemplateOutlet } from '@angular/common';
5
+ import { interactiveTriggerElement } from '@agorapulse/ui-components/dropdown-base';
5
6
 
6
7
  /** Marks the panel's content. A template, not `<ng-content>`, so nothing is created until the panel opens. */
7
8
  class DropdownContentDirective {
@@ -28,6 +29,7 @@ class DropdownPanelComponent {
28
29
  floating = createFloatingOverlay();
29
30
  content = contentChild.required(DropdownContentDirective);
30
31
  surface = viewChild.required('surface');
32
+ returnFocusTo = null;
31
33
  /** Unset means derived from the anchor mode, i.e. `bottom-start`. */
32
34
  placement = input(/* @ts-ignore */
33
35
  ...(ngDevMode ? [undefined, { debugName: "placement" }] : /* istanbul ignore next */ []));
@@ -50,20 +52,60 @@ class DropdownPanelComponent {
50
52
  open(triggerElement) {
51
53
  if (this.isOpen())
52
54
  return;
55
+ this.returnFocusTo = triggerElement ?? this.activeElement();
53
56
  this.floating.open(this.surface(), triggerElement, {
54
57
  placement: this.placement(),
55
58
  showBackdrop: this.showBackdrop(),
56
59
  panelClass: this.panelClass(),
57
60
  onClose: () => this.dismiss(),
58
61
  });
62
+ this.focusIn();
59
63
  this.opened.emit();
60
64
  }
61
65
  close() {
62
66
  if (!this.isOpen())
63
67
  return;
68
+ // Read before disposing: the pane is gone by the time we would ask.
69
+ const ours = this.holdsFocus();
70
+ const returnTo = this.returnFocusTo;
71
+ this.returnFocusTo = null;
64
72
  this.floating.close();
73
+ if (ours && returnTo)
74
+ this.returnFocus(returnTo);
65
75
  this.closed.emit();
66
76
  }
77
+ /**
78
+ * The pane sits at the end of `body`, so Tab from the trigger would walk the whole page before
79
+ * reaching it. Focus the content root when it declares a tabindex — a host that wants something
80
+ * finer focuses it afterwards, and wins.
81
+ */
82
+ focusIn() {
83
+ const surface = this.surfaceElement();
84
+ const contentRoot = surface?.firstElementChild;
85
+ const target = contentRoot instanceof HTMLElement && contentRoot.hasAttribute('tabindex') ? contentRoot : surface;
86
+ target?.focus();
87
+ }
88
+ returnFocus(trigger) {
89
+ interactiveTriggerElement(trigger).focus();
90
+ }
91
+ /** Only give focus back if it is still ours to give: the user may have clicked elsewhere. */
92
+ holdsFocus() {
93
+ const active = this.activeElement();
94
+ if (!active || active === document.body)
95
+ return true;
96
+ return this.floating.overlayRef?.overlayElement.contains(active) ?? false;
97
+ }
98
+ /** `<body>` means nobody holds focus: returning focus there would land on the page's first focusable element. */
99
+ activeElement() {
100
+ const active = document.activeElement;
101
+ if (!(active instanceof HTMLElement) || active === document.body)
102
+ return null;
103
+ return active;
104
+ }
105
+ surfaceElement() {
106
+ const child = this.floating.overlayRef?.overlayElement.firstElementChild;
107
+ return child instanceof HTMLElement ? child : null;
108
+ }
67
109
  toggle(triggerElement) {
68
110
  if (this.isOpen()) {
69
111
  this.close();
@@ -78,11 +120,11 @@ class DropdownPanelComponent {
78
120
  }
79
121
  }
80
122
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DropdownPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
81
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.5", type: DropdownPanelComponent, isStandalone: true, selector: "ap-dropdown-panel", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, showBackdrop: { classPropertyName: "showBackdrop", publicName: "showBackdrop", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, canDismiss: { classPropertyName: "canDismiss", publicName: "canDismiss", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, queries: [{ propertyName: "content", first: true, predicate: DropdownContentDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "surface", first: true, predicate: ["surface"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #surface>\n <div class=\"ap-dropdown-panel\">\n <ng-container [ngTemplateOutlet]=\"content().template\" />\n </div>\n</ng-template>\n", styles: [":host{display:none}.ap-dropdown-panel{background-color:var(--comp-dropdown-panel-background-color);border-radius:var(--comp-dropdown-panel-border-radius);box-shadow:var(--comp-dropdown-panel-box-shadow);overflow:clip;overflow-clip-margin:3px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
123
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.5", type: DropdownPanelComponent, isStandalone: true, selector: "ap-dropdown-panel", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, showBackdrop: { classPropertyName: "showBackdrop", publicName: "showBackdrop", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, canDismiss: { classPropertyName: "canDismiss", publicName: "canDismiss", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, queries: [{ propertyName: "content", first: true, predicate: DropdownContentDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "surface", first: true, predicate: ["surface"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #surface>\n <div\n class=\"ap-dropdown-panel\"\n tabindex=\"-1\">\n <ng-container [ngTemplateOutlet]=\"content().template\" />\n </div>\n</ng-template>\n", styles: [":host{display:none}.ap-dropdown-panel{background-color:var(--comp-dropdown-panel-background-color);border-radius:var(--comp-dropdown-panel-border-radius);box-shadow:var(--comp-dropdown-panel-box-shadow);overflow:clip;overflow-clip-margin:3px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
82
124
  }
83
125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DropdownPanelComponent, decorators: [{
84
126
  type: Component,
85
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ap-dropdown-panel', imports: [NgTemplateOutlet], template: "<ng-template #surface>\n <div class=\"ap-dropdown-panel\">\n <ng-container [ngTemplateOutlet]=\"content().template\" />\n </div>\n</ng-template>\n", styles: [":host{display:none}.ap-dropdown-panel{background-color:var(--comp-dropdown-panel-background-color);border-radius:var(--comp-dropdown-panel-border-radius);box-shadow:var(--comp-dropdown-panel-box-shadow);overflow:clip;overflow-clip-margin:3px}\n"] }]
127
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ap-dropdown-panel', imports: [NgTemplateOutlet], template: "<ng-template #surface>\n <div\n class=\"ap-dropdown-panel\"\n tabindex=\"-1\">\n <ng-container [ngTemplateOutlet]=\"content().template\" />\n </div>\n</ng-template>\n", styles: [":host{display:none}.ap-dropdown-panel{background-color:var(--comp-dropdown-panel-background-color);border-radius:var(--comp-dropdown-panel-border-radius);box-shadow:var(--comp-dropdown-panel-box-shadow);overflow:clip;overflow-clip-margin:3px}\n"] }]
86
128
  }], propDecorators: { content: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownContentDirective), { isSignal: true }] }], surface: [{ type: i0.ViewChild, args: ['surface', { isSignal: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], showBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBackdrop", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], canDismiss: [{ type: i0.Input, args: [{ isSignal: true, alias: "canDismiss", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
87
129
 
88
130
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"agorapulse-ui-components-dropdown-panel.mjs","sources":["../../../libs/ui-components/dropdown-panel/src/dropdown-content.directive.ts","../../../libs/ui-components/dropdown-panel/src/dropdown-panel.component.ts","../../../libs/ui-components/dropdown-panel/src/dropdown-panel.component.html","../../../libs/ui-components/dropdown-panel/src/agorapulse-ui-components-dropdown-panel.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/** Marks the panel's content. A template, not `<ng-content>`, so nothing is created until the panel opens. */\n@Directive({ selector: 'ng-template[apDropdownContent]' })\nexport class DropdownContentDirective {\n readonly template = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { createFloatingOverlay, FloatingPlacement } from '@agorapulse/ui-components/floating';\nimport { OverlayRef } from '@angular/cdk/overlay';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, contentChild, input, output, TemplateRef, viewChild } from '@angular/core';\nimport { DropdownOverlay } from '@agorapulse/ui-components/dropdown-base';\nimport { DropdownContentDirective } from './dropdown-content.directive';\n\n/**\n * The surface a dropdown opens: white, rounded, elevated — and nothing more. No role and no focus\n * trap: the content brings its own semantics (`menu`, `listbox`…). A dialog wants the popover.\n *\n * @example\n * <button [apDropdownTrigger]=\"panel\">Columns</button>\n * <ap-dropdown-panel #panel>\n * <ng-template apDropdownContent>…</ng-template>\n * </ap-dropdown-panel>\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ap-dropdown-panel',\n imports: [NgTemplateOutlet],\n templateUrl: 'dropdown-panel.component.html',\n styleUrls: ['dropdown-panel.component.scss'],\n})\nexport class DropdownPanelComponent implements DropdownOverlay {\n private readonly floating = createFloatingOverlay();\n protected readonly content = contentChild.required(DropdownContentDirective);\n private readonly surface = viewChild.required<TemplateRef<unknown>>('surface');\n\n /** Unset means derived from the anchor mode, i.e. `bottom-start`. */\n readonly placement = input<FloatingPlacement>();\n\n /** On by default: a dropdown keeps its click catcher. */\n readonly showBackdrop = input(true);\n\n readonly panelClass = input<string | string[]>('');\n\n /** Consulted before an outside click or Escape closes the panel. Return `false` to keep it open. */\n readonly canDismiss = input<() => boolean>(() => true);\n\n readonly opened = output<void>();\n\n /** Fires for every close, asked for or gestured: a host's teardown belongs here, not in its own `close()`. */\n readonly closed = output<void>();\n\n readonly isOpen = this.floating.isOpen;\n\n /** For a host that must hear the gesture before it becomes a dismissal — see the filter dropdown. */\n get overlayRef(): OverlayRef | null {\n return this.floating.overlayRef;\n }\n\n open(triggerElement?: HTMLElement): void {\n if (this.isOpen()) return;\n\n this.floating.open(this.surface(), triggerElement, {\n placement: this.placement(),\n showBackdrop: this.showBackdrop(),\n panelClass: this.panelClass(),\n onClose: () => this.dismiss(),\n });\n this.opened.emit();\n }\n\n close(): void {\n if (!this.isOpen()) return;\n\n this.floating.close();\n this.closed.emit();\n }\n\n toggle(triggerElement?: HTMLElement): void {\n if (this.isOpen()) {\n this.close();\n } else {\n this.open(triggerElement);\n }\n }\n\n private dismiss(): void {\n if (this.canDismiss()()) {\n this.close();\n }\n }\n}\n","<ng-template #surface>\n <div class=\"ap-dropdown-panel\">\n <ng-container [ngTemplateOutlet]=\"content().template\" />\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;;AAEA;MAEa,wBAAwB,CAAA;AACxB,IAAA,QAAQ,GAAG,MAAM,CAAuB,WAAW,CAAC;uGADpD,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gCAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,SAAS;mBAAC,EAAE,QAAQ,EAAE,gCAAgC,EAAE;;;ACIzD;;;;;;;;;AASG;MAQU,sBAAsB,CAAA;IACd,QAAQ,GAAG,qBAAqB,EAAE;AAChC,IAAA,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,wBAAwB,CAAC;AAC3D,IAAA,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAuB,SAAS,CAAC;;AAGrE,IAAA,SAAS,GAAG,KAAK;6FAAqB;;IAGtC,YAAY,GAAG,KAAK,CAAC,IAAI;qFAAC;IAE1B,UAAU,GAAG,KAAK,CAAoB,EAAE;mFAAC;;AAGzC,IAAA,UAAU,GAAG,KAAK,CAAgB,MAAM,IAAI;mFAAC;IAE7C,MAAM,GAAG,MAAM,EAAQ;;IAGvB,MAAM,GAAG,MAAM,EAAQ;AAEvB,IAAA,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM;;AAGtC,IAAA,IAAI,UAAU,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU;IACnC;AAEA,IAAA,IAAI,CAAC,cAA4B,EAAA;QAC7B,IAAI,IAAI,CAAC,MAAM,EAAE;YAAE;QAEnB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE;AAC/C,YAAA,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;AAC3B,YAAA,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE;AACjC,YAAA,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE;AAC7B,YAAA,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO,EAAE;AAChC,SAAA,CAAC;AACF,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACtB;IAEA,KAAK,GAAA;AACD,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE;AAEpB,QAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;AACrB,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACtB;AAEA,IAAA,MAAM,CAAC,cAA4B,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;YACf,IAAI,CAAC,KAAK,EAAE;QAChB;aAAO;AACH,YAAA,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;QAC7B;IACJ;IAEQ,OAAO,GAAA;AACX,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE;YACrB,IAAI,CAAC,KAAK,EAAE;QAChB;IACJ;uGA3DS,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAEoB,wBAAwB,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,SAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC1B/E,iKAKA,8SDec,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAIjB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAPlC,SAAS;AACW,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC,mBAAmB,EAAA,OAAA,EACpB,CAAC,gBAAgB,CAAC,EAAA,QAAA,EAAA,iKAAA,EAAA,MAAA,EAAA,CAAA,sPAAA,CAAA,EAAA;AAMwB,SAAA,CAAA,EAAA,cAAA,EAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,UAAA,CAAA,MAAA,wBAAwB,kEACP,SAAS,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,SAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,cAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,UAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,UAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,QAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AE3BjF;;AAEG;;;;"}
1
+ {"version":3,"file":"agorapulse-ui-components-dropdown-panel.mjs","sources":["../../../libs/ui-components/dropdown-panel/src/dropdown-content.directive.ts","../../../libs/ui-components/dropdown-panel/src/dropdown-panel.component.ts","../../../libs/ui-components/dropdown-panel/src/dropdown-panel.component.html","../../../libs/ui-components/dropdown-panel/src/agorapulse-ui-components-dropdown-panel.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/** Marks the panel's content. A template, not `<ng-content>`, so nothing is created until the panel opens. */\n@Directive({ selector: 'ng-template[apDropdownContent]' })\nexport class DropdownContentDirective {\n readonly template = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { createFloatingOverlay, FloatingPlacement } from '@agorapulse/ui-components/floating';\nimport { OverlayRef } from '@angular/cdk/overlay';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, contentChild, input, output, TemplateRef, viewChild } from '@angular/core';\nimport { DropdownOverlay, interactiveTriggerElement } from '@agorapulse/ui-components/dropdown-base';\nimport { DropdownContentDirective } from './dropdown-content.directive';\n\n/**\n * The surface a dropdown opens: white, rounded, elevated — and nothing more. No role and no focus\n * trap: the content brings its own semantics (`menu`, `listbox`…). A dialog wants the popover.\n *\n * @example\n * <button [apDropdownTrigger]=\"panel\">Columns</button>\n * <ap-dropdown-panel #panel>\n * <ng-template apDropdownContent>…</ng-template>\n * </ap-dropdown-panel>\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'ap-dropdown-panel',\n imports: [NgTemplateOutlet],\n templateUrl: 'dropdown-panel.component.html',\n styleUrls: ['dropdown-panel.component.scss'],\n})\nexport class DropdownPanelComponent implements DropdownOverlay {\n private readonly floating = createFloatingOverlay();\n protected readonly content = contentChild.required(DropdownContentDirective);\n private readonly surface = viewChild.required<TemplateRef<unknown>>('surface');\n private returnFocusTo: HTMLElement | null = null;\n\n /** Unset means derived from the anchor mode, i.e. `bottom-start`. */\n readonly placement = input<FloatingPlacement>();\n\n /** On by default: a dropdown keeps its click catcher. */\n readonly showBackdrop = input(true);\n\n readonly panelClass = input<string | string[]>('');\n\n /** Consulted before an outside click or Escape closes the panel. Return `false` to keep it open. */\n readonly canDismiss = input<() => boolean>(() => true);\n\n readonly opened = output<void>();\n\n /** Fires for every close, asked for or gestured: a host's teardown belongs here, not in its own `close()`. */\n readonly closed = output<void>();\n\n readonly isOpen = this.floating.isOpen;\n\n /** For a host that must hear the gesture before it becomes a dismissal — see the filter dropdown. */\n get overlayRef(): OverlayRef | null {\n return this.floating.overlayRef;\n }\n\n open(triggerElement?: HTMLElement): void {\n if (this.isOpen()) return;\n\n this.returnFocusTo = triggerElement ?? this.activeElement();\n\n this.floating.open(this.surface(), triggerElement, {\n placement: this.placement(),\n showBackdrop: this.showBackdrop(),\n panelClass: this.panelClass(),\n onClose: () => this.dismiss(),\n });\n this.focusIn();\n this.opened.emit();\n }\n\n close(): void {\n if (!this.isOpen()) return;\n\n // Read before disposing: the pane is gone by the time we would ask.\n const ours = this.holdsFocus();\n const returnTo = this.returnFocusTo;\n this.returnFocusTo = null;\n\n this.floating.close();\n if (ours && returnTo) this.returnFocus(returnTo);\n this.closed.emit();\n }\n\n /**\n * The pane sits at the end of `body`, so Tab from the trigger would walk the whole page before\n * reaching it. Focus the content root when it declares a tabindex — a host that wants something\n * finer focuses it afterwards, and wins.\n */\n private focusIn(): void {\n const surface = this.surfaceElement();\n const contentRoot = surface?.firstElementChild;\n const target = contentRoot instanceof HTMLElement && contentRoot.hasAttribute('tabindex') ? contentRoot : surface;\n target?.focus();\n }\n\n private returnFocus(trigger: HTMLElement): void {\n interactiveTriggerElement(trigger).focus();\n }\n\n /** Only give focus back if it is still ours to give: the user may have clicked elsewhere. */\n private holdsFocus(): boolean {\n const active = this.activeElement();\n if (!active || active === document.body) return true;\n return this.floating.overlayRef?.overlayElement.contains(active) ?? false;\n }\n\n /** `<body>` means nobody holds focus: returning focus there would land on the page's first focusable element. */\n private activeElement(): HTMLElement | null {\n const active = document.activeElement;\n if (!(active instanceof HTMLElement) || active === document.body) return null;\n\n return active;\n }\n\n private surfaceElement(): HTMLElement | null {\n const child = this.floating.overlayRef?.overlayElement.firstElementChild;\n return child instanceof HTMLElement ? child : null;\n }\n\n toggle(triggerElement?: HTMLElement): void {\n if (this.isOpen()) {\n this.close();\n } else {\n this.open(triggerElement);\n }\n }\n\n private dismiss(): void {\n if (this.canDismiss()()) {\n this.close();\n }\n }\n}\n","<ng-template #surface>\n <div\n class=\"ap-dropdown-panel\"\n tabindex=\"-1\">\n <ng-container [ngTemplateOutlet]=\"content().template\" />\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}