es6 Introduced inline classes for radio and checkbox. Solved more problems getting our marker mdb-form-group in place via es6 classes.

This commit is contained in:
Kevin Ross 2015-12-05 21:24:05 -06:00
parent f7f064dff4
commit 53d0b661bb
17 changed files with 359 additions and 197 deletions

View File

@ -109,8 +109,10 @@ module.exports = function (grunt) {
'dist/js/babel/textarea.js': 'js/src/textarea.js', 'dist/js/babel/textarea.js': 'js/src/textarea.js',
'dist/js/babel/select.js': 'js/src/select.js', 'dist/js/babel/select.js': 'js/src/select.js',
'dist/js/babel/checkbox.js': 'js/src/checkbox.js', 'dist/js/babel/checkbox.js': 'js/src/checkbox.js',
'dist/js/babel/checkboxInline.js': 'js/src/checkboxInline.js',
'dist/js/babel/switch.js': 'js/src/switch.js', 'dist/js/babel/switch.js': 'js/src/switch.js',
'dist/js/babel/radio.js': 'js/src/radio.js', 'dist/js/babel/radio.js': 'js/src/radio.js',
'dist/js/babel/radioInline.js': 'js/src/radioInline.js',
'dist/js/babel/fileInput.js': 'js/src/file.js', 'dist/js/babel/fileInput.js': 'js/src/file.js',
'dist/js/babel/bootstrapMaterialDesign.js': 'js/src/bootstrapMaterialDesign.js', 'dist/js/babel/bootstrapMaterialDesign.js': 'js/src/bootstrapMaterialDesign.js',
} }
@ -134,8 +136,10 @@ module.exports = function (grunt) {
'docs/dist/js/babel/textarea.js': 'js/src/textarea.js', 'docs/dist/js/babel/textarea.js': 'js/src/textarea.js',
'docs/dist/js/babel/select.js': 'js/src/select.js', 'docs/dist/js/babel/select.js': 'js/src/select.js',
'docs/dist/js/babel/checkbox.js': 'js/src/checkbox.js', 'docs/dist/js/babel/checkbox.js': 'js/src/checkbox.js',
'docs/dist/js/babel/checkboxInline.js': 'js/src/checkboxInline.js',
'docs/dist/js/babel/switch.js': 'js/src/switch.js', 'docs/dist/js/babel/switch.js': 'js/src/switch.js',
'docs/dist/js/babel/radio.js': 'js/src/radio.js', 'docs/dist/js/babel/radio.js': 'js/src/radio.js',
'docs/dist/js/babel/radioInline.js': 'js/src/radioInline.js',
'docs/dist/js/babel/fileInput.js': 'js/src/file.js', 'docs/dist/js/babel/fileInput.js': 'js/src/file.js',
'docs/dist/js/babel/bootstrapMaterialDesign.js': 'js/src/bootstrapMaterialDesign.js', 'docs/dist/js/babel/bootstrapMaterialDesign.js': 'js/src/bootstrapMaterialDesign.js',
} }
@ -162,8 +166,10 @@ module.exports = function (grunt) {
'dist/js/umd/textarea.js': 'js/src/textarea.js', 'dist/js/umd/textarea.js': 'js/src/textarea.js',
'dist/js/umd/select.js': 'js/src/select.js', 'dist/js/umd/select.js': 'js/src/select.js',
'dist/js/umd/checkbox.js': 'js/src/checkbox.js', 'dist/js/umd/checkbox.js': 'js/src/checkbox.js',
'dist/js/umd/checkboxInline.js': 'js/src/checkboxInline.js',
'dist/js/umd/switch.js': 'js/src/switch.js', 'dist/js/umd/switch.js': 'js/src/switch.js',
'dist/js/umd/radio.js': 'js/src/radio.js', 'dist/js/umd/radio.js': 'js/src/radio.js',
'dist/js/umd/radioInline.js': 'js/src/radioInline.js',
'dist/js/umd/fileInput.js': 'js/src/file.js', 'dist/js/umd/fileInput.js': 'js/src/file.js',
'dist/js/umd/bootstrapMaterialDesign.js': 'js/src/bootstrapMaterialDesign.js', 'dist/js/umd/bootstrapMaterialDesign.js': 'js/src/bootstrapMaterialDesign.js',
} }
@ -226,8 +232,10 @@ module.exports = function (grunt) {
'dist/js/babel/textarea.js', 'dist/js/babel/textarea.js',
'dist/js/babel/select.js', 'dist/js/babel/select.js',
'dist/js/babel/checkbox.js', 'dist/js/babel/checkbox.js',
'dist/js/babel/checkboxInline.js',
'dist/js/babel/switch.js', 'dist/js/babel/switch.js',
'dist/js/babel/radio.js', 'dist/js/babel/radio.js',
'dist/js/babel/radioInline.js',
'dist/js/babel/file.js', 'dist/js/babel/file.js',
'dist/js/babel/bootstrapMaterialDesign.js', 'dist/js/babel/bootstrapMaterialDesign.js',
], ],

