mirror of
https://github.com/KevinMidboe/vue-js-modal.git
synced 2025-10-29 18:00:20 +00:00
Merge pull request #46 from onekiloparsec/master
Allow to use window width and height percentages in modal size.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<demo-dog-profile-modal />
|
||||
<demo-conditional-modal/>
|
||||
<demo-focus-modal/>
|
||||
<demo-size-modal/>
|
||||
|
||||
<modal name="example-modal"
|
||||
transition="nice-modal-fade"
|
||||
@@ -55,6 +56,10 @@
|
||||
@click="$modal.show('demo-login')">
|
||||
Demo: Login
|
||||
</button>
|
||||
<button class="blue"
|
||||
@click="$modal.show('size-modal')">
|
||||
Demo: Size = 60%
|
||||
</button>
|
||||
<!--
|
||||
<button class="green"
|
||||
@click="$modal.show('input-focus-modal')">
|
||||
@@ -79,6 +84,7 @@ import DemoFocusModal from './components/InputFocusModal.vue'
|
||||
import DemoLoginModal from './components/DemoLoginModal.vue'
|
||||
import DemoDogProfileModal from './components/DogProfileModal.vue'
|
||||
import DemoConditionalModal from './components/ConditionalModal.vue'
|
||||
import DemoSizeModal from './components/SizeModal.vue'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
@@ -89,7 +95,8 @@ export default {
|
||||
DemoFocusModal,
|
||||
DemoLoginModal,
|
||||
DemoDogProfileModal,
|
||||
DemoConditionalModal
|
||||
DemoConditionalModal,
|
||||
DemoSizeModal
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
15
demo/client_side_rendering/src/components/SizeModal.vue
Normal file
15
demo/client_side_rendering/src/components/SizeModal.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<modal name="size-modal"
|
||||
transition="nice-modal-fade"
|
||||
:min-width="200"
|
||||
:min-height="200"
|
||||
:adaptive="true"
|
||||
width="60%"
|
||||
height="60%">
|
||||
<div style="height: 100%; box-sizing: border-box; padding: 10px; font-size: 13px; overflow: auto">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla dictum purus egestas libero ornare venenatis. Maecenas pharetra tortor eu tortor imperdiet, a faucibus quam finibus. Nulla id lacinia quam. Praesent imperdiet sed magna non finibus. Aenean blandit, mauris vitae lacinia rutrum, nunc mi scelerisque sem, in laoreet sem lectus ut orci. Ut egestas nulla in vehicula feugiat. Vivamus tincidunt nisi vel risus dictum suscipit. Nulla id blandit mi, vulputate aliquam enim.
|
||||
|
||||
Praesent sodales diam a tellus imperdiet condimentum. Mauris malesuada libero elit, sed tincidunt velit consectetur sit amet. Praesent consequat lobortis pellentesque. Donec pellentesque eros sit amet arcu bibendum, vel pharetra purus sodales. Morbi aliquam ac augue eu aliquam. Cras id justo sit amet tortor luctus lobortis. Vestibulum risus urna, cursus vitae feugiat non, tincidunt non massa.
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
193
dist/index.js
vendored
193
dist/index.js
vendored
File diff suppressed because one or more lines are too long
211
dist/ssr.index.js
vendored
211
dist/ssr.index.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "vue-js-modal",
|
||||
"description": "Modal Component for Vue.js",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.4",
|
||||
"author": "euvl <yev.vlasenko@gmail.com>",
|
||||
"main": "dist/index.js",
|
||||
"repository": {
|
||||
|
||||
114
src/Modal.vue
114
src/Modal.vue
@@ -19,7 +19,7 @@
|
||||
<resizer v-if="resizable"
|
||||
:min-width="minWidth"
|
||||
:min-height="minHeight"
|
||||
@resize="resize"/>
|
||||
@resize="onModalResize"/>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
@@ -30,6 +30,7 @@
|
||||
import Modal from './index'
|
||||
import Resizer from './Resizer.vue'
|
||||
import { inRange } from './util'
|
||||
import parseNumber from './parser'
|
||||
|
||||
export default {
|
||||
name: 'VueJsModal',
|
||||
@@ -75,26 +76,16 @@
|
||||
return value >= 0
|
||||
}
|
||||
},
|
||||
maxAdaptiveWidth: {
|
||||
type: Number,
|
||||
default: 1
|
||||
// ,
|
||||
// validator (value) {
|
||||
// return value > 0 && value <= 1
|
||||
// }
|
||||
},
|
||||
maxAdaptiveHeight: {
|
||||
type: Number,
|
||||
default: 1
|
||||
// ,
|
||||
// validator (value) {
|
||||
// return value > 0 && value <= 1
|
||||
// }
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
type: [Number, String],
|
||||
default: 600,
|
||||
validator (value) {
|
||||
if (typeof value === 'string') {
|
||||
let width = parseNumber(value)
|
||||
return (width.type === '%' || width.type === 'px')
|
||||
&& width.value > 0
|
||||
}
|
||||
|
||||
return value >= 0
|
||||
}
|
||||
},
|
||||
@@ -103,13 +94,13 @@
|
||||
default: 300,
|
||||
validator (value) {
|
||||
if (typeof value === 'string') {
|
||||
return value === 'auto'
|
||||
let height = parseNumber(value)
|
||||
return (height.type === '%' || height.type === 'px')
|
||||
&& height.value > 0
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
return value >= 0
|
||||
}
|
||||
}
|
||||
},
|
||||
pivotX: {
|
||||
type: Number,
|
||||
@@ -130,6 +121,9 @@
|
||||
Resizer
|
||||
},
|
||||
data () {
|
||||
let width = parseNumber(this.width)
|
||||
let height = parseNumber(this.height)
|
||||
|
||||
return {
|
||||
visible: false,
|
||||
|
||||
@@ -144,23 +138,26 @@
|
||||
},
|
||||
|
||||
modal: {
|
||||
width: this.width,
|
||||
height: this.height
|
||||
widthInit: 0,
|
||||
width: width.value,
|
||||
widthType: width.type,
|
||||
|
||||
heightInit: 0,
|
||||
height: height.value,
|
||||
heightType: height.type
|
||||
},
|
||||
|
||||
window: {
|
||||
width: 0,
|
||||
height: 0
|
||||
},
|
||||
|
||||
draggableElement: false
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible (value) {
|
||||
if (value) {
|
||||
this.visibility.overlay = true
|
||||
this.adaptSize()
|
||||
// this.adaptSize()
|
||||
|
||||
setTimeout(() => {
|
||||
this.visibility.modal = true
|
||||
@@ -200,11 +197,14 @@
|
||||
computed: {
|
||||
position () {
|
||||
const { window, modal, shift } = this
|
||||
const maxLeft = window.width - modal.width
|
||||
const maxTop = window.height - modal.height
|
||||
|
||||
const left = shift.left + this.pivotX * (window.width - modal.width)
|
||||
const top = shift.top + this.pivotY * (window.height - modal.height)
|
||||
const maxLeft = window.width - this.trueModalWidth
|
||||
const maxTop = window.height - this.trueModalHeight
|
||||
|
||||
const left = shift.left +
|
||||
this.pivotX * (window.width - this.trueModalWidth)
|
||||
const top = shift.top +
|
||||
this.pivotY * (window.height - this.trueModalHeight)
|
||||
|
||||
return {
|
||||
left: inRange(0, maxLeft, left),
|
||||
@@ -212,6 +212,28 @@
|
||||
}
|
||||
},
|
||||
|
||||
trueModalWidth () {
|
||||
const { window, modal } = this
|
||||
const value = modal.widthType === '%'
|
||||
? window.width / 100 * modal.width
|
||||
: modal.width
|
||||
|
||||
return this.adaptive
|
||||
? inRange(this.minWidth, this.window.width, value)
|
||||
: value
|
||||
},
|
||||
|
||||
trueModalHeight () {
|
||||
const { window, modal } = this
|
||||
const value = (modal.heightType === '%')
|
||||
? window.height / 100 * modal.height
|
||||
: modal.height
|
||||
|
||||
return this.adaptive
|
||||
? inRange(this.minHeight, this.window.height, value)
|
||||
: value
|
||||
},
|
||||
|
||||
modalClass () {
|
||||
return ['v--modal-box', this.classes]
|
||||
},
|
||||
@@ -220,8 +242,8 @@
|
||||
return {
|
||||
top: this.position.top + 'px',
|
||||
left: this.position.left + 'px',
|
||||
width: this.modal.width + 'px',
|
||||
height: this.modal.height + 'px'
|
||||
width: this.trueModalWidth + 'px',
|
||||
height: this.trueModalHeight + 'px'
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -229,7 +251,6 @@
|
||||
onWindowResize () {
|
||||
this.window.width = window.innerWidth
|
||||
this.window.height = window.innerHeight
|
||||
this.adaptSize()
|
||||
},
|
||||
|
||||
genEventObject (params) {
|
||||
@@ -246,27 +267,28 @@
|
||||
|
||||
return Vue.util.extend(data, params || {});
|
||||
},
|
||||
|
||||
/*
|
||||
adaptSize () {
|
||||
if (this.adaptive) {
|
||||
this.modal.width = inRange(
|
||||
0,
|
||||
this.window.width * this.maxAdaptiveWidth,
|
||||
this.modal.width)
|
||||
this.modal.height = inRange(
|
||||
0,
|
||||
this.window.height * this.maxAdaptiveHeight,
|
||||
this.modal.height)
|
||||
this.modal.width = inRange(this.minWidth, this.window.width,
|
||||
this.trueModalWidth)
|
||||
this.modal.height = inRange(this.minHeight, this.window.height,
|
||||
this.trueModalHeight)
|
||||
}
|
||||
},
|
||||
|
||||
resize (event) {
|
||||
*/
|
||||
onModalResize (event) {
|
||||
this.modal.widthType = 'px'
|
||||
this.modal.width = event.size.width
|
||||
|
||||
this.modal.heightType = 'px'
|
||||
this.modal.height = event.size.height
|
||||
|
||||
const { size } = this.modal
|
||||
const resizeEvent = this.genEventObject({ size });
|
||||
|
||||
console.log(resizeEvent)
|
||||
|
||||
this.$emit('resize', resizeEvent)
|
||||
},
|
||||
|
||||
|
||||
77
src/parser.js
Normal file
77
src/parser.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// Parses string with float number and suffix:
|
||||
// "0.001" => { type: "px", value: 0.001 }
|
||||
// "0.001px" => { type: "px", value: 0.001 }
|
||||
// "0.1%" => { type: "px", value: 0.1 }
|
||||
// "foo" => { type: "", value: "foo" }
|
||||
|
||||
var floatRegexp = '[-+]?[0-9]*\.?[0-9]+'
|
||||
|
||||
var types = [
|
||||
// {
|
||||
// name: 'rem',
|
||||
// regexp: new RegExp(`^${floatRegexp}rem\$`)
|
||||
// },
|
||||
{
|
||||
name: 'px',
|
||||
regexp: new RegExp(`^${floatRegexp}px\$`)
|
||||
},
|
||||
{
|
||||
name: '%',
|
||||
regexp: new RegExp(`^${floatRegexp}%\$`)
|
||||
},
|
||||
// Fallback option:
|
||||
// If no suffix specified, assign to px
|
||||
{
|
||||
name: 'px',
|
||||
regexp: new RegExp(`^${floatRegexp}\$`)
|
||||
}
|
||||
]
|
||||
|
||||
var getType = (value) => {
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
let type = types[i]
|
||||
if (type.regexp.test(value)) {
|
||||
return {
|
||||
type: type.name,
|
||||
value: parseFloat(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: '',
|
||||
value: value
|
||||
}
|
||||
}
|
||||
|
||||
var parse = (value) => {
|
||||
switch (typeof value) {
|
||||
case 'number':
|
||||
return { type: 'px', value }
|
||||
case 'string':
|
||||
return getType(value)
|
||||
default:
|
||||
return { type: '', value }
|
||||
}
|
||||
}
|
||||
|
||||
export default parse
|
||||
|
||||
/// tests
|
||||
/*
|
||||
console.log(parse(10))
|
||||
console.log(parse(10.10))
|
||||
console.log(parse(-10))
|
||||
|
||||
console.log(parse('5%'))
|
||||
console.log(parse('-5%'))
|
||||
console.log(parse('5.123%'))
|
||||
|
||||
console.log(parse('5px'))
|
||||
console.log(parse('-5px'))
|
||||
console.log(parse('5.123px'))
|
||||
|
||||
console.log(parse("adasd%"))
|
||||
console.log(parse(""))
|
||||
console.log(parse("+2-3px")) // fails
|
||||
*/
|
||||
Reference in New Issue
Block a user