From 0bfb393407727b9ad5e8de1e8dda6ea6a0ee21fd Mon Sep 17 00:00:00 2001 From: Patty RoDee Date: Thu, 14 Mar 2019 14:47:19 -0700 Subject: [PATCH] feat(theme): Add support for arbitrary CSS vars with fallback (#4470) --- packages/mdc-theme/README.md | 32 ++++++++++++++++++++++++++++++ packages/mdc-theme/_functions.scss | 15 ++++++++++++++ packages/mdc-theme/_mixins.scss | 13 +++++++++++- packages/mdc-theme/_variables.scss | 4 ++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/packages/mdc-theme/README.md b/packages/mdc-theme/README.md index 1a5ffa00d2a..4e5c96e277e 100644 --- a/packages/mdc-theme/README.md +++ b/packages/mdc-theme/README.md @@ -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)` diff --git a/packages/mdc-theme/_functions.scss b/packages/mdc-theme/_functions.scss index b2acd7a584c..93c67eaf333 100644 --- a/packages/mdc-theme/_functions.scss +++ b/packages/mdc-theme/_functions.scss @@ -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); +} diff --git a/packages/mdc-theme/_mixins.scss b/packages/mdc-theme/_mixins.scss index 7b4a1dbddd7..764192a8a6d 100644 --- a/packages/mdc-theme/_mixins.scss +++ b/packages/mdc-theme/_mixins.scss @@ -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); @@ -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 { diff --git a/packages/mdc-theme/_variables.scss b/packages/mdc-theme/_variables.scss index b7510c7be4b..1d7b25db47c 100644 --- a/packages/mdc-theme/_variables.scss +++ b/packages/mdc-theme/_variables.scss @@ -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; }