mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
fix: shaky header (#3727)
This commit is contained in:
@@ -34,7 +34,6 @@
|
||||
"@mui/material": "^5.14.4",
|
||||
"@react-hookz/web": "^23.1.0",
|
||||
"@toeverything/components": "^0.0.10",
|
||||
"@types/lodash.throttle": "^4.1.7",
|
||||
"async-call-rpc": "^6.3.1",
|
||||
"cmdk": "^0.2.0",
|
||||
"css-spring": "^4.1.0",
|
||||
@@ -44,7 +43,7 @@
|
||||
"jotai": "^2.3.1",
|
||||
"jotai-devtools": "^0.6.1",
|
||||
"lit": "^2.8.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lottie-web": "^5.12.2",
|
||||
"mini-css-extract-plugin": "^2.7.6",
|
||||
"next-themes": "^0.2.1",
|
||||
@@ -67,6 +66,7 @@
|
||||
"@sentry/webpack-plugin": "^2.6.2",
|
||||
"@svgr/webpack": "^8.0.1",
|
||||
"@swc/core": "^1.3.76",
|
||||
"@types/lodash.debounce": "^4.0.7",
|
||||
"@types/webpack-env": "^1.18.1",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.8.1",
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import { isDesktop } from '@affine/env/constant';
|
||||
import clsx from 'clsx';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import throttle from 'lodash.throttle';
|
||||
import debounce from 'lodash.debounce';
|
||||
import type { MutableRefObject, ReactNode } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
@@ -22,37 +22,52 @@ interface HeaderPros {
|
||||
|
||||
const useIsTinyScreen = ({
|
||||
mainContainer,
|
||||
leftDoms,
|
||||
leftStatic,
|
||||
leftSlot,
|
||||
centerDom,
|
||||
rightDoms,
|
||||
rightStatic,
|
||||
rightSlot,
|
||||
}: {
|
||||
mainContainer: HTMLElement;
|
||||
leftDoms: MutableRefObject<HTMLElement | null>[];
|
||||
leftStatic: MutableRefObject<HTMLElement | null>;
|
||||
leftSlot: MutableRefObject<HTMLElement | null>[];
|
||||
centerDom: MutableRefObject<HTMLElement | null>;
|
||||
rightDoms: MutableRefObject<HTMLElement | null>[];
|
||||
rightStatic: MutableRefObject<HTMLElement | null>;
|
||||
rightSlot: MutableRefObject<HTMLElement | null>[];
|
||||
}) => {
|
||||
const [isTinyScreen, setIsTinyScreen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = throttle(() => {
|
||||
const handleResize = debounce(() => {
|
||||
if (!centerDom.current) {
|
||||
return;
|
||||
}
|
||||
const leftTotalWidth = leftDoms.reduce((accWidth, dom) => {
|
||||
const leftStaticWidth = leftStatic.current?.clientWidth || 0;
|
||||
const leftSlotWidth = leftSlot.reduce((accWidth, dom) => {
|
||||
return accWidth + (dom.current?.clientWidth || 0);
|
||||
}, 0);
|
||||
|
||||
const rightTotalWidth = rightDoms.reduce((accWidth, dom) => {
|
||||
const rightStaticWidth = rightStatic.current?.clientWidth || 0;
|
||||
|
||||
const rightSlotWidth = rightSlot.reduce((accWidth, dom) => {
|
||||
return accWidth + (dom.current?.clientWidth || 0);
|
||||
}, 0);
|
||||
|
||||
if (!leftSlotWidth && !rightSlotWidth) {
|
||||
if (isTinyScreen) {
|
||||
setIsTinyScreen(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const containerRect = mainContainer.getBoundingClientRect();
|
||||
const centerRect = centerDom.current.getBoundingClientRect();
|
||||
|
||||
const offset = isTinyScreen ? 50 : 0;
|
||||
if (
|
||||
leftTotalWidth + containerRect.left >= centerRect.left - offset ||
|
||||
containerRect.right - centerRect.right <= rightTotalWidth + offset
|
||||
leftStaticWidth + leftSlotWidth + containerRect.left >=
|
||||
centerRect.left ||
|
||||
containerRect.right - centerRect.right <=
|
||||
rightSlotWidth + rightStaticWidth
|
||||
) {
|
||||
setIsTinyScreen(true);
|
||||
} else {
|
||||
@@ -67,7 +82,19 @@ const useIsTinyScreen = ({
|
||||
});
|
||||
|
||||
resizeObserver.observe(mainContainer);
|
||||
}, [centerDom, isTinyScreen, leftDoms, mainContainer, rightDoms]);
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, [
|
||||
centerDom,
|
||||
isTinyScreen,
|
||||
leftSlot,
|
||||
leftStatic,
|
||||
mainContainer,
|
||||
rightSlot,
|
||||
rightStatic,
|
||||
]);
|
||||
|
||||
return isTinyScreen;
|
||||
};
|
||||
@@ -84,9 +111,11 @@ export const Header = ({ left, center, right }: HeaderPros) => {
|
||||
|
||||
const isTinyScreen = useIsTinyScreen({
|
||||
mainContainer: document.querySelector('.main-container') || document.body,
|
||||
leftDoms: [sidebarSwitchRef, leftSlotRef],
|
||||
leftStatic: sidebarSwitchRef,
|
||||
leftSlot: [leftSlotRef],
|
||||
centerDom: centerSlotRef,
|
||||
rightDoms: [rightSlotRef, windowControlsRef],
|
||||
rightSlot: [rightSlotRef],
|
||||
rightStatic: windowControlsRef,
|
||||
});
|
||||
|
||||
const isWindowsDesktop = globalThis.platform === 'win32' && isDesktop;
|
||||
@@ -124,7 +153,6 @@ export const Header = ({ left, center, right }: HeaderPros) => {
|
||||
className={clsx({
|
||||
[style.headerCenter]: center,
|
||||
'is-window': isWindowsDesktop,
|
||||
'has-min-width': !isTinyScreen,
|
||||
})}
|
||||
ref={centerSlotRef}
|
||||
>
|
||||
|
||||
@@ -48,6 +48,7 @@ export const headerCenter = style({
|
||||
height: '52px',
|
||||
flexShrink: 0,
|
||||
maxWidth: '60%',
|
||||
minWidth: '300px',
|
||||
position: 'absolute',
|
||||
transform: 'translateX(-50%)',
|
||||
left: '50%',
|
||||
@@ -56,9 +57,6 @@ export const headerCenter = style({
|
||||
'&.is-window': {
|
||||
maxWidth: '50%',
|
||||
},
|
||||
'&.is-window.has-min-width': {
|
||||
minWidth: '400px',
|
||||
},
|
||||
'&.shadow': {
|
||||
position: 'static',
|
||||
visibility: 'hidden',
|
||||
@@ -76,6 +74,7 @@ export const headerSideContainer = style({
|
||||
},
|
||||
'&.block': {
|
||||
display: 'block',
|
||||
paddingBottom: '10px',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -83,6 +82,8 @@ export const headerSideContainer = style({
|
||||
export const windowAppControlsWrapper = style({
|
||||
display: 'flex',
|
||||
marginLeft: '20px',
|
||||
// header padding right
|
||||
transform: 'translateX(16px)',
|
||||
});
|
||||
|
||||
export const windowAppControl = style({
|
||||
@@ -98,7 +99,6 @@ export const windowAppControl = style({
|
||||
'&[data-type="close"]': {
|
||||
width: '56px',
|
||||
paddingRight: '5px',
|
||||
marginRight: '-12px',
|
||||
},
|
||||
'&[data-type="close"]:hover': {
|
||||
background: 'var(--affine-windows-close-button)',
|
||||
|
||||
Reference in New Issue
Block a user