diff --git a/docs/material-design/buttons.md b/docs/material-design/buttons.md index 439669e6..d4e03607 100644 --- a/docs/material-design/buttons.md +++ b/docs/material-design/buttons.md @@ -12,8 +12,6 @@ group: material-design ## Flat {% example html %} - - @@ -21,6 +19,8 @@ group: material-design + + {% endexample %} ### Disabled @@ -41,7 +41,6 @@ group: material-design ## Raised {% example html %} - @@ -49,6 +48,7 @@ group: material-design + {% endexample %} ### Disabled diff --git a/docs/material-design/test.md b/docs/material-design/test.md index 2fcb7be0..b8036d8c 100644 --- a/docs/material-design/test.md +++ b/docs/material-design/test.md @@ -5,26 +5,5 @@ group: material-design --- {% example html %} -
+ {% endexample %} diff --git a/js/src/autofill.js b/js/src/autofill.js index 6a5b6e09..8aede971 100644 --- a/js/src/autofill.js +++ b/js/src/autofill.js @@ -79,7 +79,7 @@ const Autofill = (($) => { // ------------------------------------------------------------------------ // static static _jQueryInterface(config) { - return this.each(() => { + return this.each(function () { let $element = $(this) let data = $element.data(DATA_KEY) diff --git a/js/src/baseInput.js b/js/src/baseInput.js index 0affa335..4a917235 100644 --- a/js/src/baseInput.js +++ b/js/src/baseInput.js @@ -254,7 +254,7 @@ const BaseInput = (($) => { } if (label !== undefined && label.length > 0) { - break; + break } } diff --git a/js/src/bootstrapMaterialDesign.js b/js/src/bootstrapMaterialDesign.js index d1fb2a25..1c97c557 100644 --- a/js/src/bootstrapMaterialDesign.js +++ b/js/src/bootstrapMaterialDesign.js @@ -36,6 +36,7 @@ const BootstrapMaterialDesign = (($) => { } }, ripples: { + //selector: ['.btn:not(.btn-link):not(.ripple-none)'] // testing only selector: [ '.btn:not(.btn-link):not(.ripple-none)', '.card-image:not(.ripple-none)', @@ -124,7 +125,7 @@ const BootstrapMaterialDesign = (($) => { let jqueryFn = `mdb${component.charAt(0).toUpperCase() + component.slice(1)}` // instantiate component on selector elements with config - // console.debug(`instantiating: ${component}`) + // console.debug(`instantiating: $('${selector}')[${jqueryFn}](${componentConfig})`) // eslint-disable-line no-console $(selector)[jqueryFn](componentConfig) // add to arrive if present and enabled diff --git a/js/src/ripples.js b/js/src/ripples.js index 38875474..c96cdf26 100644 --- a/js/src/ripples.js +++ b/js/src/ripples.js @@ -28,7 +28,7 @@ const Ripples = (($) => { template: `` }, decorator: { - template: `${ClassName.DECORATOR}'>` + template: `` }, trigger: { start: 'mousedown touchstart', @@ -52,14 +52,17 @@ const Ripples = (($) => { this.config = $.extend(true, {}, Default, config) // attach initial listener - this.$element.on(this.config.triggerStart, this._onStartRipple) + this.$element.on(this.config.trigger.start, (event) => { + this._onStartRipple(event) + }) } + dispose() { $.removeData(this.$element, DATA_KEY) this.$element = null - this.containerElement = null - this.decoratorElement = null + this.$container = null + this.$decorator = null this.config = null } @@ -69,7 +72,7 @@ const Ripples = (($) => { _onStartRipple(event) { // Verify if the user is just touching on a device and return if so - if (this.isTouch() && event.type === 'mousedown') { + if (this._isTouch() && event.type === 'mousedown') { return } @@ -86,7 +89,7 @@ const Ripples = (($) => { } // set the location and color each time (even if element is cached) - this.decoratorElement.css({ + this.$decorator.css({ left: relX, top: relY, 'background-color': this._getRipplesColor() @@ -103,40 +106,43 @@ const Ripples = (($) => { this.rippleEnd() }, this.config.duration) - // Detect when the user leaves the element (attach only when necessary for performance) - this.$element.on(this.config.triggerEnd, () => { - this.decoratorElement.data('mousedown', 'off') + // Detect when the user leaves the element to cleanup if not already done? + this.$element.on(this.config.trigger.end, () => { + if (this.$decorator) { // guard against race condition/mouse attack + this.$decorator.data('mousedown', 'off') - if (this.decoratorElement.data('animating') === 'off') { - this.rippleOut() + if (this.$decorator.data('animating') === 'off') { + this.rippleOut() + } } }) } _findOrCreateContainer() { - if (!this.containerElement || !this.containerElement.length > 0) { + if (!this.$container || !this.$container.length > 0) { this.$element.append(this.config.container.template) - this.containerElement = this.$element.find(Selector.CONTAINER) + this.$container = this.$element.find(Selector.CONTAINER) } // always add the rippleElement, it is always removed - this.containerElement.append(this.config.$element.template) - this.decoratorElement = this.containerElement.find(Selector.DECORATOR) + this.$container.append(this.config.decorator.template) + this.$decorator = this.$container.find(Selector.DECORATOR) } // Make sure the ripple has the styles applied (ugly hack but it works) _forceStyleApplication() { - return window.getComputedStyle(this.decoratorElement[0]).opacity + return window.getComputedStyle(this.$decorator[0]).opacity } + /** * Get the relX */ _getRelX(event) { - let wrapperOffset = this.containerElement.offset() + let wrapperOffset = this.$container.offset() let result = null - if (!this.isTouch()) { + if (!this._isTouch()) { // Get the mouse position relative to the ripple wrapper result = event.pageX - wrapperOffset.left } else { @@ -158,10 +164,10 @@ const Ripples = (($) => { * Get the relY */ _getRelY(event) { - let containerOffset = this.containerElement.offset() + let containerOffset = this.$container.offset() let result = null - if (!this.isTouch()) { + if (!this._isTouch()) { /** * Get the mouse position relative to the ripple wrapper */ @@ -194,7 +200,7 @@ const Ripples = (($) => { /** * Verify if the client is using a mobile device */ - isTouch() { + _isTouch() { return this.config.touchUserAgentRegex.test(navigator.userAgent) } @@ -202,10 +208,12 @@ const Ripples = (($) => { * End the animation of the ripple */ rippleEnd() { - this.decoratorElement.data('animating', 'off') + if (this.$decorator) { // guard against race condition/mouse attack + this.$decorator.data('animating', 'off') - if (this.decoratorElement.data('mousedown') === 'off') { - this.rippleOut(this.decoratorElement) + if (this.$decorator.data('mousedown') === 'off') { + this.rippleOut(this.$decorator) + } } } @@ -213,19 +221,21 @@ const Ripples = (($) => { * Turn off the ripple effect */ rippleOut() { - this.decoratorElement.off() + this.$decorator.off() if (Util.transitionEndSupported()) { - this.decoratorElement.addClass('ripple-out') + this.$decorator.addClass('ripple-out') } else { - this.decoratorElement.animate({opacity: 0}, 100, () => { - this.decoratorElement.triggerStart('transitionend') + this.$decorator.animate({opacity: 0}, 100, () => { + this.$decorator.trigger('transitionend') }) } - this.decoratorElement.on(Util.transitionEndSelector(), () => { - this.decoratorElement.remove() - this.decoratorElement = null + this.$decorator.on(Util.transitionEndSelector(), () => { + if (this.$decorator) { + this.$decorator.remove() + this.$decorator = null + } }) } @@ -236,7 +246,7 @@ const Ripples = (($) => { let size = this._getNewSize() if (Util.transitionEndSupported()) { - this.decoratorElement + this.$decorator .css({ '-ms-transform': `scale(${size})`, '-moz-transform': `scale(${size})`, @@ -247,14 +257,14 @@ const Ripples = (($) => { .data('animating', 'on') .data('mousedown', 'on') } else { - this.decoratorElement.animate({ + this.$decorator.animate({ width: Math.max(this.$element.outerWidth(), this.$element.outerHeight()) * 2, height: Math.max(this.$element.outerWidth(), this.$element.outerHeight()) * 2, 'margin-left': Math.max(this.$element.outerWidth(), this.$element.outerHeight()) * (-1), 'margin-top': Math.max(this.$element.outerWidth(), this.$element.outerHeight()) * (-1), opacity: 0.2 }, this.config.duration, () => { - this.decoratorElement.triggerStart('transitionend') + this.$decorator.triggerStart('transitionend') }) } } @@ -263,14 +273,14 @@ const Ripples = (($) => { * Get the new size based on the element height/width and the ripple width */ _getNewSize() { - return (Math.max(this.$element.outerWidth(), this.$element.outerHeight()) / this.decoratorElement.outerWidth()) * 2.5 + return (Math.max(this.$element.outerWidth(), this.$element.outerHeight()) / this.$decorator.outerWidth()) * 2.5 } // ------------------------------------------------------------------------ // static static _jQueryInterface(config) { - return this.each(() => { + return this.each(function () { let $element = $(this) let data = $element.data(DATA_KEY) diff --git a/js/src/util.js b/js/src/util.js index 721e1eea..016d3377 100644 --- a/js/src/util.js +++ b/js/src/util.js @@ -65,13 +65,13 @@ const Util = (($) => { !event.ctrlKey && !event.metaKey && !event.altKey - && event.which != 8 // backspace - && event.which != 9 // tab - && event.which != 13 // enter - && event.which != 16 // shift - && event.which != 17 // ctrl - && event.which != 20 // caps lock - && event.which != 27 // escape + && event.which !== 8 // backspace + && event.which !== 9 // tab + && event.which !== 13 // enter + && event.which !== 16 // shift + && event.which !== 17 // ctrl + && event.which !== 20 // caps lock + && event.which !== 27 // escape ) } return false @@ -90,8 +90,7 @@ const Util = (($) => { describe($element) { if ($element === undefined) { return 'undefined' - } - else if ($element.length === 0){ + } else if ($element.length === 0) { return '(no matching elements)' } return `${$element[0].outerHTML.split('>')[0]}>` diff --git a/scss/_buttons.scss b/scss/_buttons.scss index 4ab3c9f7..d98ef74a 100644 --- a/scss/_buttons.scss +++ b/scss/_buttons.scss @@ -3,6 +3,7 @@ // mdb default buttons are flat by default .btn { position: relative; + margin-bottom: $mdb-btn-margin-bottom; // just enough room so that focus shadows aren't covered up font-size: $mdb-btn-font-size; text-decoration: none; text-transform: uppercase; @@ -15,7 +16,7 @@ transition: box-shadow 0.2s $mdb-animation-curve-fast-out-linear-in, background-color 0.2s $mdb-animation-curve-default, color 0.2s $mdb-animation-curve-default; will-change: box-shadow, transform; - @include undo-tab-focus(); // clear out the tab-focus() from BS + @include undo-bs-tab-focus(); //-- // Colors @@ -34,28 +35,40 @@ // btn-raised &.btn-raised, .btn-group-raised & { - &:not(.btn-link) { - @include shadow-2dp(); - // contrast bg colors on hover, focus, active + // baseline shadow + @include shadow-2dp(); + + // contrast bg colors on hover, focus, active + @include mdb-hover-focus-active() { + @include mdb-button-colored-bg(true); + //border: 1px solid $red; + } + + // enlarged shadow on hover, focus + @include hover-focus() { + //border: 1px solid $blue; + @include shadow-4dp(); + } + + // :active - momentary press: big shadow, release and it is gone + // .active - persistent big shadow + &.active, + &:active { + @include focus-shadow(); + //border: 1px solid $green; + } + + // reverse any of the above for links + &.btn-link { + box-shadow: none; @include mdb-hover-focus-active() { - @include mdb-button-colored-bg(true); - //border: 1px solid $red; + box-shadow: none; } + } - // enlarged shadow on hover, focus - @include hover-focus() { - //border: 1px solid $blue; - @include shadow-4dp(); - } - - // :active - momentary press: big shadow, release and it is gone - // .active - persistent big shadow - &.active, - &:active { - @include focus-shadow(); - //border: 1px solid $green; - } + @include mdb-disabled() { + box-shadow: none; } } @@ -71,7 +84,7 @@ font-size: $mdb-btn-fab-font-size; line-height: normal; border-radius: 50%; - box-shadow: 0 1px 1.5px 0 rgba($black, 0.12), 0 1px 1px 0 rgba($black, 0.24); + box-shadow: 0 1px 1.5px 0 $gray-lighter, 0 1px 1px 0 $gray-light; .ripple-container { border-radius: 50%; @@ -122,10 +135,7 @@ .btn-group, .btn-group-vertical { // have to ratchet up the specificity to kill drop shadows on disabled raised buttons - fieldset[disabled][disabled] &, - &.disabled, - &:disabled, - &[disabled][disabled] { + @include mdb-disabled() { color: $mdb-btn-disabled; .theme-dark & { color: $mdb-btn-disabled-dark; diff --git a/scss/_forms.scss b/scss/_forms.scss index 02ee293c..69aeb18a 100644 --- a/scss/_forms.scss +++ b/scss/_forms.scss @@ -17,8 +17,7 @@ form { border-bottom: $input-btn-border-width solid $input-border-color; } - &[disabled], - fieldset[disabled] & { + @include mdb-disabled() { border-bottom: $input-btn-border-width dotted $input-border-color; } } diff --git a/scss/_variables.scss b/scss/_variables.scss index 1630b358..fa2f09e8 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -121,7 +121,7 @@ $mdb-radio-color-disabled-dark: rgba($white, 0.30); // dark theme spec: Disable $mdb-btn-font-size: .875rem !default; // 14px $mdb-btn-font-size-lg: 1rem !default; $mdb-btn-font-size-sm: .75rem !default; // 12px -$mdl-btn-border-radius: 2px !default; +$mdb-btn-margin-bottom: .3125rem !default; // 5px // btn with no other designation $mdb-btn-color: $gray-dark !default; diff --git a/scss/mixins/_buttons.scss b/scss/mixins/_buttons.scss index 56313c8a..894d2456 100644 --- a/scss/mixins/_buttons.scss +++ b/scss/mixins/_buttons.scss @@ -86,6 +86,11 @@ // default @include mdb-button-bg($mdb-btn-bg, $contrast); + // no bg for links + &.btn-link { + background-color: transparent; + } + &.btn-primary { @include mdb-button-bg($btn-primary-bg, $contrast); } @@ -106,7 +111,7 @@ } } -@mixin undo-tab-focus() { +@mixin undo-bs-tab-focus() { // clear out the tab-focus() from BS &, &:active, diff --git a/scss/mixins/_forms.scss b/scss/mixins/_forms.scss index f8c31959..e41896bc 100644 --- a/scss/mixins/_forms.scss +++ b/scss/mixins/_forms.scss @@ -1,3 +1,12 @@ +@mixin mdb-disabled() { + fieldset[disabled][disabled] &, + &.disabled, + &:disabled, + &[disabled] { + @content + } +} + @mixin mdb-selection-color() { .radio label, .radio-inline,