add align
parent
e918a45e03
commit
8736a23884
|
@ -0,0 +1,5 @@
|
|||
import addDOMEventListener from 'add-dom-event-listener'
|
||||
|
||||
export default function addEventListenerWrap (target, eventType, cb) {
|
||||
return addDOMEventListener(target, eventType, cb)
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
export default {
|
||||
methods: {
|
||||
setState (state, callback) {
|
||||
Object.assign(this.$date, state)
|
||||
Object.assign(this.$data, state)
|
||||
this.$nextTick(() => {
|
||||
callback()
|
||||
callback && callback()
|
||||
})
|
||||
},
|
||||
},
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
export default (node, props) => {
|
||||
if (node.componentOptions) {
|
||||
const propsData = node.componentOptions.propsData
|
||||
Object.assign(propsData, props)
|
||||
}
|
||||
return node
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<script>
|
||||
import PropTypes from 'vue-types'
|
||||
import align from 'dom-align'
|
||||
import addEventListener from '../_util/Dom/addEventListener'
|
||||
import cloneElement from '../_util/cloneElement'
|
||||
function noop () {
|
||||
}
|
||||
|
||||
function buffer (fn, ms) {
|
||||
let timer
|
||||
|
||||
function clear () {
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
timer = null
|
||||
}
|
||||
}
|
||||
|
||||
function bufferFn () {
|
||||
clear()
|
||||
timer = setTimeout(fn, ms)
|
||||
}
|
||||
|
||||
bufferFn.clear = clear
|
||||
|
||||
return bufferFn
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
childrenProps: PropTypes.object,
|
||||
align: PropTypes.object.isRequired,
|
||||
target: PropTypes.func.def(noop),
|
||||
monitorBufferTime: PropTypes.number.def(50),
|
||||
monitorWindowResize: PropTypes.bool.def(false),
|
||||
disabled: PropTypes.bool.def(false),
|
||||
},
|
||||
|
||||
mounted () {
|
||||
const props = this.$props
|
||||
// if parent ref not attached .... use document.getElementById
|
||||
this.forceAlign()
|
||||
if (!props.disabled && props.monitorWindowResize) {
|
||||
this.startMonitorWindowResize()
|
||||
}
|
||||
},
|
||||
|
||||
updated () {
|
||||
const props = this.$props
|
||||
|
||||
this.forceAlign()
|
||||
|
||||
if (props.monitorWindowResize && !props.disabled) {
|
||||
this.startMonitorWindowResize()
|
||||
} else {
|
||||
this.stopMonitorWindowResize()
|
||||
}
|
||||
},
|
||||
|
||||
beforeDestory () {
|
||||
this.stopMonitorWindowResize()
|
||||
},
|
||||
methods: {
|
||||
startMonitorWindowResize () {
|
||||
if (!this.resizeHandler) {
|
||||
this.bufferMonitor = buffer(this.forceAlign, this.$props.monitorBufferTime)
|
||||
this.resizeHandler = addEventListener(window, 'resize', this.bufferMonitor)
|
||||
}
|
||||
},
|
||||
|
||||
stopMonitorWindowResize () {
|
||||
if (this.resizeHandler) {
|
||||
this.bufferMonitor.clear()
|
||||
this.resizeHandler.remove()
|
||||
this.resizeHandler = null
|
||||
}
|
||||
},
|
||||
|
||||
forceAlign () {
|
||||
const props = this.$props
|
||||
if (!props.disabled) {
|
||||
const source = this.$el
|
||||
this.$emit('align', source, align(source, props.target(), props.align))
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const { childrenProps } = this.$props
|
||||
const child = this.$slots.default[0]
|
||||
if (childrenProps) {
|
||||
const newProps = {}
|
||||
for (const prop in childrenProps) {
|
||||
if (childrenProps.hasOwnProperty(prop)) {
|
||||
newProps[prop] = this.props[childrenProps[prop]]
|
||||
}
|
||||
}
|
||||
return cloneElement(child, newProps)
|
||||
}
|
||||
return child
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,81 @@
|
|||
<script>
|
||||
import Align from '../index'
|
||||
import StateMixin from '../../_util/StateMixin'
|
||||
|
||||
export default {
|
||||
mixins: [StateMixin],
|
||||
data () {
|
||||
return {
|
||||
monitor: true,
|
||||
align: {
|
||||
points: ['tl', 'tc'],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTarget () {
|
||||
const ref = this.$refs.container
|
||||
// if (!ref) {
|
||||
// // parent ref not attached
|
||||
// ref = document.getElementById('container')
|
||||
// }
|
||||
return ref
|
||||
},
|
||||
|
||||
toggleMonitor () {
|
||||
this.setState({
|
||||
monitor: !this.$data.monitor,
|
||||
})
|
||||
},
|
||||
|
||||
forceAlign () {
|
||||
this.setState({
|
||||
align: Object.assign({}, this.$data.align),
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
margin: 50,
|
||||
}}
|
||||
>
|
||||
<p>
|
||||
<button onClick={this.forceAlign}>force align</button>
|
||||
|
||||
<button onClick={this.toggleMonitor}>toggle monitor</button>
|
||||
</p>
|
||||
<div
|
||||
ref='container'
|
||||
id='container'
|
||||
style={{
|
||||
width: '80%',
|
||||
height: '500px',
|
||||
border: '1px solid red',
|
||||
}}
|
||||
>
|
||||
<Align
|
||||
target={this.getTarget}
|
||||
monitorWindowResize={this.$data.monitor}
|
||||
align={this.$data.align}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '50px',
|
||||
height: '50px',
|
||||
background: 'yellow',
|
||||
}}
|
||||
>
|
||||
source
|
||||
</div>
|
||||
</Align>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,3 @@
|
|||
// export this package's api
|
||||
import Align from './Align'
|
||||
export default Align
|
|
@ -0,0 +1,5 @@
|
|||
export default function isWindow (obj) {
|
||||
/* eslint no-eq-null: 0 */
|
||||
/* eslint eqeqeq: 0 */
|
||||
return obj != null && obj == obj.window
|
||||
}
|
Loading…
Reference in New Issue