fix: some minor ui issues (#1783)

This commit is contained in:
Peng Xiao 2023-04-03 13:24:53 +08:00 committed by GitHub
parent 95879cc1d0
commit 487ef35563
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 90 additions and 79 deletions

View File

@ -1,2 +1,2 @@
pnpm-lock.yaml
apps/electron/layers/preload/preload.d.ts

View File

@ -1,16 +1,12 @@
interface Window {
/**
* After analyzing the `exposeInMainWorld` calls,
* `packages/preload/exposedInMainWorld.d.ts` file will be generated.
* It contains all interfaces.
* `packages/preload/exposedInMainWorld.d.ts` file is required for TS is `renderer`
*
* @see https://github.com/cawa-93/dts-for-context-bridge
*/
readonly apis: {
workspaceSync: (id: string) => Promise<any>;
onThemeChange: (theme: string) => Promise<any>;
onSidebarVisibilityChange: (visible: boolean) => Promise<any>;
};
readonly appInfo: { electron: boolean; isMacOS: boolean };
/**
* After analyzing the `exposeInMainWorld` calls,
* `packages/preload/exposedInMainWorld.d.ts` file will be generated.
* It contains all interfaces.
* `packages/preload/exposedInMainWorld.d.ts` file is required for TS is `renderer`
*
* @see https://github.com/cawa-93/dts-for-context-bridge
*/
readonly apis: { workspaceSync: (id: string) => Promise<any>; onThemeChange: (theme: string) => Promise<any>; onSidebarVisibilityChange: (visible: boolean) => Promise<any>; };
readonly appInfo: { electron: boolean; isMacOS: boolean; };
}

View File

@ -8,11 +8,11 @@ import {
SettingsIcon,
} from '@blocksuite/icons';
import type { Page, PageMeta } from '@blocksuite/store';
import { useMediaQuery, useTheme } from '@mui/material';
import type React from 'react';
import { useCallback, useEffect } from 'react';
import {
useSidebarFloating,
useSidebarResizing,
useSidebarStatus,
useSidebarWidth,
@ -80,16 +80,11 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
const page = await createPage();
openPage(page.id);
}, [createPage, openPage]);
const theme = useTheme();
const floatingSlider = useMediaQuery(theme.breakpoints.down('md'));
const floatingSlider = useSidebarFloating();
const [sliderWidth, setSliderWidth] = useSidebarWidth();
const [isResizing, setIsResizing] = useSidebarResizing();
const show = isPublicWorkspace ? false : sidebarOpen;
const actualWidth = show
? floatingSlider
? 'calc(10vw + 400px)'
: sliderWidth
: 0;
const actualWidth = floatingSlider ? 'calc(10vw + 400px)' : sliderWidth;
const onResizeStart = useCallback(() => {
let resized = false;
function onMouseMove(e: MouseEvent) {
@ -117,13 +112,13 @@ export const WorkSpaceSliderBar: React.FC<WorkSpaceSliderBarProps> = ({
}, [sidebarOpen]);
return (
<>
<StyledSliderBarWrapper data-testid="sliderBar-root">
<StyledSliderBar
resizing={isResizing}
floating={floatingSlider}
style={{ width: actualWidth }}
show={show}
>
<StyledSliderBarWrapper
floating={floatingSlider}
show={show}
style={{ width: actualWidth }}
data-testid="sliderBar-root"
>
<StyledSliderBar>
<StyledSidebarSwitchWrapper>
<SidebarSwitch
visible={sidebarOpen}

View File

@ -1,41 +1,39 @@
import { displayFlex, styled } from '@affine/component';
import { getEnvironment } from '@affine/env';
import Link from 'next/link';
export const StyledSliderBarWrapper = styled('div')(() => {
const macosElectron = environment.isDesktop && environment.isMacOs;
export const StyledSliderBarWrapper = styled('div')<{
show: boolean;
floating: boolean;
}>(({ theme, show, floating }) => {
return {
height: '100%',
width: 'auto',
position: 'relative',
position: 'absolute',
'button, a': {
userSelect: 'none',
},
zIndex: theme.zIndex.modal,
transition: 'transform .25s',
transform: show ? 'translateX(0)' : 'translateX(-100%)',
maxWidth: floating ? undefined : 'calc(100vw - 698px)',
background:
!floating && macosElectron ? 'transparent' : theme.colors.hubBackground,
borderRight: '1px solid',
borderColor: theme.colors.borderColor,
};
});
export const StyledSliderBar = styled('div')<{
resizing: boolean;
show: boolean;
floating: boolean;
}>(({ theme, show, floating, resizing }) => {
const env = getEnvironment();
const macosElectron = env.isDesktop && env.isMacOs;
export const StyledSliderBar = styled('div')(({ theme }) => {
return {
whiteSpace: 'nowrap',
width: '100%',
height: '100%',
background:
!floating && macosElectron ? 'transparent' : theme.colors.hubBackground,
zIndex: theme.zIndex.modal,
transition: !resizing ? 'width .15s, padding .15s' : '',
padding: show ? '0 4px' : '0',
padding: '0 4px',
flexShrink: 0,
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
position: floating ? 'absolute' : 'relative',
maxWidth: floating ? undefined : 'calc(100vw - 698px)',
borderRight: '1px solid',
borderColor: theme.colors.borderColor,
};
});
export const StyledSidebarSwitchWrapper = styled('div')(() => {
@ -43,7 +41,7 @@ export const StyledSidebarSwitchWrapper = styled('div')(() => {
height: '52px',
flexShrink: 0,
padding: '0 16px',
...displayFlex('flex-end', 'center'),
...displayFlex(macosElectron ? 'flex-end' : 'flex-start', 'center'),
};
});
export const StyledSliderBarInnerWrapper = styled('div')(() => {
@ -92,11 +90,10 @@ export const StyledSliderModalBackground = styled('div')<{ active: boolean }>(
transition: 'opacity .15s',
pointerEvents: active ? 'auto' : 'none',
opacity: active ? 1 : 0,
display: active ? 'block' : 'none',
position: 'fixed',
top: 0,
left: 0,
right: 0,
right: active ? 0 : '100%',
bottom: 0,
zIndex: theme.zIndex.modal - 1,
background: theme.colors.modalBackground,
@ -104,7 +101,7 @@ export const StyledSliderModalBackground = styled('div')<{ active: boolean }>(
}
);
export const StyledSliderResizer = styled('div')<{ isResizing: boolean }>(
({ theme }) => {
() => {
return {
position: 'absolute',
top: 0,
@ -113,7 +110,7 @@ export const StyledSliderResizer = styled('div')<{ isResizing: boolean }>(
width: '12px',
transform: 'translateX(50%)',
cursor: 'col-resize',
zIndex: theme.zIndex.modal + 1,
zIndex: 1,
userSelect: 'none',
':hover > *': {
background: 'rgba(0, 0, 0, 0.1)',

View File

@ -1,4 +1,5 @@
import { atomWithSyncStorage } from '@affine/jotai';
import { useMediaQuery, useTheme } from '@mui/material';
import { atom, useAtom } from 'jotai';
const sideBarOpenAtom = atomWithSyncStorage('sidebarOpen', true);
@ -13,6 +14,11 @@ export function useSidebarWidth() {
return useAtom(sideBarWidthAtom);
}
export function useSidebarFloating() {
const theme = useTheme();
return useMediaQuery(theme.breakpoints.down('md'));
}
export function useSidebarResizing() {
return useAtom(sidebarResizingAtom);
}

View File

@ -26,7 +26,12 @@ import { HelpIsland } from '../components/pure/help-island';
import { PageLoading } from '../components/pure/loading';
import WorkSpaceSliderBar from '../components/pure/workspace-slider-bar';
import { useAffineRefreshAuthToken } from '../hooks/affine/use-affine-refresh-auth-token';
import { useSidebarResizing } from '../hooks/affine/use-sidebar-status';
import {
useSidebarFloating,
useSidebarResizing,
useSidebarStatus,
useSidebarWidth,
} from '../hooks/affine/use-sidebar-status';
import { useCurrentPageId } from '../hooks/current/use-current-page-id';
import { useCurrentWorkspace } from '../hooks/current/use-current-workspace';
import { useBlockSuiteWorkspaceHelper } from '../hooks/use-blocksuite-workspace-helper';
@ -246,14 +251,18 @@ export const WorkspaceLayoutInner: React.FC<React.PropsWithChildren> = ({
setOpenWorkspacesModal(true);
}, [setOpenWorkspacesModal]);
const [openQuickSearchModal, setOpenQuickSearchModalAtom] = useAtom(
openQuickSearchModalAtom
);
const [, setOpenQuickSearchModalAtom] = useAtom(openQuickSearchModalAtom);
const handleOpenQuickSearchModal = useCallback(() => {
setOpenQuickSearchModalAtom(true);
}, [setOpenQuickSearchModalAtom]);
const [resizingSidebar] = useSidebarResizing();
const lock = useAtomValue(workspaceLockAtom);
const [sidebarOpen] = useSidebarStatus();
const sidebarFloating = useSidebarFloating();
const [sidebarWidth] = useSidebarWidth();
const paddingLeft =
sidebarFloating || !sidebarOpen ? '0' : `${sidebarWidth}px`;
const [resizing] = useSidebarResizing();
if (lock) {
return <PageLoading />;
}
@ -275,7 +284,10 @@ export const WorkspaceLayoutInner: React.FC<React.PropsWithChildren> = ({
currentPath={router.asPath.split('?')[0]}
paths={isPublicWorkspace ? publicPathGenerator : pathGenerator}
/>
<MainContainerWrapper>
<MainContainerWrapper
resizing={resizing}
style={{ paddingLeft: paddingLeft }}
>
<MainContainer className="main-container">
<AffineWorkspaceEffect />
{children}

View File

@ -4,6 +4,8 @@ export const StyledPage = styled('div')<{ resizing?: boolean }>(
({ theme, resizing }) => {
return {
cursor: resizing ? 'col-resize' : 'default',
width: '100%',
position: 'relative',
height: '100vh',
transition: 'background-color .5s',
display: 'flex',
@ -24,21 +26,24 @@ export const StyledWrapper = styled('div')(() => {
};
});
export const MainContainerWrapper = styled('div')(({ theme }) => {
return {
display: 'flex',
flexGrow: 1,
position: 'relative',
maxWidth: '100vw',
overflow: 'auto',
backgroundColor: theme.colors.pageBackground,
};
});
export const MainContainerWrapper = styled('div')<{ resizing: boolean }>(
({ theme, resizing }) => {
return {
display: 'flex',
flexGrow: 1,
position: 'relative',
maxWidth: '100vw',
overflow: 'auto',
transition: resizing ? '' : 'padding-left .25s',
};
}
);
export const MainContainer = styled('div')(({ theme }) => {
return {
position: 'relative',
flexGrow: 1,
backgroundColor: theme.colors.pageBackground,
[theme.breakpoints.up('md')]: {
minWidth: '686px',
},

View File

@ -9,8 +9,8 @@ test.describe('Layout ui', () => {
await openHomePage(page);
await waitMarkdownImported(page);
await page.getByTestId('sliderBar-arrowButton-collapse').click();
const sliderBarArea = page.getByTestId('sliderBar-inner');
await expect(sliderBarArea).not.toBeVisible();
const sliderBarArea = page.getByTestId('sliderBar-root');
await expect(sliderBarArea).not.toBeInViewport();
});
test('Expand Sidebar', async ({ page }) => {
@ -18,10 +18,10 @@ test.describe('Layout ui', () => {
await waitMarkdownImported(page);
await page.getByTestId('sliderBar-arrowButton-collapse').click();
const sliderBarArea = page.getByTestId('sliderBar-inner');
await expect(sliderBarArea).not.toBeVisible();
await expect(sliderBarArea).not.toBeInViewport();
await page.getByTestId('sliderBar-arrowButton-expand').click();
await expect(sliderBarArea).toBeVisible();
await expect(sliderBarArea).toBeInViewport();
});
test('Click resizer can close sidebar', async ({ page }) => {
@ -31,7 +31,7 @@ test.describe('Layout ui', () => {
await expect(sliderBarArea).toBeVisible();
await page.getByTestId('sliderBar-resizer').click();
await expect(sliderBarArea).not.toBeVisible();
await expect(sliderBarArea).not.toBeInViewport();
});
test('Drag resizer can resize sidebar', async ({ page }) => {
@ -58,7 +58,7 @@ test.describe('Layout ui', () => {
const sliderBarModalBackground = page.getByTestId(
'sliderBar-modalBackground'
);
await expect(sliderBarArea).toBeVisible();
await expect(sliderBarArea).toBeInViewport();
await expect(sliderBarModalBackground).not.toBeVisible();
await page.setViewportSize({
@ -72,6 +72,6 @@ test.describe('Layout ui', () => {
force: true,
position: { x: 600, y: 150 },
});
await expect(sliderBarArea).not.toBeVisible();
await expect(sliderBarArea).not.toBeInViewport();
});
});

View File

@ -181,7 +181,7 @@ test.describe('Novice guidance for quick search', () => {
await expect(quickSearchTips).not.toBeVisible();
await page.getByTestId('sliderBar-arrowButton-collapse').click();
const sliderBarArea = page.getByTestId('sliderBar-inner');
await expect(sliderBarArea).not.toBeVisible();
await expect(sliderBarArea).not.toBeInViewport();
await expect(quickSearchTips).toBeVisible();
await page.locator('[data-testid=quick-search-got-it]').click();
await expect(quickSearchTips).not.toBeVisible();

View File

@ -10,6 +10,6 @@ test.describe('subpage', () => {
await waitMarkdownImported(page);
await page.getByTestId('sliderBar-arrowButton-collapse').click();
const sliderBarArea = page.getByTestId('sliderBar-inner');
await expect(sliderBarArea).not.toBeVisible();
await expect(sliderBarArea).not.toBeInViewport();
});
});