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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 50 additions and 30 deletions

View File

@ -17,7 +17,7 @@ import {
import type { Page } from '@blocksuite/store';
import { useAtomValue } from 'jotai';
import type { ReactElement, UIEvent } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import type { AllWorkspace } from '../../shared';
import ChangeLog from '../pure/workspace-slider-bar/changeLog';
@ -75,15 +75,15 @@ export const RootAppSidebar = ({
}, [createPage, openPage]);
const sidebarOpen = useAtomValue(appSidebarOpenAtom);
useEffect(() => {
if (environment.isDesktop) {
if (environment.isDesktop && typeof sidebarOpen === 'boolean') {
window.apis?.onSidebarVisibilityChange(sidebarOpen);
}
}, [sidebarOpen]);
const ref = useRef<HTMLElement>(null);
const [ref, setRef] = useState<HTMLElement | null>(null);
return (
<>
<AppSidebar
ref={ref}
ref={setRef}
footer={
<StyledNewPageButton
data-testid="new-page-button"

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]);

View File

@ -179,8 +179,9 @@ test('When opening the website for the first time, the first folding sidebar wil
const quickSearchTips = page.locator('[data-testid=quick-search-tips]');
await expect(quickSearchTips).not.toBeVisible();
await page.getByTestId('app-sidebar-arrow-button-collapse').click();
await page.waitForTimeout(200);
// fixme: when first close, the tooltip will not show
await page.getByTestId('sliderBar-arrowButton-expand').click();
await page.getByTestId('app-sidebar-arrow-button-collapse').click();
const sliderBarArea = page.getByTestId('sliderBar-inner');
await expect(sliderBarArea).not.toBeInViewport();
await expect(quickSearchTips).toBeVisible();
@ -195,8 +196,8 @@ test('After appearing once, it will not appear a second time', async ({
const quickSearchTips = page.locator('[data-testid=quick-search-tips]');
await expect(quickSearchTips).not.toBeVisible();
await page.getByTestId('app-sidebar-arrow-button-collapse').click();
await page.waitForTimeout(200);
await page.getByTestId('sliderBar-arrowButton-expand').click();
await page.getByTestId('app-sidebar-arrow-button-collapse').click();
const sliderBarArea = page.getByTestId('sliderBar');
await expect(sliderBarArea).not.toBeVisible();
await expect(quickSearchTips).toBeVisible();