From f363e1ad06dd58dde20c4d279c2a55bc29e96288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Thu, 29 Jan 2015 15:14:13 +0000 Subject: [PATCH] Checkbox improvements - Switch to using CSS masks for transparent tick. Sorry, IE, you get a white tick. - Some small visual tweaks (rounded corners, alignment). - Tidying up the JS --- app/styleguide/checkbox/_checkbox.scss | 51 +++---------- app/styleguide/checkbox/checkbox.js | 99 ++++++-------------------- app/styleguide/checkbox/tick-mask.svg | 30 ++++++++ app/styleguide/checkbox/tick.svg | 15 ++++ 4 files changed, 76 insertions(+), 119 deletions(-) create mode 100644 app/styleguide/checkbox/tick-mask.svg create mode 100644 app/styleguide/checkbox/tick.svg diff --git a/app/styleguide/checkbox/_checkbox.scss b/app/styleguide/checkbox/_checkbox.scss index da024034..ba77b140 100644 --- a/app/styleguide/checkbox/_checkbox.scss +++ b/app/styleguide/checkbox/_checkbox.scss @@ -6,7 +6,8 @@ $checkbox-label-height: 24px; $checkbox-button-size: 16px; $checkbox-inner-margin: 2px; $checkbox-padding: 8px; -$checkbox-top-offset: ($checkbox-label-height - $checkbox-button-size) / 2; +$checkbox-top-offset: + ($checkbox-label-height - $checkbox-button-size - $checkbox-inner-margin) / 2; $checkbox-ripple-size: $checkbox-label-height * 1.5; .wsk-checkbox { @@ -64,6 +65,7 @@ $checkbox-ripple-size: $checkbox-label-height * 1.5; overflow: hidden; border: 2px solid $checkbox-off-color; + border-radius: 2px; z-index: 2; @@ -102,62 +104,27 @@ $checkbox-ripple-size: $checkbox-label-height * 1.5; } } -@mixin checkbox-tick-component { +.wsk-checkbox__tick-outline { position: absolute; top: 0; left: 0; height: 100%; width: 100%; + mask: url("tick-mask.svg#mask"); - background-color: transparent; + background: transparent; @include material-animation-default(0.28s); - transition-property: background-color; + transition-property: background; .wsk-checkbox.is-checked & { - background-color: $checkbox-color; + background: $checkbox-color url("tick.svg"); } .wsk-checkbox.is-checked.is-disabled & { - background-color: $checkbox-disabled-color; + background: $checkbox-disabled-color url("tick.svg"); } } -.wsk-checkbox__tick-outline { - transform: translate(-15%, -60%) rotate(45deg); - @include checkbox-tick-component(); -} - -.wsk-checkbox__bottom-right { - transform: translate(55%, 30%) rotate(45deg); - @include checkbox-tick-component(); -} - -.wsk-checkbox__bottom-left { - transform: translate(-55%, 60%) rotate(45deg); - @include checkbox-tick-component(); -} - -.wsk-checkbox__bottom { - transform: translate(0%, 80%); - @include checkbox-tick-component(); - .wsk-checkbox.is-checked.is-disabled & { - background-color: transparent; - } -} - -.wsk-checkbox__top-left { - transform: translate(-95%, -20%) rotate(45deg); - @include checkbox-tick-component(); - .wsk-checkbox.is-checked.is-disabled & { - transform: translate(-105%, -10%) rotate(45deg); - } -} - -.wsk-checkbox__top-right { - transform: translate(85%, -70%) rotate(45deg); - @include checkbox-tick-component(); -} - .wsk-checkbox__label { position: relative; cursor: pointer; diff --git a/app/styleguide/checkbox/checkbox.js b/app/styleguide/checkbox/checkbox.js index e7f53219..c60f6df1 100644 --- a/app/styleguide/checkbox/checkbox.js +++ b/app/styleguide/checkbox/checkbox.js @@ -30,42 +30,21 @@ MaterialCheckbox.prototype.Constant_ = { * @private */ MaterialCheckbox.prototype.CssClasses_ = { - WSK_CHECKBOX_INPUT: 'wsk-checkbox__input', - - WSK_CHECKBOX_BOX_OUTLINE: 'wsk-checkbox__box-outline', - - WSK_CHECKBOX_FOCUS_HELPER: 'wsk-checkbox__focus-helper', - - WSK_CHECKBOX_TICK_OUTLINE: 'wsk-checkbox__tick-outline', - - WSK_CHECKBOX_BOT_RIGHT: 'wsk-checkbox__bottom-right', - - WSK_CHECKBOX_BOT_LEFT: 'wsk-checkbox__bottom-left', - - WSK_CHECKBOX_BOTTOM: 'wsk-checkbox__bottom', - - WSK_CHECKBOX_TOP_LEFT: 'wsk-checkbox__top-left', - - WSK_CHECKBOX_TOP_RIGHT: 'wsk-checkbox__top-right', - - WSK_JS_RIPPLE_EFFECT: 'wsk-js-ripple-effect', - - WSK_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'wsk-js-ripple-effect--ignore-events', - - WSK_CHECKBOX_RIPPLE_CONTAINER: 'wsk-checkbox__ripple-container', - - WSK_RIPPLE_CENTER: 'wsk-ripple--center', - - WSK_RIPPLE: 'wsk-ripple', - + INPUT: 'wsk-checkbox__input', + BOX_OUTLINE: 'wsk-checkbox__box-outline', + FOCUS_HELPER: 'wsk-checkbox__focus-helper', + TICK_OUTLINE: 'wsk-checkbox__tick-outline', + RIPPLE_EFFECT: 'wsk-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'wsk-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'wsk-checkbox__ripple-container', + RIPPLE_CENTER: 'wsk-ripple--center', + RIPPLE: 'wsk-ripple', IS_FOCUSED: 'is-focused', - IS_DISABLED: 'is-disabled', - - IS_CHECKED: 'is-checked' + IS_CHECKED: 'is-checked', + IS_UPGRADED: 'is-upgraded' }; - /** * Handle change of state. * @param {Event} event The event that fired. @@ -77,7 +56,6 @@ MaterialCheckbox.prototype.onChange_ = function(event) { this.updateClasses_(this.btnElement_, this.element_); }; - /** * Handle focus of element. * @param {Event} event The event that fired. @@ -89,7 +67,6 @@ MaterialCheckbox.prototype.onFocus_ = function(event) { this.element_.classList.add(this.CssClasses_.IS_FOCUSED); }; - /** * Handle lost focus of element. * @param {Event} event The event that fired. @@ -101,7 +78,6 @@ MaterialCheckbox.prototype.onBlur_ = function(event) { this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); }; - /** * Handle mouseup. * @param {Event} event The event that fired. @@ -113,7 +89,6 @@ MaterialCheckbox.prototype.onMouseUp_ = function(event) { this.blur_(); }; - /** * Handle class updates. * @param {HTMLElement} button The button whose classes we should update. @@ -136,7 +111,6 @@ MaterialCheckbox.prototype.updateClasses_ = function(button, label) { } }; - /** * Add blur. * @private @@ -151,7 +125,6 @@ MaterialCheckbox.prototype.blur_ = function(event) { }.bind(this), this.Constant_.TINY_TIMEOUT); }; - /** * Initialize element. */ @@ -160,76 +133,48 @@ MaterialCheckbox.prototype.init = function() { if (this.element_) { this.btnElement_ = this.element_.querySelector('.' + - this.CssClasses_.WSK_CHECKBOX_INPUT); + this.CssClasses_.INPUT); var boxOutline = document.createElement('span'); - boxOutline.classList.add(this.CssClasses_.WSK_CHECKBOX_BOX_OUTLINE); + boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE); var tickContainer = document.createElement('span'); - tickContainer.classList.add(this.CssClasses_.WSK_CHECKBOX_FOCUS_HELPER); + tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER); var tickOutline = document.createElement('span'); - tickOutline.classList.add(this.CssClasses_.WSK_CHECKBOX_TICK_OUTLINE); - - var bottomRight = document.createElement('span'); - bottomRight.classList.add(this.CssClasses_.WSK_CHECKBOX_BOT_RIGHT); - - var bottomLeft = document.createElement('span'); - bottomLeft.classList.add(this.CssClasses_.WSK_CHECKBOX_BOT_LEFT); - - var bottom = document.createElement('span'); - bottom.classList.add(this.CssClasses_.WSK_CHECKBOX_BOTTOM); - - var topLeft = document.createElement('span'); - topLeft.classList.add(this.CssClasses_.WSK_CHECKBOX_TOP_LEFT); - - var topRight = document.createElement('span'); - topRight.classList.add(this.CssClasses_.WSK_CHECKBOX_TOP_RIGHT); + tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE); boxOutline.appendChild(tickOutline); - boxOutline.appendChild(topLeft); - boxOutline.appendChild(topRight); - boxOutline.appendChild(bottomRight); - boxOutline.appendChild(bottomLeft); - boxOutline.appendChild(bottom); this.element_.appendChild(tickContainer); this.element_.appendChild(boxOutline); var rippleContainer; - if (this.element_.classList.contains( - this.CssClasses_.WSK_JS_RIPPLE_EFFECT)) { - this.element_.classList.add( - this.CssClasses_.WSK_JS_RIPPLE_EFFECT_IGNORE_EVENTS); + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); rippleContainer = document.createElement('span'); - rippleContainer.classList.add( - this.CssClasses_.WSK_CHECKBOX_RIPPLE_CONTAINER); - rippleContainer.classList.add(this.CssClasses_.WSK_JS_RIPPLE_EFFECT); - rippleContainer.classList.add(this.CssClasses_.WSK_RIPPLE_CENTER); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); var ripple = document.createElement('span'); - ripple.classList.add(this.CssClasses_.WSK_RIPPLE); + ripple.classList.add(this.CssClasses_.RIPPLE); rippleContainer.appendChild(ripple); this.element_.appendChild(rippleContainer); } this.btnElement_.addEventListener('change', this.onChange_.bind(this)); - this.btnElement_.addEventListener('focus', this.onFocus_.bind(this)); - this.btnElement_.addEventListener('blur', this.onBlur_.bind(this)); - this.element_.addEventListener('mouseup', this.onMouseUp_.bind(this)); - rippleContainer.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.updateClasses_(this.btnElement_, this.element_); - this.element_.classList.add('is-upgraded'); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); } }; - // The component registers itself. It can assume componentHandler is available // in the global scope. componentHandler.register({ diff --git a/app/styleguide/checkbox/tick-mask.svg b/app/styleguide/checkbox/tick-mask.svg new file mode 100644 index 00000000..b0989204 --- /dev/null +++ b/app/styleguide/checkbox/tick-mask.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + diff --git a/app/styleguide/checkbox/tick.svg b/app/styleguide/checkbox/tick.svg new file mode 100644 index 00000000..b3d6ec85 --- /dev/null +++ b/app/styleguide/checkbox/tick.svg @@ -0,0 +1,15 @@ + + + +