import type { CSSProperties } from 'vue'; import { computed, onMounted, onUnmounted, ref } from 'vue'; import { CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT, CSS_VARIABLE_LAYOUT_CONTENT_WIDTH, } from '@vben-core/shared/constants'; import { getElementVisibleRect, type VisibleDomRect, } from '@vben-core/shared/utils'; import { useCssVar, useDebounceFn } from '@vueuse/core'; /** * @zh_CN content style */ function useContentStyle() { let resizeObserver: null | ResizeObserver = null; const contentElement = ref(null); const visibleDomRect = ref(null); const contentHeight = useCssVar(CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT); const contentWidth = useCssVar(CSS_VARIABLE_LAYOUT_CONTENT_WIDTH); const overlayStyle = computed((): CSSProperties => { const { height, left, top, width } = visibleDomRect.value ?? {}; return { height: `${height}px`, left: `${left}px`, position: 'fixed', top: `${top}px`, width: `${width}px`, zIndex: 150, }; }); const debouncedCalcHeight = useDebounceFn( (_entries: ResizeObserverEntry[]) => { visibleDomRect.value = getElementVisibleRect(contentElement.value); contentHeight.value = `${visibleDomRect.value.height}px`; contentWidth.value = `${visibleDomRect.value.width}px`; }, 100, ); onMounted(() => { if (contentElement.value && !resizeObserver) { resizeObserver = new ResizeObserver(debouncedCalcHeight); resizeObserver.observe(contentElement.value); } }); onUnmounted(() => { resizeObserver?.disconnect(); resizeObserver = null; }); return { contentElement, overlayStyle, visibleDomRect }; } export { useContentStyle };