diff --git a/demos/index.html b/demos/index.html index 552846ab657..82495dc5d58 100644 --- a/demos/index.html +++ b/demos/index.html @@ -38,6 +38,7 @@
  • List
  • Select
  • Menu (simple)
  • +
  • Switch
  • Radio
  • Ripple
  • Snackbar
  • diff --git a/demos/switch.html b/demos/switch.html new file mode 100644 index 00000000000..66ad86885a6 --- /dev/null +++ b/demos/switch.html @@ -0,0 +1,110 @@ + + + + + + MDC Switch Demo + + + + + + +
    +

    MDC Switch - CSS Only

    + +
    +

    Switch on Light Theme

    +
    + +
    +
    +
    +
    + +
    +
    +

    Switch on Light Theme - Disabled

    +
    + +
    +
    +
    +
    + +
    + +
    +

    Switch on Dark Theme

    +
    + +
    +
    +
    +
    + +
    + +
    +

    Switch on Light Theme - Disabled

    +
    + +
    +
    +
    +
    + +
    + +
    + + + diff --git a/packages/material-components-web/material-components-web.scss b/packages/material-components-web/material-components-web.scss index 0d858415c45..4bfc32c6113 100644 --- a/packages/material-components-web/material-components-web.scss +++ b/packages/material-components-web/material-components-web.scss @@ -30,6 +30,7 @@ @import "@material/ripple/mdc-ripple"; @import "@material/select/mdc-select"; @import "@material/snackbar/mdc-snackbar"; +@import "@material/switch/mdc-switch"; @import "@material/textfield/mdc-textfield"; @import "@material/theme/mdc-theme"; @import "@material/typography/mdc-typography"; diff --git a/packages/material-components-web/package.json b/packages/material-components-web/package.json index 78134e04e2b..4e15b249c41 100644 --- a/packages/material-components-web/package.json +++ b/packages/material-components-web/package.json @@ -27,6 +27,7 @@ "@material/ripple": "^0.1.2", "@material/select": "^0.2.0", "@material/snackbar": "^0.1.2", + "@material/switch": "^0.1.0", "@material/textfield": "^0.2.0", "@material/theme": "^0.1.1", "@material/typography": "^0.1.1" diff --git a/packages/mdc-switch/README.md b/packages/mdc-switch/README.md new file mode 100644 index 00000000000..bcbf20e0640 --- /dev/null +++ b/packages/mdc-switch/README.md @@ -0,0 +1,48 @@ +# MDC Switch + +The MDC Switch component is a spec-aligned switch component adhering to the +[Material Design Switch requirements](https://material.io/guidelines/components/selection-controls.html#selection-controls-switch). +It works without JavaScript. + +## Installation + +``` +npm install --save @material/switch +``` + +## Usage + +```html +
    + +
    +
    +
    +
    + +``` + +### Disabled +```html +
    + +
    +
    +
    +
    + +``` + +## Classes + +### Block + +The block class is `mdc-switch`. This defines the top-level switch element. + +### Modifier + +The provided modifiers are: + +| Class | Description | +| ----------------------| -------------------------------------------- | +| `mdc-switch--disabled` | Applies disabled style to disabled switches. | diff --git a/packages/mdc-switch/_mixins.scss b/packages/mdc-switch/_mixins.scss new file mode 100644 index 00000000000..7e631768926 --- /dev/null +++ b/packages/mdc-switch/_mixins.scss @@ -0,0 +1,18 @@ +// +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@function mdc-switch-transition($property, $timing-function, $duration: $mdc-switch-transition-duration) { + @return $property $duration $timing-function; +} diff --git a/packages/mdc-switch/_variables.scss b/packages/mdc-switch/_variables.scss new file mode 100644 index 00000000000..d6f3c0bb210 --- /dev/null +++ b/packages/mdc-switch/_variables.scss @@ -0,0 +1,33 @@ +// +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +$mdc-switch-track-width: 34px; +$mdc-switch-track-height: 14px; +$mdc-switch-knob-diameter: 20px; +$mdc-switch-focus-ring-diameter: 48px; +$mdc-switch-knob-active-margin: $mdc-switch-track-width - $mdc-switch-knob-diameter; + +$mdc-switch-unchecked-track-color: #000; +$mdc-switch-unchecked-knob-color: #fafafa; +$mdc-switch-unchecked-focus-ring-color: #9e9e9e; +$mdc-switch-unchecked-knob-color-dark: #bdbdbd; +$mdc-switch-unchecked-track-color-dark: #fff; +$mdc-switch-unchecked-focus-ring-color-dark: #f1f1f1; +$mdc-switch-disabled-knob-color: #bdbdbd; +$mdc-switch-disabled-knob-color-dark: #424242; + +$mdc-switch-transition-duration: 175ms; +$mdc-switch-transition-curve: cubic-bezier(.4, 0, .2, 1); diff --git a/packages/mdc-switch/mdc-switch.scss b/packages/mdc-switch/mdc-switch.scss new file mode 100644 index 00000000000..55e15441aa6 --- /dev/null +++ b/packages/mdc-switch/mdc-switch.scss @@ -0,0 +1,194 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +@import "@material/animation/functions"; +@import "@material/animation/variables"; +@import "@material/elevation/mixins"; +@import "@material/theme/mixins"; +@import "./mixins"; +@import "./variables"; + +// postcss-bem-linter: define switch +.mdc-switch { + display: inline-block; + position: relative; + + &__native-control { + display: inline-block; + position: absolute; + top: 0; + left: 0; + width: $mdc-switch-track-width; + height: $mdc-switch-track-height; + cursor: pointer; + opacity: 0; + z-index: 2; + } + + &__background { + display: block; + position: relative; + width: $mdc-switch-track-width; + height: $mdc-switch-track-height; + border-radius: 7px; + outline: none; + background-color: transparent; + cursor: pointer; + user-select: none; + + @include mdc-theme-dark(".mdc-checkbox") { + background-color: transparent; + } + + &::before { + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + transition: + mdc-checkbox-transition(opacity, $mdc-switch-transition-curve), + mdc-checkbox-transition(background-color, $mdc-switch-transition-curve); + border-radius: 7px; + background-color: $mdc-switch-unchecked-track-color; + content: ""; + opacity: .38; + + @include mdc-theme-dark(".mdc-checkbox") { + background-color: $mdc-switch-unchecked-track-color-dark; + opacity: .3; + } + + } + + // postcss-bem-linter: ignore + .mdc-switch__knob { + display: block; + position: absolute; + top: -3px; + left: 0; + width: $mdc-switch-knob-diameter; + height: $mdc-switch-knob-diameter; + transform: translateX(0); + transition: + mdc-checkbox-transition(transform, $mdc-switch-transition-curve), + mdc-checkbox-transition(background-color, $mdc-switch-transition-curve); + border-radius: $mdc-switch-knob-diameter / 2; + background-color: $mdc-switch-unchecked-knob-color; + + @include mdc-theme-dark(".mdc-checkbox") { + background-color: $mdc-switch-unchecked-knob-color-dark; + } + + @include mdc-elevation(2); + + z-index: 1; + + // postcss-bem-linter: ignore + &::before { + position: absolute; + top: -14px; + left: -14px; + width: $mdc-switch-focus-ring-diameter; + height: $mdc-switch-focus-ring-diameter; + transform: scale(0); + transition: + mdc-checkbox-transition(transform, $mdc-switch-transition-curve), + mdc-checkbox-transition(background-color, $mdc-switch-transition-curve); + border-radius: $mdc-switch-focus-ring-diameter / 2; + background-color: transparent; + content: ""; + opacity: .2; + } + } + } +} + +.mdc-switch__native-control:focus ~ .mdc-switch__background { + + .mdc-switch__knob { + &::before { + position: absolute; + width: $mdc-switch-focus-ring-diameter; + height: $mdc-switch-focus-ring-diameter; + transform: scale(1); + transition: + mdc-checkbox-transition(transform, $mdc-switch-transition-curve), + mdc-checkbox-transition(background-color, $mdc-switch-transition-curve); + border-radius: $mdc-switch-focus-ring-diameter / 2; + background-color: $mdc-switch-unchecked-focus-ring-color; + + @include mdc-theme-dark(".mdc-checkbox") { + background-color: $mdc-switch-unchecked-focus-ring-color-dark; + opacity: .14; + } + + } + } +} + +.mdc-switch__native-control:checked ~ .mdc-switch__background { + + &::before { + @include mdc-theme-prop(background-color, primary); + opacity: .5; + } + + .mdc-switch__knob { + transform: translateX($mdc-switch-track-width - $mdc-switch-knob-diameter); + transition: + mdc-checkbox-transition(transform, $mdc-switch-transition-curve), + mdc-checkbox-transition(background-color, $mdc-switch-transition-curve); + + @include mdc-theme-prop(background-color, primary); + + &::before { + @include mdc-theme-prop(background-color, primary); + + @include mdc-theme-dark(".mdc-checkbox") { + @include mdc-theme-prop(background-color, primary); + } + + opacity: .15; + } + } +} + +// postcss-bem-linter: end + +.mdc-switch__native-control:disabled { + cursor: initial; +} + +.mdc-switch__native-control:disabled ~ .mdc-switch__background { + + &::before { + background-color: $mdc-switch-unchecked-track-color; + opacity: .12; + + @include mdc-theme-dark(".mdc-checkbox") { + background-color: $mdc-switch-unchecked-track-color-dark; + opacity: .1; + } + } + + .mdc-switch__knob { + background-color: $mdc-switch-disabled-knob-color; + + @include mdc-theme-dark(".mdc-checkbox") { + background-color: $mdc-switch-disabled-knob-color-dark; + } + } +} diff --git a/packages/mdc-switch/package.json b/packages/mdc-switch/package.json new file mode 100644 index 00000000000..74f9f388da1 --- /dev/null +++ b/packages/mdc-switch/package.json @@ -0,0 +1,18 @@ +{ + "name": "@material/switch", + "description": "The Material Components for the web switch component", + "version": "0.1.0", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/material-components/material-components-web.git" + }, + "dependencies": { + "@material/animation": "^0.1.3", + "@material/elevation": "^0.1.2", + "@material/theme": "^0.1.1" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/webpack.config.js b/webpack.config.js index 476f65ed0b3..65701427876 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -117,6 +117,7 @@ module.exports = [{ 'mdc.ripple': path.resolve('./packages/mdc-ripple/mdc-ripple.scss'), 'mdc.select': path.resolve('./packages/mdc-select/mdc-select.scss'), 'mdc.snackbar': path.resolve('./packages/mdc-snackbar/mdc-snackbar.scss'), + 'mdc.switch': path.resolve('./packages/mdc-switch/mdc-switch.scss'), 'mdc.textfield': path.resolve('./packages/mdc-textfield/mdc-textfield.scss'), 'mdc.theme': path.resolve('./packages/mdc-theme/mdc-theme.scss'), 'mdc.typography': path.resolve('./packages/mdc-typography/mdc-typography.scss'),