fix: shaky header (#3727)

This commit is contained in:
Qi
2023-08-15 02:03:14 +08:00
committed by GitHub
parent 08da58aa1e
commit d0e33c748b
4 changed files with 55 additions and 34 deletions

View File

@@ -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",

View File

@@ -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}
>

View File

@@ -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)',