angular / angular/components

bug(Menu): Incorrect position of submenu while using ng-template

Open
#26,252 3 comments 2 reactions 0 assignees View on GitHub
area: material/menu P4
Dominant language
TypeScript
Stars
25k
Forks
6.8k
Avg merge
1d 8h
Merged PRs (30d)
91

Description

### Is this a regression?

- [X] Yes, this behavior used to work in the previous version

### The previous version in which this bug was not present was

11.x

### Description

After some digging, I found the commit that break the positioning of the submenu when the menu items are created by using `ng-template`

The first related issue is #16167 and the corresponding [commit](https://github.com/angular/components/commit/44293522e98bbd975e5fba2551421af32631f2de) changed the way the padding is determined. Instead of using a fix value, it calculates the padding from the "offset of the first item".

Also, another issue (which is still open) #14842 clearly states that `@ContentChildren` does not find child elements created via `ngTemplateOutlet`.

These hand in hand break our code when we changed Angular version. Here is what happens:
- We have a template for "no-child menu items"
- The menu item is created by using `ngTemplateOutlet` when the menu item does not have any child element
- Otherwise, a `button[mat-menu-item]` is created directly

This causes a problem, since the `_items` collection of the menu does not contain the elements created from the `ng-template` so the calculated "padding" is totally wrong (in our case 200px instead of 8px).

A possible fix would be that instead of using the first item offset, the style of the first item's parent could be calculated using [window.getComputedStyle](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle), for example.

### Reproduction

Steps to reproduce (see [stackblitz](https://stackblitz.com/edit/components-issue-rlxajt?file=src/app/example-component.html)):

1. Open the main menu
2. Open a submenu (position is off)

The stackblitz is greatly simplified.

### Expected Behavior

The appropriate padding should be calculated so the submenu can be shown in the right place.

### Actual Behavior

The submenu is shown in the wrong place

### Environment

- Angular: 14.2.0
- CDK/Material: 14.2.0
- Browser(s): Google Chrome 108.0.5359.95
- Operating System (e.g. Windows, macOS, Ubuntu): Windows 10

Contributor guide

Open the contributing guide

Research direction

Start with the linked StackBlitz reproduction and inspect the menu submenu positioning logic, especially the padding calculation based on the first item offset and the `_items` collection. Compare the behavior with commit 44293522e98bbd975e5fba2551421af32631f2de and verify that items created through `ngTemplateOutlet` produce the expected submenu position and 8px padding.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.