Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

feat(aria/menu): Add possibility to create a shared menu component from aria/menu

Đang mở
#32,731 1 bình luận 6 reaction 1 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@ok7sai đang làm issue này rồi.

Từ ngày 1/4/2026.

Đánh giá

Issue này chưa được đánh giá.

Mô tả

area: aria/menu feature P3
Feature Description

When building a menu using aria/menu you have to have the following structure:

  1. an for cdkConnectedOverlay
  2. a container element with ngMenu
  3. another for ngMenuContent
  4. only then the actual ngMenuItem elements

This results in 4 structural levels that need to be repeated every time you need a new menu.

I attempted to create a shared menu component (similar to Angular Material’s MatMenu) in order to reduce this complexity to 2 levels and enable an API like:

<button appMenuTrigger #appMenuTrigger="appMenuTrigger"  [appMenu]="appMenu.formatMenu()">
  Open Menu
</button>

<app-menu #appMenu [appMenuTrigger]="appMenuTrigger">
  <app-menu-item value="Mark as read">
    <span class="icon material-symbols-outlined" aria-hidden="true">mark_email_read</span>
    <span class="label">Mark as read</span>
  </app-menu-item>

  <app-menu-item value="Snooze">
    <span class="icon material-symbols-outlined" aria-hidden="true">snooze</span>
    <span class="label">Snooze</span>
  </app-menu-item>
</app-menu>

Internally, app-menu wraps Menu and MenuContent:

@Component({
  selector: 'app-menu',
  imports: [OverlayModule, Menu, MenuContent],
  template: `
    <ng-template
      [cdkConnectedOverlayOpen]="appMenuTrigger().menuTrigger.expanded()"
      [cdkConnectedOverlay]="{ origin: appMenuTrigger().nativeElement, usePopover: 'inline' }"
      [cdkConnectedOverlayPositions]="overlayPositions"
      cdkAttachPopoverAsChild>

      <div ngMenu class="menu" #formatMenu="ngMenu">
        <ng-template ngMenuContent>
          <ng-content />
        </ng-template>
      </div>
    </ng-template>
  `
})
export class AppMenu {
  appMenuTrigger = input.required<AppMenuTrigger>();
  formatMenu = viewChild<Menu<string>>('formatMenu');
  overlayPositions: ConnectedPosition[] = [{originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4}];
}

and menu items are wrapped like this:

@Component({
  selector: 'app-menu-item',
  template: '<ng-content />',
  hostDirectives: [{ directive: MenuItem, inputs: ['value: value'] }]
})
export class AppMenuItem {}

Problem
With this approach, accessibility breaks (keyboard navigation no longer works correctly). This seems to happen because Menu cannot properly register MenuItem children when they are content projected.

Proposed enhancement
Expose a public API on Menu that allows the menu to "refresh" in order to register the items when they are content projected.

Use Case

No response

Ngôn ngữ chính
TypeScript
Star
25k
Fork
6.8k
Merge trung bình
1 ngày 5 giờ
Pull request đã merge (30 ngày)
67

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của angular/components

Tất cả issue của angular/components

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.