View File

@ -107,23 +107,15 @@ class Application {
.tooltip('_fixTitle') .tooltip('_fixTitle')
}) })
} }
fixMissingFormGroups() {
//let selectors = [
// '#search-input',
// `input.form-control[placeholder='Readonly input here…']`
//]
//for( let selector of selectors){
// $(selector).parent().wrapInner(`<div class='form-group'></div>`)
//}
}
} }
$(() => { $(() => {
let app = new Application() let app = new Application()
app.displayTypographyProperties() app.displayTypographyProperties()
app.initializeClipboard() app.initializeClipboard()
app.fixMissingFormGroups()
// $.bootstrapMaterialDesign() // FIXME: file inputs seems to be in flux, delete the offending one for now.
$('#exampleInputFile').closest('.form-group').detach()
$('body').bootstrapMaterialDesign() $('body').bootstrapMaterialDesign()
}) })

View File

@ -14,11 +14,13 @@
"../dist/js/babel/autofill.js", "../dist/js/babel/autofill.js",
"../dist/js/babel/bootstrapMaterialDesign.js", "../dist/js/babel/bootstrapMaterialDesign.js",
"../dist/js/babel/checkbox.js", "../dist/js/babel/checkbox.js",
"../dist/js/babel/checkboxInline.js",
"../dist/js/babel/fileInput.js", "../dist/js/babel/fileInput.js",
"../dist/js/babel/text.js", "../dist/js/babel/text.js",
"../dist/js/babel/textarea.js", "../dist/js/babel/textarea.js",
"../dist/js/babel/select.js", "../dist/js/babel/select.js",
"../dist/js/babel/radio.js", "../dist/js/babel/radio.js",
"../dist/js/babel/radioInline.js",
"../dist/js/babel/ripples.js", "../dist/js/babel/ripples.js",
"../dist/js/babel/switch.js", "../dist/js/babel/switch.js",
"../dist/js/babel/util.js" "../dist/js/babel/util.js"

View File

