mirror of
https://github.com/KevinMidboe/vue-js-modal.git
synced 2025-10-29 18:00:20 +00:00
extracting css
This commit is contained in:
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "none",
|
||||||
|
"singleQuote": true,
|
||||||
|
"semi": false
|
||||||
|
}
|
||||||
24
build/webpack.srr-no-css.config.js
Normal file
24
build/webpack.srr-no-css.config.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const path = require('path')
|
||||||
|
const webpack = require('webpack')
|
||||||
|
const merge = require('webpack-merge')
|
||||||
|
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||||
|
|
||||||
|
const base = require('./webpack.srr.config')
|
||||||
|
|
||||||
|
module.exports = merge(base, {
|
||||||
|
plugins: [new ExtractTextPlugin('styles.css')],
|
||||||
|
output: {
|
||||||
|
filename: 'ssr.pure.js'
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ExtractTextPlugin.extract({
|
||||||
|
fallback: 'style-loader',
|
||||||
|
use: 'css-loader'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -19,10 +19,11 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:client": "webpack --config ./build/webpack.client.config.js --progress --hide-modules",
|
"build:client": "webpack --config ./build/webpack.client.config.js --progress --hide-modules",
|
||||||
"build:server": "webpack --config ./build/webpack.server.config.js --progress --hide-modules",
|
"build:srr": "webpack --config ./build/webpack.srr.config.js --progress --hide-modules",
|
||||||
|
"build:srr-no-css": "webpack --config ./build/webpack.srr-no-css.config.js --progress --hide-modules",
|
||||||
"lint": "eslint --ext .js,.vue src test/unit/specs",
|
"lint": "eslint --ext .js,.vue src test/unit/specs",
|
||||||
"unit": "./node_modules/karma/bin/karma start test/unit/karma.conf.js",
|
"unit": "./node_modules/karma/bin/karma start test/unit/karma.conf.js",
|
||||||
"build": "npm run lint && npm run unit && npm run build:client && npm run build:server"
|
"build": "npm run lint && npm run unit && npm run build:client && npm run build:srr"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
484
src/Modal.vue
484
src/Modal.vue
@@ -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,71 +73,71 @@
|
|||||||
},
|
},
|
||||||
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') &&
|
return (width.type === "%" || width.type === "px") && width.value > 0;
|
||||||
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 (height.type === '%' || height.type === 'px') &&
|
return (
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Resizer
|
Resizer
|
||||||
},
|
},
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
visible: false,
|
visible: false,
|
||||||
|
|
||||||
@@ -153,9 +153,9 @@
|
|||||||
|
|
||||||
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 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
mutationObserver: null
|
mutationObserver: null
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
/**
|
/**
|
||||||
@@ -174,55 +174,57 @@
|
|||||||
* inside `setTimeout` and `$nextTick`, after the DOM changes.
|
* inside `setTimeout` and `$nextTick`, after the DOM changes.
|
||||||
* This fixes `$refs.modal` `undefined` bug (fixes #15)
|
* This fixes `$refs.modal` `undefined` bug (fixes #15)
|
||||||
*/
|
*/
|
||||||
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"
|
||||||
*/
|
*/
|
||||||
if (this.scrollable && !this.isAutoHeight) {
|
if (this.scrollable && !this.isAutoHeight) {
|
||||||
console.warn(`Modal "${this.name}" has scrollable flag set to true ` +
|
console.warn(
|
||||||
`but height is not "auto" (${this.height})`)
|
`Modal "${this.name}" has scrollable flag set to true ` +
|
||||||
|
`but height is not "auto" (${this.height})`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Only observe when using height: 'auto'
|
* Only observe when using height: 'auto'
|
||||||
@@ -237,80 +239,85 @@
|
|||||||
* simply stay at its initial height (won't crash).
|
* simply stay at its initial height (won't crash).
|
||||||
* (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: {
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
* pivots, window size and modal size
|
* pivots, window size and modal size
|
||||||
*/
|
*/
|
||||||
position () {
|
position() {
|
||||||
const { window, shift, pivotX, pivotY,
|
const {
|
||||||
trueModalWidth, trueModalHeight } = this
|
window,
|
||||||
|
shift,
|
||||||
|
pivotX,
|
||||||
|
pivotY,
|
||||||
|
trueModalWidth,
|
||||||
|
trueModalHeight
|
||||||
|
} = 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 = modal.widthType === '%'
|
const value =
|
||||||
|
modal.widthType === "%"
|
||||||
? window.width / 100 * modal.width
|
? window.width / 100 * modal.width
|
||||||
: modal.width
|
: modal.width;
|
||||||
|
|
||||||
return adaptive
|
return adaptive ? inRange(minWidth, window.width, value) : value;
|
||||||
? 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
|
||||||
@@ -318,49 +325,48 @@
|
|||||||
*
|
*
|
||||||
* 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 = (modal.heightType === '%')
|
const value =
|
||||||
|
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
|
height: this.isAutoHeight ? "auto" : this.trueModalHeight + "px"
|
||||||
? 'auto'
|
};
|
||||||
: (this.trueModalHeight + 'px')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -369,196 +375,193 @@
|
|||||||
* if "reset" flag is set to true - this function will be called
|
* if "reset" flag is set to true - this function will be called
|
||||||
* 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;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates event object
|
* Generates event object
|
||||||
*/
|
*/
|
||||||
genEventObject (params) {
|
genEventObject(params) {
|
||||||
var eventData = {
|
var eventData = {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
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
|
||||||
* BeforeEvents: ('before-close' and 'before-open') are `$emit`ed here,
|
* BeforeEvents: ('before-close' and 'before-open') are `$emit`ed here,
|
||||||
* 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
|
const beforeEventName = visible ? "before-close" : "before-open";
|
||||||
? '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 = typeof this.draggable !== 'string'
|
var selector =
|
||||||
? '.v--modal-box'
|
typeof this.draggable !== "string" ? ".v--modal-box" : this.draggable;
|
||||||
: 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Event handler that is triggered when background overlay is clicked
|
* Event handler that is triggered when background overlay is clicked
|
||||||
*/
|
*/
|
||||||
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 mousedown = (event) => {
|
let { clientX, clientY } = getPosition(event);
|
||||||
let target = event.target
|
|
||||||
|
|
||||||
if (target && target.nodeName === 'INPUT') {
|
document.addEventListener("mousemove", mousemove);
|
||||||
return
|
document.addEventListener("mouseup", mouseup);
|
||||||
}
|
|
||||||
|
|
||||||
let { clientX, clientY } = getPosition(event)
|
document.addEventListener("touchmove", mousemove);
|
||||||
|
document.addEventListener("touchend", mouseup);
|
||||||
|
|
||||||
document.addEventListener('mousemove', mousemove)
|
startX = clientX;
|
||||||
document.addEventListener('mouseup', mouseup)
|
startY = clientY;
|
||||||
|
cachedShiftX = this.shift.left;
|
||||||
document.addEventListener('touchmove', mousemove)
|
cachedShiftY = this.shift.top;
|
||||||
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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeDraggableListeners () {
|
removeDraggableListeners() {
|
||||||
// console.log('removing draggable handlers')
|
// console.log('removing draggable handlers')
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -569,17 +572,17 @@
|
|||||||
* wrapping afterEvents in `$nextTick` fixes `$refs.modal` undefined bug.
|
* wrapping afterEvents in `$nextTick` fixes `$refs.modal` undefined bug.
|
||||||
* (fixes #15)
|
* (fixes #15)
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -588,10 +591,9 @@
|
|||||||
* 1. modal opened
|
* 1. modal opened
|
||||||
* 2. MutationObserver's observe callback
|
* 2. MutationObserver's observe callback
|
||||||
*/
|
*/
|
||||||
updateRenderedHeight () {
|
updateRenderedHeight() {
|
||||||
if (this.$refs.modal) {
|
if (this.$refs.modal) {
|
||||||
this.modal.renderedHeight = this.$refs.modal
|
this.modal.renderedHeight = this.$refs.modal.getBoundingClientRect().height;
|
||||||
.getBoundingClientRect().height
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -599,102 +601,106 @@
|
|||||||
* Start observing modal's DOM, if childList or subtree changes,
|
* Start observing modal's DOM, if childList or subtree changes,
|
||||||
* the callback (registered in beforeMount) will be called.
|
* the callback (registered in beforeMount) will be called.
|
||||||
*/
|
*/
|
||||||
connectObserver () {
|
connectObserver() {
|
||||||
if (this.mutationObserver) {
|
if (this.mutationObserver) {
|
||||||
this.mutationObserver.observe(this.$refs.modal, {
|
this.mutationObserver.observe(this.$refs.modal, {
|
||||||
childList: true,
|
childList: true,
|
||||||
attributes: true,
|
attributes: true,
|
||||||
subtree: true
|
subtree: true
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects MutationObserver
|
* Disconnects MutationObserver
|
||||||
*/
|
*/
|
||||||
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 {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v--modal-overlay {
|
.v--modal-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(0, 0, 0, 0.2);
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v--modal-overlay.scrollable {
|
.v--modal-overlay.scrollable {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v--modal-overlay .v--modal-box {
|
.v--modal-overlay .v--modal-box {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v--modal-overlay.scrollable .v--modal-box {
|
.v--modal-overlay.scrollable .v--modal-box {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
/* transition: top 0.2s ease; */
|
/* transition: top 0.2s ease; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.v--modal {
|
.v--modal {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0 20px 60px -2px rgba(27, 33, 58, .4);
|
box-shadow: 0 20px 60px -2px rgba(27, 33, 58, 0.4);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v--modal.v--modal-fullscreen {
|
.v--modal.v--modal-fullscreen {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v--modal-top-right {
|
.v--modal-top-right {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay-fade-enter-active, .overlay-fade-leave-active {
|
.overlay-fade-enter-active,
|
||||||
|
.overlay-fade-leave-active {
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay-fade-enter, .overlay-fade-leave-active {
|
.overlay-fade-enter,
|
||||||
|
.overlay-fade-leave-active {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nice-modal-fade-enter-active, .nice-modal-fade-leave-active {
|
.nice-modal-fade-enter-active,
|
||||||
|
.nice-modal-fade-leave-active {
|
||||||
transition: all 0.4s;
|
transition: all 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nice-modal-fade-enter, .nice-modal-fade-leave-active {
|
.nice-modal-fade-enter,
|
||||||
|
.nice-modal-fade-leave-active {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-20px);
|
transform: translateY(-20px);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user