Skip to content

Commit 6a593c1

Browse files
committed
feat(material-experimental): add MDC-based mat-option and mdc-core entry point
- Sets up the MDC-based `mat-option` and `mat-optgroup` which are a prerequisite for the MDC-based `mat-select` and `mat-autocomplete`. - Adds a new `mdc-core` entry point which is the equivalent of `material/core`. We'll need this in the future for other things like an MDC-based `mat-core-theme` and for the elevation styles.
1 parent 5f76afa commit 6a593c1

File tree

21 files changed

+753
-72
lines changed

21 files changed

+753
-72
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
/src/material-experimental/mdc-checkbox/** @mmalerba
101101
/src/material-experimental/mdc-chips/** @mmalerba
102102
/src/material-experimental/mdc-color/** @jelbourn @devversion
103+
/src/material-experimental/mdc-core/** @crisbeto
103104
/src/material-experimental/mdc-density/** @devversion
104105
/src/material-experimental/mdc-dialog/** @devversion
105106
/src/material-experimental/mdc-form-field/** @devversion @mmalerba

src/material-experimental/config.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ entryPoints = [
88
"mdc-checkbox/testing",
99
"mdc-chips",
1010
"mdc-chips/testing",
11+
"mdc-core",
1112
"mdc-form-field",
1213
"mdc-form-field/testing",
1314
"mdc-input",
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
load(
2+
"//tools:defaults.bzl",
3+
"ng_module",
4+
"ng_test_library",
5+
"ng_web_test_suite",
6+
"sass_binary",
7+
"sass_library",
8+
)
9+
10+
package(default_visibility = ["//visibility:public"])
11+
12+
ng_module(
13+
name = "mdc-core",
14+
srcs = glob(
15+
["**/*.ts"],
16+
exclude = ["**/*.spec.ts"],
17+
),
18+
assets = [
19+
":option/option.css",
20+
":option/optgroup.css",
21+
] + glob(["**/*.html"]),
22+
module_name = "@angular/material-experimental/mdc-core",
23+
deps = [
24+
"//src/material/core",
25+
"@npm//@angular/common",
26+
"@npm//@angular/core",
27+
"@npm//rxjs",
28+
],
29+
)
30+
31+
sass_library(
32+
name = "mdc_core_scss_lib",
33+
srcs = glob(["**/_*.scss"]),
34+
)
35+
36+
sass_binary(
37+
name = "option_scss",
38+
src = "option/option.scss",
39+
include_paths = [
40+
"external/npm/node_modules",
41+
],
42+
deps = [
43+
"//src/material-experimental/mdc-helpers:mdc_helpers_scss_lib",
44+
"//src/material-experimental/mdc-helpers:mdc_scss_deps_lib",
45+
],
46+
)
47+
48+
sass_binary(
49+
name = "optgroup_scss",
50+
src = "option/optgroup.scss",
51+
include_paths = [
52+
"external/npm/node_modules",
53+
],
54+
deps = [
55+
"//src/material-experimental/mdc-helpers:mdc_helpers_scss_lib",
56+
"//src/material-experimental/mdc-helpers:mdc_scss_deps_lib",
57+
],
58+
)
59+
60+
#################
61+
# Test targets
62+
#################
63+
64+
ng_test_library(
65+
name = "unit_test_sources",
66+
srcs = glob(
67+
["**/*.spec.ts"],
68+
),
69+
deps = [
70+
":mdc-core",
71+
"//src/cdk/keycodes",
72+
"//src/cdk/testing/private",
73+
"@npm//@angular/platform-browser",
74+
],
75+
)
76+
77+
ng_web_test_suite(
78+
name = "unit_tests",
79+
deps = [":unit_test_sources"],
80+
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@import '../../material/core/theming/check-duplicate-styles';
2+
@import './option/option-theme';
3+
@import './option/optgroup-theme';
4+
5+
// Mixin that renders all of the core styles that depend on the theme.
6+
@mixin mat-mdc-core-theme($theme-or-color-config) {
7+
$theme: _mat-legacy-get-theme($theme-or-color-config);
8+
// Wrap the sub-theme includes in the duplicate theme styles mixin. This ensures that
9+
// there won't be multiple warnings. e.g. if `mat-mdc-core-theme` reports a warning, then
10+
// the imported themes (such as `mat-ripple-theme`) should not report again.
11+
@include _mat-check-duplicate-theme-styles($theme, 'mat-mdc-core') {
12+
@include mat-mdc-option-theme($theme);
13+
@include mat-mdc-optgroup-theme($theme);
14+
}
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export * from './public-api';
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
@import '@material/list/mixins.import';
2+
@import '@material/list/variables.import';
3+
@import '@material/theme/functions.import';
4+
@import '../../mdc-helpers/mdc-helpers';
5+
@import '../../../material/core/theming/check-duplicate-styles';
6+
7+
@mixin mat-mdc-optgroup-color($config-or-theme) {
8+
$config: mat-get-color-config($config-or-theme);
9+
10+
@include mat-using-mdc-theme($config) {
11+
.mat-mdc-optgroup-label {
12+
// Since this will usually be rendered in an overlay,
13+
// we have explicitly set the default color.
14+
@include mdc-theme-prop(color, text-primary-on-background);
15+
@include mdc-list-item-disabled-text-color($mdc-list-text-disabled-color,
16+
$query: $mat-theme-styles-query);
17+
}
18+
}
19+
}
20+
21+
@mixin mat-mdc-optgroup-typography($config-or-theme) {
22+
$config: mat-get-typography-config($config-or-theme);
23+
}
24+
25+
@mixin mat-mdc-optgroup-density($config-or-theme) {
26+
$density-scale: mat-get-density-config($config-or-theme);
27+
}
28+
29+
@mixin mat-mdc-optgroup-theme($theme-or-color-config) {
30+
$theme: _mat-legacy-get-theme($theme-or-color-config);
31+
@include _mat-check-duplicate-theme-styles($theme, 'mat-mdc-optgroup') {
32+
$color: mat-get-color-config($theme);
33+
$density: mat-get-density-config($theme);
34+
$typography: mat-get-typography-config($theme);
35+
36+
@if $color != null {
37+
@include mat-mdc-optgroup-color($color);
38+
}
39+
@if $density != null {
40+
@include mat-mdc-optgroup-density($density);
41+
}
42+
@if $typography != null {
43+
@include mat-mdc-optgroup-typography($typography);
44+
}
45+
}
46+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
@import '@material/list/mixins.import';
2+
@import '@material/list/variables.import';
3+
@import '@material/theme/functions.import';
4+
@import '../../mdc-helpers/mdc-helpers';
5+
@import '../../../material/core/theming/check-duplicate-styles';
6+
7+
@mixin mat-mdc-option-color($config-or-theme) {
8+
$config: mat-get-color-config($config-or-theme);
9+
10+
@include mat-using-mdc-theme($config) {
11+
.mat-mdc-option {
12+
// Since this will usually be rendered in an overlay,
13+
// we have explicitly set the default color.
14+
@include mdc-theme-prop(color, text-primary-on-background);
15+
@include mdc-list-item-disabled-text-color($mdc-list-text-disabled-color,
16+
$query: $mat-theme-styles-query);
17+
18+
&:hover:not(.mdc-list-item--disabled),
19+
&:focus:not(.mdc-list-item--disabled),
20+
&.mat-mdc-option-active,
21+
22+
// In multiple mode there is a checkbox to show that the option is selected.
23+
&.mdc-list-item--selected:not(.mat-mdc-option-multiple):not(.mdc-list-item--disabled) {
24+
$color: $mdc-theme-on-surface;
25+
background: rgba($color, mdc-states-opacity($color, hover));
26+
}
27+
}
28+
29+
.mat-primary .mat-mdc-option.mdc-list-item--selected:not(.mdc-list-item--disabled) {
30+
@include mdc-list-item-primary-text-ink-color(primary, $query: $mat-theme-styles-query);
31+
}
32+
33+
.mat-accent .mat-mdc-option.mdc-list-item--selected:not(.mdc-list-item--disabled) {
34+
@include mdc-list-item-primary-text-ink-color(secondary, $query: $mat-theme-styles-query);
35+
}
36+
37+
.mat-warn .mat-mdc-option.mdc-list-item--selected:not(.mdc-list-item--disabled) {
38+
@include mdc-list-item-primary-text-ink-color(error, $query: $mat-theme-styles-query);
39+
}
40+
}
41+
}
42+
43+
@mixin mat-mdc-option-typography($config-or-theme) {
44+
$config: mat-get-typography-config($config-or-theme);
45+
}
46+
47+
@mixin mat-mdc-option-density($config-or-theme) {
48+
$density-scale: mat-get-density-config($config-or-theme);
49+
}
50+
51+
@mixin mat-mdc-option-theme($theme-or-color-config) {
52+
$theme: _mat-legacy-get-theme($theme-or-color-config);
53+
@include _mat-check-duplicate-theme-styles($theme, 'mat-mdc-option') {
54+
$color: mat-get-color-config($theme);
55+
$density: mat-get-density-config($theme);
56+
$typography: mat-get-typography-config($theme);
57+
58+
@if $color != null {
59+
@include mat-mdc-option-color($color);
60+
}
61+
@if $density != null {
62+
@include mat-mdc-option-density($density);
63+
}
64+
@if $typography != null {
65+
@include mat-mdc-option-typography($typography);
66+
}
67+
}
68+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {NgModule} from '@angular/core';
10+
import {CommonModule} from '@angular/common';
11+
import {MatRippleModule, MatPseudoCheckboxModule} from '@angular/material/core';
12+
import {MatOption} from './option';
13+
import {MatOptgroup} from './optgroup';
14+
15+
16+
@NgModule({
17+
imports: [MatRippleModule, CommonModule, MatPseudoCheckboxModule],
18+
exports: [MatOption, MatOptgroup],
19+
declarations: [MatOption, MatOptgroup]
20+
})
21+
export class MatOptionModule {}
22+
23+
24+
export * from './option';
25+
export * from './optgroup';
26+
export {
27+
MatOptionSelectionChange,
28+
MatOptionParentComponent,
29+
MAT_OPTION_PARENT_COMPONENT,
30+
_countGroupLabelsBeforeOption,
31+
_getOptionScrollPosition
32+
} from '@angular/material/core';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<label
2+
class="mat-mdc-optgroup-label"
3+
[class.mdc-list-item--disabled]="disabled"
4+
[id]="_labelId">
5+
<span class="mdc-list-item__text">{{ label }} <ng-content></ng-content></span>
6+
</label>
7+
8+
<ng-content select="mat-option, ng-container"></ng-content>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@import '@material/list/mixins.import';
2+
@import '@material/list/variables.import';
3+
@import '../../mdc-helpers/mdc-helpers';
4+
5+
.mat-mdc-optgroup-label {
6+
@include mdc-list-item-base_;
7+
@include mdc-list-list-item-padding-variant(
8+
$mdc-list-textual-variant-config, $query: $mat-base-styles-query);
9+
@include mdc-list-list-item-height-variant(
10+
$mdc-list-textual-variant-config, $query: $mat-base-styles-query);
11+
@include mdc-list-item-disabled-text-opacity($mdc-list-text-disabled-opacity,
12+
$query: $mat-base-styles-query);
13+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Component, ViewEncapsulation, ChangeDetectionStrategy} from '@angular/core';
10+
import {_MatOptgroupBase} from '@angular/material/core';
11+
12+
13+
/**
14+
* Component that is used to group instances of `mat-option`.
15+
*/
16+
@Component({
17+
selector: 'mat-optgroup',
18+
exportAs: 'matOptgroup',
19+
templateUrl: 'optgroup.html',
20+
encapsulation: ViewEncapsulation.None,
21+
changeDetection: ChangeDetectionStrategy.OnPush,
22+
inputs: ['disabled'],
23+
styleUrls: ['optgroup.css'],
24+
host: {
25+
'class': 'mat-mdc-optgroup',
26+
'role': 'group',
27+
'[attr.aria-disabled]': 'disabled.toString()',
28+
'[attr.aria-labelledby]': '_labelId',
29+
}
30+
})
31+
export class MatOptgroup extends _MatOptgroupBase {
32+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<mat-pseudo-checkbox *ngIf="multiple" class="mat-mdc-option-pseudo-checkbox"
2+
[state]="selected ? 'checked' : 'unchecked'" [disabled]="disabled"></mat-pseudo-checkbox>
3+
4+
<span class="mdc-list-item__text"><ng-content></ng-content></span>
5+
6+
<div class="mat-mdc-option-ripple" mat-ripple
7+
[matRippleTrigger]="_getHostElement()"
8+
[matRippleDisabled]="disabled || disableRipple">
9+
</div>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
@import '@material/list/mixins.import';
2+
@import '@material/list/variables.import';
3+
@import '../../mdc-helpers/mdc-helpers';
4+
@import '../../../material/core/style/vendor-prefixes';
5+
@import '../../../cdk/a11y/a11y';
6+
7+
.mat-mdc-option {
8+
// Note that we include this private mixin, because the public
9+
// one adds a bunch of styles that we aren't using for the menu.
10+
@include mdc-list-item-base_;
11+
@include mdc-list-list-item-padding-variant(
12+
$mdc-list-textual-variant-config, $query: $mat-base-styles-query);
13+
@include mdc-list-list-item-height-variant(
14+
$mdc-list-textual-variant-config, $query: $mat-base-styles-query);
15+
@include mdc-list-item-disabled-text-opacity($mdc-list-text-disabled-opacity,
16+
$query: $mat-base-styles-query);
17+
@include user-select(none);
18+
19+
&:not(.mdc-list-item--disabled) {
20+
cursor: pointer;
21+
}
22+
23+
// Note that we bump the padding here, rather than padding inside the
24+
// group so that ripples still reach to the edges of the panel.
25+
.mat-mdc-optgroup &:not(.mat-mdc-option-multiple) {
26+
padding-left: $mdc-list-side-padding * 2;
27+
28+
[dir='rtl'] & {
29+
padding-left: $mdc-list-side-padding;
30+
padding-right: $mdc-list-side-padding * 2;
31+
}
32+
}
33+
34+
.mat-pseudo-checkbox {
35+
margin-right: $mdc-list-side-padding;
36+
37+
[dir='rtl'] & {
38+
margin-right: 0;
39+
margin-left: $mdc-list-side-padding;
40+
}
41+
}
42+
43+
// Increase specificity because ripple styles are part of the `mat-core` mixin and can
44+
// potentially overwrite the absolute position of the container.
45+
.mat-mdc-option-ripple {
46+
@include mat-fill;
47+
48+
// Disable pointer events for the ripple container because the container will overlay the
49+
// user content and we don't want to disable mouse events on the user content.
50+
// Pointer events can be safely disabled because the ripple trigger element is the host element.
51+
pointer-events: none;
52+
53+
// Prevents the ripple from completely covering the option in high contrast mode.
54+
@include cdk-high-contrast(active, off) {
55+
opacity: 0.5;
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)