@ -4,12 +4,12 @@ const BaseInput = (($) => {
const Default = { const Default = {
formGroup: { formGroup: {
required: true required: false
}, },
mdbFormGroup: { mdbFormGroup: {
template: `<div class='mdb-form-group'></div>`, template: `<span class='mdb-form-group'></span>`,
required: true, required: true, // strongly recommended not to override
autoCreate: true autoCreate: true // strongly recommended not to override
}, },
requiredClasses: [], requiredClasses: [],
invalidComponentMatches: [], invalidComponentMatches: [],
@ -41,10 +41,21 @@ const BaseInput = (($) => {
*/ */
class BaseInput { class BaseInput {
constructor(element, config) { /**
*
* @param element
* @param config
* @param properties - anything that needs to be set as this[key] = value. Works around the need to call `super` before using `this`
*/
constructor(element, config, properties = {}) {
this.$element = $(element) this.$element = $(element)
this.config = $.extend({}, Default, config) this.config = $.extend({}, Default, config)
// set properties for use in the constructor initialization
for (let key in properties) {
this[key] = properties[key]
}
// Enforce no overlap between components to prevent side effects // Enforce no overlap between components to prevent side effects
this._rejectInvalidComponentMatches() this._rejectInvalidComponentMatches()

View File

@ -8,11 +8,7 @@ const BaseToggle = (($) => {
* Constants * Constants
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
const Default = { const Default = {}
formGroup: {
required: false
}
}
const Selector = { const Selector = {
LABEL: 'label' LABEL: 'label'
@ -25,13 +21,13 @@ const BaseToggle = (($) => {
*/ */
class BaseToggle extends BaseInput { class BaseToggle extends BaseInput {
constructor(element, config, inputType, outerClass) { constructor(element, config, properties) {
super(element, $.extend({}, Default, config)) // properties = {inputType: checkbox, outerClass: checkbox-inline}
this.$element.after(this.config.template)
// '.checkbox|switch|radio > label > input[type=checkbox|radio]' // '.checkbox|switch|radio > label > input[type=checkbox|radio]'
// '.${this.outerClass} > label > input[type=${this.inputType}]' // '.${this.outerClass} > label > input[type=${this.inputType}]'
this.inputType = inputType
this.outerClass = outerClass super(element, $.extend({}, Default, config), properties)
this.$element.after(this.config.template)
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -39,16 +35,17 @@ const BaseToggle = (($) => {
// Demarcation element (e.g. first child of a form-group) // Demarcation element (e.g. first child of a form-group)
outerElement() { outerElement() {
// '.checkbox|switch|radio > label > input[type=checkbox|radio]' // .checkbox|switch|radio > label > input[type=checkbox|radio]
// '.${this.outerClass} > label > input[type=${this.inputType}]' // label.checkbox-inline > input[type=checkbox|radio]
return this.$element.parent().parent() // .${this.outerClass} > label > input[type=${this.inputType}]
return this.$element.parent().closest(`.${this.outerClass}`)
} }
rejectWithoutRequiredStructure() { rejectWithoutRequiredStructure() {
// '.checkbox|switch|radio > label > input[type=checkbox|radio]' // '.checkbox|switch|radio > label > input[type=checkbox|radio]'
// '.${this.outerClass} > label > input[type=${this.inputType}]' // '.${this.outerClass} > label > input[type=${this.inputType}]'
Util.assert(this.$element.parent().prop('tagName') === 'label', `${this.constructor.name}'s ${this.$element} parent element should be <label>.`) Util.assert(this.$element, !this.$element.parent().prop('tagName') === 'label', `${this.constructor.name}'s ${Util.describe(this.$element)} parent element should be <label>.`)
Util.assert(this.outerElement().hasClass(this.outerClass), `${this.constructor.name}'s ${this.$element} grandparent element should have class .${this.outerClass}.`) Util.assert(this.$element, !this.outerElement().hasClass(this.outerClass), `${this.constructor.name}'s ${Util.describe(this.$element)} outer element should have class ${this.outerClass}.`)
} }
addFocusListener() { addFocusListener() {

View File

@ -47,15 +47,18 @@ const BootstrapMaterialDesign = (($) => {
checkbox: { checkbox: {
selector: '.checkbox > label > input[type=checkbox]' selector: '.checkbox > label > input[type=checkbox]'
}, },
//checkboxInline: { checkboxInline: {
// selector: 'label.checkbox-inline > input[type=checkbox]' selector: 'label.checkbox-inline > input[type=checkbox]'
//}, },
switch: { switch: {
selector: '.switch > label > input[type=checkbox]' selector: '.switch > label > input[type=checkbox]'
}, },
radio: { radio: {
selector: '.radio > label > input[type=radio]' selector: '.radio > label > input[type=radio]'
}, },
radioInline: {
selector: 'label.radio-inline > input[type=radio]'
},
file: { file: {
selector: 'input[type=file]' selector: 'input[type=file]'
}, },
@ -67,8 +70,10 @@ const BootstrapMaterialDesign = (($) => {
instantiation: [ instantiation: [
'ripples', 'ripples',
'checkbox', 'checkbox',
'checkboxInline',
'file', 'file',
'radio', 'radio',
'radioInline',
'switch', 'switch',
'text', 'text',
'textarea', 'textarea',

View File

@ -28,14 +28,14 @@ const Checkbox = (($) => {
*/ */
class Checkbox extends BaseToggle { class Checkbox extends BaseToggle {
constructor(element, config, inputType = NAME, outerClass = NAME) { constructor(element, config, properties = {inputType: NAME, outerClass: NAME}) {
super(element, $.extend({ super(element, $.extend({
invalidComponentMatches: [File, Radio, Text, Textarea, Select] invalidComponentMatches: [File, Radio, Text, Textarea, Select]
}, Default, config), inputType, outerClass) }, Default, config), properties)
} }
dispose() { dispose(dataKey = DATA_KEY) {
super.dispose(DATA_KEY) super.dispose(dataKey)
} }
static matches($element) { static matches($element) {
@ -47,7 +47,7 @@ const Checkbox = (($) => {
} }
static rejectMatch(component, $element) { static rejectMatch(component, $element) {
Util.assert(this.matches($element), `${component} component is invalid for type='checkbox'.`) Util.assert(this.$element, this.matches($element), `${component} component element ${Util.describe($element)} is invalid for type='checkbox'.`)
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

83
js/src/checkboxInline.js Normal file
View File

@ -0,0 +1,83 @@
import Checkbox from './checkbox'
const CheckboxInline = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'checkboxInline'
const DATA_KEY = `mdb.${NAME}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class CheckboxInline extends Checkbox {
constructor(element, config, properties = {inputType: 'checkbox', outerClass: 'checkbox-inline'}) {
super(element, $.extend({}, Default, config), properties)
}
dispose() {
super.dispose(DATA_KEY)
}
//static matches($element) {
// // '.checkbox-inline > input[type=checkbox]'
// if ($element.attr('type') === 'checkbox') {
// return true
// }
// return false
//}
//
//static rejectMatch(component, $element) {
// Util.assert(this.$element, this.matches($element), `${component} component element ${Util.describe($element)} is invalid for type='checkbox'.`)
//}
// ------------------------------------------------------------------------
// protected
// ------------------------------------------------------------------------
// protected
// ------------------------------------------------------------------------
// private
// ------------------------------------------------------------------------
// static
static _jQueryInterface(config) {
return this.each(function () {
let $element = $(this)
let data = $element.data(DATA_KEY)
if (!data) {
data = new CheckboxInline(this, config)
$element.data(DATA_KEY, data)
}
})
}
}
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = CheckboxInline._jQueryInterface
$.fn[NAME].Constructor = CheckboxInline
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT
return CheckboxInline._jQueryInterface
}
return CheckboxInline
})(jQuery)
export default CheckboxInline

View File

@ -18,11 +18,7 @@ const File = (($) => {
const DATA_KEY = `mdb.${NAME}` const DATA_KEY = `mdb.${NAME}`
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = { const Default = {}
formGroup: {
required: false
}
}
const ClassName = { const ClassName = {
FILE: NAME, FILE: NAME,
@ -58,7 +54,7 @@ const File = (($) => {
} }
static rejectMatch(component, $element) { static rejectMatch(component, $element) {
Util.assert(this.matches($element), `${component} component is invalid for type='file'.`) Util.assert(this.$element, this.matches($element), `${component} component element ${Util.describe($element)} is invalid for type='file'.`)
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -67,13 +63,13 @@ const File = (($) => {
// Demarcation element (e.g. first child of a form-group) // Demarcation element (e.g. first child of a form-group)
outerElement() { outerElement() {
// label.file > input[type=file] // label.file > input[type=file]
return this.$element return this.$element.parent().closest(`.${ClassName.FILE}`)
} }
rejectWithoutRequiredStructure() { rejectWithoutRequiredStructure() {
// label.file > input[type=file] // label.file > input[type=file]
Util.assert(this.outerElement().prop('tagName') === 'label', `${this.constructor.name}'s ${Util.describe(this.$element)} parent element ${Util.describe(this.outerElement())} should be <label>.`) Util.assert(this.$element, !this.outerElement().prop('tagName') === 'label', `${this.constructor.name}'s ${Util.describe(this.$element)} parent element ${Util.describe(this.outerElement())} should be <label>.`)
Util.assert(this.outerElement().hasClass(ClassName.FILE), `${this.constructor.name}'s ${Util.describe(this.$element)} parent element ${Util.describe(this.outerElement())} should have class .${ClassName.FILE}.`) Util.assert(this.$element, !this.outerElement().hasClass(ClassName.FILE), `${this.constructor.name}'s ${Util.describe(this.$element)} parent element ${Util.describe(this.outerElement())} should have class .${ClassName.FILE}.`)
} }
addFocusListener() { addFocusListener() {

View File

@ -27,14 +27,14 @@ const Radio = (($) => {
*/ */
class Radio extends BaseToggle { class Radio extends BaseToggle {
constructor(element, config) { constructor(element, config, properties = {inputType: NAME, outerClass: NAME}) {
super(element, $.extend({ super(element, $.extend({
invalidComponentMatches: [Checkbox, File, Switch, Text] invalidComponentMatches: [Checkbox, File, Switch, Text]
}, Default, config), NAME, NAME) }, Default, config), properties)
} }
dispose() { dispose(dataKey = DATA_KEY) {
super.dispose(DATA_KEY) super.dispose(dataKey)
} }
static matches($element) { static matches($element) {
@ -46,7 +46,7 @@ const Radio = (($) => {
} }
static rejectMatch(component, $element) { static rejectMatch(component, $element) {
Util.assert(this.matches($element), `${component} component is invalid for type='radio'.`) Util.assert(this.$element, this.matches($element), `${component} component element ${Util.describe($element)} is invalid for type='radio'.`)
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

71
js/src/radioInline.js Normal file
View File

@ -0,0 +1,71 @@
import Radio from './radio'
const RadioInline = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'radioInline'
const DATA_KEY = `mdb.${NAME}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class RadioInline extends Radio {
constructor(element, config, properties = {inputType: 'radio', outerClass: 'radio-inline'}) {
super(element, $.extend({}, Default, config), properties)
}
dispose() {
super.dispose(DATA_KEY)
}
// ------------------------------------------------------------------------
// protected
// ------------------------------------------------------------------------
// protected
// ------------------------------------------------------------------------
// private
// ------------------------------------------------------------------------
// static
static _jQueryInterface(config) {
return this.each(function () {
let $element = $(this)
let data = $element.data(DATA_KEY)
if (!data) {
data = new RadioInline(this, config)
$element.data(DATA_KEY, data)
}
})
}
}
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = RadioInline._jQueryInterface
$.fn[NAME].Constructor = RadioInline
$.fn[NAME].noConflict = () => {
$.fn[NAME] = JQUERY_NO_CONFLICT
return RadioInline._jQueryInterface
}
return RadioInline
})(jQuery)
export default RadioInline

View File

@ -44,7 +44,7 @@ const Select = (($) => {
} }
static rejectMatch(component, $element) { static rejectMatch(component, $element) {
Util.assert(this.matches($element), `${component} component is invalid for <select>.`) Util.assert(this.$element, this.matches($element), `${component} component element ${Util.describe($element)} is invalid for <select>.`)
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -19,9 +19,6 @@ const Text = (($) => {
const JQUERY_NO_CONFLICT = $.fn[NAME] const JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = { const Default = {
formGroup: {
required: false
},
template: `<span class='text-input-decorator'></span>`, template: `<span class='text-input-decorator'></span>`,
requiredClasses: ['form-control'] requiredClasses: ['form-control']
} }
@ -57,7 +54,7 @@ const Text = (($) => {
} }
static rejectMatch(component, $element) { static rejectMatch(component, $element) {
Util.assert(this.matches($element), `${component} component is invalid for type='text'.`) Util.assert(this.$element, this.matches($element), `${component} component element ${Util.describe($element)} is invalid for type='text'.`)
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -42,7 +42,7 @@ const Textarea = (($) => {
} }
static rejectMatch(component, $element) { static rejectMatch(component, $element) {
Util.assert(this.matches($element), `${component} component is invalid for <textarea>.`) Util.assert(this.$element, this.matches($element), `${component} component element ${Util.describe($element)} is invalid for <textarea>.`)
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -66,13 +66,23 @@ const Util = (($) => {
return false return false
}, },
assert(test, message) { assert($element, invalidTest, message) {
if (test) { if (invalidTest) {
if (!$element === undefined) {
$element.css('border', '1px solid red')
}
console.error(message, $element) // eslint-disable-line no-console
$.error(message) $.error(message)
} }
}, },
describe($element) { describe($element) {
if ($element === undefined) {
return 'undefined'
}
else if ($element.length === 0){
return '(no matching elements)'
}
return `${$element[0].outerHTML.split('>')[0]}>` return `${$element[0].outerHTML.split('>')[0]}>`
} }
} }

View File

@ -1,15 +1,11 @@
// http://www.google.com/design/spec/components/selection-controls.html#selection-controls-checkbox // http://www.google.com/design/spec/components/selection-controls.html#selection-controls-checkbox
.form-group { label.checkbox,
} label.checkbox-inline,
.checkbox label,
.checkbox { .checkbox-inline label {
label { cursor: pointer;
cursor: pointer; padding-left: 0; // Reset for Bootstrap rule
padding-left: 0; // Reset for Bootstrap rule color: $mdb-checkbox-label-color;
color: $mdb-checkbox-label-color;
}
// Hide native checkbox // Hide native checkbox
input[type=checkbox] { input[type=checkbox] {
@ -28,12 +24,12 @@
vertical-align: middle; vertical-align: middle;
position: relative; position: relative;
top: 3px; top: 3px;
&:before { // FIXME: document why this is necessary (doesn't seem to be on chrome) &:before { // FIXME: document why this is necessary (doesn't seem to be on chrome)
display: block; display: block;
position: absolute; position: absolute;
left: 0; left: 0;
content: ""; content: "";
background-color: rgba(0,0,0,.84); background-color: rgba(0, 0, 0, .84);
height: $mdb-checkbox-size; height: $mdb-checkbox-size;
width: $mdb-checkbox-size; width: $mdb-checkbox-size;
border-radius: 100%; border-radius: 100%;
@ -61,14 +57,13 @@
margin-left: 6px; margin-left: 6px;
width: 0; width: 0;
height: 0; height: 0;
box-shadow: box-shadow: 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0 inset;
0 0 0 0 inset;
animation: checkbox-off $mdb-checkbox-animation-check forwards; animation: checkbox-off $mdb-checkbox-animation-check forwards;
} }
} }
@ -90,11 +85,11 @@
& + .checkbox-decorator .check:before { & + .checkbox-decorator .check:before {
color: $mdb-checkbox-checked-color; color: $mdb-checkbox-checked-color;
box-shadow: 0 0 0 10px, box-shadow: 0 0 0 10px,
10px -10px 0 10px, 10px -10px 0 10px,
32px 0 0 20px, 32px 0 0 20px,
0px 32px 0 20px, 0px 32px 0 20px,
-5px 5px 0 10px, -5px 5px 0 10px,
20px -12px 0 11px; 20px -12px 0 11px;
animation: checkbox-on $mdb-checkbox-animation-check forwards; animation: checkbox-on $mdb-checkbox-animation-check forwards;
} }
@ -136,54 +131,50 @@
@keyframes checkbox-on { @keyframes checkbox-on {
0% { 0% {
box-shadow: box-shadow: 0 0 0 10px,
0 0 0 10px, 10px -10px 0 10px,
10px -10px 0 10px, 32px 0 0 20px,
32px 0 0 20px, 0px 32px 0 20px,
0px 32px 0 20px, -5px 5px 0 10px,
-5px 5px 0 10px, 15px 2px 0 11px;
15px 2px 0 11px;
} }
50% { 50% {
box-shadow: box-shadow: 0 0 0 10px,
0 0 0 10px, 10px -10px 0 10px,
10px -10px 0 10px, 32px 0 0 20px,
32px 0 0 20px, 0px 32px 0 20px,
0px 32px 0 20px, -5px 5px 0 10px,
-5px 5px 0 10px, 20px 2px 0 11px;
20px 2px 0 11px;
} }
100% { 100% {
box-shadow: box-shadow: 0 0 0 10px,
0 0 0 10px, 10px -10px 0 10px,
10px -10px 0 10px, 32px 0 0 20px,
32px 0 0 20px, 0px 32px 0 20px,
0px 32px 0 20px, -5px 5px 0 10px,
-5px 5px 0 10px, 20px -12px 0 11px;
20px -12px 0 11px;
} }
} }
@keyframes checkbox-off { @keyframes checkbox-off {
0% { 0% {
box-shadow: box-shadow: 0 0 0 10px,
0 0 0 10px, 10px -10px 0 10px,
10px -10px 0 10px, 32px 0 0 20px,
32px 0 0 20px, 0px 32px 0 20px,
0px 32px 0 20px, -5px 5px 0 10px,
-5px 5px 0 10px, 20px -12px 0 11px,
20px -12px 0 11px, 0 0 0 0 inset;
0 0 0 0 inset;
} }
25% { 25% {
box-shadow: box-shadow: 0 0 0 10px,
0 0 0 10px, 10px -10px 0 10px,
10px -10px 0 10px, 32px 0 0 20px,
32px 0 0 20px, 0px 32px 0 20px,
0px 32px 0 20px, -5px 5px 0 10px,
-5px 5px 0 10px, 20px -12px 0 11px,
20px -12px 0 11px, 0 0 0 0 inset;
0 0 0 0 inset;
} }
50% { 50% {
transform: rotate(45deg); transform: rotate(45deg);
@ -191,14 +182,13 @@
margin-left: 6px; margin-left: 6px;
width: 0; width: 0;
height: 0; height: 0;
box-shadow: box-shadow: 0 0 0 10px,
0 0 0 10px, 10px -10px 0 10px,
10px -10px 0 10px, 32px 0 0 20px,
32px 0 0 20px, 0px 32px 0 20px,
0px 32px 0 20px, -5px 5px 0 10px,
-5px 5px 0 10px, 15px 2px 0 11px,
15px 2px 0 11px, 0 0 0 0 inset;
0 0 0 0 inset;
} }
51% { 51% {
transform: rotate(0deg); transform: rotate(0deg);
@ -206,14 +196,13 @@
margin-left: -2px; margin-left: -2px;
width: 20px; width: 20px;
height: 20px; height: 20px;
box-shadow: box-shadow: 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0px 0 0 10px inset;
0px 0 0 10px inset;
} }
100% { 100% {
transform: rotate(0deg); transform: rotate(0deg);
@ -221,16 +210,16 @@
margin-left: -2px; margin-left: -2px;
width: 20px; width: 20px;
height: 20px; height: 20px;
box-shadow: box-shadow: 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0 0 0 0,
0 0 0 0, 0px 0 0 0 inset;
0px 0 0 0 inset;
} }
} }
@keyframes rippleOn { @keyframes rippleOn {
0% { 0% {
opacity: 0; opacity: 0;
@ -242,6 +231,7 @@
opacity: 0; opacity: 0;
} }
} }
@keyframes rippleOff { @keyframes rippleOff {
0% { 0% {
opacity: 0; opacity: 0;

View File

@ -1,6 +1,4 @@
@mixin radio-color($color, $opacity) {
@mixin radio-color($color, $opacity){
& ~ .check, & ~ .check,
& ~ .radio-decorator { & ~ .radio-decorator {
opacity: $opacity; opacity: $opacity;
@ -15,55 +13,56 @@
} }
} }
.radio { label.radio,
label { label.radio-inline,
cursor: pointer; .radio label,
padding-left: 45px; .radio-inline label {
position: relative; cursor: pointer;
color: $mdb-radio-label-color; padding-left: 45px;
position: relative;
span { color: $mdb-radio-label-color;
display: block;
position: absolute;
left: 10px;
top: 2px;
transition-duration: 0.2s;
}
.radio-decorator {
border: 2px solid $mdb-radio-color-off;
height: 15px;
width: 15px;
border-radius: 100%;
}
.check {
height: 15px;
width: 15px;
border-radius: 100%;
background-color: $mdb-radio-color-on;
transform: scale3d(0, 0, 0);
}
.check:after {
display: block;
position: absolute;
content: "";
background-color: $mdb-text-color-primary;
left: -18px;
top: -18px;
height: 50px;
width: 50px;
border-radius: 100%;
z-index: 1;
opacity: 0;
margin: 0;
transform: scale3d(1.5, 1.5, 1);
}
input[type=radio]:not(:checked) ~ .check:after {
animation: rippleOff 500ms;
}
input[type=radio]:checked ~ .check:after {
animation: rippleOn 500ms;
}
span {
display: block;
position: absolute;
left: 10px;
top: 2px;
transition-duration: 0.2s;
}
.radio-decorator {
border: 2px solid $mdb-radio-color-off;
height: 15px;
width: 15px;
border-radius: 100%;
}
.check {
display: inline-block;
height: 15px;
width: 15px;
border-radius: 100%;
background-color: $mdb-radio-color-on;
transform: scale3d(0, 0, 0);
}
.check:after {
display: block;
position: absolute;
content: "";
background-color: $mdb-text-color-primary;
left: -18px;
top: -18px;
height: 50px;
width: 50px;
border-radius: 100%;
z-index: 1;
opacity: 0;
margin: 0;
transform: scale3d(1.5, 1.5, 1);
}
input[type=radio]:not(:checked) ~ .check:after {
animation: rippleOff 500ms;
}
input[type=radio]:checked ~ .check:after {
animation: rippleOn 500ms;
} }
input[type=radio] { input[type=radio] {
@ -92,6 +91,7 @@
} }
} }
@keyframes rippleOn { @keyframes rippleOn {
0% { 0% {
opacity: 0; opacity: 0;