Skip to content

Commit f1409d4

Browse files
devversionandrewseguin
authored andcommitted
refactor(material): add density styles for components without MDC equivalents
This commit adds density styles for all Angular Material components that do not have an equivalent MDC version. The density API for those components is not public yet. refactor: expose mdc-density styles in material/core We need to be able to access the MDC-density styles in `@angular/material` in order to provide density styles for components which do not have a MDC equivalent. feat(material/button-toggle): support density scaling feat(material/list): support for density scaling feat(material/paginator): add support for density scaling feat(material/stepper): support for density scaling Adds support for density scaling. feat(material/toolbar): add support for density scaling feat(material/tree): support for density scaling refactor: prefix copied mdc-density helpers with underscore * Prefixes all helper functions that have been copied from `mdc-density` with an underscore. This should ensure that developers do not consider these as public API. * Removes the license from MDC web. The code has been changed enough so that a license is most likely not needed anymore. Additionally, this is just a transfer from another Google-owned repository.
1 parent 3bcdc5e commit f1409d4

27 files changed

+296
-79
lines changed

src/dev-app/stepper/stepper-demo.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<mat-checkbox [(ngModel)]="isNonLinear">Disable linear mode</mat-checkbox>
22
<mat-checkbox [(ngModel)]="disableRipple">Disable header ripple</mat-checkbox>
3+
<p>
4+
<button mat-stroked-button (click)="showLabelBottom = !showLabelBottom">
5+
Toggle label position
6+
</button>
7+
</p>
38

49
<h3>Linear Vertical Stepper Demo using a single form</h3>
510
<form [formGroup]="formGroup">
@@ -52,7 +57,8 @@ <h3>Linear Vertical Stepper Demo using a single form</h3>
5257

5358
<h3>Linear Horizontal Stepper Demo using a different form for each step</h3>
5459
<mat-horizontal-stepper #linearHorizontalStepper="matHorizontalStepper" [linear]="!isNonLinear"
55-
[disableRipple]="disableRipple">
60+
[disableRipple]="disableRipple"
61+
[labelPosition]="showLabelBottom ? 'bottom' : 'end'">
5662
<mat-step [stepControl]="nameFormGroup">
5763
<form [formGroup]="nameFormGroup">
5864
<ng-template matStepLabel>Fill out your name</ng-template>

src/dev-app/stepper/stepper-demo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export class StepperDemo implements OnInit {
1919
isNonLinear = false;
2020
isNonEditable = false;
2121
disableRipple = false;
22+
showLabelBottom = false;
2223

2324
nameFormGroup: FormGroup;
2425
emailFormGroup: FormGroup;

src/material-experimental/mdc-list/_list-theme.scss

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import '@material/density/functions.import';
2+
@import '@material/list/variables.import';
13
@import '@material/list/mixins.import';
24
@import '@material/ripple/variables.import';
35
@import '../mdc-helpers/mdc-helpers';
@@ -35,7 +37,21 @@
3537
}
3638
}
3739

38-
@mixin mat-mdc-list-density($density-scale) {}
40+
@mixin mat-mdc-list-density($density-scale) {
41+
$height: mdc-density-prop-value(
42+
$density-config: $mdc-list-single-line-density-config,
43+
$density-scale: $density-scale,
44+
$property-name: height,
45+
);
46+
47+
// MDC list provides a mixin called `mdc-list-single-line-density`, but we cannot use
48+
// that mixin the generated generated density styles are scoped to `.mdc-list-item`, while
49+
// the styles should actually only affect single-line list items. This has been reported as
50+
// a bug in the MDC repository: https://github.com/material-components/material-components-web/issues/5737.
51+
.mat-mdc-list-item-single-line {
52+
@include mdc-list-single-line-height($height);
53+
}
54+
}
3955

