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", "@mui/material": "^5.14.4",
"@react-hookz/web": "^23.1.0", "@react-hookz/web": "^23.1.0",
"@toeverything/components": "^0.0.10", "@toeverything/components": "^0.0.10",
"@types/lodash.throttle": "^4.1.7",
"async-call-rpc": "^6.3.1", "async-call-rpc": "^6.3.1",
"cmdk": "^0.2.0", "cmdk": "^0.2.0",
"css-spring": "^4.1.0", "css-spring": "^4.1.0",
@@ -44,7 +43,7 @@
"jotai": "^2.3.1", "jotai": "^2.3.1",
"jotai-devtools": "^0.6.1", "jotai-devtools": "^0.6.1",
"lit": "^2.8.0", "lit": "^2.8.0",
"lodash.throttle": "^4.1.1", "lodash.debounce": "^4.0.8",
"lottie-web": "^5.12.2", "lottie-web": "^5.12.2",
"mini-css-extract-plugin": "^2.7.6", "mini-css-extract-plugin": "^2.7.6",
"next-themes": "^0.2.1", "next-themes": "^0.2.1",
@@ -67,6 +66,7 @@
"@sentry/webpack-plugin": "^2.6.2", "@sentry/webpack-plugin": "^2.6.2",
"@svgr/webpack": "^8.0.1", "@svgr/webpack": "^8.0.1",
"@swc/core": "^1.3.76", "@swc/core": "^1.3.76",
"@types/lodash.debounce": "^4.0.7",
"@types/webpack-env": "^1.18.1", "@types/webpack-env": "^1.18.1",
"copy-webpack-plugin": "^11.0.0", "copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.8.1", "css-loader": "^6.8.1",

View File

