mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 02:42:25 +08:00
feat: modify sidebar floating logic and header responsive style (#3550)
This commit is contained in:
@@ -8,6 +8,7 @@ import { isDesktop } from '@affine/env/constant';
|
|||||||
import { CloseIcon, MinusIcon, RoundedRectangleIcon } from '@blocksuite/icons';
|
import { CloseIcon, MinusIcon, RoundedRectangleIcon } from '@blocksuite/icons';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page } from '@blocksuite/store';
|
||||||
import { headerItemsAtom } from '@toeverything/infra/atom';
|
import { headerItemsAtom } from '@toeverything/infra/atom';
|
||||||
|
import clsx from 'clsx';
|
||||||
import { useAtom, useAtomValue } from 'jotai';
|
import { useAtom, useAtomValue } from 'jotai';
|
||||||
import type { FC, HTMLAttributes, PropsWithChildren, ReactNode } from 'react';
|
import type { FC, HTMLAttributes, PropsWithChildren, ReactNode } from 'react';
|
||||||
import {
|
import {
|
||||||
@@ -38,8 +39,6 @@ export type BaseHeaderProps<
|
|||||||
|
|
||||||
export enum HeaderRightItemName {
|
export enum HeaderRightItemName {
|
||||||
EditorOptionMenu = 'editorOptionMenu',
|
EditorOptionMenu = 'editorOptionMenu',
|
||||||
// some windows only items
|
|
||||||
WindowsAppControls = 'windowsAppControls',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeaderItem = {
|
type HeaderItem = {
|
||||||
@@ -63,59 +62,54 @@ const HeaderRightItems: Record<HeaderRightItemName, HeaderItem> = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[HeaderRightItemName.WindowsAppControls]: {
|
|
||||||
Component: () => {
|
|
||||||
const handleMinimizeApp = useCallback(() => {
|
|
||||||
window.apis?.ui.handleMinimizeApp().catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
const handleMaximizeApp = useCallback(() => {
|
|
||||||
window.apis?.ui.handleMaximizeApp().catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
const handleCloseApp = useCallback(() => {
|
|
||||||
window.apis?.ui.handleCloseApp().catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
data-platform-target="win32"
|
|
||||||
className={styles.windowAppControlsWrapper}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
data-type="minimize"
|
|
||||||
className={styles.windowAppControl}
|
|
||||||
onClick={handleMinimizeApp}
|
|
||||||
>
|
|
||||||
<MinusIcon />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
data-type="maximize"
|
|
||||||
className={styles.windowAppControl}
|
|
||||||
onClick={handleMaximizeApp}
|
|
||||||
>
|
|
||||||
<RoundedRectangleIcon />
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
data-type="close"
|
|
||||||
className={styles.windowAppControl}
|
|
||||||
onClick={handleCloseApp}
|
|
||||||
>
|
|
||||||
<CloseIcon />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
availableWhen: () => {
|
|
||||||
return isDesktop && globalThis.platform === 'win32';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HeaderProps = BaseHeaderProps;
|
export type HeaderProps = BaseHeaderProps;
|
||||||
|
const WindowsAppControls = () => {
|
||||||
|
const handleMinimizeApp = useCallback(() => {
|
||||||
|
window.apis?.ui.handleMinimizeApp().catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
const handleMaximizeApp = useCallback(() => {
|
||||||
|
window.apis?.ui.handleMaximizeApp().catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
const handleCloseApp = useCallback(() => {
|
||||||
|
window.apis?.ui.handleCloseApp().catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-platform-target="win32"
|
||||||
|
className={styles.windowAppControlsWrapper}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
data-type="minimize"
|
||||||
|
className={styles.windowAppControl}
|
||||||
|
onClick={handleMinimizeApp}
|
||||||
|
>
|
||||||
|
<MinusIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
data-type="maximize"
|
||||||
|
className={styles.windowAppControl}
|
||||||
|
onClick={handleMaximizeApp}
|
||||||
|
>
|
||||||
|
<RoundedRectangleIcon />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
data-type="close"
|
||||||
|
className={styles.windowAppControl}
|
||||||
|
onClick={handleCloseApp}
|
||||||
|
>
|
||||||
|
<CloseIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const PluginHeader = () => {
|
const PluginHeader = () => {
|
||||||
const rootRef = useRef<HTMLDivElement>(null);
|
const rootRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -165,7 +159,7 @@ export const Header = forwardRef<
|
|||||||
const appSidebarFloating = useAtomValue(appSidebarFloatingAtom);
|
const appSidebarFloating = useAtomValue(appSidebarFloatingAtom);
|
||||||
|
|
||||||
const mode = useAtomValue(currentModeAtom);
|
const mode = useAtomValue(currentModeAtom);
|
||||||
|
const isWindowsDesktop = globalThis.platform === 'win32' && isDesktop;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.headerContainer}
|
className={styles.headerContainer}
|
||||||
@@ -196,14 +190,25 @@ export const Header = forwardRef<
|
|||||||
data-has-warning={showWarning}
|
data-has-warning={showWarning}
|
||||||
data-testid="editor-header-items"
|
data-testid="editor-header-items"
|
||||||
data-is-edgeless={mode === 'edgeless'}
|
data-is-edgeless={mode === 'edgeless'}
|
||||||
|
data-is-page-list={props.currentPage === null}
|
||||||
>
|
>
|
||||||
<div className={styles.headerLeftSide}>
|
<div className={styles.headerLeftSide}>
|
||||||
{!open && <SidebarSwitch />}
|
<div>{!open && <SidebarSwitch />}</div>
|
||||||
{props.leftSlot}
|
<div
|
||||||
|
className={clsx(styles.headerLeftSideItem, {
|
||||||
|
[styles.headerLeftSideOpen]: open,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{props.leftSlot}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{props.children}
|
{props.children}
|
||||||
<div className={styles.headerRightSide}>
|
<div
|
||||||
|
className={clsx(styles.headerRightSide, {
|
||||||
|
[styles.headerRightSideWindow]: isWindowsDesktop,
|
||||||
|
})}
|
||||||
|
>
|
||||||
<PluginHeader />
|
<PluginHeader />
|
||||||
{useMemo(() => {
|
{useMemo(() => {
|
||||||
return Object.entries(HeaderRightItems).map(
|
return Object.entries(HeaderRightItems).map(
|
||||||
@@ -227,6 +232,7 @@ export const Header = forwardRef<
|
|||||||
);
|
);
|
||||||
}, [props])}
|
}, [props])}
|
||||||
</div>
|
</div>
|
||||||
|
{isWindowsDesktop ? <WindowsAppControls /> : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export const BlockSuiteEditorHeader: FC<
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className={styles.pageTitle}>
|
||||||
{isEditable ? (
|
{isEditable ? (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
@@ -88,11 +88,7 @@ export const BlockSuiteEditorHeader: FC<
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span data-testid="title-edit-button" onClick={handleClick}>
|
||||||
data-testid="title-edit-button"
|
|
||||||
onClick={handleClick}
|
|
||||||
style={{ cursor: 'pointer' }}
|
|
||||||
>
|
|
||||||
{title || 'Untitled'}
|
{title || 'Untitled'}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import type { ComplexStyleRule } from '@vanilla-extract/css';
|
import type { ComplexStyleRule } from '@vanilla-extract/css';
|
||||||
import { style } from '@vanilla-extract/css';
|
import { createContainer, style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
export const headerVanillaContainer = createContainer();
|
||||||
|
|
||||||
export const headerContainer = style({
|
export const headerContainer = style({
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
@@ -27,35 +29,45 @@ export const headerContainer = style({
|
|||||||
} as ComplexStyleRule);
|
} as ComplexStyleRule);
|
||||||
|
|
||||||
export const header = style({
|
export const header = style({
|
||||||
|
containerName: headerVanillaContainer,
|
||||||
|
containerType: 'inline-size',
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
height: '52px',
|
minHeight: '52px',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
padding: '0 20px',
|
padding: '8px 20px',
|
||||||
display: 'flex',
|
display: 'grid',
|
||||||
justifyContent: 'space-between',
|
gridTemplateColumns: '1fr auto 1fr',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
background: 'var(--affine-background-primary-color)',
|
background: 'var(--affine-background-primary-color)',
|
||||||
zIndex: 99,
|
zIndex: 99,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
selectors: {
|
selectors: {
|
||||||
'&[data-is-edgeless="true"]': {
|
'&[data-is-page-list="true"], &[data-is-edgeless="true"]': {
|
||||||
borderBottom: `1px solid var(--affine-border-color)`,
|
borderBottom: `1px solid var(--affine-border-color)`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'@container': {
|
||||||
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
|
alignItems: 'start',
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const titleContainer = style({
|
export const titleContainer = style({
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
margin: 'auto',
|
|
||||||
position: 'absolute',
|
|
||||||
inset: 'auto auto auto 50%',
|
|
||||||
transform: 'translate(-50%, 0px)',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
alignContent: 'unset',
|
alignContent: 'unset',
|
||||||
fontSize: 'var(--affine-font-base)',
|
fontSize: 'var(--affine-font-base)',
|
||||||
|
['WebkitAppRegion' as string]: 'no-drag',
|
||||||
|
'@container': {
|
||||||
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
|
alignItems: 'start',
|
||||||
|
paddingTop: '2px',
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const title = style({
|
export const title = style({
|
||||||
@@ -75,9 +87,26 @@ export const title = style({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as ComplexStyleRule);
|
} as ComplexStyleRule);
|
||||||
|
export const pageTitle = style({
|
||||||
|
maxWidth: '600px',
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
transition: 'width .15s',
|
||||||
|
cursor: 'pointer',
|
||||||
|
'@container': {
|
||||||
|
[`${headerVanillaContainer} (max-width: 1920px)`]: {
|
||||||
|
maxWidth: '800px',
|
||||||
|
},
|
||||||
|
[`${headerVanillaContainer} (max-width: 1300px)`]: {
|
||||||
|
maxWidth: '400px',
|
||||||
|
},
|
||||||
|
[`${headerVanillaContainer} (max-width: 768px)`]: {
|
||||||
|
maxWidth: '220px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
export const titleWrapper = style({
|
export const titleWrapper = style({
|
||||||
height: '100%',
|
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
@@ -86,10 +115,28 @@ export const titleWrapper = style({
|
|||||||
export const headerLeftSide = style({
|
export const headerLeftSide = style({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
width: '150px',
|
transition: 'all .15s',
|
||||||
'@media': {
|
'@container': {
|
||||||
'(max-width: 900px)': {
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
width: 'auto',
|
flexDirection: 'column',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
height: '68px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const headerLeftSideItem = style({
|
||||||
|
'@container': {
|
||||||
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: '0',
|
||||||
|
bottom: '8px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const headerLeftSideOpen = style({
|
||||||
|
'@container': {
|
||||||
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
|
marginLeft: '20px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -99,7 +146,21 @@ export const headerRightSide = style({
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: '12px',
|
gap: '12px',
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
|
marginLeft: '20px',
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
|
transition: 'all .15s',
|
||||||
|
'@container': {
|
||||||
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
|
position: 'absolute',
|
||||||
|
height: 'auto',
|
||||||
|
right: '0',
|
||||||
|
bottom: '8px',
|
||||||
|
marginRight: '18px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const headerRightSideWindow = style({
|
||||||
|
marginRight: '140px',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const browserWarning = style({
|
export const browserWarning = style({
|
||||||
@@ -131,22 +192,12 @@ export const closeButton = style({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const switchWrapper = style({
|
export const switchWrapper = style({
|
||||||
position: 'absolute',
|
|
||||||
right: '100%',
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
margin: 'auto',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const searchArrowWrapper = style({
|
export const searchArrowWrapper = style({
|
||||||
position: 'absolute',
|
|
||||||
left: 'calc(100% + 4px)',
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
margin: 'auto',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
@@ -164,16 +215,13 @@ export const allPageListTitleWrapper = style({
|
|||||||
color: 'var(--affine-text-primary-color)',
|
color: 'var(--affine-text-primary-color)',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
'::after': {
|
width: '100%',
|
||||||
content: '""',
|
height: '100%',
|
||||||
display: 'block',
|
'@container': {
|
||||||
width: '100%',
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
height: '1px',
|
alignItems: 'flex-start',
|
||||||
background: 'var(--affine-border-color)',
|
marginTop: '8px',
|
||||||
position: 'absolute',
|
},
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
margin: '0 1px',
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
export const pageListTitleIcon = style({
|
export const pageListTitleIcon = style({
|
||||||
@@ -220,30 +268,36 @@ export const windowAppControlsWrapper = style({
|
|||||||
gap: '2px',
|
gap: '2px',
|
||||||
transform: 'translateX(8px)',
|
transform: 'translateX(8px)',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
|
position: 'absolute',
|
||||||
|
right: '14px',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const windowAppControl = style({
|
export const windowAppControl = style({
|
||||||
WebkitAppRegion: 'no-drag',
|
WebkitAppRegion: 'no-drag',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
display: 'inline-flex',
|
display: 'inline-flex',
|
||||||
width: '42px',
|
width: '51px',
|
||||||
height: 'calc(100% - 10px)',
|
|
||||||
paddingTop: '10px',
|
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
borderRadius: '0',
|
borderRadius: '0',
|
||||||
selectors: {
|
selectors: {
|
||||||
'&[data-type="close"]': {
|
'&[data-type="close"]': {
|
||||||
width: '56px',
|
width: '56px',
|
||||||
paddingRight: '14px',
|
paddingRight: '5px',
|
||||||
marginRight: '-14px',
|
marginRight: '-12px',
|
||||||
},
|
},
|
||||||
'&[data-type="close"]:hover': {
|
'&[data-type="close"]:hover': {
|
||||||
background: 'var(--affine-error-color)',
|
background: 'var(--affine-windows-close-button)',
|
||||||
color: '#FFFFFF',
|
color: 'var(--affine-pure-white)',
|
||||||
},
|
},
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
background: 'var(--affine-background-tertiary-color)',
|
background: 'var(--affine-hover-color)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'@container': {
|
||||||
|
[`${headerVanillaContainer} (max-width: 900px)`]: {
|
||||||
|
height: '50px',
|
||||||
|
paddingTop: '0',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as ComplexStyleRule);
|
} as ComplexStyleRule);
|
||||||
|
|||||||
@@ -17,23 +17,18 @@ export const navWrapperStyle = style({
|
|||||||
paddingBottom: '8px',
|
paddingBottom: '8px',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
'@media': {
|
'@media': {
|
||||||
[`(max-width: ${floatingMaxWidth}px)`]: {
|
|
||||||
position: 'absolute',
|
|
||||||
width: `calc(${navWidthVar})`,
|
|
||||||
zIndex: 4,
|
|
||||||
backgroundColor: 'var(--affine-background-primary-color)',
|
|
||||||
selectors: {
|
|
||||||
'&[data-open="false"]': {
|
|
||||||
marginLeft: `calc((10vw + ${navWidthVar}) * -1)`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
print: {
|
print: {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
zIndex: -1,
|
zIndex: -1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
selectors: {
|
selectors: {
|
||||||
|
'&[data-is-floating="true"]': {
|
||||||
|
position: 'absolute',
|
||||||
|
width: `calc(${navWidthVar})`,
|
||||||
|
zIndex: 4,
|
||||||
|
backgroundColor: 'var(--affine-background-primary-color)',
|
||||||
|
},
|
||||||
'&[data-open="false"]': {
|
'&[data-open="false"]': {
|
||||||
marginLeft: `calc(${navWidthVar} * -1)`,
|
marginLeft: `calc(${navWidthVar} * -1)`,
|
||||||
},
|
},
|
||||||
@@ -93,17 +88,15 @@ export const sidebarFloatMaskStyle = style({
|
|||||||
right: '100%',
|
right: '100%',
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
background: 'var(--affine-background-modal-color)',
|
background: 'var(--affine-background-modal-color)',
|
||||||
'@media': {
|
selectors: {
|
||||||
[`(max-width: ${floatingMaxWidth}px)`]: {
|
'&[data-open="true"][data-is-floating="true"]': {
|
||||||
selectors: {
|
opacity: 1,
|
||||||
'&[data-open="true"]': {
|
pointerEvents: 'auto',
|
||||||
opacity: 1,
|
right: '0',
|
||||||
pointerEvents: 'auto',
|
zIndex: 3,
|
||||||
right: '0',
|
|
||||||
zIndex: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
'@media': {
|
||||||
print: {
|
print: {
|
||||||
display: 'none',
|
display: 'none',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -59,18 +59,22 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function onResize() {
|
function onResize() {
|
||||||
const { matches } = window.matchMedia(
|
const isFloatingMaxWidth = window.matchMedia(
|
||||||
`(max-width: ${floatingMaxWidth}px)`
|
`(max-width: ${floatingMaxWidth}px)`
|
||||||
);
|
).matches;
|
||||||
|
const isOverflowWidth = window.matchMedia(
|
||||||
|
`(max-width: ${appSidebarWidth / 0.4}px)`
|
||||||
|
).matches;
|
||||||
|
const isFloating = isFloatingMaxWidth || isOverflowWidth;
|
||||||
if (
|
if (
|
||||||
open === undefined &&
|
open === undefined &&
|
||||||
localStorage.getItem(APP_SIDEBAR_OPEN) === null
|
localStorage.getItem(APP_SIDEBAR_OPEN) === null
|
||||||
) {
|
) {
|
||||||
// give the initial value,
|
// give the initial value,
|
||||||
// so that the sidebar can be closed on mobile by default
|
// so that the sidebar can be closed on mobile by default
|
||||||
setOpen(!matches);
|
setOpen(!isFloating);
|
||||||
}
|
}
|
||||||
setAppSidebarFloating(matches && !!open);
|
setAppSidebarFloating(isFloating && !!open);
|
||||||
}
|
}
|
||||||
|
|
||||||
onResize();
|
onResize();
|
||||||
@@ -78,7 +82,7 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
|||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('resize', onResize);
|
window.removeEventListener('resize', onResize);
|
||||||
};
|
};
|
||||||
}, [open, setAppSidebarFloating, setOpen]);
|
}, [appSidebarWidth, open, setAppSidebarFloating, setOpen]);
|
||||||
|
|
||||||
// disable animation to avoid UI flash
|
// disable animation to avoid UI flash
|
||||||
const enableAnimation = useEnableAnimation();
|
const enableAnimation = useEnableAnimation();
|
||||||
@@ -99,6 +103,7 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
|||||||
})}
|
})}
|
||||||
data-open={open}
|
data-open={open}
|
||||||
data-is-macos-electron={isMacosDesktop}
|
data-is-macos-electron={isMacosDesktop}
|
||||||
|
data-is-floating={appSidebarFloating}
|
||||||
data-enable-animation={enableAnimation && !isResizing}
|
data-enable-animation={enableAnimation && !isResizing}
|
||||||
>
|
>
|
||||||
<nav className={navStyle} ref={navRef} data-testid="app-sidebar">
|
<nav className={navStyle} ref={navRef} data-testid="app-sidebar">
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const viewButton = style({
|
|||||||
fontSize: 'var(--affine-font-xs)',
|
fontSize: 'var(--affine-font-xs)',
|
||||||
background: 'var(--affine-white)',
|
background: 'var(--affine-white)',
|
||||||
['WebkitAppRegion' as string]: 'no-drag',
|
['WebkitAppRegion' as string]: 'no-drag',
|
||||||
maxWidth: '200px',
|
maxWidth: '150px',
|
||||||
color: 'var(--affine-text-secondary-color)',
|
color: 'var(--affine-text-secondary-color)',
|
||||||
border: '1px solid var(--affine-border-color)',
|
border: '1px solid var(--affine-border-color)',
|
||||||
transition: 'margin-left 0.2s ease-in-out',
|
transition: 'margin-left 0.2s ease-in-out',
|
||||||
@@ -30,15 +30,6 @@ export const viewButton = style({
|
|||||||
background: 'var(--affine-hover-color)',
|
background: 'var(--affine-hover-color)',
|
||||||
},
|
},
|
||||||
marginRight: '20px',
|
marginRight: '20px',
|
||||||
'@media': {
|
|
||||||
'(max-width: 1200px)': {
|
|
||||||
maxWidth: '100px',
|
|
||||||
},
|
|
||||||
'(max-width: 900px)': {
|
|
||||||
maxWidth: '150px',
|
|
||||||
marginRight: '10px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
globalStyle(`${viewButton} > span`, {
|
globalStyle(`${viewButton} > span`, {
|
||||||
display: 'block',
|
display: 'block',
|
||||||
@@ -74,6 +65,8 @@ export const deleteOption = style({
|
|||||||
export const filterButton = style({
|
export const filterButton = style({
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
marginRight: '20px',
|
||||||
padding: '4px 8px',
|
padding: '4px 8px',
|
||||||
fontSize: 'var(--affine-font-xs)',
|
fontSize: 'var(--affine-font-xs)',
|
||||||
background: 'var(--affine-white)',
|
background: 'var(--affine-white)',
|
||||||
|
|||||||
Reference in New Issue
Block a user