diff --git a/src/material-experimental/theming/_custom-tokens.scss b/src/material-experimental/theming/_custom-tokens.scss index 09f12242935e..66151236d7fa 100644 --- a/src/material-experimental/theming/_custom-tokens.scss +++ b/src/material-experimental/theming/_custom-tokens.scss @@ -856,9 +856,13 @@ @return mat.private-merge-all( _generate-typography-tokens($systems, item-label-text, label-large), ( - container-shape: _hardcode(4px, $exclude-hardcoded), + container-shape: map.get($systems, md-sys-shape, corner-extra-small), + divider-color: map.get($systems, md-sys-color, surface-variant), + divider-bottom-spacing: _hardcode(8px, $exclude-hardcoded), + divider-top-spacing: _hardcode(8px, $exclude-hardcoded), item-label-text-color: map.get($systems, md-sys-color, on-surface), item-icon-color: map.get($systems, md-sys-color, on-surface-variant), + item-icon-size: _hardcode(24px, $exclude-hardcoded), item-hover-state-layer-color: mat.private-safe-color-change( map.get($systems, md-sys-color, on-surface), $alpha: map.get($systems, md-sys-state, hover-state-layer-opacity) @@ -867,6 +871,11 @@ map.get($systems, md-sys-color, on-surface), $alpha: map.get($systems, md-sys-state, focus-state-layer-opacity) ), + item-spacing: _hardcode(12px, $exclude-hardcoded), + item-leading-spacing: _hardcode(12px, $exclude-hardcoded), + item-trailing-spacing: _hardcode(12px, $exclude-hardcoded), + item-with-icon-leading-spacing: _hardcode(12px, $exclude-hardcoded), + item-with-icon-trailing-spacing: _hardcode(12px, $exclude-hardcoded), container-color: map.get($systems, md-sys-color, surface-container), ) ); diff --git a/src/material/core/style/_menu-common.scss b/src/material/core/style/_menu-common.scss index 78888ac4da3b..934acc5d11ce 100644 --- a/src/material/core/style/_menu-common.scss +++ b/src/material/core/style/_menu-common.scss @@ -59,29 +59,16 @@ $icon-margin: 16px !default; } } -@mixin item-submenu-trigger($side-padding) { - // Increase the side padding to prevent the indicator from overlapping the text. - padding-right: $side-padding * 2; - - [dir='rtl'] & { - padding-right: $side-padding; - padding-left: $side-padding * 2; - } -} - -@mixin item-submenu-icon($side-padding) { - position: absolute; - top: 50%; - right: $side-padding; - transform: translateY(-50%); - width: 5px; +@mixin item-submenu-icon($item-spacing, $icon-size) { + width: $icon-size; height: 10px; fill: currentColor; + padding-left: $item-spacing; [dir='rtl'] & { right: auto; - left: $side-padding; - transform: translateY(-50%) scaleX(-1); + padding-right: $item-spacing; + padding-left: 0; } // Fix for Chromium-based browsers blending in the `currentColor` with the background. diff --git a/src/material/core/tokens/m2/mat/_menu.scss b/src/material/core/tokens/m2/mat/_menu.scss index 14e0ed220b0c..8b8ad3dfa6be 100644 --- a/src/material/core/tokens/m2/mat/_menu.scss +++ b/src/material/core/tokens/m2/mat/_menu.scss @@ -10,6 +10,14 @@ $prefix: (mat, menu); @function get-unthemable-tokens() { @return ( container-shape: 4px, + divider-bottom-spacing: 0, + divider-top-spacing: 0, + item-spacing: 16px, + item-icon-size: 24px, + item-leading-spacing: 16px, + item-trailing-spacing: 16px, + item-with-icon-leading-spacing: 16px, + item-with-icon-trailing-spacing: 16px, ); } @@ -26,6 +34,7 @@ $prefix: (mat, menu); item-hover-state-layer-color: $active-state-layer-color, item-focus-state-layer-color: $active-state-layer-color, container-color: inspection.get-theme-color($theme, background, card), + divider-color: inspection.get-theme-color($theme, foreground, divider), ); } diff --git a/src/material/menu/menu.scss b/src/material/menu/menu.scss index 97f0104f1803..567cfff85120 100644 --- a/src/material/menu/menu.scss +++ b/src/material/menu/menu.scss @@ -20,6 +20,7 @@ mat-menu { &, .mat-mdc-menu-item .mat-mdc-menu-item-text { @include mdc-typography.smooth-font(); + flex: 1; white-space: normal; @include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) { @@ -64,11 +65,37 @@ mat-menu { } } +.mat-divider { + // Use margin instead of padding since divider uses border-top for line + @include token-utils.use-tokens( + tokens-mat-menu.$prefix, + tokens-mat-menu.get-token-slots() + ) { + color: var(#{token-utils.get-token-variable(divider-color)}); + margin-bottom: var(#{token-utils.get-token-variable(divider-bottom-spacing)}); + margin-top: var(#{token-utils.get-token-variable(divider-top-spacing)}); + } +} + .mat-mdc-menu-item { @include mdc-helpers.disable-mdc-fallback-declarations { @include mdc-list-mixins.item-base; - @include mdc-list-mixins.item-spacing( - mdc-list-variables.$side-padding, $query: mdc-helpers.$mdc-base-styles-query); + @include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) { + @include mdc-list-mixins.item-spacing( + var(#{token-utils.get-token-variable(item-leading-spacing)}), + var(#{token-utils.get-token-variable(item-trailing-spacing)}), + $query: mdc-helpers.$mdc-base-styles-query + ); + + // stylelint-disable-next-line selector-class-pattern + &:has(.material-icons, mat-icon, [matButtonIcon]) { + @include mdc-list-mixins.item-spacing( + var(#{token-utils.get-token-variable(item-with-icon-leading-spacing)}), + var(#{token-utils.get-token-variable(item-with-icon-trailing-spacing)}), + $query: mdc-helpers.$mdc-base-styles-query + ); + } + } } // MDC's menu items are `
  • ` nodes which don't need resets, however ours @@ -129,7 +156,11 @@ mat-menu { .mat-icon { flex-shrink: 0; - margin-right: mdc-list-variables.$side-padding; + @include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) { + margin-right: var(#{token-utils.get-token-variable(item-spacing)}); + height: var(#{token-utils.get-token-variable(item-icon-size)}); + width: var(#{token-utils.get-token-variable(item-icon-size)}); + } } [dir='rtl'] & { @@ -137,14 +168,12 @@ mat-menu { .mat-icon { margin-right: 0; - margin-left: mdc-list-variables.$side-padding; + @include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) { + margin-left: var(#{token-utils.get-token-variable(item-spacing)}); + } } } - &.mat-mdc-menu-item-submenu-trigger { - @include menu-common.item-submenu-trigger(mdc-list-variables.$side-padding); - } - &:not([disabled]) { @include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) { &:hover { @@ -169,7 +198,12 @@ mat-menu { } .mat-mdc-menu-submenu-icon { - @include menu-common.item-submenu-icon(mdc-list-variables.$side-padding); + @include token-utils.use-tokens(tokens-mat-menu.$prefix, tokens-mat-menu.get-token-slots()) { + @include menu-common.item-submenu-icon( + var(#{token-utils.get-token-variable(item-spacing)}), + var(#{token-utils.get-token-variable(item-icon-size)}) + ); + } } // Increase specificity because ripple styles are part of the `mat-core` mixin and can