Your zodiac sign is: {{signCtrl.value | json}} - - -
diff --git a/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts b/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts index fef79e8ae553..5da22612c0d8 100644 --- a/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts +++ b/src/components-examples/cdk/listbox/cdk-listbox-forms-validation/cdk-listbox-forms-validation-example.ts @@ -45,13 +45,7 @@ export class CdkListboxFormsValidationExample { if (this.signCtrl.hasError('required')) { errors.push('You must enter your zodiac sign'); } - if (this.signCtrl.hasError('cdkListboxUnexpectedMultipleValues')) { - errors.push('You can only select one zodiac sign'); - } - if (this.signCtrl.hasError('cdkListboxUnexpectedOptionValues')) { - const invalidOptions = this.signCtrl.getError('cdkListboxUnexpectedOptionValues').values; - errors.push(`You entered an invalid zodiac sign: ${invalidOptions[0]}`); - } + return errors.length ? errors : null; } // #enddocregion errors diff --git a/src/components-examples/material/form-field/form-field-prefix-suffix/form-field-prefix-suffix-example.ts b/src/components-examples/material/form-field/form-field-prefix-suffix/form-field-prefix-suffix-example.ts index 98f37a5ad0a9..6f796f2d569a 100644 --- a/src/components-examples/material/form-field/form-field-prefix-suffix/form-field-prefix-suffix-example.ts +++ b/src/components-examples/material/form-field/form-field-prefix-suffix/form-field-prefix-suffix-example.ts @@ -16,7 +16,7 @@ import {MatInputModule} from '@angular/material/input'; export class FormFieldPrefixSuffixExample { hide = signal(true); clickEvent(event: MouseEvent) { - this.hide.set(!this.hide); + this.hide.set(!this.hide()); event.stopPropagation(); } } diff --git a/src/components-examples/material/table/table-http/table-http-example.css b/src/components-examples/material/table/table-http/table-http-example.css index 1ecd1a098c1d..2f3caee0c42a 100644 --- a/src/components-examples/material/table/table-http/table-http-example.css +++ b/src/components-examples/material/table/table-http/table-http-example.css @@ -35,9 +35,9 @@ table { /* Column Widths */ .mat-column-number, .mat-column-state { - max-width: 64px; + width: 64px; } .mat-column-created { - max-width: 124px; + width: 124px; } diff --git a/src/material/button/_button-base.scss b/src/material/button/_button-base.scss index cb5de5769cb2..6885abe5adf5 100644 --- a/src/material/button/_button-base.scss +++ b/src/material/button/_button-base.scss @@ -1,8 +1,5 @@ -@use '@material/touch-target' as mdc-touch-target; - @use '../core/tokens/token-utils'; @use '../core/style/layout-common'; -@use '../core/mdc-helpers/mdc-helpers'; // Adds styles necessary to provide stateful interactions with the button. This includes providing // content for the state container's ::before and ::after so that they can be given a background @@ -126,9 +123,19 @@ // the button itself would require us to wrap it in another div. See: // https://github.com/material-components/material-components-web/tree/master/packages/mdc-button#making-buttons-accessible .mat-mdc-button-touch-target { - @include mdc-touch-target.touch-target( - $set-width: $is-square, - $query: mdc-helpers.$mdc-base-styles-query); + position: absolute; + top: 50%; + height: 48px; + + @if $is-square { + left: 50%; + width: 48px; + transform: translate(-50%, -50%); + } @else { + left: 0; + right: 0; + transform: translateY(-50%); + } @include token-utils.use-tokens($prefix, $slots) { @include token-utils.create-token-slot(display, touch-target-display); diff --git a/src/material/button/_button-theme.scss b/src/material/button/_button-theme.scss index 906466a02fda..ee85325714fb 100644 --- a/src/material/button/_button-theme.scss +++ b/src/material/button/_button-theme.scss @@ -1,8 +1,3 @@ -@use '@material/button/button-text-theme' as mdc-button-text-theme; -@use '@material/button/button-filled-theme' as mdc-button-filled-theme; -@use '@material/button/button-protected-theme' as mdc-button-protected-theme; -@use '@material/button/button-outlined-theme' as mdc-button-outlined-theme; - @use '../core/theming/theming'; @use '../core/theming/inspection'; @use '../core/theming/validation'; @@ -29,7 +24,7 @@ tokens-mat-text-button.get-color-tokens($theme) ); - @include mdc-button-text-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mdc-text-button.$prefix, $mdc-tokens); @include token-utils.create-token-values(tokens-mat-text-button.$prefix, $mat-tokens); } @@ -44,7 +39,7 @@ tokens-mat-filled-button.get-color-tokens($theme) ); - @include mdc-button-filled-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mdc-filled-button.$prefix, $mdc-tokens); @include token-utils.create-token-values(tokens-mat-filled-button.$prefix, $mat-tokens); } @@ -59,7 +54,7 @@ tokens-mat-protected-button.get-color-tokens($theme) ); - @include mdc-button-protected-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mdc-protected-button.$prefix, $mdc-tokens); @include token-utils.create-token-values(tokens-mat-protected-button.$prefix, $mat-tokens); } @@ -74,7 +69,7 @@ tokens-mat-outlined-button.get-color-tokens($theme) ); - @include mdc-button-outlined-theme.theme($mdc-tokens); + @include token-utils.create-token-values(tokens-mdc-outlined-button.$prefix, $mdc-tokens); @include token-utils.create-token-values(tokens-mat-outlined-button.$prefix, $mat-tokens); } @@ -97,10 +92,14 @@ token-utils.get-tokens-for($tokens, tokens-mat-filled-button.$prefix, $options...); $mat-outlined-button-tokens: token-utils.get-tokens-for($tokens, tokens-mat-outlined-button.$prefix, $options...); - @include mdc-button-text-theme.theme($mdc-text-button-tokens); - @include mdc-button-protected-theme.theme($mdc-protected-button-tokens); - @include mdc-button-filled-theme.theme($mdc-filled-button-tokens); - @include mdc-button-outlined-theme.theme($mdc-outlined-button-tokens); + + @include token-utils.create-token-values(tokens-mdc-text-button.$prefix, $mdc-text-button-tokens); + @include token-utils.create-token-values( + tokens-mdc-protected-button.$prefix, $mdc-protected-button-tokens); + @include token-utils.create-token-values( + tokens-mdc-filled-button.$prefix, $mdc-filled-button-tokens); + @include token-utils.create-token-values( + tokens-mdc-outlined-button.$prefix, $mdc-outlined-button-tokens); @include token-utils.create-token-values(tokens-mat-text-button.$prefix, $mat-text-button-tokens); @include token-utils.create-token-values( tokens-mat-protected-button.$prefix, $mat-protected-button-tokens); @@ -119,13 +118,13 @@ } @else { @include sass-utils.current-selector-or-root() { - @include mdc-button-text-theme.theme( + @include token-utils.create-token-values(tokens-mdc-text-button.$prefix, tokens-mdc-text-button.get-unthemable-tokens()); - @include mdc-button-filled-theme.theme( + @include token-utils.create-token-values(tokens-mdc-filled-button.$prefix, tokens-mdc-filled-button.get-unthemable-tokens()); - @include mdc-button-protected-theme.theme( + @include token-utils.create-token-values(tokens-mdc-protected-button.$prefix, tokens-mdc-protected-button.get-unthemable-tokens()); - @include mdc-button-outlined-theme.theme( + @include token-utils.create-token-values(tokens-mdc-outlined-button.$prefix, tokens-mdc-outlined-button.get-unthemable-tokens()); @include token-utils.create-token-values(tokens-mat-text-button.$prefix, @@ -223,14 +222,14 @@ } @else { @include sass-utils.current-selector-or-root() { - @include mdc-button-text-theme.theme( + @include token-utils.create-token-values(tokens-mdc-text-button.$prefix, tokens-mdc-text-button.get-typography-tokens($theme)); - @include mdc-button-filled-theme.theme( + @include token-utils.create-token-values(tokens-mdc-filled-button.$prefix, tokens-mdc-filled-button.get-typography-tokens($theme)); - @include mdc-button-outlined-theme.theme( - tokens-mdc-outlined-button.get-typography-tokens($theme)); - @include mdc-button-protected-theme.theme( + @include token-utils.create-token-values(tokens-mdc-protected-button.$prefix, tokens-mdc-protected-button.get-typography-tokens($theme)); + @include token-utils.create-token-values(tokens-mdc-outlined-button.$prefix, + tokens-mdc-outlined-button.get-typography-tokens($theme)); @include token-utils.create-token-values(tokens-mat-text-button.$prefix, tokens-mat-text-button.get-typography-tokens($theme)); @@ -252,14 +251,14 @@ } @else { @include sass-utils.current-selector-or-root() { - @include mdc-button-text-theme.theme( + @include token-utils.create-token-values(tokens-mdc-text-button.$prefix, tokens-mdc-text-button.get-density-tokens($theme)); - @include mdc-button-filled-theme.theme( + @include token-utils.create-token-values(tokens-mdc-filled-button.$prefix, tokens-mdc-filled-button.get-density-tokens($theme)); - @include mdc-button-outlined-theme.theme( - tokens-mdc-outlined-button.get-density-tokens($theme)); - @include mdc-button-protected-theme.theme( + @include token-utils.create-token-values(tokens-mdc-protected-button.$prefix, tokens-mdc-protected-button.get-density-tokens($theme)); + @include token-utils.create-token-values(tokens-mdc-outlined-button.$prefix, + tokens-mdc-outlined-button.get-density-tokens($theme)); @include token-utils.create-token-values(tokens-mat-text-button.$prefix, tokens-mat-text-button.get-density-tokens($theme)); diff --git a/src/material/button/button.scss b/src/material/button/button.scss index aed1f32c07e5..7cc65bbcd4d0 100644 --- a/src/material/button/button.scss +++ b/src/material/button/button.scss @@ -1,16 +1,6 @@ -@use 'sass:map'; -@use '@material/button/button' as mdc-button; -@use '@material/button/variables' as mdc-button-variables; -@use '@material/button/button-text-theme' as mdc-button-text-theme; -@use '@material/button/button-filled-theme' as mdc-button-filled-theme; -@use '@material/button/button-protected-theme' as mdc-button-protected-theme; -@use '@material/button/button-outlined-theme' as mdc-button-outlined-theme; -@use '@material/typography/typography' as mdc-typography; -@use '@material/theme/custom-properties' as mdc-custom-properties; - @use './button-base'; -@use '../core/mdc-helpers/mdc-helpers'; @use '../core/style/private' as style-private; +@use '../core/style/vendor-prefixes'; @use '../core/tokens/token-utils'; @use '../core/focus-indicators/private' as focus-indicators-private; @use '../core/tokens/m2/mdc/filled-button' as tokens-mdc-filled-button; @@ -22,127 +12,233 @@ @use '../core/tokens/m2/mdc/text-button' as tokens-mdc-text-button; @use '../core/tokens/m2/mat/text-button' as tokens-mat-text-button; -@include mdc-helpers.disable-mdc-fallback-declarations { - @include mdc-button.static-styles-without-ripple($query: mdc-helpers.$mdc-base-styles-query); +.mat-mdc-button-base { + text-decoration: none; } -@include mdc-custom-properties.configure($emit-fallback-values: false, $emit-fallback-vars: false) { - .mat-mdc-button { - $mdc-text-button-slots: tokens-mdc-text-button.get-token-slots(); - - @include mdc-button-text-theme.theme-styles($mdc-text-button-slots); - @include button-base.mat-private-button-horizontal-layout(tokens-mat-text-button.$prefix, - tokens-mat-text-button.get-token-slots(), true); - @include button-base.mat-private-button-ripple(tokens-mat-text-button.$prefix, - tokens-mat-text-button.get-token-slots()); - @include button-base.mat-private-button-touch-target(false, tokens-mat-text-button.$prefix, - tokens-mat-text-button.get-token-slots()); - - @include token-utils.use-tokens(tokens-mdc-text-button.$prefix, $mdc-text-button-slots) { - // We need to re-apply the disabled tokens since MDC uses - // `:disabled` which doesn't apply to anchors. - @include button-base.mat-private-button-disabled { - @include token-utils.create-token-slot(color, disabled-label-text-color); - } - } +.mdc-button { + @include vendor-prefixes.user-select(none); + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + min-width: 64px; + border: none; + outline: none; + line-height: inherit; + -webkit-appearance: none; + overflow: visible; + vertical-align: middle; + background: transparent; + padding: 0 8px; + + &::-moz-focus-inner { + padding: 0; + border: 0; } - .mat-mdc-unelevated-button { - $mdc-filled-button-slots: tokens-mdc-filled-button.get-token-slots(); - - @include mdc-button-filled-theme.theme-styles($mdc-filled-button-slots); - @include button-base.mat-private-button-horizontal-layout(tokens-mat-filled-button.$prefix, - tokens-mat-filled-button.get-token-slots(), false); - @include button-base.mat-private-button-ripple(tokens-mat-filled-button.$prefix, - tokens-mat-filled-button.get-token-slots()); - @include button-base.mat-private-button-touch-target(false, tokens-mat-filled-button.$prefix, - tokens-mat-filled-button.get-token-slots()); - - @include token-utils.use-tokens(tokens-mdc-filled-button.$prefix, $mdc-filled-button-slots) { - // We need to re-apply the disabled tokens since MDC uses - // `:disabled` which doesn't apply to anchors. - @include button-base.mat-private-button-disabled { - @include token-utils.create-token-slot(color, disabled-label-text-color); - @include token-utils.create-token-slot(background-color, disabled-container-color); - } + &:active { + outline: none; + } + + &:hover { + cursor: pointer; + } + + &:disabled { + cursor: default; + pointer-events: none; + } + + &[hidden] { + display: none; + } + + .mdc-button__label { + position: relative; + } +} + +.mat-mdc-button { + $mat-text-button-slots: tokens-mat-text-button.get-token-slots(); + + @include button-base.mat-private-button-horizontal-layout(tokens-mat-text-button.$prefix, + $mat-text-button-slots, true); + @include button-base.mat-private-button-ripple(tokens-mat-text-button.$prefix, + $mat-text-button-slots); + @include button-base.mat-private-button-touch-target(false, tokens-mat-text-button.$prefix, + $mat-text-button-slots); + + @include token-utils.use-tokens( + tokens-mdc-text-button.$prefix, + tokens-mdc-text-button.get-token-slots() + ) { + @include token-utils.create-token-slot(height, container-height); + @include token-utils.create-token-slot(font-family, label-text-font); + @include token-utils.create-token-slot(font-size, label-text-size); + @include token-utils.create-token-slot(letter-spacing, label-text-tracking); + @include token-utils.create-token-slot(text-transform, label-text-transform); + @include token-utils.create-token-slot(font-weight, label-text-weight); + + &, .mdc-button__ripple { + @include token-utils.create-token-slot(border-radius, container-shape); + } + + &:not(:disabled) { + @include token-utils.create-token-slot(color, label-text-color); + } + + // We need to re-apply the disabled tokens since MDC uses + // `:disabled` which doesn't apply to anchors. + @include button-base.mat-private-button-disabled { + @include token-utils.create-token-slot(color, disabled-label-text-color); } } +} - .mat-mdc-raised-button { - $mdc-button-protected-slots: tokens-mdc-protected-button.get-token-slots(); - - @include mdc-button-protected-theme.theme-styles(map.merge($mdc-button-protected-slots, ( - // Exclude the elevation tokens here since we output them manually below. - container-elevation: null, - hover-container-elevation: null, - disabled-container-elevation: null, - focus-container-elevation: null, - pressed-container-elevation: null, - container-shadow-color: null, - ))); - @include button-base.mat-private-button-horizontal-layout(tokens-mat-protected-button.$prefix, - tokens-mat-protected-button.get-token-slots(), false); - @include button-base.mat-private-button-ripple(tokens-mat-protected-button.$prefix, - tokens-mat-protected-button.get-token-slots()); - @include button-base.mat-private-button-touch-target(false, tokens-mat-protected-button.$prefix, - tokens-mat-protected-button.get-token-slots()); - - @include token-utils.use-tokens( - tokens-mdc-protected-button.$prefix, - $mdc-button-protected-slots) { - @include button-base.mat-private-button-elevation(container-elevation); - - &:hover { - @include button-base.mat-private-button-elevation(hover-container-elevation); - } +.mat-mdc-unelevated-button { + $mat-filled-button-slots: tokens-mat-filled-button.get-token-slots(); + transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); - &:focus { - @include button-base.mat-private-button-elevation(focus-container-elevation); - } + @include button-base.mat-private-button-horizontal-layout(tokens-mat-filled-button.$prefix, + $mat-filled-button-slots, false); + @include button-base.mat-private-button-ripple(tokens-mat-filled-button.$prefix, + $mat-filled-button-slots); + @include button-base.mat-private-button-touch-target(false, tokens-mat-filled-button.$prefix, + $mat-filled-button-slots); - &:active, &:focus:active { - @include button-base.mat-private-button-elevation(pressed-container-elevation); - } + @include token-utils.use-tokens( + tokens-mdc-filled-button.$prefix, + tokens-mdc-filled-button.get-token-slots() + ) { + @include token-utils.create-token-slot(height, container-height); + @include token-utils.create-token-slot(font-family, label-text-font); + @include token-utils.create-token-slot(font-size, label-text-size); + @include token-utils.create-token-slot(letter-spacing, label-text-tracking); + @include token-utils.create-token-slot(text-transform, label-text-transform); + @include token-utils.create-token-slot(font-weight, label-text-weight); + + &:not(:disabled) { + @include token-utils.create-token-slot(color, label-text-color); + @include token-utils.create-token-slot(background-color, container-color); + } - // We need to re-apply the disabled tokens since MDC uses - // `:disabled` which doesn't apply to anchors. - @include button-base.mat-private-button-disabled { - @include token-utils.create-token-slot(color, disabled-label-text-color); - @include token-utils.create-token-slot(background-color, disabled-container-color); + &, .mdc-button__ripple { + @include token-utils.create-token-slot(border-radius, container-shape); + } - &.mat-mdc-button-disabled { - @include button-base.mat-private-button-elevation(disabled-container-elevation); - } - } + // We need to re-apply the disabled tokens since MDC uses + // `:disabled` which doesn't apply to anchors. + @include button-base.mat-private-button-disabled { + @include token-utils.create-token-slot(color, disabled-label-text-color); + @include token-utils.create-token-slot(background-color, disabled-container-color); } } +} + +.mat-mdc-raised-button { + $mat-protected-button-slots: tokens-mat-protected-button.get-token-slots(); + transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1); + + @include button-base.mat-private-button-horizontal-layout(tokens-mat-protected-button.$prefix, + $mat-protected-button-slots, false); + @include button-base.mat-private-button-ripple(tokens-mat-protected-button.$prefix, + $mat-protected-button-slots); + @include button-base.mat-private-button-touch-target(false, tokens-mat-protected-button.$prefix, + $mat-protected-button-slots); + + @include token-utils.use-tokens( + tokens-mdc-protected-button.$prefix, + tokens-mdc-protected-button.get-token-slots() + ) { + @include button-base.mat-private-button-elevation(container-elevation); + @include token-utils.create-token-slot(height, container-height); + @include token-utils.create-token-slot(font-family, label-text-font); + @include token-utils.create-token-slot(font-size, label-text-size); + @include token-utils.create-token-slot(letter-spacing, label-text-tracking); + @include token-utils.create-token-slot(text-transform, label-text-transform); + @include token-utils.create-token-slot(font-weight, label-text-weight); + + &:not(:disabled) { + @include token-utils.create-token-slot(color, label-text-color); + @include token-utils.create-token-slot(background-color, container-color); + } + + &, .mdc-button__ripple { + @include token-utils.create-token-slot(border-radius, container-shape); + } + + &:hover { + @include button-base.mat-private-button-elevation(hover-container-elevation); + } + + &:focus { + @include button-base.mat-private-button-elevation(focus-container-elevation); + } - .mat-mdc-outlined-button { - $mdc-outlined-button-slots: tokens-mdc-outlined-button.get-token-slots(); - - @include mdc-button-outlined-theme.theme-styles($mdc-outlined-button-slots); - @include button-base.mat-private-button-horizontal-layout(tokens-mat-outlined-button.$prefix, - tokens-mat-outlined-button.get-token-slots(), false); - @include button-base.mat-private-button-ripple(tokens-mat-outlined-button.$prefix, - tokens-mat-outlined-button.get-token-slots()); - @include button-base.mat-private-button-touch-target(false, tokens-mat-outlined-button.$prefix, - tokens-mat-outlined-button.get-token-slots()); - - @include token-utils.use-tokens( - tokens-mdc-outlined-button.$prefix, - $mdc-outlined-button-slots) { - // We need to re-apply the disabled tokens since MDC uses - // `:disabled` which doesn't apply to anchors. - @include button-base.mat-private-button-disabled { - @include token-utils.create-token-slot(color, disabled-label-text-color); - @include token-utils.create-token-slot(border-color, disabled-outline-color); + &:active, &:focus:active { + @include button-base.mat-private-button-elevation(pressed-container-elevation); + } + + // We need to re-apply the disabled tokens since MDC uses + // `:disabled` which doesn't apply to anchors. + @include button-base.mat-private-button-disabled { + @include token-utils.create-token-slot(color, disabled-label-text-color); + @include token-utils.create-token-slot(background-color, disabled-container-color); + + &.mat-mdc-button-disabled { + @include button-base.mat-private-button-elevation(disabled-container-elevation); } } } } -.mat-mdc-button-base { - text-decoration: none; +.mat-mdc-outlined-button { + $mat-outlined-button-slots: tokens-mat-outlined-button.get-token-slots(); + border-style: solid; + transition: border 280ms cubic-bezier(0.4, 0, 0.2, 1); + + @include button-base.mat-private-button-horizontal-layout(tokens-mat-outlined-button.$prefix, + $mat-outlined-button-slots, false); + @include button-base.mat-private-button-ripple(tokens-mat-outlined-button.$prefix, + $mat-outlined-button-slots); + @include button-base.mat-private-button-touch-target(false, tokens-mat-outlined-button.$prefix, + $mat-outlined-button-slots); + + @include token-utils.use-tokens( + tokens-mdc-outlined-button.$prefix, + tokens-mdc-outlined-button.get-token-slots() + ) { + @include token-utils.create-token-slot(height, container-height); + @include token-utils.create-token-slot(font-family, label-text-font); + @include token-utils.create-token-slot(font-size, label-text-size); + @include token-utils.create-token-slot(letter-spacing, label-text-tracking); + @include token-utils.create-token-slot(text-transform, label-text-transform); + @include token-utils.create-token-slot(font-weight, label-text-weight); + @include token-utils.create-token-slot(border-radius, container-shape); + @include token-utils.create-token-slot(border-width, outline-width); + + &:not(:disabled) { + @include token-utils.create-token-slot(color, label-text-color); + @include token-utils.create-token-slot(border-color, outline-color); + } + + // We need to re-apply the disabled tokens since MDC uses + // `:disabled` which doesn't apply to anchors. + @include button-base.mat-private-button-disabled { + @include token-utils.create-token-slot(color, disabled-label-text-color); + @include token-utils.create-token-slot(border-color, disabled-outline-color); + } + + // TODO(crisbeto): this causes a weird gap between the ripple and the + // outline. We should remove it and update the screenshot tests. + .mdc-button__ripple { + @include token-utils.create-token-slot(border-width, outline-width); + border-style: solid; + border-color: transparent; + } + } } .mat-mdc-button, @@ -155,7 +251,7 @@ // Similar to MDC's `_icon-structure`, apart from the margin which we // handle via custom tokens in `mat-private-button-horizontal-layout`. & > .mat-icon { - $icon-size: mdc-typography.px-to-rem(18px); + $icon-size: 1.125rem; display: inline-block; position: relative; vertical-align: top; @@ -174,12 +270,11 @@ // then. See: https://github.com/angular/components/issues/13738 .mat-mdc-outlined-button .mat-mdc-button-ripple, .mat-mdc-outlined-button .mdc-button__ripple { - $offset: -(mdc-button-variables.$outlined-border-width); + $offset: -1px; top: $offset; left: $offset; bottom: $offset; right: $offset; - border-width: $offset; } // For the button element, default inset/offset values are necessary to ensure that diff --git a/src/material/chips/_chips-theme.scss b/src/material/chips/_chips-theme.scss index 736b195ec173..2528a8685bdb 100644 --- a/src/material/chips/_chips-theme.scss +++ b/src/material/chips/_chips-theme.scss @@ -1,5 +1,4 @@ @use 'sass:color'; -@use '@material/chips/chip-theme' as mdc-chip-theme; @use '../core/tokens/m2/mdc/chip' as tokens-mdc-chip; @use '../core/tokens/m2/mat/chip' as tokens-mat-chip; @use '../core/tokens/token-utils'; @@ -17,9 +16,10 @@ } @else { .mat-mdc-standard-chip { - @include mdc-chip-theme.theme(tokens-mdc-chip.get-unthemable-tokens()); @include token-utils.create-token-values( - tokens-mat-chip.$prefix, tokens-mat-chip.get-unthemable-tokens()); + tokens-mdc-chip.$prefix, tokens-mdc-chip.get-unthemable-tokens()); + @include token-utils.create-token-values( + tokens-mat-chip.$prefix, tokens-mat-chip.get-unthemable-tokens()); } } } @@ -35,32 +35,32 @@ } @else { .mat-mdc-standard-chip { - $default-color-tokens: tokens-mdc-chip.get-color-tokens($theme); - @include mdc-chip-theme.theme($default-color-tokens); @include token-utils.create-token-values( - tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme)); + tokens-mdc-chip.$prefix, tokens-mdc-chip.get-color-tokens($theme)); + @include token-utils.create-token-values( + tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme)); &.mat-mdc-chip-selected, &.mat-mdc-chip-highlighted { &.mat-primary { - $primary-color-tokens: tokens-mdc-chip.get-color-tokens($theme, primary); - @include mdc-chip-theme.theme($primary-color-tokens); @include token-utils.create-token-values( - tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme, primary)); + tokens-mdc-chip.$prefix, tokens-mdc-chip.get-color-tokens($theme, primary)); + @include token-utils.create-token-values( + tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme, primary)); } &.mat-accent { - $accent-color-tokens: tokens-mdc-chip.get-color-tokens($theme, accent); - @include mdc-chip-theme.theme($accent-color-tokens); @include token-utils.create-token-values( - tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme, accent)); + tokens-mdc-chip.$prefix, tokens-mdc-chip.get-color-tokens($theme, accent)); + @include token-utils.create-token-values( + tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme, accent)); } &.mat-warn { - $warn-color-tokens: tokens-mdc-chip.get-color-tokens($theme, warn); - @include mdc-chip-theme.theme($warn-color-tokens); @include token-utils.create-token-values( - tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme, warn)); + tokens-mdc-chip.$prefix, tokens-mdc-chip.get-color-tokens($theme, warn)); + @include token-utils.create-token-values( + tokens-mat-chip.$prefix, tokens-mat-chip.get-color-tokens($theme, warn)); } } } @@ -74,12 +74,11 @@ @include _theme-from-tokens(inspection.get-theme-tokens($theme, typography)); } @else { - $typography-tokens: tokens-mdc-chip.get-typography-tokens($theme); - .mat-mdc-standard-chip { - @include mdc-chip-theme.theme($typography-tokens); @include token-utils.create-token-values( - tokens-mat-chip.$prefix, tokens-mat-chip.get-typography-tokens($theme)); + tokens-mdc-chip.$prefix, tokens-mdc-chip.get-typography-tokens($theme)); + @include token-utils.create-token-values( + tokens-mat-chip.$prefix, tokens-mat-chip.get-typography-tokens($theme)); } } } @@ -91,12 +90,11 @@ @include _theme-from-tokens(inspection.get-theme-tokens($theme, density)); } @else { - $density-tokens: tokens-mdc-chip.get-density-tokens($theme); - .mat-mdc-chip.mat-mdc-standard-chip { - @include mdc-chip-theme.theme($density-tokens); @include token-utils.create-token-values( - tokens-mat-chip.$prefix, tokens-mat-chip.get-density-tokens($theme)); + tokens-mdc-chip.$prefix, tokens-mdc-chip.get-density-tokens($theme)); + @include token-utils.create-token-values( + tokens-mat-chip.$prefix, tokens-mat-chip.get-density-tokens($theme)); } } } @@ -141,6 +139,6 @@ 'Calls to Angular Material theme mixins with an M3 theme must be wrapped in a selector'); $mdc-chip-tokens: token-utils.get-tokens-for($tokens, tokens-mdc-chip.$prefix, $options...); $mat-chip-tokens: token-utils.get-tokens-for($tokens, tokens-mat-chip.$prefix, $options...); - @include mdc-chip-theme.theme($mdc-chip-tokens); + @include token-utils.create-token-values(tokens-mdc-chip.$prefix, $mdc-chip-tokens); @include token-utils.create-token-values(tokens-mat-chip.$prefix, $mat-chip-tokens); } diff --git a/src/material/chips/chip-grid.spec.ts b/src/material/chips/chip-grid.spec.ts index cb18d49372f9..264675e33f49 100644 --- a/src/material/chips/chip-grid.spec.ts +++ b/src/material/chips/chip-grid.spec.ts @@ -3,6 +3,7 @@ import {Direction, Directionality} from '@angular/cdk/bidi'; import { BACKSPACE, DELETE, + DOWN_ARROW, END, ENTER, HOME, @@ -10,6 +11,7 @@ import { RIGHT_ARROW, SPACE, TAB, + UP_ARROW, } from '@angular/cdk/keycodes'; import { createKeyboardEvent, @@ -309,6 +311,48 @@ describe('MDC-based MatChipGrid', () => { .withContext('Expected focused item not to have changed.') .toBe(previousActiveElement); }); + + it('should focus primary action in next row when pressing DOWN ARROW on primary action', () => { + chips.first.focus(); + expect(document.activeElement).toBe(primaryActions[0]); + + dispatchKeyboardEvent(primaryActions[0], 'keydown', DOWN_ARROW); + fixture.detectChanges(); + + expect(document.activeElement).toBe(primaryActions[1]); + }); + + it('should focus primary action in previous row when pressing UP ARROW on primary action', () => { + const lastIndex = primaryActions.length - 1; + chips.last.focus(); + expect(document.activeElement).toBe(primaryActions[lastIndex]); + + dispatchKeyboardEvent(primaryActions[lastIndex], 'keydown', UP_ARROW); + fixture.detectChanges(); + + expect(document.activeElement).toBe(primaryActions[lastIndex - 1]); + }); + + it('should focus(trailing action in next row when pressing DOWN ARROW on(trailing action', () => { + trailingActions[0].focus(); + expect(document.activeElement).toBe(trailingActions[0]); + + dispatchKeyboardEvent(trailingActions[0], 'keydown', DOWN_ARROW); + fixture.detectChanges(); + + expect(document.activeElement).toBe(trailingActions[1]); + }); + + it('should focus trailing action in previous row when pressing UP ARROW on trailing action', () => { + const lastIndex = trailingActions.length - 1; + trailingActions[lastIndex].focus(); + expect(document.activeElement).toBe(trailingActions[lastIndex]); + + dispatchKeyboardEvent(trailingActions[lastIndex], 'keydown', UP_ARROW); + fixture.detectChanges(); + + expect(document.activeElement).toBe(trailingActions[lastIndex - 1]); + }); }); describe('RTL', () => { @@ -1034,11 +1078,8 @@ describe('MDC-based MatChipGrid', () => { template: `