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/select.js': 'js/src/select.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/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/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/select.js': 'js/src/select.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/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/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/select.js': 'js/src/select.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/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/bootstrapMaterialDesign.js': 'js/src/bootstrapMaterialDesign.js',
}
@ -226,8 +232,10 @@ module.exports = function (grunt) {
'dist/js/babel/textarea.js',
'dist/js/babel/select.js',
'dist/js/babel/checkbox.js',
'dist/js/babel/checkboxInline.js',
'dist/js/babel/switch.js',
'dist/js/babel/radio.js',
'dist/js/babel/radioInline.js',
'dist/js/babel/file.js',
'dist/js/babel/bootstrapMaterialDesign.js',
],

View File

@ -107,23 +107,15 @@ class Application {
.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()
app.displayTypographyProperties()
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()
})

View File

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

View File

@ -4,12 +4,12 @@ const BaseInput = (($) => {
const Default = {
formGroup: {
required: true
required: false
},
mdbFormGroup: {
template: `<div class='mdb-form-group'></div>`,
required: true,
autoCreate: true
template: `<span class='mdb-form-group'></span>`,
required: true, // strongly recommended not to override
autoCreate: true // strongly recommended not to override
},
requiredClasses: [],
invalidComponentMatches: [],
@ -41,10 +41,21 @@ const 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.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
this._rejectInvalidComponentMatches()

View File

@ -8,11 +8,7 @@ const BaseToggle = (($) => {
* Constants
* ------------------------------------------------------------------------
*/
const Default = {
formGroup: {
required: false
}
}
const Default = {}
const Selector = {
LABEL: 'label'
@ -25,13 +21,13 @@ const BaseToggle = (($) => {
*/
class BaseToggle extends BaseInput {
constructor(element, config, inputType, outerClass) {
super(element, $.extend({}, Default, config))
this.$element.after(this.config.template)
constructor(element, config, properties) {
// properties = {inputType: checkbox, outerClass: checkbox-inline}
// '.checkbox|switch|radio > label > input[type=checkbox|radio]'
// '.${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)
outerElement() {
// '.checkbox|switch|radio > label > input[type=checkbox|radio]'
// '.${this.outerClass} > label > input[type=${this.inputType}]'
return this.$element.parent().parent()
// .checkbox|switch|radio > label > input[type=checkbox|radio]
// label.checkbox-inline > input[type=checkbox|radio]
// .${this.outerClass} > label > input[type=${this.inputType}]
return this.$element.parent().closest(`.${this.outerClass}`)
}
rejectWithoutRequiredStructure() {
// '.checkbox|switch|radio > label > input[type=checkbox|radio]'
// '.${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.outerElement().hasClass(this.outerClass), `${this.constructor.name}'s ${this.$element} grandparent element should have class .${this.outerClass}.`)
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.$element, !this.outerElement().hasClass(this.outerClass), `${this.constructor.name}'s ${Util.describe(this.$element)} outer element should have class ${this.outerClass}.`)
}
addFocusListener() {

View File

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

View File

@ -28,14 +28,14 @@ const Checkbox = (($) => {
*/
class Checkbox extends BaseToggle {
constructor(element, config, inputType = NAME, outerClass = NAME) {
constructor(element, config, properties = {inputType: NAME, outerClass: NAME}) {
super(element, $.extend({
invalidComponentMatches: [File, Radio, Text, Textarea, Select]
}, Default, config), inputType, outerClass)
}, Default, config), properties)
}
dispose() {
super.dispose(DATA_KEY)
dispose(dataKey = DATA_KEY) {
super.dispose(dataKey)
}
static matches($element) {
@ -47,7 +47,7 @@ const Checkbox = (($) => {
}
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 JQUERY_NO_CONFLICT = $.fn[NAME]
const Default = {
formGroup: {
required: false
}
}
const Default = {}
const ClassName = {
FILE: NAME,
@ -58,7 +54,7 @@ const File = (($) => {
}
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)
outerElement() {
// label.file > input[type=file]
return this.$element
return this.$element.parent().closest(`.${ClassName.FILE}`)
}
rejectWithoutRequiredStructure() {
// 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.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().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().hasClass(ClassName.FILE), `${this.constructor.name}'s ${Util.describe(this.$element)} parent element ${Util.describe(this.outerElement())} should have class .${ClassName.FILE}.`)
}
addFocusListener() {

View File

@ -27,14 +27,14 @@ const Radio = (($) => {
*/
class Radio extends BaseToggle {
constructor(element, config) {
constructor(element, config, properties = {inputType: NAME, outerClass: NAME}) {
super(element, $.extend({
invalidComponentMatches: [Checkbox, File, Switch, Text]
}, Default, config), NAME, NAME)
}, Default, config), properties)
}
dispose() {
super.dispose(DATA_KEY)
dispose(dataKey = DATA_KEY) {
super.dispose(dataKey)
}
static matches($element) {
@ -46,7 +46,7 @@ const Radio = (($) => {
}
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) {
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 Default = {
formGroup: {
required: false
},
template: `<span class='text-input-decorator'></span>`,
requiredClasses: ['form-control']
}
@ -57,7 +54,7 @@ const Text = (($) => {
}
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) {
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
},
assert(test, message) {
if (test) {
assert($element, invalidTest, message) {
if (invalidTest) {
if (!$element === undefined) {
$element.css('border', '1px solid red')
}
console.error(message, $element) // eslint-disable-line no-console
$.error(message)
}
},
describe($element) {
if ($element === undefined) {
return 'undefined'
}
else if ($element.length === 0){
return '(no matching elements)'
}
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
.form-group {
}
.checkbox {
label {
cursor: pointer;
padding-left: 0; // Reset for Bootstrap rule
color: $mdb-checkbox-label-color;
}
label.checkbox,
label.checkbox-inline,
.checkbox label,
.checkbox-inline label {
cursor: pointer;
padding-left: 0; // Reset for Bootstrap rule
color: $mdb-checkbox-label-color;
// Hide native checkbox
input[type=checkbox] {
@ -28,12 +24,12 @@
vertical-align: middle;
position: relative;
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;
position: absolute;
left: 0;
content: "";
background-color: rgba(0,0,0,.84);
background-color: rgba(0, 0, 0, .84);
height: $mdb-checkbox-size;
width: $mdb-checkbox-size;
border-radius: 100%;
@ -61,14 +57,13 @@
margin-left: 6px;
width: 0;
height: 0;
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 inset;
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 inset;
animation: checkbox-off $mdb-checkbox-animation-check forwards;
}
}
@ -90,11 +85,11 @@
& + .checkbox-decorator .check:before {
color: $mdb-checkbox-checked-color;
box-shadow: 0 0 0 10px,
10px -10px 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px -12px 0 11px;
20px -12px 0 11px;
animation: checkbox-on $mdb-checkbox-animation-check forwards;
}
@ -136,54 +131,50 @@
@keyframes checkbox-on {
0% {
box-shadow:
0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
15px 2px 0 11px;
box-shadow: 0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
15px 2px 0 11px;
}
50% {
box-shadow:
0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px 2px 0 11px;
box-shadow: 0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px 2px 0 11px;
}
100% {
box-shadow:
0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px -12px 0 11px;
box-shadow: 0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px -12px 0 11px;
}
}
@keyframes checkbox-off {
0% {
box-shadow:
0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px -12px 0 11px,
0 0 0 0 inset;
box-shadow: 0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px -12px 0 11px,
0 0 0 0 inset;
}
25% {
box-shadow:
0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px -12px 0 11px,
0 0 0 0 inset;
box-shadow: 0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
20px -12px 0 11px,
0 0 0 0 inset;
}
50% {
transform: rotate(45deg);
@ -191,14 +182,13 @@
margin-left: 6px;
width: 0;
height: 0;
box-shadow:
0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
15px 2px 0 11px,
0 0 0 0 inset;
box-shadow: 0 0 0 10px,
10px -10px 0 10px,
32px 0 0 20px,
0px 32px 0 20px,
-5px 5px 0 10px,
15px 2px 0 11px,
0 0 0 0 inset;
}
51% {
transform: rotate(0deg);
@ -206,14 +196,13 @@
margin-left: -2px;
width: 20px;
height: 20px;
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,
0px 0 0 10px inset;
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,
0px 0 0 10px inset;
}
100% {
transform: rotate(0deg);
@ -221,16 +210,16 @@
margin-left: -2px;
width: 20px;
height: 20px;
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,
0px 0 0 0 inset;
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,
0px 0 0 0 inset;
}
}
@keyframes rippleOn {
0% {
opacity: 0;
@ -242,6 +231,7 @@
opacity: 0;
}
}
@keyframes rippleOff {
0% {
opacity: 0;

View File

@ -1,6 +1,4 @@
@mixin radio-color($color, $opacity){
@mixin radio-color($color, $opacity) {
& ~ .check,
& ~ .radio-decorator {
opacity: $opacity;
@ -15,55 +13,56 @@
}
}
.radio {
label {
cursor: pointer;
padding-left: 45px;
position: relative;
color: $mdb-radio-label-color;
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 {
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;
}
label.radio,
label.radio-inline,
.radio label,
.radio-inline label {
cursor: pointer;
padding-left: 45px;
position: relative;
color: $mdb-radio-label-color;
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] {
@ -92,6 +91,7 @@
}
}
@keyframes rippleOn {
0% {
opacity: 0;