104 lines
2.7 KiB
Vue
104 lines
2.7 KiB
Vue
<template>
|
|
<q-dialog
|
|
v-model="modelValue"
|
|
class="q-ma-none"
|
|
>
|
|
<q-card
|
|
class="q-pa-none q-ma-none w100 q-pb-md no-scroll rounded-card no-wrap overflow-hidden"
|
|
ref="cardRef"
|
|
style="
|
|
max-height: calc(100vh - 48px - 2 * max(var(--tg-content-safe-area-inset-top) + var(--tg-safe-area-inset-top), var(--tg-safe-area-inset-bottom)));
|
|
width: calc(100vw - 32px);
|
|
"
|
|
>
|
|
<q-resize-observer @resize="onResizeCard" />
|
|
<q-card-section class="row items-center q-pb-none" ref="cardHeaderRef">
|
|
<div class="flex no-wrap items-center w100">
|
|
<q-resize-observer @resize="onHeaderResize"/>
|
|
<span class="text-bold">
|
|
{{ $t(title)}}
|
|
</span>
|
|
<q-space />
|
|
<q-btn icon="close" flat round dense v-close-popup />
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<div
|
|
ref="cardBodyRef"
|
|
class="q-px-none q-ma-none"
|
|
>
|
|
<pn-shadow-scroll
|
|
:height="bodyHeight"
|
|
>
|
|
<div ref="cardBodyInnerRef" class="q-pa-none q-ma-none">
|
|
<q-resize-observer @resize="updateDimensions" />
|
|
<slot/>
|
|
</div>
|
|
</pn-shadow-scroll>
|
|
</div>
|
|
</q-card>
|
|
</q-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, watch, nextTick } from 'vue'
|
|
import { useSlots } from 'vue'
|
|
|
|
const modelValue = defineModel<boolean>({
|
|
required: true
|
|
})
|
|
|
|
defineProps<{
|
|
title: string
|
|
}>()
|
|
|
|
const slots = useSlots()
|
|
const cardBodyInnerRef = ref<HTMLElement | null>(null)
|
|
|
|
const headerHeight = ref(0)
|
|
const bodyInnerHeight = ref(0)
|
|
const bodyHeight = ref(0)
|
|
const cardHeight = ref(0)
|
|
|
|
interface sizeParams {
|
|
height: number,
|
|
width: number
|
|
}
|
|
|
|
function onResizeCard (size :sizeParams) {
|
|
cardHeight.value = size.width
|
|
}
|
|
|
|
function onHeaderResize (size: sizeParams) {
|
|
headerHeight.value = size.height
|
|
}
|
|
|
|
const updateDimensions = async () => {
|
|
await nextTick(() => {
|
|
bodyInnerHeight.value = cardBodyInnerRef.value?.offsetHeight || 0
|
|
|
|
const maxH = cardMaxHeight()
|
|
|
|
const availableForBody = maxH - headerHeight.value - 32 // 16 - md-padding + 16px - shadow-block
|
|
bodyHeight.value = Math.min(bodyInnerHeight.value + 32, availableForBody)
|
|
})
|
|
}
|
|
|
|
watch(() => slots.body?.(), updateDimensions, { flush: 'post' })
|
|
watch(modelValue, updateDimensions)
|
|
|
|
const cardRef = ref()
|
|
function cardMaxHeight () {
|
|
const el = cardRef.value?.$el
|
|
if (el) {
|
|
const computedStyle = window.getComputedStyle(el)
|
|
return parseFloat(computedStyle.maxHeight)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
</style>
|