quasar
Version:
Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
115 lines (92 loc) • 2.44 kB
JavaScript
import { h, ref, computed, watch, getCurrentInstance } from 'vue'
import QDialog from '../dialog/QDialog.js'
import QMenu from '../menu/QMenu.js'
import useAnchor, {
useAnchorProps
} from '../../composables/private.use-anchor/use-anchor.js'
import { createComponent } from '../../utils/private.create/create.js'
import { injectProp } from '../../utils/private.inject-obj-prop/inject-obj-prop.js'
export default createComponent({
name: 'QPopupProxy',
props: {
...useAnchorProps,
breakpoint: {
type: [String, Number],
default: 450
}
},
emits: ['show', 'hide'],
setup(props, { slots, emit, attrs }) {
const { proxy } = getCurrentInstance()
const { $q } = proxy
const showing = ref(false)
const popupRef = ref(null)
const breakpoint = computed(() => parseInt(props.breakpoint, 10))
const { canShow } = useAnchor({ showing })
function getType() {
return $q.screen.width < breakpoint.value ||
$q.screen.height < breakpoint.value
? 'dialog'
: 'menu'
}
const type = ref(getType())
const popupProps = computed(() =>
type.value === 'menu' ? { maxHeight: '99vh' } : {}
)
watch(
() => getType(),
val => {
if (showing.value !== true) {
type.value = val
}
}
)
function onShow(evt) {
showing.value = true
emit('show', evt)
}
function onHide(evt) {
showing.value = false
type.value = getType()
emit('hide', evt)
}
// expose public methods
Object.assign(proxy, {
show(evt) {
if (canShow(evt) === true) popupRef.value.show(evt)
},
hide(evt) {
popupRef.value.hide(evt)
},
toggle(evt) {
popupRef.value.toggle(evt)
}
})
injectProp(proxy, 'currentComponent', () => ({
type: type.value,
ref: popupRef.value
}))
return () => {
const data = {
ref: popupRef,
...popupProps.value,
...attrs,
onShow,
onHide
}
let component
if (type.value === 'dialog') {
component = QDialog
} else {
component = QMenu
Object.assign(data, {
target: props.target,
contextMenu: props.contextMenu,
noParentEvent: true,
separateClosePopup: true
})
}
return h(component, data, slots.default)
}
}
})