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
master
Sérgio Gomes 2015-01-29 15:14:13 +00:00
parent 83fd3af6e4
commit f363e1ad06
4 changed files with 76 additions and 119 deletions

View File

@ -6,7 +6,8 @@ $checkbox-label-height: 24px;
$checkbox-button-size: 16px; $checkbox-button-size: 16px;
$checkbox-inner-margin: 2px; $checkbox-inner-margin: 2px;
$checkbox-padding: 8px; $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; $checkbox-ripple-size: $checkbox-label-height * 1.5;
.wsk-checkbox { .wsk-checkbox {
@ -64,6 +65,7 @@ $checkbox-ripple-size: $checkbox-label-height * 1.5;
overflow: hidden; overflow: hidden;
border: 2px solid $checkbox-off-color; border: 2px solid $checkbox-off-color;
border-radius: 2px;
z-index: 2; 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; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
height: 100%; height: 100%;
width: 100%; width: 100%;
mask: url("tick-mask.svg#mask");
background-color: transparent; background: transparent;
@include material-animation-default(0.28s); @include material-animation-default(0.28s);
transition-property: background-color; transition-property: background;
.wsk-checkbox.is-checked & { .wsk-checkbox.is-checked & {
background-color: $checkbox-color; background: $checkbox-color url("tick.svg");
} }
.wsk-checkbox.is-checked.is-disabled & { .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 { .wsk-checkbox__label {
position: relative; position: relative;
cursor: pointer; cursor: pointer;

View File

@ -30,42 +30,21 @@ MaterialCheckbox.prototype.Constant_ = {
* @private * @private
*/ */
MaterialCheckbox.prototype.CssClasses_ = { MaterialCheckbox.prototype.CssClasses_ = {
WSK_CHECKBOX_INPUT: 'wsk-checkbox__input', INPUT: 'wsk-checkbox__input',
BOX_OUTLINE: 'wsk-checkbox__box-outline',
WSK_CHECKBOX_BOX_OUTLINE: 'wsk-checkbox__box-outline', FOCUS_HELPER: 'wsk-checkbox__focus-helper',
TICK_OUTLINE: 'wsk-checkbox__tick-outline',
WSK_CHECKBOX_FOCUS_HELPER: 'wsk-checkbox__focus-helper', RIPPLE_EFFECT: 'wsk-js-ripple-effect',
RIPPLE_IGNORE_EVENTS: 'wsk-js-ripple-effect--ignore-events',
WSK_CHECKBOX_TICK_OUTLINE: 'wsk-checkbox__tick-outline', RIPPLE_CONTAINER: 'wsk-checkbox__ripple-container',
RIPPLE_CENTER: 'wsk-ripple--center',
WSK_CHECKBOX_BOT_RIGHT: 'wsk-checkbox__bottom-right', RIPPLE: 'wsk-ripple',
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',
IS_FOCUSED: 'is-focused', IS_FOCUSED: 'is-focused',
IS_DISABLED: 'is-disabled', IS_DISABLED: 'is-disabled',
IS_CHECKED: 'is-checked',
IS_CHECKED: 'is-checked' IS_UPGRADED: 'is-upgraded'
}; };
/** /**
* Handle change of state. * Handle change of state.
* @param {Event} event The event that fired. * @param {Event} event The event that fired.
@ -77,7 +56,6 @@ MaterialCheckbox.prototype.onChange_ = function(event) {
this.updateClasses_(this.btnElement_, this.element_); this.updateClasses_(this.btnElement_, this.element_);
}; };
/** /**
* Handle focus of element. * Handle focus of element.
* @param {Event} event The event that fired. * @param {Event} event The event that fired.
@ -89,7 +67,6 @@ MaterialCheckbox.prototype.onFocus_ = function(event) {
this.element_.classList.add(this.CssClasses_.IS_FOCUSED); this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
}; };
/** /**
* Handle lost focus of element. * Handle lost focus of element.
* @param {Event} event The event that fired. * @param {Event} event The event that fired.
@ -101,7 +78,6 @@ MaterialCheckbox.prototype.onBlur_ = function(event) {
this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
}; };
/** /**
* Handle mouseup. * Handle mouseup.
* @param {Event} event The event that fired. * @param {Event} event The event that fired.
@ -113,7 +89,6 @@ MaterialCheckbox.prototype.onMouseUp_ = function(event) {
this.blur_(); this.blur_();
}; };
/** /**
* Handle class updates. * Handle class updates.
* @param {HTMLElement} button The button whose classes we should update. * @param {HTMLElement} button The button whose classes we should update.
@ -136,7 +111,6 @@ MaterialCheckbox.prototype.updateClasses_ = function(button, label) {
} }
}; };
/** /**
* Add blur. * Add blur.
* @private * @private
@ -151,7 +125,6 @@ MaterialCheckbox.prototype.blur_ = function(event) {
}.bind(this), this.Constant_.TINY_TIMEOUT); }.bind(this), this.Constant_.TINY_TIMEOUT);
}; };
/** /**
* Initialize element. * Initialize element.
*/ */
@ -160,76 +133,48 @@ MaterialCheckbox.prototype.init = function() {
if (this.element_) { if (this.element_) {
this.btnElement_ = this.element_.querySelector('.' + this.btnElement_ = this.element_.querySelector('.' +
this.CssClasses_.WSK_CHECKBOX_INPUT); this.CssClasses_.INPUT);
var boxOutline = document.createElement('span'); 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'); 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'); var tickOutline = document.createElement('span');
tickOutline.classList.add(this.CssClasses_.WSK_CHECKBOX_TICK_OUTLINE); tickOutline.classList.add(this.CssClasses_.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);
boxOutline.appendChild(tickOutline); 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(tickContainer);
this.element_.appendChild(boxOutline); this.element_.appendChild(boxOutline);
var rippleContainer; var rippleContainer;
if (this.element_.classList.contains( if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
this.CssClasses_.WSK_JS_RIPPLE_EFFECT)) { this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
this.element_.classList.add(
this.CssClasses_.WSK_JS_RIPPLE_EFFECT_IGNORE_EVENTS);
rippleContainer = document.createElement('span'); rippleContainer = document.createElement('span');
rippleContainer.classList.add( rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
this.CssClasses_.WSK_CHECKBOX_RIPPLE_CONTAINER); rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT);
rippleContainer.classList.add(this.CssClasses_.WSK_JS_RIPPLE_EFFECT); rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER);
rippleContainer.classList.add(this.CssClasses_.WSK_RIPPLE_CENTER);
var ripple = document.createElement('span'); var ripple = document.createElement('span');
ripple.classList.add(this.CssClasses_.WSK_RIPPLE); ripple.classList.add(this.CssClasses_.RIPPLE);
rippleContainer.appendChild(ripple); rippleContainer.appendChild(ripple);
this.element_.appendChild(rippleContainer); this.element_.appendChild(rippleContainer);
} }
this.btnElement_.addEventListener('change', this.onChange_.bind(this)); this.btnElement_.addEventListener('change', this.onChange_.bind(this));
this.btnElement_.addEventListener('focus', this.onFocus_.bind(this)); this.btnElement_.addEventListener('focus', this.onFocus_.bind(this));
this.btnElement_.addEventListener('blur', this.onBlur_.bind(this)); this.btnElement_.addEventListener('blur', this.onBlur_.bind(this));
this.element_.addEventListener('mouseup', this.onMouseUp_.bind(this)); this.element_.addEventListener('mouseup', this.onMouseUp_.bind(this));
rippleContainer.addEventListener('mouseup', this.onMouseUp_.bind(this)); rippleContainer.addEventListener('mouseup', this.onMouseUp_.bind(this));
this.updateClasses_(this.btnElement_, this.element_); 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 // The component registers itself. It can assume componentHandler is available
// in the global scope. // in the global scope.
componentHandler.register({ componentHandler.register({

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0 0 1 1"
preserveAspectRatio="xMinYMin meet">
<defs>
<clipPath id="clip">
<path
d="M 0,0 0,1 1,1 1,0 0,0 z M 0.8534375,0.1671875 0.9596875,0.273125 0.429375,0.8034375 0.323125,0.9096875 0.2171875,0.8034375 0.0403125,0.626875 0.1465625,0.520625 0.323125,0.6975 0.8534375,0.1671875 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</clipPath>
<mask id="mask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<path
d="M 0,0 0,1 1,1 1,0 0,0 z M 0.8534375,0.1671875 0.9596875,0.273125 0.429375,0.8034375 0.323125,0.9096875 0.2171875,0.8034375 0.0403125,0.626875 0.1465625,0.520625 0.323125,0.6975 0.8534375,0.1671875 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</mask>
</defs>
<rect
width="1"
height="1"
x="0"
y="0"
clip-path="url(#clip)"
style="fill:#000000;fill-opacity:1;stroke:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0 0 1 1"
preserveAspectRatio="xMinYMin meet">
<path
d="M 0.04038059,0.6267767 0.14644661,0.52071068 0.42928932,0.80355339 0.3232233,0.90961941 z M 0.21715729,0.80355339 0.85355339,0.16715729 0.95961941,0.2732233 0.3232233,0.90961941 z"
id="rect3780"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</svg>

After

Width:  |  Height:  |  Size: 648 B