extracting css

This commit is contained in:
yev
2017-12-27 20:35:19 +00:00
parent 2be134436f
commit d302df7310

View File

@@ -28,13 +28,13 @@
</transition> </transition>
</template> </template>
<script> <script>
import Modal from "./index"; import Modal from './index'
import Resizer from "./Resizer.vue"; import Resizer from './Resizer.vue'
import { inRange } from "./util"; import { inRange } from './util'
import parseNumber from "./parser"; import parseNumber from './parser'
export default { export default {
name: "VueJsModal", name: 'VueJsModal',
props: { props: {
name: { name: {
required: true, required: true,
@@ -73,64 +73,64 @@ export default {
}, },
classes: { classes: {
type: [String, Array], type: [String, Array],
default: "v--modal" default: 'v--modal'
}, },
minWidth: { minWidth: {
type: Number, type: Number,
default: 0, default: 0,
validator(value) { validator(value) {
return value >= 0; return value >= 0
} }
}, },
minHeight: { minHeight: {
type: Number, type: Number,
default: 0, default: 0,
validator(value) { validator(value) {
return value >= 0; return value >= 0
} }
}, },
width: { width: {
type: [Number, String], type: [Number, String],
default: 600, default: 600,
validator(value) { validator(value) {
if (typeof value === "string") { if (typeof value === 'string') {
let width = parseNumber(value); let width = parseNumber(value)
return (width.type === "%" || width.type === "px") && width.value > 0; return (width.type === '%' || width.type === 'px') && width.value > 0
} }
return value >= 0; return value >= 0
} }
}, },
height: { height: {
type: [Number, String], type: [Number, String],
default: 300, default: 300,
validator(value) { validator(value) {
if (typeof value === "string") { if (typeof value === 'string') {
if (value === "auto") { if (value === 'auto') {
return true; return true
} }
let height = parseNumber(value); let height = parseNumber(value)
return ( return (
(height.type === "%" || height.type === "px") && height.value > 0 (height.type === '%' || height.type === 'px') && height.value > 0
); )
} }
return value >= 0; return value >= 0
} }
}, },
pivotX: { pivotX: {
type: Number, type: Number,
default: 0.5, default: 0.5,
validator(value) { validator(value) {
return value >= 0 && value <= 1; return value >= 0 && value <= 1
} }
}, },
pivotY: { pivotY: {
type: Number, type: Number,
default: 0.5, default: 0.5,
validator(value) { validator(value) {
return value >= 0 && value <= 1; return value >= 0 && value <= 1
} }
} }
}, },
@@ -153,9 +153,9 @@ export default {
modal: { modal: {
width: 0, width: 0,
widthType: "px", widthType: 'px',
height: 0, height: 0,
heightType: "px", heightType: 'px',
renderedHeight: 0 renderedHeight: 0
}, },
@@ -165,7 +165,7 @@ export default {
}, },
mutationObserver: null mutationObserver: null
}; }
}, },
watch: { watch: {
/** /**
@@ -176,47 +176,47 @@ export default {
*/ */
visible(value) { visible(value) {
if (value) { if (value) {
this.visibility.overlay = true; this.visibility.overlay = true
setTimeout(() => { setTimeout(() => {
this.visibility.modal = true; this.visibility.modal = true
this.$nextTick(() => { this.$nextTick(() => {
this.addDraggableListeners(); this.addDraggableListeners()
this.callAfterEvent(true); this.callAfterEvent(true)
}); })
}, this.delay); }, this.delay)
} else { } else {
this.visibility.modal = false; this.visibility.modal = false
setTimeout(() => { setTimeout(() => {
this.visibility.overlay = false; this.visibility.overlay = false
this.$nextTick(() => { this.$nextTick(() => {
this.removeDraggableListeners(); this.removeDraggableListeners()
this.callAfterEvent(false); this.callAfterEvent(false)
}); })
}, this.delay); }, this.delay)
} }
} }
}, },
created() { created() {
this.setInitialSize(); this.setInitialSize()
}, },
/** /**
* Sets global listeners * Sets global listeners
*/ */
beforeMount() { beforeMount() {
Modal.event.$on("toggle", (name, state, params) => { Modal.event.$on('toggle', (name, state, params) => {
if (name === this.name) { if (name === this.name) {
if (typeof state === "undefined") { if (typeof state === 'undefined') {
state = !this.visible; state = !this.visible
} }
this.toggle(state, params); this.toggle(state, params)
} }
}); })
window.addEventListener("resize", this.onWindowResize); window.addEventListener('resize', this.onWindowResize)
this.onWindowResize(); this.onWindowResize()
/** /**
* Making sure that autoHeight is enabled when using "scrollable" * Making sure that autoHeight is enabled when using "scrollable"
*/ */
@@ -224,7 +224,7 @@ export default {
console.warn( console.warn(
`Modal "${this.name}" has scrollable flag set to true ` + `Modal "${this.name}" has scrollable flag set to true ` +
`but height is not "auto" (${this.height})` `but height is not "auto" (${this.height})`
); )
} }
/** /**
* Only observe when using height: 'auto' * Only observe when using height: 'auto'
@@ -240,37 +240,37 @@ export default {
* (Provide polyfill to support IE < 11) * (Provide polyfill to support IE < 11)
*/ */
const MutationObserver = (function() { const MutationObserver = (function() {
const prefixes = ["", "WebKit", "Moz", "O", "Ms"]; const prefixes = ['', 'WebKit', 'Moz', 'O', 'Ms']
for (let i = 0; i < prefixes.length; i++) { for (let i = 0; i < prefixes.length; i++) {
let name = prefixes[i] + "MutationObserver"; let name = prefixes[i] + 'MutationObserver'
if (name in window) { if (name in window) {
return window[name]; return window[name]
} }
} }
return false; return false
})(); })()
if (MutationObserver) { if (MutationObserver) {
this.mutationObserver = new MutationObserver(mutations => { this.mutationObserver = new MutationObserver(mutations => {
this.updateRenderedHeight(); this.updateRenderedHeight()
}); })
} }
} }
if (this.clickToClose) { if (this.clickToClose) {
window.addEventListener("keyup", this.onEscapeKeyUp); window.addEventListener('keyup', this.onEscapeKeyUp)
} }
}, },
/** /**
* Removes "resize" window listener * Removes "resize" window listener
*/ */
beforeDestroy() { beforeDestroy() {
window.removeEventListener("resize", this.onWindowResize); window.removeEventListener('resize', this.onWindowResize)
if (this.clickToClose) { if (this.clickToClose) {
window.removeEventListener("keyup", this.onEscapeKeyUp); window.removeEventListener('keyup', this.onEscapeKeyUp)
} }
}, },
computed: { computed: {
@@ -278,7 +278,7 @@ export default {
* Returns true if height is set to "auto" * Returns true if height is set to "auto"
*/ */
isAutoHeight() { isAutoHeight() {
return this.modal.heightType === "auto"; return this.modal.heightType === 'auto'
}, },
/** /**
* Calculates and returns modal position based on the * Calculates and returns modal position based on the
@@ -292,32 +292,30 @@ export default {
pivotY, pivotY,
trueModalWidth, trueModalWidth,
trueModalHeight trueModalHeight
} = this; } = this
const maxLeft = window.width - trueModalWidth; const maxLeft = window.width - trueModalWidth
const maxTop = window.height - trueModalHeight; const maxTop = window.height - trueModalHeight
const left = shift.left + pivotX * maxLeft; const left = shift.left + pivotX * maxLeft
const top = shift.top + pivotY * maxTop; const top = shift.top + pivotY * maxTop
return { return {
left: inRange(0, maxLeft, left), left: inRange(0, maxLeft, left),
top: inRange(0, maxTop, top) top: inRange(0, maxTop, top)
}; }
}, },
/** /**
* Returns pixel width (if set with %) and makes sure that modal size * Returns pixel width (if set with %) and makes sure that modal size
* fits the window * fits the window
*/ */
trueModalWidth() { trueModalWidth() {
const { window, modal, adaptive, minWidth } = this; const { window, modal, adaptive, minWidth } = this
const value = const value =
modal.widthType === "%" modal.widthType === '%' ? window.width / 100 * modal.width : modal.width
? window.width / 100 * modal.width
: modal.width;
return adaptive ? inRange(minWidth, window.width, value) : value; return adaptive ? inRange(minWidth, window.width, value) : value
}, },
/** /**
* Returns pixel height (if set with %) and makes sure that modal size * Returns pixel height (if set with %) and makes sure that modal size
@@ -326,47 +324,47 @@ export default {
* Returns modal.renderedHeight if height set as "auto" * Returns modal.renderedHeight if height set as "auto"
*/ */
trueModalHeight() { trueModalHeight() {
const { window, modal, isAutoHeight, adaptive } = this; const { window, modal, isAutoHeight, adaptive } = this
const value = const value =
modal.heightType === "%" modal.heightType === '%'
? window.height / 100 * modal.height ? window.height / 100 * modal.height
: modal.height; : modal.height
if (isAutoHeight) { if (isAutoHeight) {
// use renderedHeight when height 'auto' // use renderedHeight when height 'auto'
return this.modal.renderedHeight; return this.modal.renderedHeight
} }
return adaptive return adaptive
? inRange(this.minHeight, this.window.height, value) ? inRange(this.minHeight, this.window.height, value)
: value; : value
}, },
/** /**
* Returns class list for screen overlay (modal background) * Returns class list for screen overlay (modal background)
*/ */
overlayClass() { overlayClass() {
return { return {
"v--modal-overlay": true, 'v--modal-overlay': true,
scrollable: this.scrollable && this.isAutoHeight scrollable: this.scrollable && this.isAutoHeight
}; }
}, },
/** /**
* Returns class list for modal itself * Returns class list for modal itself
*/ */
modalClass() { modalClass() {
return ["v--modal-box", this.classes]; return ['v--modal-box', this.classes]
}, },
/** /**
* CSS styles for position and size of the modal * CSS styles for position and size of the modal
*/ */
modalStyle() { modalStyle() {
return { return {
top: this.position.top + "px", top: this.position.top + 'px',
left: this.position.left + "px", left: this.position.left + 'px',
width: this.trueModalWidth + "px", width: this.trueModalWidth + 'px',
height: this.isAutoHeight ? "auto" : this.trueModalHeight + "px" height: this.isAutoHeight ? 'auto' : this.trueModalHeight + 'px'
}; }
} }
}, },
methods: { methods: {
@@ -376,25 +374,25 @@ export default {
* every time "beforeOpen" is triggered * every time "beforeOpen" is triggered
*/ */
setInitialSize() { setInitialSize() {
let { modal } = this; let { modal } = this
let width = parseNumber(this.width); let width = parseNumber(this.width)
let height = parseNumber(this.height); let height = parseNumber(this.height)
modal.width = width.value; modal.width = width.value
modal.widthType = width.type; modal.widthType = width.type
modal.height = height.value; modal.height = height.value
modal.heightType = height.type; modal.heightType = height.type
}, },
onEscapeKeyUp(event) { onEscapeKeyUp(event) {
if (event.which === 27 && this.visible) { if (event.which === 27 && this.visible) {
this.$modal.hide(this.name); this.$modal.hide(this.name)
} }
}, },
onWindowResize() { onWindowResize() {
this.window.width = window.innerWidth; this.window.width = window.innerWidth
this.window.height = window.innerHeight; this.window.height = window.innerHeight
}, },
/** /**
@@ -406,24 +404,24 @@ export default {
timestamp: Date.now(), timestamp: Date.now(),
canceled: false, canceled: false,
ref: this.$refs.modal ref: this.$refs.modal
}; }
return Object.assign(eventData, params || {}); return Object.assign(eventData, params || {})
}, },
/** /**
* Event handler which is triggered on modal resize * Event handler which is triggered on modal resize
*/ */
onModalResize(event) { onModalResize(event) {
this.modal.widthType = "px"; this.modal.widthType = 'px'
this.modal.width = event.size.width; this.modal.width = event.size.width
this.modal.heightType = "px"; this.modal.heightType = 'px'
this.modal.height = event.size.height; this.modal.height = event.size.height
const { size } = this.modal; const { size } = this.modal
const resizeEvent = this.genEventObject({ size }); const resizeEvent = this.genEventObject({ size })
this.$emit("resize", resizeEvent); this.$emit('resize', resizeEvent)
}, },
/** /**
* Event handler which is triggered on $modal.show and $modal.hight * Event handler which is triggered on $modal.show and $modal.hight
@@ -431,59 +429,59 @@ export default {
* but AfterEvents ('opened' and 'closed') are moved to `watch.visible`. * but AfterEvents ('opened' and 'closed') are moved to `watch.visible`.
*/ */
toggle(state, params) { toggle(state, params) {
const { reset, scrollable, visible } = this; const { reset, scrollable, visible } = this
const beforeEventName = visible ? "before-close" : "before-open"; const beforeEventName = visible ? 'before-close' : 'before-open'
if (beforeEventName === "before-open") { if (beforeEventName === 'before-open') {
/** /**
* Need to unfocus previously focused element, otherwise * Need to unfocus previously focused element, otherwise
* all keypress events (ESC press, for example) will trigger on that element. * all keypress events (ESC press, for example) will trigger on that element.
*/ */
if (document.activeElement) { if (document.activeElement) {
document.activeElement.blur(); document.activeElement.blur()
} }
if (reset) { if (reset) {
this.setInitialSize(); this.setInitialSize()
this.shift.left = 0; this.shift.left = 0
this.shift.top = 0; this.shift.top = 0
} }
if (scrollable) { if (scrollable) {
document.body.classList.add("v--modal-block-scroll"); document.body.classList.add('v--modal-block-scroll')
} }
} else { } else {
if (scrollable) { if (scrollable) {
document.body.classList.remove("v--modal-block-scroll"); document.body.classList.remove('v--modal-block-scroll')
} }
} }
let stopEventExecution = false; let stopEventExecution = false
const stop = () => { const stop = () => {
stopEventExecution = true; stopEventExecution = true
}; }
const beforeEvent = this.genEventObject({ stop, state, params }); const beforeEvent = this.genEventObject({ stop, state, params })
this.$emit(beforeEventName, beforeEvent); this.$emit(beforeEventName, beforeEvent)
if (!stopEventExecution) { if (!stopEventExecution) {
this.visible = state; this.visible = state
// after events are called in `watch.visible` // after events are called in `watch.visible`
} }
}, },
getDraggableElement() { getDraggableElement() {
var selector = var selector =
typeof this.draggable !== "string" ? ".v--modal-box" : this.draggable; typeof this.draggable !== 'string' ? '.v--modal-box' : this.draggable
if (selector) { if (selector) {
var handler = this.$refs.overlay.querySelector(selector); var handler = this.$refs.overlay.querySelector(selector)
if (handler) { if (handler) {
return handler; return handler
} }
} }
}, },
@@ -492,72 +490,72 @@ export default {
*/ */
onBackgroundClick() { onBackgroundClick() {
if (this.clickToClose) { if (this.clickToClose) {
this.toggle(false); this.toggle(false)
} }
}, },
addDraggableListeners() { addDraggableListeners() {
if (!this.draggable) { if (!this.draggable) {
return; return
} }
let dragger = this.getDraggableElement(); let dragger = this.getDraggableElement()
if (dragger) { if (dragger) {
let startX = 0; let startX = 0
let startY = 0; let startY = 0
let cachedShiftX = 0; let cachedShiftX = 0
let cachedShiftY = 0; let cachedShiftY = 0
let getPosition = event => { let getPosition = event => {
return event.touches && event.touches.length > 0 return event.touches && event.touches.length > 0
? event.touches[0] ? event.touches[0]
: event; : event
};
let mousedown = event => {
let target = event.target;
if (target && target.nodeName === "INPUT") {
return;
} }
let { clientX, clientY } = getPosition(event); let mousedown = event => {
let target = event.target
document.addEventListener("mousemove", mousemove); if (target && target.nodeName === 'INPUT') {
document.addEventListener("mouseup", mouseup); return
}
document.addEventListener("touchmove", mousemove); let { clientX, clientY } = getPosition(event)
document.addEventListener("touchend", mouseup);
startX = clientX; document.addEventListener('mousemove', mousemove)
startY = clientY; document.addEventListener('mouseup', mouseup)
cachedShiftX = this.shift.left;
cachedShiftY = this.shift.top; document.addEventListener('touchmove', mousemove)
document.addEventListener('touchend', mouseup)
startX = clientX
startY = clientY
cachedShiftX = this.shift.left
cachedShiftY = this.shift.top
// event.preventDefault() // event.preventDefault()
}; }
let mousemove = event => { let mousemove = event => {
let { clientX, clientY } = getPosition(event); let { clientX, clientY } = getPosition(event)
this.shift.left = cachedShiftX + clientX - startX; this.shift.left = cachedShiftX + clientX - startX
this.shift.top = cachedShiftY + clientY - startY; this.shift.top = cachedShiftY + clientY - startY
event.preventDefault(); event.preventDefault()
}; }
let mouseup = event => { let mouseup = event => {
document.removeEventListener("mousemove", mousemove); document.removeEventListener('mousemove', mousemove)
document.removeEventListener("mouseup", mouseup); document.removeEventListener('mouseup', mouseup)
document.removeEventListener("touchmove", mousemove); document.removeEventListener('touchmove', mousemove)
document.removeEventListener("touchend", mouseup); document.removeEventListener('touchend', mouseup)
event.preventDefault(); event.preventDefault()
}; }
dragger.addEventListener("mousedown", mousedown); dragger.addEventListener('mousedown', mousedown)
dragger.addEventListener("touchstart", mousedown); dragger.addEventListener('touchstart', mousedown)
} }
}, },
@@ -574,15 +572,15 @@ export default {
*/ */
callAfterEvent(state) { callAfterEvent(state) {
if (state) { if (state) {
this.connectObserver(); this.connectObserver()
} else { } else {
this.disconnectObserver(); this.disconnectObserver()
} }
const eventName = state ? "opened" : "closed"; const eventName = state ? 'opened' : 'closed'
const event = this.genEventObject({ state }); const event = this.genEventObject({ state })
this.$emit(eventName, event); this.$emit(eventName, event)
}, },
/** /**
@@ -593,7 +591,7 @@ export default {
*/ */
updateRenderedHeight() { updateRenderedHeight() {
if (this.$refs.modal) { if (this.$refs.modal) {
this.modal.renderedHeight = this.$refs.modal.getBoundingClientRect().height; this.modal.renderedHeight = this.$refs.modal.getBoundingClientRect().height
} }
}, },
@@ -607,7 +605,7 @@ export default {
childList: true, childList: true,
attributes: true, attributes: true,
subtree: true subtree: true
}); })
} }
}, },
@@ -616,11 +614,11 @@ export default {
*/ */
disconnectObserver() { disconnectObserver() {
if (this.mutationObserver) { if (this.mutationObserver) {
this.mutationObserver.disconnect(); this.mutationObserver.disconnect()
}
} }
} }
} }
};
</script> </script>
<style> <style>
.v--modal-block-scroll { .v--modal-block-scroll {