<!-- @license Copyright (c) 2015 The Polymer Project Authors. All rights reserved. This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt --> <link rel="import" href="../polymer/polymer.html"> <link rel="import" href="../paper-styles/color.html"> <link rel="import" href="../paper-styles/default-theme.html"> <link rel="import" href="../paper-ripple/paper-ripple.html"> <link rel="import" href="../paper-behaviors/paper-checked-element-behavior.html"> <!-- Material design: [Switch](https://www.google.com/design/spec/components/selection-controls.html#selection-controls-switch) `paper-toggle-button` provides a ON/OFF switch that user can toggle the state by tapping or by dragging the switch. Example: <paper-toggle-button></paper-toggle-button> ### Styling The following custom properties and mixins are available for styling: Custom property | Description | Default ----------------|-------------|---------- `--paper-toggle-button-unchecked-bar-color` | Slider color when the input is not checked | `#000000` `--paper-toggle-button-unchecked-button-color` | Button color when the input is not checked | `--paper-grey-50` `--paper-toggle-button-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--dark-primary-color` `--paper-toggle-button-checked-bar-color` | Slider button color when the input is checked | `--default-primary-color` `--paper-toggle-button-checked-button-color` | Button color when the input is checked | `--default-primary-color` `--paper-toggle-button-checked-ink-color` | Selected/focus ripple color when the input is checked | `--default-primary-color` `--paper-toggle-button-unchecked-bar` | Mixin applied to the slider when the input is not checked | `{}` `--paper-toggle-button-unchecked-button` | Mixin applied to the slider button when the input is not checked | `{}` `--paper-toggle-button-checked-bar` | Mixin applied to the slider when the input is checked | `{}` `--paper-toggle-button-checked-button` | Mixin applied to the slider button when the input is checked | `{}` `--paper-toggle-button-label-color` | Label color | `--primary-text-color` @group Paper Elements @element paper-toggle-button @hero hero.svg @demo demo/index.html --> <dom-module id="paper-toggle-button"> <template strip-whitespace> <style> :host { display: inline-block; } :host([disabled]) { pointer-events: none; } :host(:focus) { outline:none; } .toggle-bar { position: absolute; height: 100%; width: 100%; border-radius: 8px; pointer-events: none; opacity: 0.4; transition: background-color linear .08s; background-color: var(--paper-toggle-button-unchecked-bar-color, #000000); @apply(--paper-toggle-button-unchecked-bar); } .toggle-button { position: absolute; top: -3px; height: 20px; width: 20px; border-radius: 50%; box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.6); transition: -webkit-transform linear .08s, background-color linear .08s; transition: transform linear .08s, background-color linear .08s; will-change: transform; background-color: var(--paper-toggle-button-unchecked-button-color, --paper-grey-50); @apply(--paper-toggle-button-unchecked-button); } .toggle-button.dragging { -webkit-transition: none; transition: none; } :host([checked]:not([disabled])) .toggle-bar { opacity: 0.5; background-color: var(--paper-toggle-button-checked-bar-color, --default-primary-color); @apply(--paper-toggle-button-checked-bar); } :host([disabled]) .toggle-bar { background-color: #000; opacity: 0.12; } :host([checked]) .toggle-button { -webkit-transform: translate(16px, 0); transform: translate(16px, 0); } :host([checked]:not([disabled])) .toggle-button { background-color: var(--paper-toggle-button-checked-button-color, --default-primary-color); @apply(--paper-toggle-button-checked-button); } :host([disabled]) .toggle-button { background-color: #bdbdbd; opacity: 1; } .toggle-ink { position: absolute; top: -14px; left: -14px; width: 48px; height: 48px; opacity: 0.5; pointer-events: none; color: var(--paper-toggle-button-unchecked-ink-color, --primary-text-color); } :host([checked]) .toggle-ink { color: var(--paper-toggle-button-checked-ink-color, --default-primary-color); } .toggle-container { display: inline-block; position: relative; width: 36px; height: 14px; } .toggle-label { position: relative; top: -2px; display: inline-block; vertical-align: middle; margin-left: 10px; white-space: normal; pointer-events: none; color: var(--paper-toggle-button-label-color, --primary-text-color); } </style> <div class="toggle-container"> <div id="toggleBar" class="toggle-bar"></div> <div id="toggleButton" class="toggle-button"></div> </div> <div class="toggle-label"><content></content></div> </template> <script> Polymer({ is: 'paper-toggle-button', behaviors: [ Polymer.PaperCheckedElementBehavior ], hostAttributes: { role: 'button', 'aria-pressed': 'false', tabindex: 0 }, properties: { /** * Fired when the checked state changes due to user interaction. * * @event change */ /** * Fired when the checked state changes. * * @event iron-change */ }, listeners: { track: '_ontrack' }, _ontrack: function(event) { var track = event.detail; if (track.state === 'start') { this._trackStart(track); } else if (track.state === 'track') { this._trackMove(track); } else if (track.state === 'end') { this._trackEnd(track); } }, _trackStart: function(track) { this._width = this.$.toggleBar.offsetWidth / 2; /* * keep an track-only check state to keep the dragging behavior smooth * while toggling activations */ this._trackChecked = this.checked; this.$.toggleButton.classList.add('dragging'); }, _trackMove: function(track) { var dx = track.dx; this._x = Math.min(this._width, Math.max(0, this._trackChecked ? this._width + dx : dx)); this.translate3d(this._x + 'px', 0, 0, this.$.toggleButton); this._userActivate(this._x > (this._width / 2)); }, _trackEnd: function(track) { this.$.toggleButton.classList.remove('dragging'); this.transform('', this.$.toggleButton); }, // customize the element's ripple _createRipple: function() { this._rippleContainer = this.$.toggleButton; var ripple = Polymer.PaperRippleBehavior._createRipple(); ripple.id = 'ink'; ripple.setAttribute('recenters', ''); ripple.classList.add('circle', 'toggle-ink'); return ripple; } }); </script> </dom-module>