4056
@mixin mat-mdc-list-theme($theme) {
4157
$color: mat-get-color-config($theme);

src/material-experimental/mdc-list/list-base.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
7676
this._ngZone.runOutsideAngular(() => {
7777
this._subscriptions.add(this.lines.changes.pipe(startWith(this.lines))
7878
.subscribe((lines: QueryList<ElementRef<Element>>) => {
79+
this._element.nativeElement.classList
80+
.toggle('mat-mdc-list-item-single-line', lines.length <= 1);
7981
lines.forEach((line: ElementRef<Element>, index: number) => {
8082
toggleClass(line.nativeElement,
8183
'mdc-list-item__primary-text', index === 0 && lines.length > 1);

src/material/button-toggle/BUILD.bazel

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ ng_module(
3333
sass_library(
3434
name = "button_toggle_scss_lib",
3535
srcs = glob(["**/_*.scss"]),
36-
deps = ["//src/material/core:core_scss_lib"],
36+
deps = [
37+
"//src/cdk/a11y:a11y_scss_lib",
38+
"//src/material/core:core_scss_lib",
39+
],
3740
)
3841

3942
sass_binary(

src/material/button-toggle/_button-toggle-theme.scss

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
@import '../../cdk/a11y/a11y';
12
@import '../core/style/elevation';
23
@import '../core/theming/palette';
34
@import '../core/theming/theming';
45
@import '../core/typography/typography-utils';
6+
@import '../core/density/index';
7+
@import './button-toggle-variables';
58

69
@mixin mat-button-toggle-color($config) {
710
$foreground: map-get($config, foreground);
@@ -86,7 +89,21 @@
8689
}
8790
}
8891

89-
@mixin _mat-button-toggle-density($density-scale) {}
92+
@mixin _mat-button-toggle-density($density-scale) {
93+
$standard-height: _mat-density-prop-value(
94+
$mat-button-toggle-standard-density-config, $density-scale, height);
95+
96+
.mat-button-toggle-appearance-standard .mat-button-toggle-label-content {
97+
line-height: $standard-height;
98+
}
99+
100+
@include cdk-high-contrast(active, off) {
101+
.mat-button-toggle-checked.mat-button-toggle-appearance-standard
102+
.mat-button-toggle-focus-overlay {
103+
border-bottom: solid $standard-height;
104+
}
105+
}
106+
}
90107

91108
@mixin mat-button-toggle-theme($theme) {
92109
$color: mat-get-color-config($theme);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
$mat-button-toggle-standard-height: 48px !default;
2+
// Minimum height for highest density can vary based on the content that developers
3+
// project into button-toggle's. We use a minimum of `24px` though because commonly
4+
// icons or text are displayed. Icons by default have a size of `24px`.
5+
$mat-button-toggle-standard-minimum-height: 24px !default;
6+
$mat-button-toggle-standard-maximum-height: $mat-button-toggle-standard-height !default;
7+
8+
$mat-button-toggle-standard-density-config: (
9+
height: (
10+
default: $mat-button-toggle-standard-height,
11+
maximum: $mat-button-toggle-standard-maximum-height,
12+
minimum: $mat-button-toggle-standard-minimum-height,
13+
)
14+
) !default;

src/material/button-toggle/button-toggle.scss

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
@import '../../cdk/a11y/a11y';
44

55
$mat-button-toggle-standard-padding: 0 12px !default;
6-
$mat-button-toggle-standard-height: 48px !default;
76
$mat-button-toggle-standard-border-radius: 4px !default;
87

98
$mat-button-toggle-legacy-padding: 0 16px !default;
@@ -104,7 +103,6 @@ $mat-button-toggle-legacy-border-radius: 2px !default;
104103
position: relative;
105104

106105
.mat-button-toggle-appearance-standard & {
107-
line-height: $mat-button-toggle-standard-height;
108106
padding: $mat-button-toggle-standard-padding;
109107
}
110108
}
@@ -135,14 +133,6 @@ $mat-button-toggle-legacy-border-radius: 2px !default;
135133
}
136134
}
137135

138-
@include cdk-high-contrast(active, off) {
139-
.mat-button-toggle-checked {
140-
&.mat-button-toggle-appearance-standard .mat-button-toggle-focus-overlay {
141-
border-bottom: solid $mat-button-toggle-standard-height;
142-
}
143-
}
144-
}
145-
146136
// Increase specificity because ripple styles are part of the `mat-core` mixin and can
147137
// potentially overwrite the absolute position of the container.
148138
.mat-button-toggle .mat-button-toggle-ripple {

src/material/core/density/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Density Sass functions and mixins have been extracted from `@material/density`. We do this to
2+
avoid adding a new dependency to `@angular/material` until we figured out how dependencies on
3+
MDC are managed.

src/material/core/density/_index.scss

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Taken from mat-density with small modifications to not rely on the new Sass module system.
2+
// https://github.com/material-components/material-components-web/blob/master/packages/mdc-density
3+
4+
$_mat-density-interval: 4px !default;
5+
$_mat-density-minimum-scale: minimum !default;
6+
$_mat-density-maximum-scale: maximum !default;
7+
$_mat-density-supported-scales: (default, minimum, maximum) !default;
8+
$_mat-density-supported-properties: (height, size) !default;
9+
$_mat-density-default-scale: 0 !default;
10+
11+
@function _mat-density-prop-value($density-config, $density-scale, $property-name) {
12+
@if (type-of($density-scale) == 'string' and
13+
index($list: $_mat-density-supported-scales, $value: $density-scale) == null) {
14+
@error 'mat-density: Supported density scales #{$_mat-density-supported-scales}, ' +
15+
'but received #{$density-scale}.';
16+
}
17+
18+
@if (index($list: $_mat-density-supported-properties, $value: $property-name) == null) {
19+
@error 'mat-density: Supported density properties #{$_mat-density-supported-properties},' +
20+
'but received #{$property-name}.';
21+
}
22+
23+
$value: null;
24+
$property-scale-map: map_get($density-config, $property-name);
25+
26+
@if map_has_key($property-scale-map, $density-scale) {
27+
$value: map_get($property-scale-map, $density-scale);
28+
}
29+
@else {
30+
$value: map_get($property-scale-map, default) + $density-scale * $_mat-density-interval;
31+
}
32+
33+
$min-value: map_get($property-scale-map, $_mat-density-minimum-scale);
34+
$max-value: map_get($property-scale-map, $_mat-density-maximum-scale);
35+
36+
@if ($value < $min-value or $value > $max-value) {
37+
@error 'mat-density: #{$property-name} must be between #{$min-value} and ' +
38+
'#{$max-value} (inclusive), but received #{$value}.';
39+
}
40+
41+
@return $value;
42+
}

src/material/paginator/BUILD.bazel

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ ng_module(
3434
sass_library(
3535
name = "paginator_scss_lib",
3636
srcs = glob(["**/_*.scss"]),
37-
deps = ["//src/material/core:core_scss_lib"],
37+
deps = [
38+
"//src/material/core:core_scss_lib",
39+
],
3840
)
3941

4042
sass_binary(

src/material/paginator/_paginator-theme.scss

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
@import '../core/theming/palette';
22
@import '../core/theming/theming';
33
@import '../core/typography/typography-utils';
4-
4+
@import '../core/density/index';
5+
@import './paginator-variables';
56

67
@mixin mat-paginator-color($config) {
78
$foreground: map-get($config, foreground);
@@ -47,7 +48,12 @@
4748
}
4849
}
4950

50-
@mixin _mat-paginator-density($density-scale) {}
51+
@mixin _mat-paginator-density($density-scale) {
52+
$height: _mat-density-prop-value($mat-paginator-density-config, $density-scale, height);
53+
.mat-paginator-container {
54+
min-height: $height;
55+
}
56+
}
5157

5258
@mixin mat-paginator-theme($theme) {
5359
$color: mat-get-color-config($theme);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
$mat-paginator-height: 56px !default;
2+
// Minimum height for paginator's in the highest density is determined based on how
3+
// much the paginator can shrink until the content exceeds (i.e. navigation buttons).
4+
$mat-paginator-minimum-height: 40px !default;
5+
$mat-paginator-maximum-height: $mat-paginator-height !default;
6+
7+
$mat-paginator-density-config: (
8+
height: (
9+
default: $mat-paginator-height,
10+
maximum: $mat-paginator-maximum-height,
11+
minimum: $mat-paginator-minimum-height,
12+
)
13+
) !default;

src/material/paginator/paginator.scss

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
$mat-paginator-height: 56px;
21
$mat-paginator-padding: 0 8px;
3-
42
$mat-paginator-page-size-margin-right: 8px;
53

64
$mat-paginator-items-per-page-label-margin: 0 4px;
75
$mat-paginator-selector-margin: 6px 4px 0 4px;
86
$mat-paginator-selector-trigger-width: 56px;
97
$mat-paginator-selector-trigger-outline-width: 64px;
108
$mat-paginator-selector-trigger-fill-width: 64px;
9+
1110
$mat-paginator-range-label-margin: 0 32px 0 24px;
11+
$mat-paginator-button-icon-size: 28px;
1212

1313
.mat-paginator {
1414
display: block;
@@ -24,7 +24,6 @@ $mat-paginator-range-label-margin: 0 32px 0 24px;
2424
display: flex;
2525
align-items: center;
2626
justify-content: flex-end;
27-
min-height: $mat-paginator-height;
2827
padding: $mat-paginator-padding;
2928
flex-wrap: wrap-reverse;
3029
width: 100%;
@@ -68,7 +67,7 @@ $mat-paginator-range-label-margin: 0 32px 0 24px;
6867
}
6968

7069
.mat-paginator-icon {
71-
width: $mat-paginator-height / 2;
70+
width: $mat-paginator-button-icon-size;
7271
fill: currentColor;
7372

7473
[dir='rtl'] & {

src/material/stepper/BUILD.bazel

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,27 @@ ng_module(
4242
sass_library(
4343
name = "stepper_scss_lib",
4444
srcs = glob(["**/_*.scss"]),
45-
deps = ["//src/material/core:core_scss_lib"],
45+
deps = [
46+
"//src/material/core:core_scss_lib",
47+
],
4648
)
4749

4850
sass_binary(
4951
name = "stepper_scss",
5052
src = "stepper.scss",
51-
deps = ["//src/material/core:core_scss_lib"],
53+
deps = [
54+
":stepper_scss_lib",
55+
"//src/material/core:core_scss_lib",
56+
],
5257
)
5358

5459
sass_binary(
5560
name = "step_header_scss",
5661
src = "step-header.scss",
57-
deps = ["//src/material/core:core_scss_lib"],
62+
deps = [
63+
":stepper_scss_lib",
64+
"//src/material/core:core_scss_lib",
65+
],
5866
)
5967

6068
ng_test_library(

src/material/stepper/_stepper-theme.scss

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
@import '../core/theming/palette';
22
@import '../core/theming/theming';
33
@import '../core/typography/typography-utils';
4+
@import '../core/density/index';
5+
@import './stepper-variables';
46

57
@mixin mat-stepper-color($config) {
68
$foreground: map-get($config, foreground);
@@ -102,7 +104,38 @@
102104
}
103105
}
104106

105-
@mixin _mat-stepper-density($density-scale) {}
107+
@mixin _mat-stepper-density($density-scale) {
108+
$height: _mat-density-prop-value($mat-stepper-density-config, $density-scale, height);
109+
$vertical-padding: ($height - $mat-stepper-label-header-height) / 2;
110+
111+
.mat-horizontal-stepper-header {
112+
height: $height;
113+
}
114+
115+
.mat-stepper-label-position-bottom .mat-horizontal-stepper-header,
116+
.mat-vertical-stepper-header, {
117+
padding: $vertical-padding $mat-stepper-side-gap;
118+
}
119+
120+
// Ensures that the vertical lines for the step content exceed into the step
121+
// headers with a given distance (`$mat-stepper-line-gap`) to the step icon.
122+
.mat-stepper-vertical-line::before {
123+
top: $mat-stepper-line-gap - $vertical-padding;
124+
bottom: $mat-stepper-line-gap - $vertical-padding;
125+
}
126+
127+
// Ensures that the horizontal lines for the step header are centered vertically.
128+
.mat-stepper-label-position-bottom .mat-horizontal-stepper-header {
129+
&::after, &::before {
130+
top: $vertical-padding + $mat-stepper-label-header-height / 2;
131+
}
132+
}
133+
134+
// Ensures that the horizontal line for the step content is aligned centered vertically.
135+
.mat-stepper-label-position-bottom .mat-stepper-horizontal-line {
136+
top: $vertical-padding + $mat-stepper-label-header-height / 2;
137+
}
138+
}
106139

107140
@mixin mat-stepper-theme($theme) {
108141
$color: mat-get-color-config($theme);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
$mat-stepper-header-height: 72px !default;
2+
// Minimum height for highest density stepper's is determined based on how much
3+
// stepper headers can shrink until the step icon or step label exceed. We can't use
4+
// a value below `42px` because the optional label for steps would otherwise exceed.
5+
$mat-stepper-header-minimum-height: 42px !default;
6+
$mat-stepper-header-maximum-height: $mat-stepper-header-height !default;
7+
8+
$mat-stepper-density-config: (
9+
height: (
10+
default: $mat-stepper-header-height,
11+
maximum: $mat-stepper-header-maximum-height,
12+
minimum: $mat-stepper-header-minimum-height,
13+
)
14+
) !default;
15+
16+
// Note: These variables are not denoted with `!default` because they are used in the non-theme
17+
// component styles. Modifying these variables does not have the desired effect for consumers.
18+
$mat-stepper-label-header-height: 24px;
19+
$mat-stepper-label-position-bottom-top-gap: 16px;
20+
$mat-stepper-label-min-width: 50px;
21+
22+
$mat-vertical-stepper-content-margin: 36px;
23+
24+
$mat-stepper-side-gap: 24px;
25+
$mat-stepper-line-width: 1px;
26+
$mat-stepper-line-gap: 8px;
27+
28+
$mat-step-sub-label-font-size: 12px;
29+
$mat-step-header-icon-size: 16px;

0 commit comments

Comments
 (0)