228 lines
7.8 KiB
SCSS
228 lines
7.8 KiB
SCSS
|
|
@use '@angular/cdk';
|
||
|
|
@use '../core/tokens/m2/mat/menu' as tokens-mat-menu;
|
||
|
|
@use '../core/tokens/token-utils';
|
||
|
|
@use '../core/style/menu-common';
|
||
|
|
@use '../core/style/button-common';
|
||
|
|
@use '../core/style/vendor-prefixes';
|
||
|
|
|
||
|
|
// Prevent rendering mat-menu as it can affect the flex layout.
|
||
|
|
mat-menu {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.mat-mdc-menu-content {
|
||
|
|
margin: 0;
|
||
|
|
padding: 8px 0;
|
||
|
|
outline: 0;
|
||
|
|
|
||
|
|
&,
|
||
|
|
.mat-mdc-menu-item .mat-mdc-menu-item-text {
|
||
|
|
@include vendor-prefixes.smooth-font();
|
||
|
|
flex: 1;
|
||
|
|
white-space: normal;
|
||
|
|
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
@include token-utils.create-token-slot(font-family, item-label-text-font);
|
||
|
|
@include token-utils.create-token-slot(line-height, item-label-text-line-height);
|
||
|
|
@include token-utils.create-token-slot(font-size, item-label-text-size);
|
||
|
|
@include token-utils.create-token-slot(letter-spacing, item-label-text-tracking);
|
||
|
|
@include token-utils.create-token-slot(font-weight, item-label-text-weight);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.mat-mdc-menu-panel {
|
||
|
|
@include menu-common.base;
|
||
|
|
box-sizing: border-box;
|
||
|
|
outline: 0;
|
||
|
|
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
@include token-utils.create-token-slot(border-radius, container-shape);
|
||
|
|
@include token-utils.create-token-slot(background-color, container-color);
|
||
|
|
@include token-utils.create-token-slot(box-shadow, container-elevation-shadow);
|
||
|
|
}
|
||
|
|
|
||
|
|
// TODO(crisbeto): we don't need this for anything, but it was there when
|
||
|
|
// we used MDC's structural styles and removing it leads to sub-pixels
|
||
|
|
// differences in text rendering which break a lot of screenshots internally.
|
||
|
|
// We should clean it up eventually and re-approve all the screenshots.
|
||
|
|
will-change: transform, opacity;
|
||
|
|
|
||
|
|
// Prevent users from interacting with the panel while it's animating. Note that
|
||
|
|
// people won't be able to click through it, because the overlay pane will catch the click.
|
||
|
|
// This fixes the following issues:
|
||
|
|
// * Users accidentally opening sub-menus when the `overlapTrigger` option is enabled.
|
||
|
|
// * Users accidentally tapping on content inside the sub-menu on touch devices, if the
|
||
|
|
// sub-menu overlaps the trigger. The issue is due to touch devices emulating the
|
||
|
|
// `mouseenter` event by dispatching it on tap.
|
||
|
|
&.ng-animating {
|
||
|
|
pointer-events: none;
|
||
|
|
|
||
|
|
// If the same menu is assigned to multiple triggers and the user moves quickly between them
|
||
|
|
// (e.g. in a nested menu), the panel for the old menu may show up as empty while it's
|
||
|
|
// animating away. Hide such cases since they can look off to users.
|
||
|
|
&:has(.mat-mdc-menu-content:empty) {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@include cdk.high-contrast {
|
||
|
|
outline: solid 1px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.mat-divider {
|
||
|
|
// Use margin instead of padding since divider uses border-top to render out the line.
|
||
|
|
@include token-utils.use-tokens(
|
||
|
|
tokens-mat-menu.$prefix,
|
||
|
|
tokens-mat-menu.get-token-slots()
|
||
|
|
) {
|
||
|
|
color: token-utils.get-token-variable(divider-color);
|
||
|
|
margin-bottom: token-utils.get-token-variable(divider-bottom-spacing);
|
||
|
|
margin-top: token-utils.get-token-variable(divider-top-spacing);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.mat-mdc-menu-item {
|
||
|
|
display: flex;
|
||
|
|
position: relative;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: flex-start;
|
||
|
|
overflow: hidden;
|
||
|
|
padding: 0;
|
||
|
|
|
||
|
|
// MDC's menu items are `<li>` nodes which don't need resets, however ours
|
||
|
|
// can be anything, including buttons, so we need to do the reset ourselves.
|
||
|
|
cursor: pointer;
|
||
|
|
width: 100%;
|
||
|
|
text-align: left;
|
||
|
|
box-sizing: border-box;
|
||
|
|
color: inherit;
|
||
|
|
font-size: inherit;
|
||
|
|
background: none;
|
||
|
|
text-decoration: none;
|
||
|
|
margin: 0; // Resolves an issue where buttons have an extra 2px margin on Safari.
|
||
|
|
min-height: 48px;
|
||
|
|
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
@include token-utils.create-token-slot(padding-left, item-leading-spacing);
|
||
|
|
@include token-utils.create-token-slot(padding-right, item-trailing-spacing);
|
||
|
|
}
|
||
|
|
|
||
|
|
@include button-common.reset;
|
||
|
|
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
$icons-selector: '.material-icons, mat-icon, [matButtonIcon]';
|
||
|
|
|
||
|
|
[dir='rtl'] & {
|
||
|
|
@include token-utils.create-token-slot(padding-left, item-trailing-spacing);
|
||
|
|
@include token-utils.create-token-slot(padding-right, item-leading-spacing);
|
||
|
|
}
|
||
|
|
|
||
|
|
&:has(#{$icons-selector}) {
|
||
|
|
@include token-utils.create-token-slot(padding-left, item-with-icon-leading-spacing);
|
||
|
|
@include token-utils.create-token-slot(padding-right, item-with-icon-trailing-spacing);
|
||
|
|
}
|
||
|
|
|
||
|
|
[dir='rtl'] &:has(#{$icons-selector}) {
|
||
|
|
@include token-utils.create-token-slot(padding-left, item-with-icon-trailing-spacing);
|
||
|
|
@include token-utils.create-token-slot(padding-right, item-with-icon-leading-spacing);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
// The class selector isn't specific enough to overide the link pseudo selectors so we need
|
||
|
|
// to target them specifically, otherwise the item color might be overwritten by the user
|
||
|
|
// agent resets of the app.
|
||
|
|
&, &:visited, &:link {
|
||
|
|
@include token-utils.create-token-slot(color, item-label-text-color);
|
||
|
|
}
|
||
|
|
|
||
|
|
.mat-icon-no-color,
|
||
|
|
.mat-mdc-menu-submenu-icon {
|
||
|
|
@include token-utils.create-token-slot(color, item-icon-color);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
&[disabled] {
|
||
|
|
cursor: default;
|
||
|
|
opacity: 0.38;
|
||
|
|
|
||
|
|
// The browser prevents clicks on disabled buttons from propagating which prevents the menu
|
||
|
|
// from closing, but clicks on child nodes still propagate which is inconsistent (see #16694).
|
||
|
|
// In order to keep the behavior consistent and prevent the menu from closing, we add an overlay
|
||
|
|
// on top of the content that will catch all the clicks while disabled.
|
||
|
|
&::after {
|
||
|
|
display: block;
|
||
|
|
position: absolute;
|
||
|
|
content: '';
|
||
|
|
top: 0;
|
||
|
|
left: 0;
|
||
|
|
bottom: 0;
|
||
|
|
right: 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Inherited from MDC and necessary for some internal tests.
|
||
|
|
&:focus {
|
||
|
|
outline: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.mat-icon {
|
||
|
|
flex-shrink: 0;
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
margin-right: token-utils.get-token-variable(item-spacing);
|
||
|
|
height: token-utils.get-token-variable(item-icon-size);
|
||
|
|
width: token-utils.get-token-variable(item-icon-size);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[dir='rtl'] & {
|
||
|
|
text-align: right;
|
||
|
|
|
||
|
|
.mat-icon {
|
||
|
|
margin-right: 0;
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
margin-left: token-utils.get-token-variable(item-spacing);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
&:not([disabled]) {
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
&:hover {
|
||
|
|
@include token-utils.create-token-slot(background-color, item-hover-state-layer-color);
|
||
|
|
}
|
||
|
|
|
||
|
|
&.cdk-program-focused,
|
||
|
|
&.cdk-keyboard-focused,
|
||
|
|
&.mat-mdc-menu-item-highlighted {
|
||
|
|
@include token-utils.create-token-slot(background-color, item-focus-state-layer-color);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@include cdk.high-contrast {
|
||
|
|
$outline-width: 1px;
|
||
|
|
|
||
|
|
// We need to move the item 1px down, because Firefox seems to have
|
||
|
|
// an issue rendering the top part of the outline (see #21524).
|
||
|
|
margin-top: $outline-width;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.mat-mdc-menu-submenu-icon {
|
||
|
|
@include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) {
|
||
|
|
@include menu-common.item-submenu-icon(
|
||
|
|
token-utils.get-token-variable(item-spacing),
|
||
|
|
token-utils.get-token-variable(item-icon-size)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Increase specificity because ripple styles are part of the `mat-core` mixin and can
|
||
|
|
// potentially overwrite the absolute position of the container.
|
||
|
|
.mat-mdc-menu-item .mat-mdc-menu-ripple {
|
||
|
|
@include menu-common.item-ripple;
|
||
|
|
}
|