@testgorilla/tgo-ui 12.2.0 → 12.3.2

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 (85) hide show
  1. package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs +3 -0
  2. package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs.map +1 -1
  3. package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs +6 -1
  4. package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs.map +1 -1
  5. package/fesm2022/testgorilla-tgo-ui-components-audio-waveform.mjs +1 -1
  6. package/fesm2022/testgorilla-tgo-ui-components-audio-waveform.mjs.map +1 -1
  7. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs +6 -4
  8. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs.map +1 -1
  9. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs +1 -1
  10. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs.map +1 -1
  11. package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs +3 -0
  12. package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs.map +1 -1
  13. package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs +3 -0
  14. package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs.map +1 -1
  15. package/fesm2022/testgorilla-tgo-ui-components-button.mjs +19 -4
  16. package/fesm2022/testgorilla-tgo-ui-components-button.mjs.map +1 -1
  17. package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs +3 -0
  18. package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs.map +1 -1
  19. package/fesm2022/testgorilla-tgo-ui-components-core.mjs +11 -1
  20. package/fesm2022/testgorilla-tgo-ui-components-core.mjs.map +1 -1
  21. package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs +7 -1
  22. package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs.map +1 -1
  23. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs +3 -0
  24. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs.map +1 -1
  25. package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs +3 -0
  26. package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs.map +1 -1
  27. package/fesm2022/testgorilla-tgo-ui-components-field.mjs +8 -2
  28. package/fesm2022/testgorilla-tgo-ui-components-field.mjs.map +1 -1
  29. package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs +3 -0
  30. package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs.map +1 -1
  31. package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs +12 -3
  32. package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs.map +1 -1
  33. package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs +6 -2
  34. package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs.map +1 -1
  35. package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs +3 -0
  36. package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs.map +1 -1
  37. package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs +3 -0
  38. package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs.map +1 -1
  39. package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs +6 -0
  40. package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs.map +1 -1
  41. package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs +3 -0
  42. package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs.map +1 -1
  43. package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs +3 -0
  44. package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs.map +1 -1
  45. package/fesm2022/testgorilla-tgo-ui-components-popover.mjs +250 -50
  46. package/fesm2022/testgorilla-tgo-ui-components-popover.mjs.map +1 -1
  47. package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs +4 -0
  48. package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs.map +1 -1
  49. package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs +4 -1
  50. package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs.map +1 -1
  51. package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs +5 -2
  52. package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs.map +1 -1
  53. package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs +3 -0
  54. package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs.map +1 -1
  55. package/fesm2022/testgorilla-tgo-ui-components-scale.mjs +9 -2
  56. package/fesm2022/testgorilla-tgo-ui-components-scale.mjs.map +1 -1
  57. package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs +89 -7
  58. package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs.map +1 -1
  59. package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs +3 -0
  60. package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs.map +1 -1
  61. package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs +7 -4
  62. package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs.map +1 -1
  63. package/fesm2022/testgorilla-tgo-ui-components-slider.mjs +13 -4
  64. package/fesm2022/testgorilla-tgo-ui-components-slider.mjs.map +1 -1
  65. package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs +3 -0
  66. package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs.map +1 -1
  67. package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs +1 -1
  68. package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs.map +1 -1
  69. package/fesm2022/testgorilla-tgo-ui-components-table.mjs +3 -0
  70. package/fesm2022/testgorilla-tgo-ui-components-table.mjs.map +1 -1
  71. package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs +3 -0
  72. package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs.map +1 -1
  73. package/mcp/catalog.json +1 -1
  74. package/package.json +2 -2
  75. package/types/testgorilla-tgo-ui-components-alert-banner.d.ts +1 -0
  76. package/types/testgorilla-tgo-ui-components-autocomplete-v2.d.ts +1 -1
  77. package/types/testgorilla-tgo-ui-components-button.d.ts +32 -0
  78. package/types/testgorilla-tgo-ui-components-core.d.ts +1 -0
  79. package/types/testgorilla-tgo-ui-components-field.d.ts +1 -0
  80. package/types/testgorilla-tgo-ui-components-infinite-scroll-table.d.ts +3 -3
  81. package/types/testgorilla-tgo-ui-components-popover.d.ts +51 -5
  82. package/types/testgorilla-tgo-ui-components-radio-button.d.ts +1 -0
  83. package/types/testgorilla-tgo-ui-components-scale.d.ts +1 -0
  84. package/types/testgorilla-tgo-ui-components-side-navigation.d.ts +59 -1
  85. package/types/testgorilla-tgo-ui-components-slider.d.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"testgorilla-tgo-ui-components-overflow-menu.mjs","names":[],"sources":["../../../components/overflow-menu/overflow-menu.component.ts","../../../components/overflow-menu/overflow-menu.component.html","../../../components/overflow-menu/overflow-menu.component.module.ts"],"sourcesContent":["import { FocusMonitor } from '@angular/cdk/a11y';\nimport { DOCUMENT, NgClass, NgTemplateOutlet, AsyncPipe } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n EventEmitter,\n Inject,\n inject,\n Input,\n input,\n NgZone,\n OnInit,\n Optional,\n Output,\n QueryList,\n signal,\n SimpleChanges,\n TemplateRef,\n ViewChild,\n ViewChildren,\n ViewEncapsulation,\n OnChanges,\n AfterViewInit,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { MatMenu, MatMenuTrigger, MatMenuItem } from '@angular/material/menu';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { startWith } from 'rxjs';\n\nimport { ButtonColor, ButtonSize, ButtonComponent } from '@testgorilla/tgo-ui/components/button';\nimport { ApplicationTheme, EllipseTextDirective, UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\nimport { IconName, IconComponent } from '@testgorilla/tgo-ui/components/icon';\n\nimport {\n MenuConfig,\n OverflowMenuButtonModify,\n OverflowMenuButtonsType,\n OverflowMenuSelectionMode,\n} from './overflow-menu.model';\n\nconst DEFAULT_MENU_CONFIG: MenuConfig = {\n overlapTrigger: false,\n panelClass: '',\n xPosition: 'after',\n yPosition: 'below',\n};\n\n@Component({\n selector: 'ui-overflow-menu',\n templateUrl: './overflow-menu.component.html',\n styleUrls: ['./overflow-menu.component.scss'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgClass,\n MatMenuTrigger,\n MatTooltip,\n ButtonComponent,\n NgTemplateOutlet,\n IconComponent,\n MatMenu,\n EllipseTextDirective,\n MatMenuItem,\n AsyncPipe,\n UiTranslatePipe,\n ],\n})\nexport class OverflowMenuComponent implements OnInit, OnChanges, AfterViewInit {\n /**\n * Menu buttons\n *\n * @type {OverflowMenuButtonsType[]}\n * @memberof OverflowMenuComponent\n */\n @Input() buttons: OverflowMenuButtonsType[];\n\n /**\n * Menu icon trigger\n *\n * @memberof OverflowMenuComponent\n */\n @Input() iconTrigger: IconName = 'Menu-ellipsis';\n\n /**\n * Label menu\n *\n * @memberof OverflowMenuComponent\n */\n @Input() menuLabel = '';\n\n /**\n *\n * Defines the application theme\n *\n * @type {ApplicationTheme}\n * @memberof OverflowMenuComponent\n */\n @Input() applicationTheme: ApplicationTheme = 'light';\n\n /**\n * A string representing the ARIA label for accessibility.\n * This label is used to provide an accessible name for the input element.\n * @type {string}\n * @memberof OverflowMenuComponent\n */\n @Input() ariaLabel: string;\n\n @Input() testId: string | null = null;\n\n /**\n * A string representing the ARIA requirement for accessibility.\n * This attribute is used to indicate whether an input field is required for form submission.\n * @type {boolean}\n * @memberof OverflowMenuComponent\n */\n @Input() ariaRequired = false;\n\n /**\n * A string representing the ARIA requirement for accessibility.\n * This attribute is used to indicate whether an input for description.\n * @type {text}\n * @memberof OverflowMenuComponent\n */\n @Input() describedby = '';\n\n /**\n * Custom template for the button (optional)\n *\n * @type {TemplateRef<unknown>}\n * @memberof OverflowMenuComponent\n */\n @Input() contentTemplateRef: TemplateRef<unknown>;\n\n /**\n * Button variant for the overflow menu trigger\n * When null, uses the default icon rendering\n *\n * @type {ButtonColor | null}\n * @memberof OverflowMenuComponent\n */\n @Input() buttonVariant: ButtonColor | null = null;\n\n /**\n * Button size for the overflow menu trigger\n *\n * @type {ButtonSize}\n * @memberof OverflowMenuComponent\n */\n @Input() buttonSize: ButtonSize = 'medium';\n\n @Input() menuConfig: MenuConfig = DEFAULT_MENU_CONFIG;\n\n /**\n * Selection semantics of the menu. 'single' renders every entry as a menuitemradio whose\n * aria-checked and right-aligned check come from the button's isSelected flag; 'none' keeps\n * plain menuitem entries.\n *\n * @type {OverflowMenuSelectionMode}\n * @memberof OverflowMenuComponent\n */\n readonly selectionMode = input<OverflowMenuSelectionMode>('none');\n\n /**\n * Element the dropdown is positioned against, instead of the trigger: an element, or a selector\n * resolved as the trigger's closest matching ancestor (e.g. `'ui-tag'` to open from the start of\n * the tag the trigger sits in). Read when the dropdown is first opened.\n *\n * @type {string | HTMLElement | null}\n * @memberof OverflowMenuComponent\n */\n readonly menuAnchor = input<string | HTMLElement | null>(null);\n\n /**\n * Makes the open dropdown as wide as its anchor (`menuAnchor`, or the trigger when none is set),\n * instead of sizing it to its content. Measured each time it opens.\n *\n * @type {boolean}\n * @default false\n * @memberof OverflowMenuComponent\n */\n readonly shouldMatchAnchorWidth = input(false, { transform: booleanAttribute });\n\n @Input() isDynamicMenu = false;\n\n @Input() withRemovableOption = false;\n\n @Output() selectItem: EventEmitter<string> = new EventEmitter<string>();\n\n @Output() menuOpened = new EventEmitter<void>();\n\n @Output() menuClosed = new EventEmitter<void>();\n\n @ViewChildren(MatMenu) matmenus: QueryList<MatMenu>;\n @ViewChildren(MatMenuTrigger) matTrigger: QueryList<MatMenuTrigger>;\n @ViewChild('buttonElement') buttonElement: ElementRef<HTMLElement>;\n\n menuItems: string[] = [];\n submenus: Array<OverflowMenuButtonModify[]> = [];\n\n isMenuRendered = signal(false);\n isMenuOpened = signal(false);\n isFocused = signal(false);\n\n get menuItemHasHovered(): boolean {\n return this.submenus.some(menu => menu.some(item => item.isHovered));\n }\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly anchoredTriggers = new WeakSet<MatMenuTrigger>();\n private readonly document = inject(DOCUMENT);\n\n constructor(\n @Optional() @Inject('CANOPYUI_DEFAULT_APPLICATION_THEME') private readonly defaultAppTheme: ApplicationTheme,\n private readonly focusMonitor: FocusMonitor,\n private readonly ngZone: NgZone\n ) {\n if (defaultAppTheme) {\n this.applicationTheme = defaultAppTheme;\n }\n }\n\n ngOnInit() {\n this.createSubmenus(this.buttons, 's0', 1);\n this.reindex();\n }\n\n ngOnChanges(changes: SimpleChanges) {\n // Selection menus re-render on their own: the natural flow is to hand in a new buttons array\n // after a pick, and requiring isDynamicMenu for the check to move would be an untold coupling.\n if (changes['buttons'] && (this.isDynamicMenu || this.selectionMode() === 'single')) {\n this.resetSubmenus();\n this.createSubmenus(this.buttons, 's0', 1);\n this.reindex();\n }\n }\n\n ngAfterViewInit() {\n this.isMenuRendered.set(true);\n\n // The trigger renders after this hook (it waits on isMenuRendered), so anchor it once it appears.\n this.matTrigger.changes\n .pipe(startWith(this.matTrigger), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.anchorTrigger(this.matTrigger.first));\n\n setTimeout(() => {\n this.focusMonitor\n .monitor(this.buttonElement)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(origin =>\n this.ngZone.run(() => {\n if (origin === 'keyboard') {\n this.isFocused.set(true);\n } else {\n if (!this.isMenuOpened()) {\n this.isFocused.set(false);\n }\n }\n })\n );\n }, 300);\n }\n\n /**\n * MatMenuTrigger has no public way to position against another element: it takes its origin from\n * the protected `_getOverlayOrigin()` when it first creates the overlay. Overriding it on the root\n * trigger lets `menuAnchor` move the origin, falling back to the trigger itself.\n */\n private anchorTrigger(trigger: MatMenuTrigger | undefined): void {\n if (!trigger || this.anchoredTriggers.has(trigger)) {\n return;\n }\n this.anchoredTriggers.add(trigger);\n\n const anchorable = trigger as unknown as { _getOverlayOrigin: () => ElementRef<HTMLElement> | HTMLElement };\n // eslint-disable-next-line no-underscore-dangle -- _getOverlayOrigin is MatMenuTrigger's protected origin hook\n const ownOrigin = anchorable._getOverlayOrigin.bind(trigger);\n // eslint-disable-next-line no-underscore-dangle -- see above\n anchorable._getOverlayOrigin = () => this.resolveMenuAnchor() ?? ownOrigin();\n }\n\n private resolveMenuAnchor(): HTMLElement | null {\n const anchor = this.menuAnchor();\n if (typeof anchor === 'string') {\n return this.buttonElement?.nativeElement.closest<HTMLElement>(anchor) ?? null;\n }\n return anchor;\n }\n\n /** Sizes the open panel to the anchor (or the trigger), overriding Material's 112–280px panel limits. */\n private matchPanelToAnchorWidth(): void {\n if (!this.shouldMatchAnchorWidth()) {\n return;\n }\n const anchor = this.resolveMenuAnchor() ?? this.buttonElement?.nativeElement;\n const panelId = this.matmenus.first?.panelId;\n const panel = panelId ? this.document.getElementById(panelId) : null;\n if (!anchor || !panel) {\n return;\n }\n const width = `${anchor.getBoundingClientRect().width}px`;\n panel.style.width = width;\n panel.style.minWidth = width;\n panel.style.maxWidth = width;\n // The theme also caps the content at 340px; left alone, it would stop short of a wider panel.\n const content = panel.querySelector<HTMLElement>('.mat-mdc-menu-content');\n if (content) {\n content.style.maxWidth = 'none';\n }\n }\n\n /** Opens the dropdown programmatically, as if the trigger had been used. */\n openMenu(): void {\n this.matTrigger.first?.openMenu();\n }\n\n /** Closes the dropdown, whichever way it was opened. */\n closeMenu(): void {\n this.matTrigger.first?.closeMenu();\n }\n\n onSelectItem(event: Event, value: string) {\n if (value) {\n this.selectItem.emit(value);\n }\n }\n\n onMenuOpened(): void {\n this.menuOpened.emit();\n this.isMenuOpened.set(true);\n this.matchPanelToAnchorWidth();\n\n if (this.isFocused()) {\n setTimeout(() => {\n // eslint-disable-next-line no-underscore-dangle -- _allItems is MatMenu's internal item query\n this.matmenus.first._allItems.first.focus('keyboard');\n }, 300);\n }\n }\n\n onMenuClosed(): void {\n this.isMenuOpened.set(false);\n this.menuClosed.emit();\n }\n\n onButtonFocus(button: OverflowMenuButtonModify) {\n if (this.isFocused()) {\n button.isFocused = true;\n }\n }\n\n onButtonBlur(button: OverflowMenuButtonModify) {\n button.isFocused = false;\n }\n\n onButtonClick(button: OverflowMenuButtonModify, $event: Event) {\n if (button.disabled) {\n $event.preventDefault();\n $event.stopPropagation();\n } else {\n this.onSelectItem($event, button.value);\n }\n }\n\n onSubmenuOpened(): void {\n this.isMenuOpened.set(!this.isMenuOpened);\n if (this.isFocused()) {\n setTimeout(() => {\n // eslint-disable-next-line no-underscore-dangle -- _allItems is MatMenu's internal item query\n this.matmenus.last._allItems.first.focus('keyboard');\n }, 300);\n }\n }\n\n trackByButton = (_: number, btn: OverflowMenuButtonModify) => btn.action ?? btn.value ?? btn.label;\n\n onButtonHover(button: OverflowMenuButtonModify, state: boolean) {\n button.isHovered = state;\n }\n\n getMenu(index: unknown) {\n return typeof index === 'number' && index >= 0 && this.matmenus\n ? (this.matmenus.find((x, i) => i === index) ?? null)\n : null;\n }\n\n private reindex() {\n this.submenus.forEach((menu: OverflowMenuButtonsType[]) => {\n menu.forEach((item: OverflowMenuButtonsType) => {\n if (item.subMenu !== -1) {\n item.subMenu = this.menuItems.indexOf(`${item.action}`);\n }\n });\n });\n }\n\n private resetSubmenus() {\n this.submenus = [];\n this.menuItems = [];\n }\n\n private createSubmenus(menu: OverflowMenuButtonsType[], prefix: string, count: number): void {\n this.menuItems.push(prefix);\n this.submenus.push(\n menu.map((item: OverflowMenuButtonsType, index: number) => ({\n label: item.label,\n icon: item.icon,\n isDestructive: item.isDestructive,\n tooltipText: item.tooltipText,\n value: item.value,\n disabled: item.disabled,\n isSelected: item.isSelected,\n btnTemplate: item.btnTemplate,\n subMenu: item.subMenu ? 0 : -1,\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- an empty action falls back to a generated key\n action: item.action ? item.action : prefix + index,\n isTitleButton: item.isTitleButton,\n hideTitleButton: item.hideTitleButton,\n isPremium: item.isPremium,\n // The template reads these off the copy, so omitting them leaves the menu items' ARIA unset.\n ariaLabel: item.ariaLabel,\n describedby: item.describedby,\n testId: item.testId,\n }))\n );\n\n menu.forEach((item: OverflowMenuButtonsType, index: number) => {\n if (item.subMenu) {\n this.createSubmenus((item as { subMenu: OverflowMenuButtonsType[] }).subMenu, prefix + index, count + 1);\n }\n });\n }\n}\n","<div class=\"overflow-menu-container\" [attr.theme]=\"applicationTheme\">\n @if (isMenuRendered()) {\n <button\n #buttonElement\n [ngClass]=\"{\n 'icon-button': !contentTemplateRef && !buttonVariant,\n 'content-template': contentTemplateRef,\n 'no-hover': buttonVariant,\n }\"\n [matMenuTriggerFor]=\"matmenus.first\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-required]=\"ariaRequired\"\n [attr.aria-describedby]=\"'describedby'\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"isMenuOpened()\"\n [attr.data-testid]=\"testId\"\n (menuOpened)=\"onMenuOpened()\"\n (menuClosed)=\"onMenuClosed()\"\n class=\"overflow-menu-opener\"\n [matTooltip]=\"menuLabel\"\n >\n <span [id]=\"'describedby'\" [style.display]=\"'none'\">{{ describedby }}</span>\n @if (buttonVariant) {\n <ui-button\n [variant]=\"buttonVariant\"\n [justIcon]=\"true\"\n [iconName]=\"iconTrigger\"\n [applicationTheme]=\"applicationTheme\"\n [disabled]=\"false\"\n [size]=\"buttonSize\"\n >\n </ui-button>\n } @else if (contentTemplateRef) {\n <ng-container [ngTemplateOutlet]=\"contentTemplateRef\"></ng-container>\n } @else {\n <ui-icon\n [name]=\"iconTrigger\"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'24'\"\n [color]=\"'rebrand-black'\"\n ></ui-icon>\n }\n </button>\n }\n\n <!-- Tracked by index so refreshing the buttons re-renders the rows without destroying an open\n mat-menu, whose trigger would otherwise be left holding a dead overlay. -->\n @for (menu of submenus; track $index) {\n <mat-menu\n [xPosition]=\"menuConfig.xPosition\"\n [yPosition]=\"menuConfig.yPosition\"\n #matMenu\n [class]=\"'overflow-menu ' + menuConfig.panelClass\"\n [overlapTrigger]=\"menuConfig.overlapTrigger\"\n backdropClass=\"overflow-menu-backdrop\"\n >\n @for (button of menu; track trackByButton(id, button); let id = $index) {\n @if (button.btnTemplate) {\n <!-- Menu option by provided button template-->\n <ng-container\n [ngTemplateOutlet]=\"button.btnTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: button }\"\n ></ng-container>\n } @else if (withRemovableOption) {\n <!-- Simple menu option that can be removed dynamically -->\n <div class=\"menu-option\" [ngClass]=\"{ 'is-destructive': button.isDestructive, disabled: button.disabled }\">\n <span\n [id]=\"'labelledby-' + button.label + id\"\n class=\"label\"\n uiEllipseText\n [refresh]=\"isMenuOpened()\"\n [maxDiffPixels]=\"1\"\n [isMultiline]=\"true\"\n (onChangeTextState)=\"button.isTextEllipsed = $event\"\n >{{ button.label }}\n </span>\n @if (button.icon) {\n <ui-button\n variant=\"icon-button\"\n [applicationTheme]=\"applicationTheme\"\n [iconName]=\"button.icon\"\n [tooltip]=\"button.tooltipText ? button.tooltipText : button.isTextEllipsed ? button.label : ''\"\n [tooltipPosition]=\"'above'\"\n [size]=\"'medium'\"\n (focus)=\"onButtonFocus(button)\"\n (blur)=\"onButtonBlur(button)\"\n (mouseenter)=\"onButtonHover(button, true)\"\n (mouseleave)=\"onButtonHover(button, false)\"\n (click)=\"onSelectItem($event, button.value)\"\n [testId]=\"button.testId ?? null\"\n [ariaLabel]=\"button.ariaLabel || button.label\"\n >\n </ui-button>\n }\n </div>\n } @else {\n <!-- Default non-removable menu option -->\n @if (button.isTitleButton && !button.hideTitleButton) {\n <div class=\"menu-title\">{{ button.label }}</div>\n }\n @if (!button.isTitleButton) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"getMenu(button.subMenu)\"\n (menuOpened)=\"onSubmenuOpened()\"\n (focus)=\"onButtonFocus(button)\"\n (blur)=\"onButtonBlur(button)\"\n (mouseenter)=\"onButtonHover(button, true)\"\n (mouseleave)=\"onButtonHover(button, false)\"\n [ngClass]=\"{\n 'is-destructive': button.isDestructive,\n disabled: button.disabled,\n 'overflow-menu-item-selectable': selectionMode() === 'single',\n }\"\n disableRipple\n (click)=\"onButtonClick(button, $event)\"\n [matTooltip]=\"button.tooltipText ? button.tooltipText : button.isTextEllipsed ? button.label : ''\"\n [attr.aria-labelledby]=\"'labelledby-' + button.label + id\"\n [attr.aria-describedby]=\"'describedby-' + button.label + id\"\n [attr.aria-label]=\"button.ariaLabel || null\"\n [role]=\"selectionMode() === 'single' ? 'menuitemradio' : 'menuitem'\"\n [attr.aria-checked]=\"selectionMode() === 'single' ? !!button.isSelected : null\"\n [attr.data-testid]=\"button.testId ?? null\"\n matTooltipPosition=\"right\"\n >\n <span [id]=\"'describedby-' + button.label + id\" [style.display]=\"'none'\">\n {{\n button.disabled\n ? ('MENU.MENUITEM_DISABLED' | uiTranslate | async) + ' ' + (button.describedby || '')\n : button.describedby\n }}\n </span>\n @if (button.icon) {\n <ui-icon\n [name]=\"button.icon\"\n [toggleIconStyle]=\"true\"\n [filled]=\"\n button.disabled ? false : button.isHovered ? true : menuItemHasHovered ? false : !!button.isFocused\n \"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'24'\"\n [color]=\"button.disabled ? 'dark' : button.isDestructive ? 'red' : 'rebrand-black'\"\n ></ui-icon>\n }\n <span\n [id]=\"'labelledby-' + button.label + id\"\n class=\"label\"\n uiEllipseText\n [refresh]=\"isMenuOpened()\"\n [maxDiffPixels]=\"1\"\n [isMultiline]=\"true\"\n (onChangeTextState)=\"button.isTextEllipsed = $event\"\n >{{ button.label }}</span\n >\n @if (selectionMode() === 'single' && button.isSelected) {\n <ui-icon\n class=\"overflow-menu-selected-check\"\n [name]=\"'Check-small-in-line'\"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'16'\"\n [color]=\"'rebrand-black'\"\n ></ui-icon>\n }\n @if (button.isPremium) {\n <ui-icon\n [name]=\"'Premium-circle-in-line'\"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'24'\"\n class=\"premium-icon\"\n ></ui-icon>\n }\n </button>\n }\n }\n }\n\n <ng-content select=\"[menu-content]\"></ng-content>\n </mat-menu>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatTooltipModule } from '@angular/material/tooltip';\n\nimport { ButtonComponentModule } from '@testgorilla/tgo-ui/components/button';\nimport { EllipseTextDirective, UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\nimport { IconComponentModule } from '@testgorilla/tgo-ui/components/icon';\n\nimport { OverflowMenuComponent } from './overflow-menu.component';\n\n@NgModule({\n imports: [\n CommonModule,\n ButtonComponentModule,\n IconComponentModule,\n MatMenuModule,\n MatButtonModule,\n MatTooltipModule,\n EllipseTextDirective,\n UiTranslatePipe,\n OverflowMenuComponent,\n ],\n exports: [OverflowMenuComponent],\n})\nexport class OverflowMenuComponentModule {}\n"],"mappings":"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"}
