Added support fro height: auto and scrollable flag

This commit is contained in:
euvl
2017-07-24 13:35:25 +01:00
parent ad288e3e75
commit 31ac33e206
5 changed files with 180 additions and 55 deletions

View File

@@ -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,

View File

@@ -1,15 +1,52 @@
<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"
:draggable="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>
</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

File diff suppressed because one or more lines are too long

View File

@@ -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;

View File

@@ -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)) {