fix: sidebar regression (#2195)

This commit is contained in:
Himself65
2023-04-28 15:02:47 -05:00
committed by GitHub
parent 73a7c01580
commit 31cccafb40
8 changed files with 50 additions and 30 deletions

View File

@@ -13,7 +13,7 @@ export const navStyle = style({
height: '100%',
display: 'flex',
flexDirection: 'column',
transition: 'margin-left .3s',
transition: 'margin-left .3s, width .3s',
zIndex: parseInt(baseTheme.zIndexModal),
borderRight: '1px solid var(--affine-border-color)',
'@media': {
@@ -61,6 +61,7 @@ export const navHeaderStyle = style({
},
selectors: {
'&[data-is-macos-electron="true"]': {
WebkitAppRegion: 'drag',
justifyContent: 'flex-end',
},
},

View File

@@ -1,6 +1,9 @@
import { atomWithStorage } from 'jotai/utils';
export const appSidebarOpenAtom = atomWithStorage('app-sidebar-open', true);
export const appSidebarOpenAtom = atomWithStorage(
'app-sidebar-open',
undefined as boolean | undefined
);
export const appSidebarWidthAtom = atomWithStorage(
'app-sidebar-width',
256 /* px */

View File

@@ -2,7 +2,7 @@ import { IconButton } from '@affine/component';
import { SidebarIcon } from '@blocksuite/icons';
import type { Meta, StoryFn } from '@storybook/react';
import { useAtom } from 'jotai';
import { useRef } from 'react';
import { useState } from 'react';
import { AppSidebar, appSidebarOpenAtom, ResizeIndicator } from '.';
import { navHeaderStyle, sidebarButtonStyle } from './index.css';
@@ -16,7 +16,7 @@ const Footer = () => <div>Add Page</div>;
export const Default: StoryFn = () => {
const [open, setOpen] = useAtom(appSidebarOpenAtom);
const ref = useRef<HTMLElement>(null);
const [ref, setRef] = useState<HTMLElement | null>(null);
return (
<>
<main
@@ -29,7 +29,7 @@ export const Default: StoryFn = () => {
flexDirection: 'row',
}}
>
<AppSidebar footer={<Footer />} ref={ref}>
<AppSidebar footer={<Footer />} ref={setRef}>
Test
</AppSidebar>
<ResizeIndicator targetElement={ref} />

View File

@@ -8,10 +8,11 @@ import { assignInlineVars } from '@vanilla-extract/dynamic';
import { useAtom, useAtomValue } from 'jotai';
import type { PropsWithChildren, ReactElement } from 'react';
import type { ReactNode } from 'react';
import { forwardRef, useCallback, useImperativeHandle, useRef } from 'react';
import { forwardRef, useCallback, useEffect } from 'react';
import { IconButton } from '../../ui/button/IconButton';
import {
floatingMaxWidth,
navBodyStyle,
navFooterStyle,
navHeaderStyle,
@@ -30,24 +31,38 @@ export type AppSidebarProps = PropsWithChildren<{
export const AppSidebar = forwardRef<HTMLElement, AppSidebarProps>(
function AppSidebar(props, forwardedRef): ReactElement {
const ref = useRef<HTMLElement>(null);
const [open, setOpen] = useAtom(appSidebarOpenAtom);
const appSidebarWidth = useAtomValue(appSidebarWidthAtom);
const initialRender = open === undefined;
const handleSidebarOpen = useCallback(() => {
setOpen(open => !open);
}, [setOpen]);
useImperativeHandle(forwardedRef, () => ref.current as HTMLElement);
useEffect(() => {
if (open === undefined) {
// give the initial value,
// so that the sidebar can be closed on mobile by default
const { matches } = window.matchMedia(
`(min-width: ${floatingMaxWidth}px)`
);
setOpen(matches);
}
}, [open, setOpen]);
const environment = getEnvironment();
const isMacosDesktop = environment.isDesktop && environment.isMacOs;
if (initialRender) {
// avoid the UI flash
return <div />;
}
return (
<>
<nav
className={navStyle}
ref={ref}
ref={forwardedRef}
style={assignInlineVars({
[navWidthVar]: `${appSidebarWidth}px`,
})}
@@ -96,9 +111,7 @@ export const AppSidebar = forwardRef<HTMLElement, AppSidebarProps>(
data-testid="app-sidebar-float-mask"
data-open={open}
className={sidebarFloatMaskStyle}
onClick={useCallback(() => {
setOpen(false);
}, [setOpen])}
onClick={() => setOpen(false)}
/>
</>
);

View File

@@ -4,13 +4,14 @@ import { navWidthVar } from '../index.css';
export const spacerStyle = style({
position: 'absolute',
width: '1px',
left: navWidthVar,
top: 0,
bottom: 0,
width: '7px',
height: '100%',
borderLeft: '1px solid var(--affine-border-color)',
zIndex: 'calc(var(--affine-z-index-modal) - 1)',
backgroundColor: 'var(--affine-border-color)',
backgroundColor: 'transparent',
opacity: 0,
cursor: 'col-resize',
'@media': {

View File

@@ -1,7 +1,7 @@
import type { Instance } from '@popperjs/core';
import { createPopper } from '@popperjs/core';
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import type { ReactElement, RefObject } from 'react';
import type { ReactElement } from 'react';
import {
useCallback,
useDeferredValue,
@@ -14,7 +14,7 @@ import { appSidebarOpenAtom, appSidebarWidthAtom } from '../index.jotai';
import { spacerStyle } from './index.css';
export type ResizeIndicatorProps = {
targetElement: RefObject<HTMLElement>;
targetElement: HTMLElement | null;
};
export const ResizeIndicator = (props: ResizeIndicatorProps): ReactElement => {
@@ -25,14 +25,15 @@ export const ResizeIndicator = (props: ResizeIndicatorProps): ReactElement => {
const [isResizing, setIsResizing] = useState(false);
useEffect(() => {
if (ref.current) {
if (props.targetElement.current) {
popperRef.current = createPopper(
props.targetElement.current,
ref.current,
{
placement: 'right',
}
);
if (props.targetElement) {
const popper = createPopper(props.targetElement, ref.current, {
placement: 'right',
});
popperRef.current = popper;
return () => {
popper.destroy();
popperRef.current = null;
};
}
}
}, [props.targetElement]);