diff --git a/packages/mdc-switch/_mixins.scss b/packages/mdc-switch/_mixins.scss index 8cecbd6a711..e1833c0b936 100644 --- a/packages/mdc-switch/_mixins.scss +++ b/packages/mdc-switch/_mixins.scss @@ -23,56 +23,285 @@ @import "@material/theme/mixins"; @import "@material/ripple/mixins"; @import "@material/rtl/mixins"; +@import "@material/elevation/mixins"; +@import "@material/feature-targeting/functions"; +@import "@material/feature-targeting/mixins"; +@import "./functions"; @import "./variables"; -@mixin mdc-switch-toggled-on-color($color) { - @include mdc-switch-toggled-on-track-color($color); - @include mdc-switch-toggled-on-thumb-color($color); - @include mdc-switch-toggled-on-ripple-color($color); +// +// Public +// + +@mixin mdc-switch($query: mdc-feature-all()) { + // postcss-bem-linter: define switch + + $feat-animation: mdc-feature-create-target($query, animation); + $feat-structure: mdc-feature-create-target($query, structure); + + @include mdc-ripple-common($query); + + .mdc-switch { + @include mdc-feature-targets($feat-structure) { + @include mdc-switch-base_; + } + + @include mdc-switch-toggled-on-track-color($mdc-switch-baseline-theme-color, $query); + @include mdc-switch-toggled-on-thumb-color($mdc-switch-baseline-theme-color, $query); + @include mdc-switch-toggled-off-track-color($mdc-switch-toggled-off-track-color, $query); + @include mdc-switch-toggled-off-thumb-color($mdc-switch-toggled-off-thumb-color, $query); + @include mdc-switch-toggled-off-ripple-color($mdc-switch-toggled-off-ripple-color, $query); + } + + .mdc-switch__native-control { + @include mdc-feature-targets($feat-structure) { + @include mdc-switch__native-control_; + } + } + + .mdc-switch__track { + @include mdc-switch__track_($query); + } + + .mdc-switch__thumb-underlay { + @include mdc-switch__thumb-underlay_($query); + } + + .mdc-switch__thumb { + @include mdc-switch__thumb_($query); + } + + .mdc-switch--checked { + @include mdc-feature-targets($feat-structure) { + .mdc-switch__track { + @include mdc-switch__track-checked_; + } + + .mdc-switch__thumb-underlay { + @include mdc-switch__thumb-underlay-checked_; + } + + .mdc-switch__native-control { + @include mdc-switch__native-control-checked_; + } + } + } + + .mdc-switch--disabled { + @include mdc-feature-targets($feat-structure) { + @include mdc-switch--disabled-base_; + + .mdc-switch__thumb { + @include mdc-switch__thumb-disabled_; + } + + .mdc-switch__native-control { + @include mdc-switch__native-control-disabled_; + } + } + } + + // postcss-bem-linter: end +} + +@mixin mdc-switch-toggled-on-color($color, $query: mdc-feature-all()) { + @include mdc-switch-toggled-on-track-color($color, $query); + @include mdc-switch-toggled-on-thumb-color($color, $query); + @include mdc-switch-toggled-on-ripple-color($color, $query); } -@mixin mdc-switch-toggled-off-color($color) { - @include mdc-switch-toggled-off-track-color($color); - @include mdc-switch-toggled-off-thumb-color($color); - @include mdc-switch-toggled-off-ripple-color($color); +@mixin mdc-switch-toggled-off-color($color, $query: mdc-feature-all()) { + @include mdc-switch-toggled-off-track-color($color, $query); + @include mdc-switch-toggled-off-thumb-color($color, $query); + @include mdc-switch-toggled-off-ripple-color($color, $query); } -@mixin mdc-switch-toggled-on-track-color($color) { +@mixin mdc-switch-toggled-on-track-color($color, $query: mdc-feature-all()) { + $feat-color: mdc-feature-create-target($query, color); + &.mdc-switch--checked .mdc-switch__track { - @include mdc-theme-prop(background-color, $color); - @include mdc-theme-prop(border-color, $color); + @include mdc-feature-targets($feat-color) { + @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); + } } } -@mixin mdc-switch-toggled-on-thumb-color($color) { +@mixin mdc-switch-toggled-on-thumb-color($color, $query: mdc-feature-all()) { + $feat-color: mdc-feature-create-target($query, color); + &.mdc-switch--checked .mdc-switch__thumb { - @include mdc-theme-prop(background-color, $color); - @include mdc-theme-prop(border-color, $color); + @include mdc-feature-targets($feat-color) { + @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); + } } } -@mixin mdc-switch-toggled-on-ripple-color($color) { +@mixin mdc-switch-toggled-on-ripple-color($color, $query: mdc-feature-all()) { &.mdc-switch--checked .mdc-switch__thumb-underlay { - @include mdc-states($color); + @include mdc-states($color, false, $query); } } -@mixin mdc-switch-toggled-off-track-color($color) { +@mixin mdc-switch-toggled-off-track-color($color, $query: mdc-feature-all()) { + $feat-color: mdc-feature-create-target($query, color); + &:not(.mdc-switch--checked) .mdc-switch__track { - @include mdc-theme-prop(background-color, $color); - @include mdc-theme-prop(border-color, $color); + @include mdc-feature-targets($feat-color) { + @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); + } } } -@mixin mdc-switch-toggled-off-thumb-color($color) { +@mixin mdc-switch-toggled-off-thumb-color($color, $query: mdc-feature-all()) { + $feat-color: mdc-feature-create-target($query, color); + &:not(.mdc-switch--checked) .mdc-switch__thumb { - @include mdc-theme-prop(background-color, $color); - @include mdc-theme-prop(border-color, $color); + @include mdc-feature-targets($feat-color) { + @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); + } } } -@mixin mdc-switch-toggled-off-ripple-color($color) { +@mixin mdc-switch-toggled-off-ripple-color($color, $query: mdc-feature-all()) { &:not(.mdc-switch--checked) .mdc-switch__thumb-underlay { - @include mdc-states($color); + @include mdc-states($color, false, $query); + } +} + +// +// Private +// + +// Structure +@mixin mdc-switch-base_ { + display: inline-block; + position: relative; + outline: none; + user-select: none; +} + +@mixin mdc-switch__track_($query: mdc-feature-all()) { + $feat-animation: mdc-feature-create-target($query, animation); + $feat-structure: mdc-feature-create-target($query, structure); + + @include mdc-feature-targets($feat-structure) { + box-sizing: border-box; + width: $mdc-switch-track-width; + height: $mdc-switch-track-height; + border: 1px solid; + border-radius: $mdc-switch-track-height / 2; + opacity: .38; + } + + @include mdc-feature-targets($feat-animation) { + transition: + mdc-switch-transition(opacity), + mdc-switch-transition(background-color), + mdc-switch-transition(border-color); + } +} + +@mixin mdc-switch__thumb-underlay_($query: mdc-feature-all()) { + $feat-animation: mdc-feature-create-target($query, animation); + $feat-color: mdc-feature-create-target($query, color); + $feat-structure: mdc-feature-create-target($query, structure); + + @include mdc-ripple-surface($query); + @include mdc-ripple-radius-unbounded(100%, $query); + @include mdc-states($mdc-switch-baseline-theme-color, false, $query); + + @include mdc-feature-targets($feat-structure) { + @include mdc-rtl-reflexive-position(left, $mdc-switch-tap-target-initial-position); + + display: flex; + position: absolute; + // Ensures the knob is centered on the track. + top: -(($mdc-switch-tap-target-size - $mdc-switch-track-height) / 2); + align-items: center; + justify-content: center; + width: $mdc-switch-tap-target-size; + height: $mdc-switch-tap-target-size; + transform: translateX(0); + } + + @include mdc-feature-targets($feat-animation) { + transition: + mdc-switch-transition(transform), + mdc-switch-transition(background-color), + mdc-switch-transition(border-color); + } +} + +@mixin mdc-switch__native-control_ { + @include mdc-rtl-reflexive-position(left, 0); + + position: absolute; + top: 0; + width: $mdc-switch-native-control-width; + height: $mdc-switch-tap-target-size; + margin: 0; + opacity: 0; + cursor: pointer; + pointer-events: auto; +} + +@mixin mdc-switch__thumb_($query: mdc-feature-all()) { + $feat-structure: mdc-feature-create-target($query, structure); + $feat-color: mdc-feature-create-target($query, color); + + @include mdc-elevation($z-value: 2, $query: $query); + + @include mdc-feature-targets($feat-structure) { + box-sizing: border-box; + width: $mdc-switch-thumb-diameter; + height: $mdc-switch-thumb-diameter; + border: $mdc-switch-thumb-diameter / 2 solid; + border-radius: 50%; + // Allow events to go through to the native control, necessary for IE and Edge. + pointer-events: none; + z-index: 1; + } +} + +// Checked state + +@mixin mdc-switch__track-checked_ { + opacity: .54; +} + +@mixin mdc-switch__thumb-underlay-checked_ { + transform: translateX($mdc-switch-thumb-active-margin); + + @include mdc-rtl { + transform: translateX(-($mdc-switch-thumb-active-margin)); } } + +@mixin mdc-switch__native-control-checked_ { + // Translate the native control the opposite direction so that the tap target stays the same. + transform: translateX(-($mdc-switch-thumb-active-margin)); + + @include mdc-rtl { + transform: translateX($mdc-switch-thumb-active-margin); + } +} + +// Disabled state + +@mixin mdc-switch--disabled-base_ { + opacity: .38; + pointer-events: none; +} + +@mixin mdc-switch__thumb-disabled_ { + border-width: 1px; // In high contrast mode, only show outline of knob. +} + +@mixin mdc-switch__native-control-disabled_ { + cursor: default; + pointer-events: none; +} diff --git a/packages/mdc-switch/mdc-switch.scss b/packages/mdc-switch/mdc-switch.scss index d2e99dccaa4..9d23d9f2fe0 100644 --- a/packages/mdc-switch/mdc-switch.scss +++ b/packages/mdc-switch/mdc-switch.scss @@ -20,120 +20,5 @@ // THE SOFTWARE. // -@import "@material/elevation/mixins"; -@import "@material/rtl/mixins"; -@import "@material/ripple/common"; -@import "@material/ripple/mixins"; -@import "./functions"; @import "./mixins"; -@import "./variables"; - -.mdc-switch { - @include mdc-switch-toggled-on-track-color($mdc-switch-baseline-theme-color); - @include mdc-switch-toggled-on-thumb-color($mdc-switch-baseline-theme-color); - @include mdc-switch-toggled-off-track-color($mdc-switch-toggled-off-track-color); - @include mdc-switch-toggled-off-thumb-color($mdc-switch-toggled-off-thumb-color); - @include mdc-switch-toggled-off-ripple-color($mdc-switch-toggled-off-ripple-color); - - display: inline-block; - position: relative; - outline: none; - user-select: none; -} - -.mdc-switch__native-control { - @include mdc-rtl-reflexive-position(left, 0); - - position: absolute; - top: 0; - width: $mdc-switch-native-control-width; - height: $mdc-switch-tap-target-size; - margin: 0; - opacity: 0; - cursor: pointer; - pointer-events: auto; -} - -.mdc-switch__track { - box-sizing: border-box; - width: $mdc-switch-track-width; - height: $mdc-switch-track-height; - transition: - mdc-switch-transition(opacity), - mdc-switch-transition(background-color), - mdc-switch-transition(border-color); - border: 1px solid; - border-radius: $mdc-switch-track-height / 2; - opacity: .38; -} - -.mdc-switch__thumb-underlay { - @include mdc-rtl-reflexive-position(left, $mdc-switch-tap-target-initial-position); - @include mdc-ripple-surface(); - @include mdc-ripple-radius-unbounded; - @include mdc-states($mdc-switch-baseline-theme-color); - - display: flex; - position: absolute; - // Ensures the knob is centered on the track. - top: -(($mdc-switch-tap-target-size - $mdc-switch-track-height) / 2); - align-items: center; - justify-content: center; - width: $mdc-switch-tap-target-size; - height: $mdc-switch-tap-target-size; - transform: translateX(0); - transition: - mdc-switch-transition(transform), - mdc-switch-transition(background-color), - mdc-switch-transition(border-color); -} - -.mdc-switch__thumb { - @include mdc-elevation(2); - - box-sizing: border-box; - width: $mdc-switch-thumb-diameter; - height: $mdc-switch-thumb-diameter; - border: $mdc-switch-thumb-diameter / 2 solid; - border-radius: 50%; - // Allow events to go through to the native control, necessary for IE and Edge. - pointer-events: none; - z-index: 1; -} - -.mdc-switch--checked { - .mdc-switch__track { - opacity: .54; - } - - .mdc-switch__thumb-underlay { - transform: translateX($mdc-switch-thumb-active-margin); - - @include mdc-rtl { - transform: translateX(-($mdc-switch-thumb-active-margin)); - } - } - - // Translate the native control the opposite direction so that the tap target stays the same. - .mdc-switch__native-control { - transform: translateX(-($mdc-switch-thumb-active-margin)); - - @include mdc-rtl { - transform: translateX($mdc-switch-thumb-active-margin); - } - } -} - -.mdc-switch--disabled { - opacity: .38; - pointer-events: none; - - .mdc-switch__thumb { - border-width: 1px; // In high contrast mode, only show outline of knob. - } - - .mdc-switch__native-control { - cursor: default; - pointer-events: none; - } -} +@include mdc-switch; diff --git a/test/scss/feature-targeting.scss b/test/scss/feature-targeting.scss index 48e89ef28ce..3652ad504cc 100644 --- a/test/scss/feature-targeting.scss +++ b/test/scss/feature-targeting.scss @@ -7,6 +7,7 @@ @import "@material/radio/mixins"; @import "@material/ripple/mixins"; @import "@material/typography/mixins"; +@import "@material/switch/mixins"; .mdc-test { // Button @@ -66,4 +67,15 @@ @include mdc-typography-overflow-ellipsis($query: mdc-feature-any()); @include mdc-typography-baseline-top(0, $query: mdc-feature-any()); @include mdc-typography-baseline-bottom(0, $query: mdc-feature-any()); + + // Switch + @include mdc-switch($query: mdc-feature-any()); + @include mdc-switch-toggled-on-color(on-surface, $query: mdc-feature-any()); + @include mdc-switch-toggled-off-color(on-surface, $query: mdc-feature-any()); + @include mdc-switch-toggled-on-ripple-color(on-surface, $query: mdc-feature-any()); + @include mdc-switch-toggled-off-ripple-color(on-surface, $query: mdc-feature-any()); + @include mdc-switch-toggled-on-track-color(on-surface, $query: mdc-feature-any()); + @include mdc-switch-toggled-on-thumb-color(on-surface, $query: mdc-feature-any()); + @include mdc-switch-toggled-off-track-color(on-surface, $query: mdc-feature-any()); + @include mdc-switch-toggled-off-thumb-color(on-surface, $query: mdc-feature-any()); }