-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(elevation): move elevation rules into theme stylesheets #11344
Conversation
@benelliott are you saying this is only breaking when a theme is missing? If that's the case, it wouldn't be considered breaking because a theme has always been required. |
@jelbourn The situations I can think of are:
So yes I think so, unless there is a situation I'm not thinking of! |
src/lib/core/style/_elevation.scss
Outdated
@@ -151,6 +151,14 @@ $_mat-elevation-prefix: 'mat-elevation-z'; | |||
#{map-get(_get-ambient-map($color, $opacity), $zValue)}; | |||
} | |||
|
|||
@mixin mat-theme-elevation($zValue, $theme, $opacity: $mat-elevation-opacity) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new mixins need descriptions similar to the existing ones
src/lib/core/style/_elevation.scss
Outdated
@@ -151,6 +151,14 @@ $_mat-elevation-prefix: 'mat-elevation-z'; | |||
#{map-get(_get-ambient-map($color, $opacity), $zValue)}; | |||
} | |||
|
|||
@mixin mat-theme-elevation($zValue, $theme, $opacity: $mat-elevation-opacity) { | |||
$foreground: map-get($theme, foreground); | |||
$elevation-color: map-get($foreground, elevation); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typically the background and foreground palettes are fixed regardless of theme; how would you go about changing the color of the shadow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took the position that wanting to change the elevation color was a fairly advanced use case, so it would be admissible for it to be changed by providing angular-material-theme
with a fully custom theme map (as opposed to using the mat-light-theme
and mat-dark-theme
functions). This is what I do in a project where I want full control over the colors used in the app, however it has just occurred to me that it may not be part of the public API(?).
An alternative solution could be to provide it as an optional fourth argument to the mat-light-theme
and mat-dark-theme
functions (with default value black
), and then to convert the $mat-light-theme-foreground
and $mat-dark-theme-foreground
variables into functions that take the elevation color as their only argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@josephperrott and I took a closer look at this, and found that we're going to have some cases in Google where it will be more common to want to customize the shadow color based on the theme colors, so we probably want to make it more ergonomic to customize the shadow based on that.
We'd also want to avoid adding a lot of excess css to the theme so most people wouldn't end up using. I'm still thinking about a good way to approach it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jelbourn Perhaps the additional parameter to the theme
functions could be used instead?
An alternative way to avoid adding CSS to the themes could be to remove all internal usages of the mixins, and only to rely on the .mat-elevation-z?
classes for applying elevation to Material components. This approach would actually reduce the amount of CSS overall, as only the output of
@for $zValue from 0 through 24 {
.#{$_mat-elevation-prefix}#{$zValue} {
@include mat-theme-elevation($zValue, $theme);
}
}
would be rendered (component stylesheets would be smaller as they no longer include the box shadow rules).
Perhaps overridable elevation could then be implemented like this:
$_mat-overridable-elevation-prefix: 'mat-overridable-elevation-z';
@for $zValue from 0 through 24 {
.#{$_mat-overridable-elevation-prefix}#{$zValue}:not([class*='#{$_mat-elevation-prefix}']) {
@include mat-theme-elevation($zValue, $theme);
}
}
and the old mat-overridable-elevation
mixin would be deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of using the common set of css classes for everything. We would have to make sure they're still easily overridable, though.
I guess what this PR is really about is being able to customize the base shadow color, which makes sense to be in the foreground palette. If we want to set a shadow based on another palette, I don't see a way around explicitly passing the color in the component's theme file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it boils down to two approaches:
1) Extend the current elevation mixins to support themes, and move their usages to the theme stylesheets (as in the current PR).
Advantages:
- Code changes are minimal
- CSS size increase is negligible
Disadvantages:
- Moving elevation rules to the theme stylesheets means that everyone's CSS gets larger, regardless of whether they use those components
- Size of elevation CSS will increase linearly with the number of components added to the library
2) Incorporate the theme color into the mat-elevation-z*
CSS classes and only use these classes to apply elevation to components
Advantages:
- CSS size will not increase as components are introduced to the library
- CSS size may actually be reduced, as there is currently duplication from using the mixin in both the
mat-elevation-z
classes and the internal component stylesheets - Since elevation rules can only come from one set of classes, inspecting element elevation becomes simpler
Disadvantages:
- Components will now have to directly apply their own elevation rules in TypeScript. This is potentially a major refactor - for example,
MatButton
will have to applymat-elevation-z8
if it has themat-raised-button
attribute set. This logic in itself may be trivial but it would require a wave of new unit tests - Will probably have to remove the
$_mat-elevation-prefix
variable and just use the static string if elevation is applied statically as classes in component templates (alternately, could mirror this variable in TypeScript and only ever apply these classes in TypeScript within the library)
I'm happy to take a shot at the second option if you think it is more appropriate.
@crisbeto do you have any opinions on this? I would lean towards just making the elevation part of the theme solely because it's a simpler change |
Keeping it in the theme sounds good. My only nit is that, IMO, the new mixins should be made private (prefixed with an underscore) since I don't see them being particularly useful for consumers. |
Hi @benelliott! This PR has merge conflicts due to recent upstream merges. |
1 similar comment
Hi @benelliott! This PR has merge conflicts due to recent upstream merges. |
265c4d3
to
3a5a245
Compare
Rebased and added suggestion from @crisbeto. |
3a5a245
to
73bcbd1
Compare
@crisbeto Is there anything else you would like me to change before this can be merged? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Leaving the final say to @jelbourn.
I'm running a presubmit of this PR against Google apps to make sure it doesn't cause any breakages |
Cool, thanks. |
Hi @benelliott! This PR has merge conflicts due to recent upstream merges. |
@jelbourn what happened with the presubmit on this one, should we mark lgtm, merge-ready? |
Presubmit was black across the board, need to update some build files for another pass |
73bcbd1
to
89fe6d3
Compare
Hi @jelbourn, I've just rebased to resolve the conflicts. Is black good or bad for a presubmit? |
@benelliott I've changed all of the internal components to only use elevation in their theme files, if you rebase I'll take another stab at getting this in |
357e85b
to
a05cf07
Compare
@mmalerba Nice - rebased. Not sure why ngbot didn't ping me about the conflicts this time round. |
Hi @benelliott! This PR has merge conflicts due to recent upstream merges. |
a42b68a
to
6d1818d
Compare
src/lib/button/_button-base.scss
Outdated
&:not([disabled]):active { | ||
@include mat-overridable-elevation(8); | ||
} | ||
|
||
&[disabled] { | ||
box-shadow: none; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to move to the theme too, I'm seeing screenshots with disabled buttons that have shadows (this is basically the equivalent of mat-elevation(0)
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
card has a similar one that should go into the theme file:
&.mat-card-flat {
box-shadow: none;
}
Move all usages of elevation mixins out of component stylesheets and into their respective themes. This allows the elevation color to be changed based on the theme. Add new `mat-theme-elevation` and `mat-theme-overridable-elevation` shorthand mixins to apply the current theme's elevation color. Replace all usages of `mat-elevation` mixins with themed equivalents. Add `elevation` property to the default `foreground` theme palettes. Closes angular#11343 BREAKING CHANGE: Because `mat-elevation` usages have been moved out of component stylesheets, users who have not invoked a theme mixin will not see any elevation shadows on Material components. However, users that have created a custom theme which lacks the `elevation` property will still see the default black shadows. Additionally, users who want to use themed elevations in their custom components can create their own shorthand mixin: ``` @import '~angular/material/theming'; $myTheme: ... @mixin my-elevation($zValue) { @include mat-theme-elevation($zValue, $myTheme); } ``` and then invoke `angular-material-theme` with the `$myTheme` variable.
6d1818d
to
995957c
Compare
Hi @mmalerba, I've addressed your comments + rebased + given the flat card and disabled buttons a quick once-over on the demo app. I decided to use elevation 0 instead of |
🎉🎉🎉 |
* Currently if chips are disabled with the spec 2018 alignment, it's not clear whether a chip is disabled or not. The chip still has a focus effect, hover effect and pointer cursor for the `mat-chip-remove`. * Also moves the `@include mat-elevation` to the theme (probably introduced before: angular#11344 has been merged)
* Fixes a remaining elevation style which is not created inside of the theme. (related to: angular#11344)
* Currently if chips are disabled with the spec 2018 alignment, it's not clear whether a chip is disabled or not. The chip still has a focus effect, hover effect and pointer cursor for the `mat-chip-remove`. * Also moves the `@include mat-elevation` to the theme (probably introduced before: angular#11344 has been merged)
Fixes a remaining elevation style which is not created inside of the theme. (related to: #11344)
Fixes a remaining elevation style which is not created inside of the theme. (related to: angular#11344)
* Currently if chips are disabled with the spec 2018 alignment, it's not clear whether a chip is disabled or not. The chip still has a focus effect, hover effect and pointer cursor for the `mat-chip-remove`. * Also moves the `@include mat-elevation` to the theme (probably introduced before: #11344 has been merged)
* Currently if chips are disabled with the spec 2018 alignment, it's not clear whether a chip is disabled or not. The chip still has a focus effect, hover effect and pointer cursor for the `mat-chip-remove`. * Also moves the `@include mat-elevation` to the theme (probably introduced before: angular#11344 has been merged)
* Currently if chips are disabled with the spec 2018 alignment, it's not clear whether a chip is disabled or not. The chip still has a focus effect, hover effect and pointer cursor for the `mat-chip-remove`. * Also moves the `@include mat-elevation` to the theme (probably introduced before: angular#11344 has been merged)
* Currently if chips are disabled with the spec 2018 alignment, it's not clear whether a chip is disabled or not. The chip still has a focus effect, hover effect and pointer cursor for the `mat-chip-remove`. * Also moves the `@include mat-elevation` to the theme (probably introduced before: #11344 has been merged)
* Currently if chips are disabled with the spec 2018 alignment, it's not clear whether a chip is disabled or not. The chip still has a focus effect, hover effect and pointer cursor for the `mat-chip-remove`. * Also moves the `@include mat-elevation` to the theme (probably introduced before: #11344 has been merged)
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Move all usages of elevation mixins out of component stylesheets and into their respective themes.
This allows the elevation color to be changed based on the theme. Add new
mat-theme-elevation
and
mat-theme-overridable-elevation
shorthand mixins to apply the current theme's elevationcolor. Replace all usages of
mat-elevation
mixins with themed equivalents. Addelevation
property to the default
foreground
theme palettes.Closes #11343
BREAKING CHANGE:
Because
mat-elevation
usages have been moved out of component stylesheets, users who havenot invoked a theme mixin will not see any elevation shadows on Material components.
However, users that have created a custom theme which lacks the
elevation
property willstill see the default black shadows.
Additionally, users who want to use themed elevations in their custom components can create
their own shorthand mixin:
and then invoke
angular-material-theme
with the$myTheme
variable.