mirror of
https://github.com/mdbootstrap/mdb-ui-kit.git
synced 2024-11-25 19:14:09 +03:00
ripples es6 refactoring with a util class
This commit is contained in:
parent
3abd40f72a
commit
8cb4f02d63
|
@ -86,6 +86,7 @@ module.exports = function (grunt) {
|
|||
modules: 'ignore'
|
||||
},
|
||||
files: {
|
||||
'js/dist/util.js' : 'js/src/util.js',
|
||||
'js/dist/ripples.js' : 'js/src/ripples.js' //,
|
||||
//'js/dist/alert.js' : 'js/src/alert.js',
|
||||
//'js/dist/button.js' : 'js/src/button.js',
|
||||
|
@ -112,6 +113,7 @@ module.exports = function (grunt) {
|
|||
modules: 'umd'
|
||||
},
|
||||
files: {
|
||||
'dist/js/umd/util.js' : 'js/src/util.js',
|
||||
'dist/js/umd/ripples.js' : 'js/src/ripples.js' //,
|
||||
//'dist/js/umd/alert.js' : 'js/src/alert.js',
|
||||
//'dist/js/umd/button.js' : 'js/src/button.js',
|
||||
|
@ -173,6 +175,7 @@ module.exports = function (grunt) {
|
|||
},
|
||||
bootstrap: {
|
||||
src: [
|
||||
'js/src/util.js',
|
||||
'js/src/ripples.js',
|
||||
//'js/src/alert.js',
|
||||
//'js/src/button.js',
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const Foo = (($) => {
|
||||
import Util from './util'
|
||||
|
||||
const Foo = (($) => {
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
|
@ -8,21 +9,8 @@ const Foo = (($) => {
|
|||
*/
|
||||
const NAME = 'foo'
|
||||
const DATA_KEY = `bmd.${NAME}`
|
||||
const EVENT_KEY = `.${DATA_KEY}`
|
||||
const DATA_API_KEY = '.data-api'
|
||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
||||
|
||||
const Selector = {
|
||||
DATA_DISMISS: '[data-dismiss="foo"]'
|
||||
}
|
||||
|
||||
const Event = {
|
||||
CLOSE: `close${EVENT_KEY}`,
|
||||
CLOSED: `closed${EVENT_KEY}`,
|
||||
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
|
@ -31,34 +19,15 @@ const Foo = (($) => {
|
|||
class Foo {
|
||||
|
||||
constructor(element) {
|
||||
this._element = element
|
||||
}
|
||||
|
||||
// getters
|
||||
static get NAME() {
|
||||
return NAME
|
||||
}
|
||||
|
||||
// public
|
||||
close(element) {
|
||||
element = element || this._element
|
||||
|
||||
let rootElement = this._getRootElement(element)
|
||||
let customEvent = this._triggerCloseEvent(rootElement)
|
||||
|
||||
if (customEvent.isDefaultPrevented()) {
|
||||
return
|
||||
}
|
||||
|
||||
this._removeElement(rootElement)
|
||||
this.element = element
|
||||
}
|
||||
|
||||
dispose() {
|
||||
$.removeData(this._element, DATA_KEY)
|
||||
this._element = null
|
||||
$.removeData(this.element, DATA_KEY)
|
||||
this.element = null
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// private
|
||||
|
||||
_bar(element) {
|
||||
|
@ -66,7 +35,7 @@ const Foo = (($) => {
|
|||
return x
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// static
|
||||
static _jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
|
@ -83,32 +52,8 @@ const Foo = (($) => {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
static _handleClose(fooInstance) {
|
||||
return function (event) {
|
||||
if (event) {
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
fooInstance.close(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
$(document).on(
|
||||
Event.CLICK_DATA_API,
|
||||
Selector.DATA_DISMISS,
|
||||
Foo._handleClose(new Foo())
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// FIXME: look at bootstrap/Util.js for transition support functions
|
||||
|
||||
const Ripples = (($) => {
|
||||
|
||||
/**
|
||||
|
@ -8,7 +10,17 @@ const Ripples = (($) => {
|
|||
const NAME = 'ripples'
|
||||
const DATA_KEY = `bmd.${NAME}`
|
||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
||||
const DEFAULT_OPTIONS = {}
|
||||
|
||||
const Default = {
|
||||
containerSelector: '.ripple-container',
|
||||
rippleSelector: 'div.ripple',
|
||||
containerTemplate: `<div class='ripple-container'></div>`,
|
||||
rippleTemplate: `<div class='ripple'></div>`,
|
||||
touchUserAgentRegex: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i,
|
||||
triggerStart: 'mousedown touchstart',
|
||||
triggerEnd: 'mouseup mouseleave touchend',
|
||||
duration: 500
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
|
@ -17,18 +29,20 @@ const Ripples = (($) => {
|
|||
*/
|
||||
class Ripples {
|
||||
|
||||
constructor(element, options) {
|
||||
this._element = $(element)
|
||||
this._options = $.extend({}, DEFAULT_OPTIONS, options)
|
||||
this._element.on("mousedown touchstart", this._onStartRipple)
|
||||
constructor(element, config) {
|
||||
this.element = $(element)
|
||||
this.config = $.extend({}, Default, config)
|
||||
|
||||
// attach initial listener
|
||||
this.element.on(this.config.triggerStart, this._onStartRipple)
|
||||
}
|
||||
|
||||
dispose() {
|
||||
$.removeData(this._element, DATA_KEY)
|
||||
this._element = null
|
||||
this._containerElement = null
|
||||
this._rippleElement = null
|
||||
this._options = null
|
||||
$.removeData(this.element, DATA_KEY)
|
||||
this.element = null
|
||||
this.containerElement = null
|
||||
this.rippleElement = null
|
||||
this.config = null
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -54,7 +68,7 @@ const Ripples = (($) => {
|
|||
}
|
||||
|
||||
// set the location and color each time (even if element is cached)
|
||||
this._rippleElement.addClass("ripple").css({
|
||||
this.rippleElement.css({
|
||||
"left": relX,
|
||||
"top": relY,
|
||||
"background-color": this._getRipplesColor()
|
||||
|
@ -69,38 +83,39 @@ const Ripples = (($) => {
|
|||
// Call the rippleEnd function when the transition "on" ends
|
||||
setTimeout(() => {
|
||||
this.rippleEnd()
|
||||
}, 500)
|
||||
}, this.config.duration)
|
||||
|
||||
// Detect when the user leaves the element (attach only when necessary for performance)
|
||||
this._element.on("mouseup mouseleave touchend", () => {
|
||||
this._rippleElement.data("mousedown", "off")
|
||||
this.element.on(this.config.triggerEnd, () => {
|
||||
this.rippleElement.data("mousedown", "off")
|
||||
|
||||
if (this._rippleElement.data("animating") === "off") {
|
||||
if (this.rippleElement.data("animating") === "off") {
|
||||
this.rippleOut()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
_findOrCreateContainer() {
|
||||
if (!this._containerElement || !this._containerElement.length > 0) {
|
||||
this._element.append("<div class='ripple-container'><div class='ripple'></div></div>")
|
||||
this._containerElement = this._element.find(".ripple-container")
|
||||
this._rippleElement = this._containerElement.find("div.ripple")
|
||||
if (!this.containerElement || !this.containerElement.length > 0) {
|
||||
this.element.append(this.config.containerTemplate)
|
||||
this.containerElement = this.element.find(this.config.containerSelector)
|
||||
}
|
||||
|
||||
return this._containerElement
|
||||
// always add the rippleElement, it is always removed
|
||||
this.containerElement.append(this.config.rippleTemplate)
|
||||
this.rippleElement = this.containerElement.find(this.config.rippleSelector)
|
||||
}
|
||||
|
||||
// Make sure the ripple has the styles applied (ugly hack but it works)
|
||||
_forceStyleApplication() {
|
||||
return window.getComputedStyle(this._rippleElement[0]).opacity
|
||||
return window.getComputedStyle(this.rippleElement[0]).opacity
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relX
|
||||
*/
|
||||
_getRelX(event) {
|
||||
let wrapperOffset = this._containerElement.offset()
|
||||
let wrapperOffset = this.containerElement.offset()
|
||||
|
||||
let result = null
|
||||
if (!this.isTouch()) {
|
||||
|
@ -125,7 +140,7 @@ const Ripples = (($) => {
|
|||
* Get the relY
|
||||
*/
|
||||
_getRelY(event) {
|
||||
let containerOffset = this._containerElement.offset()
|
||||
let containerOffset = this.containerElement.offset()
|
||||
let result = null
|
||||
|
||||
if (!this.isTouch()) {
|
||||
|
@ -154,43 +169,25 @@ const Ripples = (($) => {
|
|||
* Get the ripple color
|
||||
*/
|
||||
_getRipplesColor() {
|
||||
let color = this._element.data("ripple-color") ? this._element.data("ripple-color") : window.getComputedStyle(this._element[0]).color
|
||||
let color = this.element.data("ripple-color") ? this.element.data("ripple-color") : window.getComputedStyle(this.element[0]).color
|
||||
return color
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if the client browser has transistion support
|
||||
*/
|
||||
_hasTransitionSupport() {
|
||||
let thisBody = document.body || document.documentElement
|
||||
let thisStyle = thisBody.style
|
||||
|
||||
let support = (
|
||||
thisStyle.transition !== undefined ||
|
||||
thisStyle.WebkitTransition !== undefined ||
|
||||
thisStyle.MozTransition !== undefined ||
|
||||
thisStyle.MsTransition !== undefined ||
|
||||
thisStyle.OTransition !== undefined
|
||||
)
|
||||
|
||||
return support
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if the client is using a mobile device
|
||||
*/
|
||||
isTouch() {
|
||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||
return this.config.touchUserAgentRegex.test(navigator.userAgent)
|
||||
}
|
||||
|
||||
/**
|
||||
* End the animation of the ripple
|
||||
*/
|
||||
rippleEnd() {
|
||||
this._rippleElement.data("animating", "off")
|
||||
this.rippleElement.data("animating", "off")
|
||||
|
||||
if (this._rippleElement.data("mousedown") === "off") {
|
||||
this.rippleOut(this._rippleElement)
|
||||
if (this.rippleElement.data("mousedown") === "off") {
|
||||
this.rippleOut(this.rippleElement)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,18 +195,19 @@ const Ripples = (($) => {
|
|||
* Turn off the ripple effect
|
||||
*/
|
||||
rippleOut() {
|
||||
this._rippleElement.off()
|
||||
this.rippleElement.off()
|
||||
|
||||
if (this._hasTransitionSupport()) {
|
||||
this._rippleElement.addClass("ripple-out")
|
||||
if ($.transitionEndSupported()) {
|
||||
this.rippleElement.addClass("ripple-out")
|
||||
} else {
|
||||
this._rippleElement.animate({ "opacity": 0 }, 100, () => {
|
||||
this._rippleElement.trigger("transitionend")
|
||||
this.rippleElement.animate({ "opacity": 0 }, 100, () => {
|
||||
this.rippleElement.triggerStart("transitionend")
|
||||
})
|
||||
}
|
||||
|
||||
this._rippleElement.on("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", () => {
|
||||
this._rippleElement.remove()
|
||||
this.rippleElement.on($.transitionEndSelector(), () => {
|
||||
this.rippleElement.remove()
|
||||
this.rippleElement = null
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -219,8 +217,8 @@ const Ripples = (($) => {
|
|||
rippleOn() {
|
||||
let size = this._getNewSize()
|
||||
|
||||
if (this._hasTransitionSupport()) {
|
||||
this._rippleElement
|
||||
if ($.transitionEndSupported()) {
|
||||
this.rippleElement
|
||||
.css({
|
||||
"-ms-transform": `scale(${size})`,
|
||||
"-moz-transform": `scale(${size})`,
|
||||
|
@ -231,14 +229,14 @@ const Ripples = (($) => {
|
|||
.data("animating", "on")
|
||||
.data("mousedown", "on")
|
||||
} else {
|
||||
this._rippleElement.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),
|
||||
this.rippleElement.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
|
||||
}, 500, () => {
|
||||
this._rippleElement.trigger("transitionend")
|
||||
}, this.config.duration, () => {
|
||||
this.rippleElement.triggerStart("transitionend")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +245,7 @@ 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._rippleElement.outerWidth()) * 2.5
|
||||
return (Math.max(this.element.outerWidth(), this.element.outerHeight()) / this.rippleElement.outerWidth()) * 2.5
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
82
js/src/util.js
Normal file
82
js/src/util.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
const Util = (($) => {
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Private TransitionEnd Helpers
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
let transitionEnd = false
|
||||
let transitionEndSelector = ""
|
||||
|
||||
const TransitionEndEvent = {
|
||||
WebkitTransition: 'webkitTransitionEnd',
|
||||
MozTransition: 'transitionend',
|
||||
OTransition: 'oTransitionEnd otransitionend',
|
||||
transition: 'transitionend'
|
||||
}
|
||||
|
||||
function transitionEndTest() {
|
||||
if (window.QUnit) {
|
||||
return false
|
||||
}
|
||||
|
||||
let el = document.createElement('mdb')
|
||||
|
||||
for (let name in TransitionEndEvent) {
|
||||
if (el.style[name] !== undefined) {
|
||||
return TransitionEndEvent[name] //{ end: TransitionEndEvent[name] }
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function setTransitionEndSupport() {
|
||||
transitionEnd = transitionEndTest()
|
||||
$.fn.transitionEndSupported = () => {
|
||||
return transitionEnd
|
||||
}
|
||||
|
||||
// generate a selector
|
||||
for (let name in TransitionEndEvent) {
|
||||
transitionEndSelector += ` ${TransitionEndEvent[name]}`
|
||||
}
|
||||
$.fn.transitionEndSelector = () => {
|
||||
return transitionEndSelector
|
||||
} // FIXME: make this a Util.* method instead?
|
||||
}
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Public Util Api
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
let Util = {
|
||||
|
||||
isChar(evt) {
|
||||
if (typeof evt.which == "undefined") {
|
||||
return true
|
||||
} else if (typeof evt.which == "number" && evt.which > 0) {
|
||||
return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8 && evt.which != 9
|
||||
}
|
||||
else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
|
||||
/* /!**
|
||||
* Verify if the client browser has transistion support
|
||||
*!/
|
||||
hasTransitionSupport() {
|
||||
return transition
|
||||
}*/
|
||||
}
|
||||
|
||||
setTransitionEndSupport()
|
||||
return Util
|
||||
|
||||
})(jQuery)
|
||||
|
||||
export default Util
|
Loading…
Reference in New Issue
Block a user