Меню по центру экрана, Наложение меню на кнопку по центру

Согласно материальной проблеме 9631 центрирование mat-menu по кнопке выглядит следующим образом.

проблема в том, что его поддержка отклоняется от спецификации и может выглядеть странно.


Мне нужна эта функциональность ... Поскольку написание моего собственного CDK-оверлея потребует больше времени, чем переопределение компонента mat-menu ... Меня не интересует воссоздание mat-menu, мне просто нужно, чтобы меню было центрировано .. Меня также не интересует какая-либо другая библиотека для этого, я хочу использовать Материал mat-menu, поэтому мой вопрос следующий.

Вопрос:

Используя angular directive, как я могу переопределить частные переменные и методы MatMenuTrigger, чтобы центрировать наложение CDK по кнопке?

введите описание изображения здесь


comment
Нет спецификации для центрирования меню с его триггером - поэтому это кажется неоднозначным. Спецификация выравнивания - RTL (или LTR) - так же, как и со списками, - потому что меню - это список (а триггер - это заголовок списка). Из спецификации: в меню отображается список вариантов. ИМО, это совсем не двусмысленно. Посмотрите на примеры - триггер и содержимое меню выстраиваются в линию RTL (за исключением крайних случаев экрана / браузера). В MD на самом деле нет концепции выравнивания по центру, поэтому, если вы хотите это сделать, вы должны определить свои собственные правила - не ищите их в спецификациях. Я сильно сомневаюсь, что директива может сработать.   -  person G. Tranter    schedule 10.01.2019
comment
Глядя на Exposed dropdown menu примеры, можно увидеть несколько снимков экрана в разделе поведения, которые изображают меню непосредственно под ним ... возможно, это потому, что элементы в раскрывающемся списке не выходят за пределы содержимого меню, поэтому он не смещается ни в одну из них. RTL или LTR ... Я все еще считаю это неоднозначным, поскольку приведенные примеры подразумевают выпадающий список по центру. material.io/design/components/menus.html#exposed-dropdown- меню   -  person Marshal    schedule 10.01.2019
comment
В зависимости от того, как вы решите смотреть на него, расположенное ниже изображение не обязательно совпадает с расположением по центру (хотя оно может также оказаться визуально центрированным). Снимки экрана, приведенные непосредственно ниже, основаны на выравнивании содержимого RTL и имеют одинаковую ширину. Я не вижу примеров меню, которое было бы шире или уже, чем триггер, но все же по центру. Если ваше меню имеет ту же ширину, что и ваш триггер, выравнивание RTL (или LTR) приведет к тому, что оно будет отображаться по центру, как раскрывающееся окно. Я не интерпретирую этот тип центрированного внешнего вида как центрированного выравнивания, потому что контент является RTL.   -  person G. Tranter    schedule 10.01.2019
comment
Спасибо за ваш взгляд на это, то, что вы описали, определенно помогает мне лучше понять интерпретацию спецификации.   -  person Marshal    schedule 11.01.2019


Ответы (1)


Я выбрал Директиву, потому что MatMenuTrigger - это Directive, имело смысл воспроизвести логику, используемую источником Материала.

Пока что это подход, который я придумал, я не уверен, является ли такой подход к классу «приемлемым» сам по себе, или есть какие-либо негативные последствия для этого.

Я открыт для конструктивного обсуждения этого подхода для любых рекомендаций или улучшений.


Stackblitz

https://stackblitz.com/edit/angular-jpgjdc-nqmyht?embed=1&file=app/center-matmenu.directive.ts

По сути, я отделяю matMenuTrigger от кнопки, помещая его в div, оборачивая _5 _... это так, чтобы я мог программно открывать меню из директивы, а не из кнопки.

  • Я также назначаю menuTrigger templateRef на div и передаю его как вход в свой center-mat-menu селектор.
<button mat-button [center-mat-menu]="menuTrigger">Menu</button>
<div #menuTrigger="matMenuTrigger" [matMenuTriggerFor]="menu">
 <mat-menu #menu="matMenu">

Оттуда я создаю слушателя через @HostListener

@HostListener('click', ['$event'])

А затем репликация логики директивы MatMenuTrigger для управления размещением, инициализации меню и запуска анимации открытия при нажатии.

Это в основном репликация метода openMenu() в источнике menu-trigger.ts, за исключением того, что я манипулирую левым и верхним стилями после инициализации меню и до того, как я вызываю this.menuTrigger.menu['_startAnimation']();, чтобы открыть меню.

person Marshal    schedule 10.01.2019
comment
Хорошая работа, но работает только при первом открытии. Если вы измените размер окна приложения, пока оно открыто, оно вернется к исходному выравниванию. И лично я считаю, что это неправильно - просто мнение. Это могло бы выглядеть правильно, если бы меню не было списком (возможно, сеткой), поэтому элементы не были размещены в строках RTL, но в этом случае я не думаю, что центрирование под триггером будет иметь большое значение. - person G. Tranter; 10.01.2019
comment
Хорошо поймал! Я забыл подписаться на positionChanges наблюдаемое в positionStrategy. Я отредактировал stackblitz, чтобы включить исправление для этого, дайте мне знать, если заметите что-нибудь еще. Я понимаю, что вы имеете в виду под элементами выравнивания по левому краю в раскрывающемся списке по сравнению с кнопкой выше, выглядящей неправильно ... в моем сценарии я загружаю [innerHTML] в раскрывающемся списке и не думал об этом ... ваши наблюдения и отзывы очень ценятся ! - person Marshal; 11.01.2019