mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-06-16 21:03:58 +08:00
refactor(hooks): share floating action-bar height syncing
AuthFilesPage and ConfigPage duplicated the ResizeObserver-to-CSS-variable wiring for their bottom action bars; extract useActionBarHeightVar and use it in both.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import { useLayoutEffect, type RefObject } from 'react';
|
||||
|
||||
/**
|
||||
* 将悬浮操作条的实时高度同步到根元素 CSS 变量,供页面底部留白使用。
|
||||
* active 为 false 或元素未挂载时清除变量。
|
||||
*/
|
||||
export function useActionBarHeightVar(
|
||||
ref: RefObject<HTMLElement | null>,
|
||||
cssVar: string,
|
||||
active: boolean
|
||||
) {
|
||||
useLayoutEffect(() => {
|
||||
if (typeof window === 'undefined') return;
|
||||
|
||||
const actionsEl = active ? ref.current : null;
|
||||
if (!actionsEl) {
|
||||
document.documentElement.style.removeProperty(cssVar);
|
||||
return;
|
||||
}
|
||||
|
||||
const updateHeight = () => {
|
||||
const height = actionsEl.getBoundingClientRect().height;
|
||||
document.documentElement.style.setProperty(cssVar, `${height}px`);
|
||||
};
|
||||
|
||||
updateHeight();
|
||||
window.addEventListener('resize', updateHeight);
|
||||
|
||||
const ro = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(updateHeight);
|
||||
ro?.observe(actionsEl);
|
||||
|
||||
return () => {
|
||||
ro?.disconnect();
|
||||
window.removeEventListener('resize', updateHeight);
|
||||
document.documentElement.style.removeProperty(cssVar);
|
||||
};
|
||||
}, [ref, cssVar, active]);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import { animate } from 'motion/mini';
|
||||
import type { AnimationPlaybackControlsWithThen } from 'motion-dom';
|
||||
import { useInterval } from '@/hooks/useInterval';
|
||||
import { useHeaderRefresh } from '@/hooks/useHeaderRefresh';
|
||||
import { useActionBarHeightVar } from '@/hooks/useActionBarHeightVar';
|
||||
import { usePageTransitionLayer } from '@/components/common/PageTransitionLayer';
|
||||
import { Card } from '@/components/ui/Card';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
@@ -492,32 +493,11 @@ export function AuthFilesPage() {
|
||||
[filter, navigate]
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (typeof window === 'undefined') return;
|
||||
|
||||
const actionsEl = floatingBatchActionsRef.current;
|
||||
if (!actionsEl) {
|
||||
document.documentElement.style.removeProperty('--auth-files-action-bar-height');
|
||||
return;
|
||||
}
|
||||
|
||||
const updatePadding = () => {
|
||||
const height = actionsEl.getBoundingClientRect().height;
|
||||
document.documentElement.style.setProperty('--auth-files-action-bar-height', `${height}px`);
|
||||
};
|
||||
|
||||
updatePadding();
|
||||
window.addEventListener('resize', updatePadding);
|
||||
|
||||
const ro = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(updatePadding);
|
||||
ro?.observe(actionsEl);
|
||||
|
||||
return () => {
|
||||
ro?.disconnect();
|
||||
window.removeEventListener('resize', updatePadding);
|
||||
document.documentElement.style.removeProperty('--auth-files-action-bar-height');
|
||||
};
|
||||
}, [batchActionBarVisible, selectionCount]);
|
||||
useActionBarHeightVar(
|
||||
floatingBatchActionsRef,
|
||||
'--auth-files-action-bar-height',
|
||||
batchActionBarVisible
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
selectionCountRef.current = selectionCount;
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
lazy,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
@@ -25,6 +24,7 @@ import {
|
||||
import { VisualConfigEditor } from '@/components/config/VisualConfigEditor';
|
||||
import { DiffModal } from '@/components/config/DiffModal';
|
||||
import { useMediaQuery } from '@/hooks/useMediaQuery';
|
||||
import { useActionBarHeightVar } from '@/hooks/useActionBarHeightVar';
|
||||
import { useUnsavedChangesGuard } from '@/hooks/useUnsavedChangesGuard';
|
||||
import { useVisualConfig } from '@/hooks/useVisualConfig';
|
||||
import { useNotificationStore, useAuthStore, useThemeStore, useConfigStore } from '@/stores';
|
||||
@@ -427,29 +427,7 @@ export function ConfigPage() {
|
||||
}, [lastSearchedQuery, performSearch]);
|
||||
|
||||
// Keep bottom floating actions from covering page content by syncing its height to a CSS variable.
|
||||
useLayoutEffect(() => {
|
||||
if (typeof window === 'undefined' || !shouldRenderFloatingActions) return;
|
||||
|
||||
const actionsEl = floatingActionsRef.current;
|
||||
if (!actionsEl) return;
|
||||
|
||||
const updatePadding = () => {
|
||||
const height = actionsEl.getBoundingClientRect().height;
|
||||
document.documentElement.style.setProperty('--config-action-bar-height', `${height}px`);
|
||||
};
|
||||
|
||||
updatePadding();
|
||||
window.addEventListener('resize', updatePadding);
|
||||
|
||||
const ro = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(updatePadding);
|
||||
ro?.observe(actionsEl);
|
||||
|
||||
return () => {
|
||||
ro?.disconnect();
|
||||
window.removeEventListener('resize', updatePadding);
|
||||
document.documentElement.style.removeProperty('--config-action-bar-height');
|
||||
};
|
||||
}, [shouldRenderFloatingActions]);
|
||||
useActionBarHeightVar(floatingActionsRef, '--config-action-bar-height', shouldRenderFloatingActions);
|
||||
|
||||
// Status text
|
||||
const getStatusText = () => {
|
||||
|
||||
Reference in New Issue
Block a user