<!-- @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-ripple/paper-ripple.html"> <link rel="import" href="../paper-styles/default-theme.html"> <link rel="import" href="../paper-styles/color.html"> <link rel="import" href="../paper-behaviors/paper-inky-focus-behavior.html"> <link rel="import" href="../iron-checked-element-behavior/iron-checked-element-behavior.html"> <!-- `paper-checkbox` is a button that can be either checked or unchecked. User can tap the checkbox to check or uncheck it. Usually you use checkboxes to allow user to select multiple options from a set. If you have a single ON/OFF option, avoid using a single checkbox and use `paper-toggle-button` instead. Example: <paper-checkbox>label</paper-checkbox> <paper-checkbox checked> label</paper-checkbox> ### Styling The following custom properties and mixins are available for styling: Custom property | Description | Default ----------------|-------------|---------- `--paper-checkbox-unchecked-background-color` | Checkbox background color when the input is not checked | `transparent` `--paper-checkbox-unchecked-color` | Checkbox border color when the input is not checked | `--primary-text-color` `--paper-checkbox-unchecked-ink-color` | Selected/focus ripple color when the input is not checked | `--primary-text-color` `--paper-checkbox-checked-color` | Checkbox color when the input is checked | `--default-primary-color` `--paper-checkbox-checked-ink-color` | Selected/focus ripple color when the input is checked | `--default-primary-color` `--paper-checkbox-checkmark-color` | Checkmark color | `white` `--paper-checkbox-label-color` | Label color | `--primary-text-color` `--paper-checkbox-error-color` | Checkbox color when invalid | `--google-red-500` @demo demo/index.html --> <dom-module id="paper-checkbox"> <template> <style> :host { display: inline-block; white-space: nowrap; } :host(:focus) { outline: none; } .hidden { display: none; } #checkboxContainer { display: inline-block; position: relative; width: 18px; height: 18px; cursor: pointer; -webkit-transform: translateZ(0); transform: translateZ(0); vertical-align: middle; background-color: var(--paper-checkbox-unchecked-background-color, transparent); } :host #ink { position: absolute; top: -15px; left: -15px; width: 48px; height: 48px; color: var(--paper-checkbox-unchecked-ink-color, --primary-text-color); opacity: 0.6; pointer-events: none; } :host #ink[checked] { color: var(--paper-checkbox-checked-ink-color, --default-primary-color); } :host #checkbox { position: relative; box-sizing: border-box; height: 100%; border: solid 2px; border-color: var(--paper-checkbox-unchecked-color, --primary-text-color); border-radius: 2px; pointer-events: none; -webkit-transition: background-color 140ms, border-color 140ms; transition: background-color 140ms, border-color 140ms; } /* checkbox checked animations */ #checkbox.checked #checkmark { -webkit-animation: checkmark-expand 140ms ease-out forwards; animation: checkmark-expand 140ms ease-out forwards; } @-webkit-keyframes checkmark-expand { 0% { top: 9px; left: 6px; width: 0px; height: 0px; } 100% { top: -1px; left: 4px; width: 5px; height: 10px; } } @keyframes checkmark-expand { 0% { top: 9px; left: 6px; width: 0px; height: 0px; } 100% { top: -1px; left: 4px; width: 5px; height: 10px; } } :host #checkbox.checked { background-color: var(--paper-checkbox-checked-color, --default-primary-color); border-color: var(--paper-checkbox-checked-color, --default-primary-color); } :host #checkmark { -webkit-transform: rotate(45deg); transform: rotate(45deg); position: absolute; top: -1px; left: 4px; width: 5px; height: 10px; border-style: solid; border-top: none; border-left: none; border-right-width: 2px; border-bottom-width: 2px; border-color: var(--paper-checkbox-checkmark-color, white); } /* label */ #checkboxLabel { position: relative; display: inline-block; vertical-align: middle; padding-left: 8px; white-space: normal; pointer-events: none; color: var(--paper-checkbox-label-color, --primary-text-color); } #checkboxLabel[hidden] { display: none; } /* disabled state */ :host([disabled]) { pointer-events: none; } :host([disabled]) #checkbox { opacity: 0.5; border-color: var(--paper-checkbox-unchecked-color, --primary-text-color); } :host([disabled][checked]) #checkbox { background-color: var(--paper-checkbox-unchecked-color, --primary-text-color); opacity: 0.5; } :host([disabled]) #checkboxLabel { opacity: 0.65; } /* invalid state */ #checkbox.invalid:not(.checked) { border-color: var(--paper-checkbox-error-color, --google-red-500); } </style> <div id="checkboxContainer"> <paper-ripple id="ink" class="circle" center checked$="[[checked]]"></paper-ripple> <div id="checkbox" class$="[[_computeCheckboxClass(checked, invalid)]]"> <div id="checkmark" class$="[[_computeCheckmarkClass(checked)]]"></div> </div> </div> <div id="checkboxLabel"><content></content></div> </template> <script> Polymer({ is: 'paper-checkbox', behaviors: [ Polymer.PaperInkyFocusBehavior, Polymer.IronCheckedElementBehavior ], hostAttributes: { role: 'checkbox', 'aria-checked': 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 */ ariaActiveAttribute: { type: String, value: 'aria-checked' } }, attached: function() { this._isReady = true; // Don't stomp over a user-set aria-label. if (!this.getAttribute('aria-label')) { this.updateAriaLabel(); } }, /** * Update the checkbox aria-label. This is a temporary workaround not * being able to observe changes in <content> * (see: https://github.com/Polymer/polymer/issues/1773) * * Call this if you manually change the contents of the checkbox * and want the aria-label to match the new contents. */ updateAriaLabel: function() { this.setAttribute('aria-label', Polymer.dom(this).textContent.trim()); }, // button-behavior hook _buttonStateChanged: function() { if (this.disabled) { return; } if (this._isReady) { this.checked = this.active; } }, _computeCheckboxClass: function(checked, invalid) { var className = ''; if (checked) { className += 'checked '; } if (invalid) { className += 'invalid'; } return className; }, _computeCheckmarkClass: function(checked) { return checked ? '' : 'hidden'; } }); </script> </dom-module>