useAvailableHeight
Measures how much room a pane actually has, for the panels that fill the screen and scroll inside themselves — Chat, Email.
Import
ts
import { useAvailableHeight } from '@shared/composables/useAvailableHeight'Signature
ts
function useAvailableHeight(target: Ref<HTMLElement | null>): {
height: Ref<string | null>
measure: () => void
}Returns
| Member | Type | Description |
|---|---|---|
height | Ref<string | null> | A CSS length such as '742px'. null until the first measurement. |
measure | () => void | Re-measures on the next animation frame. |
The floor is 420px. Below that the pane stops shrinking and the page is allowed to scroll instead.
Example
vue
<script setup lang="ts">
import { useAvailableHeight } from '@shared/composables/useAvailableHeight'
import { ref } from 'vue'
const pane = ref<HTMLElement | null>(null)
const { height } = useAvailableHeight(pane)
</script>
<template>
<div ref="pane" class="overflow-y-auto" :style="{ height: height ?? undefined }">
<slot />
</div>
</template>Notes
h-fullcannot do this.mainisflex-1with nomin-h-0, so a percentage height resolves against a content-driven height and CSS falls back to the content's own. The number has to be measured.- The measurement is the scrolling column's client height, minus the chrome above and below
main, minus the padding and borders of every ancestor between the target andmain. - Those insets are walked, not read from a rect. Reading only
main's padding misses the card thatModernLayoutadds, and a bounding rect includes the flex slack that is itself a function of the height being computed. - With no
mainor no scrolling ancestor it falls back to100dvhminus the element's top. - Resize is coalesced into one animation frame. Resize events fire in bursts, and measuring mid-burst reads a layout that is about to change again.
- It measures twice on mount — once as soon as the element exists, once after the layout settles — because fonts loading and the sidebar transition both shift the chrome height.
- It re-measures when
targetchanges, so av-ifon the pane is handled. - Listeners and the pending frame are cleaned up before unmount.
Related
- Layouts — the shell being measured around.
useResponsiveLayout— what changes at each width.