mirror of
https://github.com/KevinMidboe/vue-js-modal.git
synced 2025-10-29 18:00:20 +00:00
13
CHANGELOG.md
Normal file
13
CHANGELOG.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## v1.2.6
|
||||
|
||||
* Added `"auto"` value support for `height` property.
|
||||
|
||||
* Added `scrollable` flag that allowes modal content to be scrolled when height is "auto".
|
||||
|
||||
* Added CHANGELOG file.
|
||||
|
||||
## v1.2.5
|
||||
|
||||
* `height` and `width` props can be set using percents.
|
||||
|
||||
* Better handling of `min-width` and `min-height`
|
||||
16
README.md
16
README.md
@@ -77,12 +77,13 @@ For full demo please look at `demo/server_side_rendering`
|
||||
| resizable | false | Boolean | false | If true, allows to resize modal window, keeping it in the center of the screen. |
|
||||
| adaptive | false | Boolean | false | If true, modal box will try to adapt to the window size |
|
||||
| draggable | false | [Boolean, String]| false | If true, modal box will be draggable. |
|
||||
| scrollable | false | Boolean | false | If `height` property is `auto` and the modal height exceeds window height - you will be able to scroll modal |
|
||||
| reset | false | Boolean | false | Resets position and size before showing modal |
|
||||
| clickToClose | false | Boolean | true | If set to `false`, it will not be possible to close modal by clicking on the background |
|
||||
| transition| false | String | | Transition name |
|
||||
| classes | false | [String, Array] | 'vue--modal'| Classes that will be applied to the actual modal box, if not specified, the default 'vue--modal' class will be applied |
|
||||
| width | false | [String, Number] | 600 | Width in pixels or percents (e.g. 50 or "50px", "50%") |
|
||||
| height | false | [String, Number] | 300 | Height in pixels or percents (e.g. 50 or "50px", "50%") |
|
||||
| height | false | [String, Number] | 300 | Height in pixels or percents (e.g. 50 or "50px", "50%") or `"auto"` |
|
||||
| minWidth | false | Number | 0 | The minimum width to which modal can be resized |
|
||||
| minHeight | false | Number | 0 | The minimum height to which modal can be resized |
|
||||
| pivotX | false | Number (0 - 1.0) | 0.5 | Horizontal position in %, default is 0.5 (meaning that modal box will be in the middle (50% from top) of the window |
|
||||
@@ -140,6 +141,19 @@ And then forbits closing it for the next 5000 ms
|
||||
|
||||
### Other
|
||||
|
||||
#### Height: "auto"
|
||||
|
||||
From `v1.2.6` height can be set to "auto". If you want to be able to scroll modal in case it's height exceeds window height - you can set flag `scrollable="true"`.
|
||||
|
||||
p.s. `scrollable` will only work with `height="auto"`.
|
||||
|
||||
Example:
|
||||
|
||||
```vue
|
||||
<modal name="foo" height="auto" :scrollable="true">...</modal>
|
||||
```
|
||||
|
||||
|
||||
#### Close button
|
||||
|
||||
If you want to have a Close (x) button in the top-right corner, you can use "top-right" slot for it. There is deliberately no predefined Close button style - you will have to implement/use your own button.
|
||||
|
||||
@@ -58,27 +58,18 @@
|
||||
</button>
|
||||
<button class="blue"
|
||||
@click="$modal.show('size-modal')">
|
||||
Demo: Size = 60%
|
||||
Demo: Width: 60%, Height: auto
|
||||
</button>
|
||||
<!--
|
||||
<button class="green"
|
||||
@click="$modal.show('input-focus-modal')">
|
||||
Demo: Focus Input
|
||||
</button>
|
||||
-->
|
||||
<button :class="canBeShown ? 'green' : 'red'"
|
||||
@click="conditionalShow">
|
||||
Can <b v-if="!canBeShown">NOT</b> be shown
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<props-table />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModesTable from './components/ModesTable.vue'
|
||||
import PropsTable from './components/PropsTable.vue'
|
||||
import DemoErrorModal from './components/DemoErrorModal.vue'
|
||||
import DemoFocusModal from './components/InputFocusModal.vue'
|
||||
import DemoLoginModal from './components/DemoLoginModal.vue'
|
||||
@@ -90,7 +81,6 @@ export default {
|
||||
name: 'app',
|
||||
components: {
|
||||
ModesTable,
|
||||
PropsTable,
|
||||
DemoErrorModal,
|
||||
DemoFocusModal,
|
||||
DemoLoginModal,
|
||||
|
||||
@@ -1,15 +1,51 @@
|
||||
<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.
|
||||
transition="nice-modal-fade"
|
||||
:min-width="200"
|
||||
:min-height="200"
|
||||
:pivot-y="0.25"
|
||||
:adaptive="true"
|
||||
:scrollable="true"
|
||||
:reset="true"
|
||||
width="60%"
|
||||
height="auto"
|
||||
@before-open="beforeOpen"
|
||||
@before-close="beforeClose">
|
||||
<div class="size-modal-content">
|
||||
<div>A new paragraph will be added every 5 sec to show how <b>height</b> scales.</div>
|
||||
<div v-for="(p, i) in paragraphs" :key="i">
|
||||
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.
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'SizeModalTest',
|
||||
data () {
|
||||
return {
|
||||
paragraphs: [true],
|
||||
timer: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
beforeOpen () {
|
||||
this.timer = setInterval(() => {
|
||||
this.paragraphs.push(true)
|
||||
}, 5000)
|
||||
},
|
||||
|
||||
beforeClose () {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
this.paragraphs = []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.size-modal-content {
|
||||
padding: 10px;
|
||||
font-style: 13px;
|
||||
}
|
||||
</style>
|
||||
74
dist/index.js
vendored
74
dist/index.js
vendored
File diff suppressed because one or more lines are too long
74
dist/ssr.index.js
vendored
74
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.5",
|
||||
"version": "1.2.6",
|
||||
"author": "euvl <yev.vlasenko@gmail.com>",
|
||||
"main": "dist/index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<transition name="overlay-fade">
|
||||
<div v-if="visibility.overlay"
|
||||
ref="overlay"
|
||||
class="v--modal-overlay"
|
||||
:class="overlayClass"
|
||||
:aria-expanded="visible.toString()"
|
||||
:data-modal="name"
|
||||
@mousedown.stop="onBackgroundClick">
|
||||
@@ -16,7 +16,7 @@
|
||||
:style="modalStyle"
|
||||
@mousedown.stop>
|
||||
<slot/>
|
||||
<resizer v-if="resizable"
|
||||
<resizer v-if="resizable && !isAutoHeight"
|
||||
:min-width="minWidth"
|
||||
:min-height="minHeight"
|
||||
@resize="onModalResize"/>
|
||||
@@ -55,6 +55,10 @@
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
scrollable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
reset: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
@@ -102,6 +106,10 @@
|
||||
default: 300,
|
||||
validator (value) {
|
||||
if (typeof value === 'string') {
|
||||
if (value === 'auto') {
|
||||
return true
|
||||
}
|
||||
|
||||
let height = parseNumber(value)
|
||||
return (height.type === '%' || height.type === 'px')
|
||||
&& height.value > 0
|
||||
@@ -159,7 +167,6 @@
|
||||
visible (value) {
|
||||
if (value) {
|
||||
this.visibility.overlay = true
|
||||
// this.adaptSize()
|
||||
|
||||
setTimeout(() => {
|
||||
this.visibility.modal = true
|
||||
@@ -195,50 +202,75 @@
|
||||
|
||||
window.addEventListener('resize', this.onWindowResize)
|
||||
this.onWindowResize()
|
||||
|
||||
if (this.scrollable && !this.isAutoHeight) {
|
||||
console.warn(`Modal "${this.name}" has scrollable flag set to true ` +
|
||||
`but height is not "auto" (${this.height})`)
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('resize', this.onWindowResize)
|
||||
},
|
||||
computed: {
|
||||
isAutoHeight () {
|
||||
return this.modal.heightType === 'auto'
|
||||
},
|
||||
|
||||
position () {
|
||||
const { window, modal, shift } = this
|
||||
const { window, modal, shift, pivotX, pivotY,
|
||||
trueModalWidth, trueModalHeight, isAutoHeight } = this
|
||||
|
||||
const maxLeft = window.width - this.trueModalWidth
|
||||
const maxTop = window.height - this.trueModalHeight
|
||||
const maxLeft = window.width - trueModalWidth
|
||||
const maxTop = window.height - trueModalHeight
|
||||
|
||||
const left = shift.left +
|
||||
this.pivotX * (window.width - this.trueModalWidth)
|
||||
const top = shift.top +
|
||||
this.pivotY * (window.height - this.trueModalHeight)
|
||||
const minTop = this.scrollable
|
||||
? Number.NEGATIVE_INFINITY
|
||||
: 0
|
||||
|
||||
const left = shift.left + pivotX * maxLeft
|
||||
const top = shift.top + pivotY * maxTop
|
||||
|
||||
return {
|
||||
left: inRange(0, maxLeft, left),
|
||||
top: inRange(0, maxTop, top)
|
||||
top: inRange(minTop, maxTop, top)
|
||||
}
|
||||
},
|
||||
|
||||
trueModalWidth () {
|
||||
const { window, modal } = this
|
||||
const { window, modal, adaptive, minWidth } = this
|
||||
|
||||
const value = modal.widthType === '%'
|
||||
? window.width / 100 * modal.width
|
||||
: modal.width
|
||||
|
||||
return this.adaptive
|
||||
? inRange(this.minWidth, this.window.width, value)
|
||||
return adaptive
|
||||
? inRange(minWidth, window.width, value)
|
||||
: value
|
||||
},
|
||||
|
||||
trueModalHeight () {
|
||||
const { window, modal } = this
|
||||
const { window, modal, isAutoHeight, adaptive } = this
|
||||
|
||||
const value = (modal.heightType === '%')
|
||||
? window.height / 100 * modal.height
|
||||
: modal.height
|
||||
|
||||
return this.adaptive
|
||||
if (isAutoHeight) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return adaptive
|
||||
? inRange(this.minHeight, this.window.height, value)
|
||||
: value
|
||||
},
|
||||
|
||||
overlayClass () {
|
||||
return {
|
||||
'v--modal-overlay': true,
|
||||
'scrollable': this.scrollable && this.isAutoHeight
|
||||
}
|
||||
},
|
||||
|
||||
modalClass () {
|
||||
return ['v--modal-box', this.classes]
|
||||
},
|
||||
@@ -248,7 +280,9 @@
|
||||
top: this.position.top + 'px',
|
||||
left: this.position.left + 'px',
|
||||
width: this.trueModalWidth + 'px',
|
||||
height: this.trueModalHeight + 'px'
|
||||
height: this.isAutoHeight
|
||||
? 'auto'
|
||||
: (this.trueModalHeight + 'px')
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -424,6 +458,7 @@
|
||||
<style>
|
||||
.v--modal-overlay {
|
||||
position: fixed;
|
||||
box-sizing: border-box;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
@@ -433,12 +468,23 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.v--modal-overlay.scrollable {
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.v--modal-overlay .v--modal-box {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.v--modal-overlay.scrollable .v--modal-box {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.v--modal {
|
||||
background-color: white;
|
||||
text-align: left;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// "0.001px" => { type: "px", value: 0.001 }
|
||||
// "0.1%" => { type: "px", value: 0.1 }
|
||||
// "foo" => { type: "", value: "foo" }
|
||||
// "auto" => { type: "auto", value: 0 }
|
||||
|
||||
var floatRegexp = '[-+]?[0-9]*\.?[0-9]+'
|
||||
|
||||
@@ -24,6 +25,13 @@ var types = [
|
||||
]
|
||||
|
||||
var getType = (value) => {
|
||||
if (value === 'auto') {
|
||||
return {
|
||||
type: value,
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
let type = types[i]
|
||||
if (type.regexp.test(value)) {
|
||||
|
||||
Reference in New Issue
Block a user