import { CdkMenuTrigger } from '@angular/cdk/menu'; import { computed, Directive, effect, forwardRef, inject, input } from '@angular/core'; import { createMenuPosition, MENU_SIDE, type MenuAlign, type MenuSide, } from '@spartan-ng/brain/core'; import { classes } from '@spartan-ng/styles/utils'; import { injectHlmDropdownMenuConfig } from './hlm-dropdown-menu-token'; @Directive({ selector: '[hlmDropdownMenuSubTrigger]', providers: [{ provide: MENU_SIDE, useExisting: forwardRef(() => HlmDropdownMenuSubTrigger) }], hostDirectives: [ { directive: CdkMenuTrigger, inputs: [ 'cdkMenuTriggerFor: hlmDropdownMenuSubTrigger', 'cdkMenuTriggerData: hlmDropdownMenuTriggerData', ], outputs: [ 'cdkMenuOpened: hlmDropdownMenuSubOpened', 'cdkMenuClosed: hlmDropdownMenuSubClosed', ], }, ], host: { 'data-slot': 'dropdown-menu-sub-trigger' }, }) export class HlmDropdownMenuSubTrigger { private readonly _cdkTrigger = inject(CdkMenuTrigger, { host: true }); private readonly _config = injectHlmDropdownMenuConfig(); public readonly align = input(this._config.align); public readonly side = input(this._config.side); private readonly _menuPosition = computed(() => createMenuPosition(this.align(), this.side())); constructor() { // CDK sets transform-origin on the submenu content from the resolved position; the content reads it // to animate from the anchored corner and to derive its data-side. Cast tolerates @angular/cdk < 21.2 // (we still support >=21.0), where the property is absent and the assignment is a harmless no-op. (this._cdkTrigger as { transformOriginSelector?: string }).transformOriginSelector = '[data-slot="dropdown-menu-sub"]'; effect(() => { this._cdkTrigger.menuPosition = this._menuPosition(); }); classes(() => 'aria-expanded:bg-accent aria-expanded:text-accent-foreground'); } }