@@ -7,7 +7,7 @@ import {
import { isDesktop } from '@affine/env/constant'; import { isDesktop } from '@affine/env/constant';
import clsx from 'clsx'; import clsx from 'clsx';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
import throttle from 'lodash.throttle'; import debounce from 'lodash.debounce';
import type { MutableRefObject, ReactNode } from 'react'; import type { MutableRefObject, ReactNode } from 'react';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
@@ -22,37 +22,52 @@ interface HeaderPros {
const useIsTinyScreen = ({ const useIsTinyScreen = ({
mainContainer, mainContainer,
leftDoms, leftStatic,
leftSlot,
centerDom, centerDom,
rightDoms, rightStatic,
rightSlot,
}: { }: {
mainContainer: HTMLElement; mainContainer: HTMLElement;
leftDoms: MutableRefObject<HTMLElement | null>[]; leftStatic: MutableRefObject<HTMLElement | null>;
leftSlot: MutableRefObject<HTMLElement | null>[];
centerDom: MutableRefObject<HTMLElement | null>; centerDom: MutableRefObject<HTMLElement | null>;
rightDoms: MutableRefObject<HTMLElement | null>[]; rightStatic: MutableRefObject<HTMLElement | null>;
rightSlot: MutableRefObject<HTMLElement | null>[];
}) => { }) => {
const [isTinyScreen, setIsTinyScreen] = useState(false); const [isTinyScreen, setIsTinyScreen] = useState(false);
useEffect(() => { useEffect(() => {
const handleResize = throttle(() => { const handleResize = debounce(() => {
if (!centerDom.current) { if (!centerDom.current) {
return; 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); return accWidth + (dom.current?.clientWidth || 0);
}, 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); return accWidth + (dom.current?.clientWidth || 0);
}, 0); }, 0);
if (!leftSlotWidth && !rightSlotWidth) {
if (isTinyScreen) {
setIsTinyScreen(false);
}
return;
}
const containerRect = mainContainer.getBoundingClientRect(); const containerRect = mainContainer.getBoundingClientRect();
const centerRect = centerDom.current.getBoundingClientRect(); const centerRect = centerDom.current.getBoundingClientRect();
const offset = isTinyScreen ? 50 : 0;
if ( if (
leftTotalWidth + containerRect.left >= centerRect.left - offset || leftStaticWidth + leftSlotWidth + containerRect.left >=
containerRect.right - centerRect.right <= rightTotalWidth + offset centerRect.left ||
containerRect.right - centerRect.right <=
rightSlotWidth + rightStaticWidth
) { ) {
setIsTinyScreen(true); setIsTinyScreen(true);
} else { } else {
@@ -67,7 +82,19 @@ const useIsTinyScreen = ({
}); });
resizeObserver.observe(mainContainer); resizeObserver.observe(mainContainer);
}, [centerDom, isTinyScreen, leftDoms, mainContainer, rightDoms]);
return () => {
resizeObserver.disconnect();
};
}, [
centerDom,
isTinyScreen,
leftSlot,
leftStatic,
mainContainer,
rightSlot,
rightStatic,
]);
return isTinyScreen; return isTinyScreen;
}; };
@@ -84,9 +111,11 @@ export const Header = ({ left, center, right }: HeaderPros) => {
const isTinyScreen = useIsTinyScreen({ const isTinyScreen = useIsTinyScreen({
mainContainer: document.querySelector('.main-container') || document.body, mainContainer: document.querySelector('.main-container') || document.body,
leftDoms: [sidebarSwitchRef, leftSlotRef], leftStatic: sidebarSwitchRef,
leftSlot: [leftSlotRef],
centerDom: centerSlotRef, centerDom: centerSlotRef,
rightDoms: [rightSlotRef, windowControlsRef], rightSlot: [rightSlotRef],
rightStatic: windowControlsRef,
}); });
const isWindowsDesktop = globalThis.platform === 'win32' && isDesktop; const isWindowsDesktop = globalThis.platform === 'win32' && isDesktop;
@@ -124,7 +153,6 @@ export const Header = ({ left, center, right }: HeaderPros) => {
className={clsx({ className={clsx({
[style.headerCenter]: center, [style.headerCenter]: center,
'is-window': isWindowsDesktop, 'is-window': isWindowsDesktop,
'has-min-width': !isTinyScreen,
})} })}
ref={centerSlotRef} ref={centerSlotRef}
> >

View File

@@ -48,6 +48,7 @@ export const headerCenter = style({
height: '52px', height: '52px',
flexShrink: 0, flexShrink: 0,
maxWidth: '60%', maxWidth: '60%',
minWidth: '300px',
position: 'absolute', position: 'absolute',
transform: 'translateX(-50%)', transform: 'translateX(-50%)',
left: '50%', left: '50%',
@@ -56,9 +57,6 @@ export const headerCenter = style({
'&.is-window': { '&.is-window': {
maxWidth: '50%', maxWidth: '50%',
}, },
'&.is-window.has-min-width': {
minWidth: '400px',
},
'&.shadow': { '&.shadow': {
position: 'static', position: 'static',
visibility: 'hidden', visibility: 'hidden',
@@ -76,6 +74,7 @@ export const headerSideContainer = style({
}, },
'&.block': { '&.block': {
display: 'block', display: 'block',
paddingBottom: '10px',
}, },
}, },
}); });
@@ -83,6 +82,8 @@ export const headerSideContainer = style({
export const windowAppControlsWrapper = style({ export const windowAppControlsWrapper = style({
display: 'flex', display: 'flex',
marginLeft: '20px', marginLeft: '20px',
// header padding right
transform: 'translateX(16px)',
}); });
export const windowAppControl = style({ export const windowAppControl = style({
@@ -98,7 +99,6 @@ export const windowAppControl = style({
'&[data-type="close"]': { '&[data-type="close"]': {
width: '56px', width: '56px',
paddingRight: '5px', paddingRight: '5px',
marginRight: '-12px',
}, },
'&[data-type="close"]:hover': { '&[data-type="close"]:hover': {
background: 'var(--affine-windows-close-button)', background: 'var(--affine-windows-close-button)',

View File

@@ -247,7 +247,7 @@ __metadata:
"@svgr/webpack": ^8.0.1 "@svgr/webpack": ^8.0.1
"@swc/core": ^1.3.76 "@swc/core": ^1.3.76
"@toeverything/components": ^0.0.10 "@toeverything/components": ^0.0.10
"@types/lodash.throttle": ^4.1.7 "@types/lodash.debounce": ^4.0.7
"@types/webpack-env": ^1.18.1 "@types/webpack-env": ^1.18.1
async-call-rpc: ^6.3.1 async-call-rpc: ^6.3.1
cmdk: ^0.2.0 cmdk: ^0.2.0
@@ -262,7 +262,7 @@ __metadata:
jotai: ^2.3.1 jotai: ^2.3.1
jotai-devtools: ^0.6.1 jotai-devtools: ^0.6.1
lit: ^2.8.0 lit: ^2.8.0
lodash.throttle: ^4.1.1 lodash.debounce: ^4.0.8
lottie-web: ^5.12.2 lottie-web: ^5.12.2
mini-css-extract-plugin: ^2.7.6 mini-css-extract-plugin: ^2.7.6
next-themes: ^0.2.1 next-themes: ^0.2.1
@@ -12043,12 +12043,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/lodash.throttle@npm:^4.1.7": "@types/lodash.debounce@npm:^4.0.7":
version: 4.1.7 version: 4.0.7
resolution: "@types/lodash.throttle@npm:4.1.7" resolution: "@types/lodash.debounce@npm:4.0.7"
dependencies: dependencies:
"@types/lodash": "*" "@types/lodash": "*"
checksum: 6e1b3836488fecbdc537b6ad9b3fe4855c7336b0fa388773cd57d486619f565a48cabc04b28677fd3819be3f2d13d2bb8f9d4428aa5632885c86cb99729bfd69 checksum: e873b2d77f89010876baba3437ef826b17221b98948e00b5590828334a481dea1c8f9d28543210e564adc53199584f42c3cb171f8b6c3614fefc0b4e0888679c
languageName: node languageName: node
linkType: hard linkType: hard
@@ -23755,13 +23755,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lodash.throttle@npm:^4.1.1":
version: 4.1.1
resolution: "lodash.throttle@npm:4.1.1"
checksum: 129c0a28cee48b348aef146f638ef8a8b197944d4e9ec26c1890c19d9bf5a5690fe11b655c77a4551268819b32d27f4206343e30c78961f60b561b8608c8c805
languageName: node
linkType: hard
"lodash.truncate@npm:^4.4.2": "lodash.truncate@npm:^4.4.2":
version: 4.4.2 version: 4.4.2
resolution: "lodash.truncate@npm:4.4.2" resolution: "lodash.truncate@npm:4.4.2"