Skip to content

Commit

Permalink
feat(theme): Add support for arbitrary CSS vars with fallback (#4470)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickrodee committed Mar 14, 2019
1 parent 44abbed commit 0bfb393
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 1 deletion.
32 changes: 32 additions & 0 deletions packages/mdc-theme/README.md
Expand Up @@ -110,6 +110,38 @@ Property Name | Description
`on-secondary` | A text/iconography color that is usable on top of secondary color
`on-surface` | A text/iconography color that is usable on top of surface color

#### `mdc-theme-prop` with CSS Custom Properties

> **Note** The Sass map `$style` argument is intended *only* for use with color mixins.
The `mdc-theme-prop` mixin also accepts a Sass map for the `$style` argument. The map must contain the following fields:

Fields | Description
--- | ---
`varname` | The name of a CSS custom property
`fallback` | A fallback value for the CSS custom property

For example, the following Sass...

```
.foo {
@include mdc-theme-prop(color, (
varname: --foo-color,
fallback: red,
));
}
```

...will produce the following CSS...

```
.foo {
color: red;
color: var(--foo-color, red);
}
```

The above output CSS will apply the `fallback` field's value for all supported browsers (including IE11) while allowing for CSS custom property use as a progressive enhancement. Browsers like IE11 that do not support CSS custom properties will apply the `color: red;` and ignore the `color: var(--foo-color, red);`. This argument type is intended for clients who need custom color application outside of the existing theme properties.

#### `mdc-theme-luminance($color)`

Expand Down
15 changes: 15 additions & 0 deletions packages/mdc-theme/_functions.scss
Expand Up @@ -64,3 +64,18 @@
@function mdc-theme-contrast-tone($color) {
@return if(mdc-theme-tone($color) == "dark", "light", "dark");
}

@function mdc-theme-is-var-with-fallback_($style) {
@return type-of($style) == "map" and map-has-key($style, "varname") and map-has-key($style, "fallback");
}

@function mdc-theme-get-var-fallback_($style) {
@return map-get($style, "fallback");
}

@function mdc-theme-var_($style) {
$var: map-get($style, "varname");
$fallback: mdc-theme-get-var-fallback_($style);

@return var(#{$var}, $fallback);
}
13 changes: 12 additions & 1 deletion packages/mdc-theme/_mixins.scss
Expand Up @@ -23,6 +23,7 @@
@import "@material/feature-targeting/functions";
@import "@material/feature-targeting/mixins";
@import "./variables";
@import "./functions";

@mixin mdc-theme-core-styles($query: mdc-feature-all()) {
$feat-color: mdc-feature-create-target($query, color);
Expand Down Expand Up @@ -67,7 +68,17 @@
// $edgeOptOut controls whether to feature-detect around Edge to avoid emitting CSS variables for it,
// intended for use in cases where interactions with pseudo-element styles cause problems due to Edge bugs.
@mixin mdc-theme-prop($property, $style, $important: false, $edgeOptOut: false) {
@if mdc-theme-is-valid-theme-prop-value_($style) {
@if mdc-theme-is-var-with-fallback_($style) {
@if $important {
#{$property}: mdc-theme-get-var-fallback_($style) !important;
/* @alternate */
#{$property}: mdc-theme-var_($style) !important;
} @else {
#{$property}: mdc-theme-get-var-fallback_($style);
/* @alternate */
#{$property}: mdc-theme-var_($style);
}
} @else if mdc-theme-is-valid-theme-prop-value_($style) {
@if $important {
#{$property}: $style !important;
} @else {
Expand Down
4 changes: 4 additions & 0 deletions packages/mdc-theme/_variables.scss
Expand Up @@ -129,6 +129,10 @@ $mdc-theme-property-values: (
//
// NOTE: This function must be defined in _variables.scss instead of _functions.scss to avoid circular imports.
@function mdc-theme-prop-value($style) {
@if mdc-theme-is-var-with-fallback_($style) {
@return mdc-theme-get-var-fallback_($style);
}

@if mdc-theme-is-valid-theme-prop-value_($style) {
@return $style;
}
Expand Down

0 comments on commit 0bfb393

Please sign in to comment.