1
+ {"version":3,"file":"testgorilla-tgo-ui-components-overflow-menu.mjs","names":[],"sources":["../../../components/overflow-menu/overflow-menu.component.ts","../../../components/overflow-menu/overflow-menu.component.html","../../../components/overflow-menu/overflow-menu.component.module.ts"],"sourcesContent":["import { FocusMonitor } from '@angular/cdk/a11y';\nimport { DOCUMENT, NgClass, NgTemplateOutlet, AsyncPipe } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n EventEmitter,\n Inject,\n inject,\n Input,\n input,\n NgZone,\n OnInit,\n Optional,\n Output,\n QueryList,\n signal,\n SimpleChanges,\n TemplateRef,\n ViewChild,\n ViewChildren,\n ViewEncapsulation,\n OnChanges,\n AfterViewInit,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { MatMenu, MatMenuTrigger, MatMenuItem } from '@angular/material/menu';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { startWith } from 'rxjs';\n\nimport { ButtonColor, ButtonSize, ButtonComponent } from '@testgorilla/tgo-ui/components/button';\nimport { ApplicationTheme, EllipseTextDirective, UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\nimport { IconName, IconComponent } from '@testgorilla/tgo-ui/components/icon';\n\nimport {\n MenuConfig,\n OverflowMenuButtonModify,\n OverflowMenuButtonsType,\n OverflowMenuSelectionMode,\n} from './overflow-menu.model';\n\nconst DEFAULT_MENU_CONFIG: MenuConfig = {\n overlapTrigger: false,\n panelClass: '',\n xPosition: 'after',\n yPosition: 'below',\n};\n\n@Component({\n selector: 'ui-overflow-menu',\n templateUrl: './overflow-menu.component.html',\n styleUrls: ['./overflow-menu.component.scss'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgClass,\n MatMenuTrigger,\n MatTooltip,\n ButtonComponent,\n NgTemplateOutlet,\n IconComponent,\n MatMenu,\n EllipseTextDirective,\n MatMenuItem,\n AsyncPipe,\n UiTranslatePipe,\n ],\n})\nexport class OverflowMenuComponent implements OnInit, OnChanges, AfterViewInit {\n /**\n * Menu buttons\n *\n * @type {OverflowMenuButtonsType[]}\n * @memberof OverflowMenuComponent\n */\n @Input() buttons: OverflowMenuButtonsType[];\n\n /**\n * Menu icon trigger\n *\n * @memberof OverflowMenuComponent\n */\n @Input() iconTrigger: IconName = 'Menu-ellipsis';\n\n /**\n * Label menu\n *\n * @memberof OverflowMenuComponent\n */\n @Input() menuLabel = '';\n\n /**\n *\n * Defines the application theme\n *\n * @type {ApplicationTheme}\n * @memberof OverflowMenuComponent\n */\n @Input() applicationTheme: ApplicationTheme = 'light';\n\n /**\n * A string representing the ARIA label for accessibility.\n * This label is used to provide an accessible name for the input element.\n * @type {string}\n * @memberof OverflowMenuComponent\n */\n @Input() ariaLabel: string;\n\n @Input() testId: string | null = null;\n\n /**\n * A string representing the ARIA requirement for accessibility.\n * This attribute is used to indicate whether an input field is required for form submission.\n * @type {boolean}\n * @memberof OverflowMenuComponent\n */\n @Input() ariaRequired = false;\n\n /**\n * A string representing the ARIA requirement for accessibility.\n * This attribute is used to indicate whether an input for description.\n * @type {text}\n * @memberof OverflowMenuComponent\n */\n @Input() describedby = '';\n\n /**\n * Custom template for the button (optional)\n *\n * @type {TemplateRef<unknown>}\n * @memberof OverflowMenuComponent\n */\n @Input() contentTemplateRef: TemplateRef<unknown>;\n\n /**\n * Button variant for the overflow menu trigger\n * When null, uses the default icon rendering\n *\n * @type {ButtonColor | null}\n * @memberof OverflowMenuComponent\n */\n @Input() buttonVariant: ButtonColor | null = null;\n\n /**\n * Button size for the overflow menu trigger\n *\n * @type {ButtonSize}\n * @memberof OverflowMenuComponent\n */\n @Input() buttonSize: ButtonSize = 'medium';\n\n @Input() menuConfig: MenuConfig = DEFAULT_MENU_CONFIG;\n\n /**\n * Selection semantics of the menu. 'single' renders every entry as a menuitemradio whose\n * aria-checked and right-aligned check come from the button's isSelected flag; 'none' keeps\n * plain menuitem entries.\n *\n * @type {OverflowMenuSelectionMode}\n * @memberof OverflowMenuComponent\n */\n readonly selectionMode = input<OverflowMenuSelectionMode>('none');\n\n /**\n * Element the dropdown is positioned against, instead of the trigger: an element, or a selector\n * resolved as the trigger's closest matching ancestor (e.g. `'ui-tag'` to open from the start of\n * the tag the trigger sits in). Read when the dropdown is first opened.\n *\n * @type {string | HTMLElement | null}\n * @memberof OverflowMenuComponent\n */\n readonly menuAnchor = input<string | HTMLElement | null>(null);\n\n /**\n * Makes the open dropdown as wide as its anchor (`menuAnchor`, or the trigger when none is set),\n * instead of sizing it to its content. Measured each time it opens.\n *\n * @type {boolean}\n * @default false\n * @memberof OverflowMenuComponent\n */\n readonly shouldMatchAnchorWidth = input(false, { transform: booleanAttribute });\n\n @Input() isDynamicMenu = false;\n\n @Input() withRemovableOption = false;\n\n @Output() selectItem: EventEmitter<string> = new EventEmitter<string>();\n\n @Output() menuOpened = new EventEmitter<void>();\n\n @Output() menuClosed = new EventEmitter<void>();\n\n @ViewChildren(MatMenu) matmenus: QueryList<MatMenu>;\n @ViewChildren(MatMenuTrigger) matTrigger: QueryList<MatMenuTrigger>;\n @ViewChild('buttonElement') buttonElement: ElementRef<HTMLElement>;\n\n menuItems: string[] = [];\n submenus: Array<OverflowMenuButtonModify[]> = [];\n\n isMenuRendered = signal(false);\n isMenuOpened = signal(false);\n isFocused = signal(false);\n\n get menuItemHasHovered(): boolean {\n return this.submenus.some(menu => menu.some(item => item.isHovered));\n }\n\n private readonly destroyRef = inject(DestroyRef);\n private readonly anchoredTriggers = new WeakSet<MatMenuTrigger>();\n private readonly document = inject(DOCUMENT);\n\n constructor(\n @Optional() @Inject('CANOPYUI_DEFAULT_APPLICATION_THEME') private readonly defaultAppTheme: ApplicationTheme,\n private readonly focusMonitor: FocusMonitor,\n private readonly ngZone: NgZone\n ) {\n if (defaultAppTheme) {\n this.applicationTheme = defaultAppTheme;\n }\n }\n\n ngOnInit() {\n this.createSubmenus(this.buttons, 's0', 1);\n this.reindex();\n }\n\n ngOnChanges(changes: SimpleChanges) {\n // Selection menus re-render on their own: the natural flow is to hand in a new buttons array\n // after a pick, and requiring isDynamicMenu for the check to move would be an untold coupling.\n if (changes['buttons'] && (this.isDynamicMenu || this.selectionMode() === 'single')) {\n this.resetSubmenus();\n this.createSubmenus(this.buttons, 's0', 1);\n this.reindex();\n }\n }\n\n ngAfterViewInit() {\n this.isMenuRendered.set(true);\n\n // The trigger renders after this hook (it waits on isMenuRendered), so anchor it once it appears.\n this.matTrigger.changes\n .pipe(startWith(this.matTrigger), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.anchorTrigger(this.matTrigger.first));\n\n setTimeout(() => {\n this.focusMonitor\n .monitor(this.buttonElement)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(origin =>\n this.ngZone.run(() => {\n if (origin === 'keyboard') {\n this.isFocused.set(true);\n } else {\n if (!this.isMenuOpened()) {\n this.isFocused.set(false);\n }\n }\n })\n );\n }, 300);\n }\n\n /**\n * MatMenuTrigger has no public way to position against another element: it takes its origin from\n * the protected `_getOverlayOrigin()` when it first creates the overlay. Overriding it on the root\n * trigger lets `menuAnchor` move the origin, falling back to the trigger itself.\n */\n private anchorTrigger(trigger: MatMenuTrigger | undefined): void {\n if (!trigger || this.anchoredTriggers.has(trigger)) {\n return;\n }\n this.anchoredTriggers.add(trigger);\n\n const anchorable = trigger as unknown as { _getOverlayOrigin: () => ElementRef<HTMLElement> | HTMLElement };\n // eslint-disable-next-line no-underscore-dangle -- _getOverlayOrigin is MatMenuTrigger's protected origin hook\n const ownOrigin = anchorable._getOverlayOrigin.bind(trigger);\n // eslint-disable-next-line no-underscore-dangle -- see above\n anchorable._getOverlayOrigin = () => this.resolveMenuAnchor() ?? ownOrigin();\n }\n\n private resolveMenuAnchor(): HTMLElement | null {\n const anchor = this.menuAnchor();\n if (typeof anchor === 'string') {\n return this.buttonElement?.nativeElement.closest<HTMLElement>(anchor) ?? null;\n }\n return anchor;\n }\n\n /** Sizes the open panel to the anchor (or the trigger), overriding Material's 112–280px panel limits. */\n private matchPanelToAnchorWidth(): void {\n if (!this.shouldMatchAnchorWidth()) {\n return;\n }\n const anchor = this.resolveMenuAnchor() ?? this.buttonElement?.nativeElement;\n const panelId = this.matmenus.first?.panelId;\n const panel = panelId ? this.document.getElementById(panelId) : null;\n if (!anchor || !panel) {\n return;\n }\n const width = `${anchor.getBoundingClientRect().width}px`;\n panel.style.width = width;\n panel.style.minWidth = width;\n panel.style.maxWidth = width;\n // The theme also caps the content at 340px; left alone, it would stop short of a wider panel.\n const content = panel.querySelector<HTMLElement>('.mat-mdc-menu-content');\n if (content) {\n content.style.maxWidth = 'none';\n }\n }\n\n /** Opens the dropdown programmatically, as if the trigger had been used. */\n openMenu(): void {\n this.matTrigger.first?.openMenu();\n }\n\n /** Closes the dropdown, whichever way it was opened. */\n closeMenu(): void {\n this.matTrigger.first?.closeMenu();\n }\n\n onSelectItem(event: Event, value: string) {\n if (value) {\n this.selectItem.emit(value);\n }\n }\n\n onMenuOpened(): void {\n this.menuOpened.emit();\n this.isMenuOpened.set(true);\n this.matchPanelToAnchorWidth();\n\n if (this.isFocused()) {\n setTimeout(() => {\n // eslint-disable-next-line no-underscore-dangle -- _allItems is MatMenu's internal item query\n this.matmenus.first._allItems.first.focus('keyboard');\n }, 300);\n }\n }\n\n onMenuClosed(): void {\n this.isMenuOpened.set(false);\n this.menuClosed.emit();\n }\n\n onButtonFocus(button: OverflowMenuButtonModify) {\n if (this.isFocused()) {\n button.isFocused = true;\n }\n }\n\n onButtonBlur(button: OverflowMenuButtonModify) {\n button.isFocused = false;\n }\n\n onButtonClick(button: OverflowMenuButtonModify, $event: Event) {\n if (button.disabled) {\n $event.preventDefault();\n $event.stopPropagation();\n } else {\n this.onSelectItem($event, button.value);\n }\n }\n\n onSubmenuOpened(): void {\n this.isMenuOpened.set(!this.isMenuOpened);\n if (this.isFocused()) {\n setTimeout(() => {\n // eslint-disable-next-line no-underscore-dangle -- _allItems is MatMenu's internal item query\n this.matmenus.last._allItems.first.focus('keyboard');\n }, 300);\n }\n }\n\n trackByButton = (_: number, btn: OverflowMenuButtonModify) => btn.action ?? btn.value ?? btn.label;\n\n onButtonHover(button: OverflowMenuButtonModify, state: boolean) {\n button.isHovered = state;\n }\n\n getMenu(index: unknown) {\n return typeof index === 'number' && index >= 0 && this.matmenus\n ? (this.matmenus.find((x, i) => i === index) ?? null)\n : null;\n }\n\n private reindex() {\n this.submenus.forEach((menu: OverflowMenuButtonsType[]) => {\n menu.forEach((item: OverflowMenuButtonsType) => {\n if (item.subMenu !== -1) {\n item.subMenu = this.menuItems.indexOf(`${item.action}`);\n }\n });\n });\n }\n\n private resetSubmenus() {\n this.submenus = [];\n this.menuItems = [];\n }\n\n private createSubmenus(menu: OverflowMenuButtonsType[], prefix: string, count: number): void {\n this.menuItems.push(prefix);\n this.submenus.push(\n menu.map((item: OverflowMenuButtonsType, index: number) => ({\n label: item.label,\n icon: item.icon,\n isDestructive: item.isDestructive,\n tooltipText: item.tooltipText,\n value: item.value,\n disabled: item.disabled,\n isSelected: item.isSelected,\n btnTemplate: item.btnTemplate,\n subMenu: item.subMenu ? 0 : -1,\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- an empty action falls back to a generated key\n action: item.action ? item.action : prefix + index,\n isTitleButton: item.isTitleButton,\n hideTitleButton: item.hideTitleButton,\n isPremium: item.isPremium,\n // The template reads these off the copy, so omitting them leaves the menu items' ARIA unset.\n ariaLabel: item.ariaLabel,\n describedby: item.describedby,\n testId: item.testId,\n }))\n );\n\n menu.forEach((item: OverflowMenuButtonsType, index: number) => {\n if (item.subMenu) {\n this.createSubmenus((item as { subMenu: OverflowMenuButtonsType[] }).subMenu, prefix + index, count + 1);\n }\n });\n }\n}\n","<div class=\"overflow-menu-container\" [attr.theme]=\"applicationTheme\">\n @if (isMenuRendered()) {\n <button\n #buttonElement\n [ngClass]=\"{\n 'icon-button': !contentTemplateRef && !buttonVariant,\n 'content-template': contentTemplateRef,\n 'no-hover': buttonVariant,\n }\"\n [matMenuTriggerFor]=\"matmenus.first\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-required]=\"ariaRequired\"\n [attr.aria-describedby]=\"'describedby'\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"isMenuOpened()\"\n [attr.data-testid]=\"testId\"\n (menuOpened)=\"onMenuOpened()\"\n (menuClosed)=\"onMenuClosed()\"\n class=\"overflow-menu-opener\"\n [matTooltip]=\"menuLabel\"\n >\n <span [id]=\"'describedby'\" [style.display]=\"'none'\">{{ describedby }}</span>\n @if (buttonVariant) {\n <ui-button\n [variant]=\"buttonVariant\"\n [justIcon]=\"true\"\n [iconName]=\"iconTrigger\"\n [applicationTheme]=\"applicationTheme\"\n [disabled]=\"false\"\n [size]=\"buttonSize\"\n >\n </ui-button>\n } @else if (contentTemplateRef) {\n <ng-container [ngTemplateOutlet]=\"contentTemplateRef\"></ng-container>\n } @else {\n <ui-icon\n [name]=\"iconTrigger\"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'24'\"\n [color]=\"'rebrand-black'\"\n ></ui-icon>\n }\n </button>\n }\n\n <!-- Tracked by index so refreshing the buttons re-renders the rows without destroying an open\n mat-menu, whose trigger would otherwise be left holding a dead overlay. -->\n @for (menu of submenus; track $index) {\n <mat-menu\n [xPosition]=\"menuConfig.xPosition\"\n [yPosition]=\"menuConfig.yPosition\"\n #matMenu\n [class]=\"'overflow-menu ' + menuConfig.panelClass\"\n [overlapTrigger]=\"menuConfig.overlapTrigger\"\n backdropClass=\"overflow-menu-backdrop\"\n >\n @for (button of menu; track trackByButton(id, button); let id = $index) {\n @if (button.btnTemplate) {\n <!-- Menu option by provided button template-->\n <ng-container\n [ngTemplateOutlet]=\"button.btnTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: button }\"\n ></ng-container>\n } @else if (withRemovableOption) {\n <!-- Simple menu option that can be removed dynamically -->\n <div class=\"menu-option\" [ngClass]=\"{ 'is-destructive': button.isDestructive, disabled: button.disabled }\">\n <span\n [id]=\"'labelledby-' + button.label + id\"\n class=\"label\"\n uiEllipseText\n [refresh]=\"isMenuOpened()\"\n [maxDiffPixels]=\"1\"\n [isMultiline]=\"true\"\n (onChangeTextState)=\"button.isTextEllipsed = $event\"\n >{{ button.label }}\n </span>\n @if (button.icon) {\n <ui-button\n variant=\"icon-button\"\n [applicationTheme]=\"applicationTheme\"\n [iconName]=\"button.icon\"\n [tooltip]=\"button.tooltipText ? button.tooltipText : button.isTextEllipsed ? button.label : ''\"\n [tooltipPosition]=\"'above'\"\n [size]=\"'medium'\"\n (focus)=\"onButtonFocus(button)\"\n (blur)=\"onButtonBlur(button)\"\n (mouseenter)=\"onButtonHover(button, true)\"\n (mouseleave)=\"onButtonHover(button, false)\"\n (click)=\"onSelectItem($event, button.value)\"\n [testId]=\"button.testId ?? null\"\n [ariaLabel]=\"button.ariaLabel || button.label\"\n >\n </ui-button>\n }\n </div>\n } @else {\n <!-- Default non-removable menu option -->\n @if (button.isTitleButton && !button.hideTitleButton) {\n <div class=\"menu-title\">{{ button.label }}</div>\n }\n @if (!button.isTitleButton) {\n <button\n mat-menu-item\n [matMenuTriggerFor]=\"getMenu(button.subMenu)\"\n (menuOpened)=\"onSubmenuOpened()\"\n (focus)=\"onButtonFocus(button)\"\n (blur)=\"onButtonBlur(button)\"\n (mouseenter)=\"onButtonHover(button, true)\"\n (mouseleave)=\"onButtonHover(button, false)\"\n [ngClass]=\"{\n 'is-destructive': button.isDestructive,\n disabled: button.disabled,\n 'overflow-menu-item-selectable': selectionMode() === 'single',\n }\"\n disableRipple\n (click)=\"onButtonClick(button, $event)\"\n [matTooltip]=\"button.tooltipText ? button.tooltipText : button.isTextEllipsed ? button.label : ''\"\n [attr.aria-labelledby]=\"'labelledby-' + button.label + id\"\n [attr.aria-describedby]=\"'describedby-' + button.label + id\"\n [attr.aria-label]=\"button.ariaLabel || null\"\n [role]=\"selectionMode() === 'single' ? 'menuitemradio' : 'menuitem'\"\n [attr.aria-checked]=\"selectionMode() === 'single' ? !!button.isSelected : null\"\n [attr.data-testid]=\"button.testId ?? null\"\n matTooltipPosition=\"right\"\n >\n <span [id]=\"'describedby-' + button.label + id\" [style.display]=\"'none'\">\n {{\n button.disabled\n ? ('MENU.MENUITEM_DISABLED' | uiTranslate | async) + ' ' + (button.describedby || '')\n : button.describedby\n }}\n </span>\n @if (button.icon) {\n <ui-icon\n [name]=\"button.icon\"\n [toggleIconStyle]=\"true\"\n [filled]=\"\n button.disabled ? false : button.isHovered ? true : menuItemHasHovered ? false : !!button.isFocused\n \"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'24'\"\n [color]=\"button.disabled ? 'dark' : button.isDestructive ? 'red' : 'rebrand-black'\"\n ></ui-icon>\n }\n <span\n [id]=\"'labelledby-' + button.label + id\"\n class=\"label\"\n uiEllipseText\n [refresh]=\"isMenuOpened()\"\n [maxDiffPixels]=\"1\"\n [isMultiline]=\"true\"\n (onChangeTextState)=\"button.isTextEllipsed = $event\"\n >{{ button.label }}</span\n >\n @if (selectionMode() === 'single' && button.isSelected) {\n <ui-icon\n class=\"overflow-menu-selected-check\"\n [name]=\"'Check-small-in-line'\"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'16'\"\n [color]=\"'rebrand-black'\"\n ></ui-icon>\n }\n @if (button.isPremium) {\n <ui-icon\n [name]=\"'Premium-circle-in-line'\"\n [applicationTheme]=\"applicationTheme\"\n [size]=\"'24'\"\n class=\"premium-icon\"\n ></ui-icon>\n }\n </button>\n }\n }\n }\n\n <ng-content select=\"[menu-content]\"></ng-content>\n </mat-menu>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatTooltipModule } from '@angular/material/tooltip';\n\nimport { ButtonComponentModule } from '@testgorilla/tgo-ui/components/button';\nimport { EllipseTextDirective, UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\nimport { IconComponentModule } from '@testgorilla/tgo-ui/components/icon';\n\nimport { OverflowMenuComponent } from './overflow-menu.component';\n\n@NgModule({\n imports: [\n CommonModule,\n ButtonComponentModule,\n IconComponentModule,\n MatMenuModule,\n MatButtonModule,\n MatTooltipModule,\n EllipseTextDirective,\n UiTranslatePipe,\n OverflowMenuComponent,\n ],\n exports: [OverflowMenuComponent],\n})\nexport class OverflowMenuComponentModule {}\n"],"mappings":"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"}
@@ -85,12 +85,15 @@ var PageHeaderComponent = class PageHeaderComponent {
85
85
  "ariaExpanded",
86
86
  "ariaControls",
87
87
  "ariaPressed",
88
+ "ariaHasPopup",
88
89
  "ariaRequired",
89
90
  "ariaLabelledby",
90
91
  "ariaDescribedby",
91
92
  "preventDefault",
92
93
  "hasBackground",
93
94
  "circular",
95
+ "isSingleLineLabel",
96
+ "iconButtonShape",
94
97
  "tooltipPosition",
95
98
  "role",
96
99
  "iconFilled",
@@ -1 +1 @@
1
- {"version":3,"file":"testgorilla-tgo-ui-components-page-header.mjs","names":[],"sources":["../../../components/page-header/page-header.component.ts","../../../components/page-header/page-header.component.html","../../../components/page-header/page-header.component.module.ts"],"sourcesContent":["import { NgClass, AsyncPipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n booleanAttribute,\n Component,\n EventEmitter,\n HostBinding,\n Inject,\n Input,\n Optional,\n Output,\n} from '@angular/core';\nimport { Observable } from 'rxjs';\n\nimport { ButtonComponent } from '@testgorilla/tgo-ui/components/button';\nimport { ApplicationTheme, IS_MOBILE_TOKEN, UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\n\n@Component({\n selector: 'ui-page-header',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './page-header.component.html',\n styleUrls: ['./page-header.component.scss'],\n imports: [ButtonComponent, NgClass, AsyncPipe, UiTranslatePipe],\n})\nexport class PageHeaderComponent {\n /**\n * Flag to determine whether the \"Back\" button should be displayed.\n * @default true\n * @memberof PageHeaderComponent\n */\n @Input({ transform: booleanAttribute }) showBackButton = true;\n\n /**\n * Back button tooltip for mobile variation\n * @property tooltip\n * @memberof PageHeaderComponent\n */\n @Input() tooltip = 'COMMON.BACK';\n\n @Input() backButtonTestId: string | null = null;\n\n /**\n *\n * Defines the application theme\n *\n * @type {ApplicationTheme}\n * @memberof PageHeaderComponent\n */\n @HostBinding('attr.theme')\n @Input()\n applicationTheme: ApplicationTheme = 'light';\n\n /**\n * Event triggered when the \"Back\" button is clicked.\n * @memberof PageHeaderComponent\n */\n @Output() back = new EventEmitter<void>();\n\n constructor(\n @Optional() @Inject('CANOPYUI_DEFAULT_APPLICATION_THEME') private readonly defaultAppTheme: ApplicationTheme,\n @Inject(IS_MOBILE_TOKEN) protected readonly isMobile$: Observable<boolean>\n ) {\n if (defaultAppTheme) {\n this.applicationTheme = defaultAppTheme;\n }\n }\n\n protected onBack(): void {\n this.back.emit();\n }\n}\n","<ng-container>\n <div class=\"page-header-container\">\n <div class=\"page-header-content\">\n @if ((isMobile$ | async) === false) {\n @if (showBackButton) {\n <ui-button\n [applicationTheme]=\"applicationTheme\"\n [tooltip]=\"('COMMON.BACK' | uiTranslate | async)!\"\n (click)=\"onBack()\"\n [ariaLabel]=\"('COMMON.BACK' | uiTranslate | async)!\"\n [variant]=\"'ghost'\"\n [justIcon]=\"true\"\n [iconName]=\"applicationTheme === 'classic' ? 'Arrow_left' : 'Arrow-chevron-left-in-line'\"\n [testId]=\"backButtonTestId\"\n ></ui-button>\n }\n } @else {\n <ui-button\n [applicationTheme]=\"applicationTheme\"\n class=\"mobile-back-btn\"\n [tooltip]=\"('COMMON.BACK' | uiTranslate | async)!\"\n [variant]=\"'icon-button'\"\n [ariaLabel]=\"('COMMON.BACK' | uiTranslate | async)!\"\n (click)=\"onBack()\"\n [justIcon]=\"true\"\n [iconName]=\"applicationTheme === 'classic' ? 'Arrow_left' : 'Arrow-chevron-left-in-line'\"\n [testId]=\"backButtonTestId\"\n ></ui-button>\n }\n\n <div class=\"main-content\" [ngClass]=\"{ 'remove-margin': !showBackButton }\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n\n <div class=\"right-side\">\n <ng-content select=\"[right-side]\"></ng-content>\n </div>\n </div>\n </div>\n</ng-container>\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { ButtonComponentModule } from '@testgorilla/tgo-ui/components/button';\nimport { UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\n\nimport { PageHeaderComponent } from './page-header.component';\n\n@NgModule({\n imports: [CommonModule, ButtonComponentModule, UiTranslatePipe, PageHeaderComponent],\n exports: [PageHeaderComponent],\n})\nexport class PageHeaderModule {}\n"],"mappings":"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"}
1
+ {"version":3,"file":"testgorilla-tgo-ui-components-page-header.mjs","names":[],"sources":["../../../components/page-header/page-header.component.ts","../../../components/page-header/page-header.component.html","../../../components/page-header/page-header.component.module.ts"],"sourcesContent":["import { NgClass, AsyncPipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n booleanAttribute,\n Component,\n EventEmitter,\n HostBinding,\n Inject,\n Input,\n Optional,\n Output,\n} from '@angular/core';\nimport { Observable } from 'rxjs';\n\nimport { ButtonComponent } from '@testgorilla/tgo-ui/components/button';\nimport { ApplicationTheme, IS_MOBILE_TOKEN, UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\n\n@Component({\n selector: 'ui-page-header',\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './page-header.component.html',\n styleUrls: ['./page-header.component.scss'],\n imports: [ButtonComponent, NgClass, AsyncPipe, UiTranslatePipe],\n})\nexport class PageHeaderComponent {\n /**\n * Flag to determine whether the \"Back\" button should be displayed.\n * @default true\n * @memberof PageHeaderComponent\n */\n @Input({ transform: booleanAttribute }) showBackButton = true;\n\n /**\n * Back button tooltip for mobile variation\n * @property tooltip\n * @memberof PageHeaderComponent\n */\n @Input() tooltip = 'COMMON.BACK';\n\n @Input() backButtonTestId: string | null = null;\n\n /**\n *\n * Defines the application theme\n *\n * @type {ApplicationTheme}\n * @memberof PageHeaderComponent\n */\n @HostBinding('attr.theme')\n @Input()\n applicationTheme: ApplicationTheme = 'light';\n\n /**\n * Event triggered when the \"Back\" button is clicked.\n * @memberof PageHeaderComponent\n */\n @Output() back = new EventEmitter<void>();\n\n constructor(\n @Optional() @Inject('CANOPYUI_DEFAULT_APPLICATION_THEME') private readonly defaultAppTheme: ApplicationTheme,\n @Inject(IS_MOBILE_TOKEN) protected readonly isMobile$: Observable<boolean>\n ) {\n if (defaultAppTheme) {\n this.applicationTheme = defaultAppTheme;\n }\n }\n\n protected onBack(): void {\n this.back.emit();\n }\n}\n","<ng-container>\n <div class=\"page-header-container\">\n <div class=\"page-header-content\">\n @if ((isMobile$ | async) === false) {\n @if (showBackButton) {\n <ui-button\n [applicationTheme]=\"applicationTheme\"\n [tooltip]=\"('COMMON.BACK' | uiTranslate | async)!\"\n (click)=\"onBack()\"\n [ariaLabel]=\"('COMMON.BACK' | uiTranslate | async)!\"\n [variant]=\"'ghost'\"\n [justIcon]=\"true\"\n [iconName]=\"applicationTheme === 'classic' ? 'Arrow_left' : 'Arrow-chevron-left-in-line'\"\n [testId]=\"backButtonTestId\"\n ></ui-button>\n }\n } @else {\n <ui-button\n [applicationTheme]=\"applicationTheme\"\n class=\"mobile-back-btn\"\n [tooltip]=\"('COMMON.BACK' | uiTranslate | async)!\"\n [variant]=\"'icon-button'\"\n [ariaLabel]=\"('COMMON.BACK' | uiTranslate | async)!\"\n (click)=\"onBack()\"\n [justIcon]=\"true\"\n [iconName]=\"applicationTheme === 'classic' ? 'Arrow_left' : 'Arrow-chevron-left-in-line'\"\n [testId]=\"backButtonTestId\"\n ></ui-button>\n }\n\n <div class=\"main-content\" [ngClass]=\"{ 'remove-margin': !showBackButton }\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n\n <div class=\"right-side\">\n <ng-content select=\"[right-side]\"></ng-content>\n </div>\n </div>\n </div>\n</ng-container>\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { ButtonComponentModule } from '@testgorilla/tgo-ui/components/button';\nimport { UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\n\nimport { PageHeaderComponent } from './page-header.component';\n\n@NgModule({\n imports: [CommonModule, ButtonComponentModule, UiTranslatePipe, PageHeaderComponent],\n exports: [PageHeaderComponent],\n})\nexport class PageHeaderModule {}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, Directive, ElementRef, HostListener, Injectable, Injector, NgZone, inject, input, signal } from "@angular/core";
1
3
  import { Overlay } from "@angular/cdk/overlay";
2
4
  import { ComponentPortal } from "@angular/cdk/portal";
3
- import * as i0 from "@angular/core";
4
- import { ChangeDetectionStrategy, Component, Directive, ElementRef, HostListener, Injector, NgZone, inject, input, signal } from "@angular/core";
5
- import { Subscription } from "rxjs";
5
+ import { Subject, Subscription } from "rxjs";
6
6
  import { CdkTrapFocus } from "@angular/cdk/a11y";
7
7
  import { NgTemplateOutlet } from "@angular/common";
8
8
  import * as i1 from "@testgorilla/tgo-ui/components/card";
@@ -14,8 +14,12 @@ var PopoverComponent = class PopoverComponent {
14
14
  this.popoverCard = input(true, ...ngDevMode ? [{ debugName: "popoverCard" }] : /* istanbul ignore next */ []);
15
15
  this.popoverCardSize = input("medium", ...ngDevMode ? [{ debugName: "popoverCardSize" }] : /* istanbul ignore next */ []);
16
16
  this.trapFocus = input(false, ...ngDevMode ? [{ debugName: "trapFocus" }] : /* istanbul ignore next */ []);
17
+ this.restoreFocusTo = input(null, ...ngDevMode ? [{ debugName: "restoreFocusTo" }] : /* istanbul ignore next */ []);
17
18
  this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
18
19
  }
20
+ ngOnInit() {
21
+ this.restoreFocusTo()?.focus({ preventScroll: true });
22
+ }
19
23
  static {
20
24
  this.ɵfac = i0.ɵɵngDeclareFactory({
21
25
  minVersion: "12.0.0",
@@ -69,6 +73,13 @@ var PopoverComponent = class PopoverComponent {
69
73
  isRequired: false,
70
74
  transformFunction: null
71
75
  },
76
+ restoreFocusTo: {
77
+ classPropertyName: "restoreFocusTo",
78
+ publicName: "restoreFocusTo",
79
+ isSignal: true,
80
+ isRequired: false,
81
+ transformFunction: null
82
+ },
72
83
  ariaLabel: {
73
84
  classPropertyName: "ariaLabel",
74
85
  publicName: "ariaLabel",
@@ -186,6 +197,14 @@ i0.ɵɵngDeclareClassMetadata({
186
197
  required: false
187
198
  }]
188
199
  }],
200
+ restoreFocusTo: [{
201
+ type: i0.Input,
202
+ args: [{
203
+ isSignal: true,
204
+ alias: "restoreFocusTo",
205
+ required: false
206
+ }]
207
+ }],
189
208
  ariaLabel: [{
190
209
  type: i0.Input,
191
210
  args: [{
@@ -196,20 +215,119 @@ i0.ɵɵngDeclareClassMetadata({
196
215
  }]
197
216
  }
198
217
  });
218
+ const END_PLACEMENT_VIEWPORT_MARGIN = 16;
219
+ const popoverPositions = ({ placement, align, offset }) => placement === "end" ? [{
220
+ originX: "end",
221
+ originY: "top",
222
+ overlayX: "start",
223
+ overlayY: "top",
224
+ offsetX: offset
225
+ }, {
226
+ originX: "start",
227
+ originY: "top",
228
+ overlayX: "end",
229
+ overlayY: "top",
230
+ offsetX: -offset
231
+ }] : [{
232
+ originX: align,
233
+ originY: "bottom",
234
+ overlayX: align,
235
+ overlayY: "top",
236
+ offsetY: offset
237
+ }, {
238
+ originX: align,
239
+ originY: "top",
240
+ overlayX: align,
241
+ overlayY: "bottom",
242
+ offsetY: -offset
243
+ }];
244
+ var PopoverOverlayService = class PopoverOverlayService {
245
+ constructor() {
246
+ this.overlay = inject(Overlay);
247
+ }
248
+ create(anchor, config) {
249
+ const positionStrategy = this.overlay.position().flexibleConnectedTo(anchor).withPositions(popoverPositions(config)).withViewportMargin(config.placement === "end" ? END_PLACEMENT_VIEWPORT_MARGIN : 0);
250
+ return this.overlay.create({
251
+ positionStrategy,
252
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
253
+ hasBackdrop: false
254
+ });
255
+ }
256
+ attach(overlayRef, injector, template, close, options) {
257
+ const ref = overlayRef.attach(new ComponentPortal(PopoverComponent, null, injector));
258
+ ref.setInput("templateRef", template);
259
+ ref.setInput("ctx", { close });
260
+ ref.setInput("popoverCard", options.isCard);
261
+ ref.setInput("popoverCardSize", options.cardSize);
262
+ ref.setInput("trapFocus", options.trapFocus);
263
+ ref.setInput("restoreFocusTo", options.restoreFocusTo ?? null);
264
+ ref.setInput("ariaLabel", options.ariaLabel);
265
+ return ref;
266
+ }
267
+ dismissOnOutsideOrEscape(overlayRef, anchor, close) {
268
+ const subscriptions = new Subscription();
269
+ subscriptions.add(overlayRef.outsidePointerEvents().subscribe((event) => {
270
+ if (!anchor.contains(event.target)) close();
271
+ }));
272
+ subscriptions.add(overlayRef.keydownEvents().subscribe((event) => {
273
+ if (event.key !== "Escape") return;
274
+ event.preventDefault();
275
+ close();
276
+ }));
277
+ return subscriptions;
278
+ }
279
+ static {
280
+ this.ɵfac = i0.ɵɵngDeclareFactory({
281
+ minVersion: "12.0.0",
282
+ version: "22.2.4",
283
+ ngImport: i0,
284
+ type: PopoverOverlayService,
285
+ deps: [],
286
+ target: i0.ɵɵFactoryTarget.Injectable
287
+ });
288
+ }
289
+ static {
290
+ this.ɵprov = i0.ɵɵngDeclareInjectable({
291
+ minVersion: "12.0.0",
292
+ version: "22.2.4",
293
+ ngImport: i0,
294
+ type: PopoverOverlayService,
295
+ providedIn: "root"
296
+ });
297
+ }
298
+ };
299
+ i0.ɵɵngDeclareClassMetadata({
300
+ minVersion: "12.0.0",
301
+ version: "22.2.4",
302
+ ngImport: i0,
303
+ type: PopoverOverlayService,
304
+ decorators: [{
305
+ type: Injectable,
306
+ args: [{ providedIn: "root" }]
307
+ }]
308
+ });
309
+ const POPOVER_DEFAULTS = {
310
+ placement: "below",
311
+ align: "center",
312
+ offset: 4,
313
+ isCard: true,
314
+ cardSize: "medium"
315
+ };
199
316
  var PopoverDirective = class PopoverDirective {
200
317
  constructor() {
201
318
  this.uiPopover = input.required(...ngDevMode ? [{ debugName: "uiPopover" }] : /* istanbul ignore next */ []);
202
- this.popoverOffset = input(4, ...ngDevMode ? [{ debugName: "popoverOffset" }] : /* istanbul ignore next */ []);
203
- this.popoverAlign = input("center", ...ngDevMode ? [{ debugName: "popoverAlign" }] : /* istanbul ignore next */ []);
319
+ this.popoverOffset = input(POPOVER_DEFAULTS.offset, ...ngDevMode ? [{ debugName: "popoverOffset" }] : /* istanbul ignore next */ []);
320
+ this.popoverAlign = input(POPOVER_DEFAULTS.align, ...ngDevMode ? [{ debugName: "popoverAlign" }] : /* istanbul ignore next */ []);
321
+ this.popoverPlacement = input(POPOVER_DEFAULTS.placement, ...ngDevMode ? [{ debugName: "popoverPlacement" }] : /* istanbul ignore next */ []);
204
322
  this.popoverOpen = input(false, ...ngDevMode ? [{ debugName: "popoverOpen" }] : /* istanbul ignore next */ []);
205
- this.popoverCard = input(true, ...ngDevMode ? [{ debugName: "popoverCard" }] : /* istanbul ignore next */ []);
206
- this.popoverCardSize = input("medium", ...ngDevMode ? [{ debugName: "popoverCardSize" }] : /* istanbul ignore next */ []);
323
+ this.popoverCard = input(POPOVER_DEFAULTS.isCard, ...ngDevMode ? [{ debugName: "popoverCard" }] : /* istanbul ignore next */ []);
324
+ this.popoverCardSize = input(POPOVER_DEFAULTS.cardSize, ...ngDevMode ? [{ debugName: "popoverCardSize" }] : /* istanbul ignore next */ []);
207
325
  this.popoverTrigger = input("hover", ...ngDevMode ? [{ debugName: "popoverTrigger" }] : /* istanbul ignore next */ []);
208
326
  this.popoverAriaLabel = input("", ...ngDevMode ? [{ debugName: "popoverAriaLabel" }] : /* istanbul ignore next */ []);
209
327
  this.uiPopoverDisabled = input(false, ...ngDevMode ? [{ debugName: "uiPopoverDisabled" }] : /* istanbul ignore next */ []);
210
328
  this.openState = signal(false, ...ngDevMode ? [{ debugName: "openState" }] : /* istanbul ignore next */ []);
211
329
  this.isOpen = this.openState.asReadonly();
212
- this.overlay = inject(Overlay);
330
+ this.popoverOverlay = inject(PopoverOverlayService);
213
331
  this.elementRef = inject(ElementRef);
214
332
  this.injector = inject(Injector);
215
333
  this.ngZone = inject(NgZone);
@@ -238,14 +356,10 @@ var PopoverDirective = class PopoverDirective {
238
356
  if (!this.overlayRef) this.createOverlay();
239
357
  const overlayRef = this.overlayRef;
240
358
  if (!overlayRef || overlayRef.hasAttached()) return;
241
- const portal = new ComponentPortal(PopoverComponent, null, this.injector);
242
- const ref = overlayRef.attach(portal);
243
- ref.setInput("templateRef", this.uiPopover());
244
- ref.setInput("ctx", { close: () => this.close() });
245
- ref.setInput("popoverCard", this.popoverCard());
246
- ref.setInput("popoverCardSize", this.popoverCardSize());
247
- ref.setInput("trapFocus", this.popoverTrigger() === "click");
248
- ref.setInput("ariaLabel", this.popoverAriaLabel());
359
+ this.popoverOverlay.attach(overlayRef, this.injector, this.uiPopover(), () => this.close(), {
360
+ ...this.config(),
361
+ trapFocus: this.popoverTrigger() === "click"
362
+ });
249
363
  if (this.popoverTrigger() === "hover") {
250
364
  const el = overlayRef.overlayElement;
251
365
  const enter = () => this.ngZone.run(() => this.cancelClose());
@@ -274,40 +388,19 @@ var PopoverDirective = class PopoverDirective {
274
388
  if (this.isOpen()) this.close();
275
389
  else this.open();
276
390
  }
277
- createOverlay() {
278
- const align = this.popoverAlign();
279
- const positionStrategy = this.overlay.position().flexibleConnectedTo(this.elementRef).withPositions([{
280
- originX: align,
281
- originY: "bottom",
282
- overlayX: align,
283
- overlayY: "top",
284
- offsetY: this.popoverOffset()
285
- }, {
286
- originX: align,
287
- originY: "top",
288
- overlayX: align,
289
- overlayY: "bottom",
290
- offsetY: -this.popoverOffset()
291
- }]);
292
- this.overlayRef = this.overlay.create({
293
- positionStrategy,
294
- scrollStrategy: this.overlay.scrollStrategies.reposition(),
295
- hasBackdrop: false
296
- });
297
- if (this.popoverTrigger() === "click") this.listenForDismiss(this.overlayRef);
391
+ config() {
392
+ return {
393
+ placement: this.popoverPlacement(),
394
+ align: this.popoverAlign(),
395
+ offset: this.popoverOffset(),
396
+ isCard: this.popoverCard(),
397
+ cardSize: this.popoverCardSize(),
398
+ ariaLabel: this.popoverAriaLabel()
399
+ };
298
400
  }
299
- listenForDismiss(overlayRef) {
300
- const subscriptions = new Subscription();
301
- subscriptions.add(overlayRef.outsidePointerEvents().subscribe((event) => {
302
- if (this.elementRef.nativeElement.contains(event.target)) return;
303
- this.close();
304
- }));
305
- subscriptions.add(overlayRef.keydownEvents().subscribe((event) => {
306
- if (event.key !== "Escape") return;
307
- event.preventDefault();
308
- this.close();
309
- }));
310
- this.dismissSubscriptions = subscriptions;
401
+ createOverlay() {
402
+ this.overlayRef = this.popoverOverlay.create(this.elementRef, this.config());
403
+ if (this.popoverTrigger() === "click") this.dismissSubscriptions = this.popoverOverlay.dismissOnOutsideOrEscape(this.overlayRef, this.elementRef.nativeElement, () => this.close());
311
404
  }
312
405
  scheduleOpen() {
313
406
  this.openTimeout = setTimeout(() => this.open(), 100);
@@ -376,6 +469,13 @@ var PopoverDirective = class PopoverDirective {
376
469
  isRequired: false,
377
470
  transformFunction: null
378
471
  },
472
+ popoverPlacement: {
473
+ classPropertyName: "popoverPlacement",
474
+ publicName: "popoverPlacement",
475
+ isSignal: true,
476
+ isRequired: false,
477
+ transformFunction: null
478
+ },
379
479
  popoverOpen: {
380
480
  classPropertyName: "popoverOpen",
381
481
  publicName: "popoverOpen",
@@ -467,6 +567,14 @@ i0.ɵɵngDeclareClassMetadata({
467
567
  required: false
468
568
  }]
469
569
  }],
570
+ popoverPlacement: [{
571
+ type: i0.Input,
572
+ args: [{
573
+ isSignal: true,
574
+ alias: "popoverPlacement",
575
+ required: false
576
+ }]
577
+ }],
470
578
  popoverOpen: [{
471
579
  type: i0.Input,
472
580
  args: [{
@@ -529,6 +637,98 @@ i0.ɵɵngDeclareClassMetadata({
529
637
  }]
530
638
  }
531
639
  });
532
- export { PopoverDirective };
640
+ var PopoverRef = class {
641
+ constructor(anchor, overlayRef, destroyRef) {
642
+ this.anchor = anchor;
643
+ this.overlayRef = overlayRef;
644
+ this.openState = signal(true, ...ngDevMode ? [{ debugName: "openState" }] : /* istanbul ignore next */ []);
645
+ this.closedSubject$ = new Subject();
646
+ this.isOpen = this.openState.asReadonly();
647
+ this.closed$ = this.closedSubject$.asObservable();
648
+ this.stopClosingOnDestroy = destroyRef?.onDestroy(() => {
649
+ this.stopClosingOnDestroy = void 0;
650
+ this.close();
651
+ });
652
+ }
653
+ close() {
654
+ if (!this.openState()) return;
655
+ this.openState.set(false);
656
+ this.stopClosingOnDestroy?.();
657
+ this.overlayRef.dispose();
658
+ this.closedSubject$.next();
659
+ this.closedSubject$.complete();
660
+ }
661
+ };
662
+ var PopoverService = class PopoverService {
663
+ constructor() {
664
+ this.popoverOverlay = inject(PopoverOverlayService);
665
+ this.injector = inject(Injector);
666
+ this.active = null;
667
+ }
668
+ open(anchor, template, config = {}) {
669
+ const current = this.openRefFor(anchor);
670
+ if (current) return current;
671
+ this.active?.close();
672
+ const { destroyRef, ...popoverConfig } = config;
673
+ const resolved = {
674
+ ...POPOVER_DEFAULTS,
675
+ ariaLabel: "",
676
+ ...popoverConfig
677
+ };
678
+ const overlayRef = this.popoverOverlay.create(anchor, resolved);
679
+ const ref = new PopoverRef(anchor, overlayRef, destroyRef);
680
+ const close = () => ref.close();
681
+ this.popoverOverlay.attach(overlayRef, this.injector, template, close, {
682
+ ...resolved,
683
+ trapFocus: true,
684
+ restoreFocusTo: anchor
685
+ });
686
+ this.popoverOverlay.dismissOnOutsideOrEscape(overlayRef, anchor, close);
687
+ this.active = ref;
688
+ return ref;
689
+ }
690
+ toggle(anchor, template, config = {}) {
691
+ const current = this.openRefFor(anchor);
692
+ if (current) {
693
+ current.close();
694
+ return null;
695
+ }
696
+ return this.open(anchor, template, config);
697
+ }
698
+ openRefFor(anchor) {
699
+ const active = this.active;
700
+ return active?.anchor === anchor && active.isOpen() ? active : null;
701
+ }
702
+ static {
703
+ this.ɵfac = i0.ɵɵngDeclareFactory({
704
+ minVersion: "12.0.0",
705
+ version: "22.2.4",
706
+ ngImport: i0,
707
+ type: PopoverService,
708
+ deps: [],
709
+ target: i0.ɵɵFactoryTarget.Injectable
710
+ });
711
+ }
712
+ static {
713
+ this.ɵprov = i0.ɵɵngDeclareInjectable({
714
+ minVersion: "12.0.0",
715
+ version: "22.2.4",
716
+ ngImport: i0,
717
+ type: PopoverService,
718
+ providedIn: "root"
719
+ });
720
+ }
721
+ };
722
+ i0.ɵɵngDeclareClassMetadata({
723
+ minVersion: "12.0.0",
724
+ version: "22.2.4",
725
+ ngImport: i0,
726
+ type: PopoverService,
727
+ decorators: [{
728
+ type: Injectable,
729
+ args: [{ providedIn: "root" }]
730
+ }]
731
+ });
732
+ export { PopoverDirective, PopoverRef, PopoverService };
533
733
 
534
734
  //# sourceMappingURL=testgorilla-tgo-ui-components-popover.mjs.map