50 lines
1.4 KiB
JavaScript
50 lines
1.4 KiB
JavaScript
import { onMounted, onUnmounted, ref, nextTick, watch } from 'vue'
|
|
import { UI_CONFIG } from '../config/ui'
|
|
|
|
export function useFillHeight(elementRef, extraMargin = 0) {
|
|
const height = ref('auto')
|
|
|
|
const updateHeight = () => {
|
|
if (!elementRef.value) return
|
|
|
|
const rect = elementRef.value.getBoundingClientRect()
|
|
const windowHeight = window.innerHeight
|
|
|
|
// Calculate available space: window height - element top position - footer height - padding - extra margin
|
|
const bottomOffset = UI_CONFIG.footerHeight + UI_CONFIG.pagePadding + extraMargin
|
|
const availableHeight = windowHeight - rect.top - bottomOffset
|
|
|
|
// Ensure minimum height
|
|
if (availableHeight > 100) {
|
|
height.value = `${availableHeight}px`
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
// Initial update after render
|
|
nextTick(() => {
|
|
updateHeight()
|
|
window.addEventListener('resize', updateHeight)
|
|
})
|
|
|
|
// Also update after a short delay to ensure layout is settled (e.g. sidebar transitions)
|
|
setTimeout(updateHeight, 300)
|
|
|
|
// Watch for element appearing (v-if) or changing
|
|
watch(elementRef, () => {
|
|
nextTick(updateHeight)
|
|
// Additional update for layout stability
|
|
setTimeout(updateHeight, 100)
|
|
})
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('resize', updateHeight)
|
|
})
|
|
|
|
return {
|
|
height,
|
|
updateHeight
|
|
}
|
|
}
|