mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-25 15:41:31 +03:00
fix: unify sidebar switch (#2616)
This commit is contained in:
parent
248cd9a8ab
commit
f5aee7c360
@ -1,26 +0,0 @@
|
||||
export const SidebarSwitchIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M11 5.00009V19.0001M6 7.62509H8M6 10.2501H8M6 12.8751H8M6.2 19.0001H17.8C18.9201 19.0001 19.4802 19.0001 19.908 18.8094C20.2843 18.6416 20.5903 18.3739 20.782 18.0446C21 17.6702 21 17.1802 21 16.2001V7.80009C21 6.82 21 6.32995 20.782 5.95561C20.5903 5.62632 20.2843 5.35861 19.908 5.19083C19.4802 5.00009 18.9201 5.00009 17.8 5.00009H6.2C5.0799 5.00009 4.51984 5.00009 4.09202 5.19083C3.71569 5.35861 3.40973 5.62632 3.21799 5.95561C3 6.32995 3 6.82 3 7.80009V16.2001C3 17.1802 3 17.6702 3.21799 18.0446C3.40973 18.3739 3.71569 18.6416 4.09202 18.8094C4.51984 19.0001 5.07989 19.0001 6.2 19.0001Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M11 5.00009V19.0001M6 7.62509H8M6 10.2501H8M6 12.8751H8M6.2 19.0001H17.8C18.9201 19.0001 19.4802 19.0001 19.908 18.8094C20.2843 18.6416 20.5903 18.3739 20.782 18.0446C21 17.6702 21 17.1802 21 16.2001V7.80009C21 6.82 21 6.32995 20.782 5.95561C20.5903 5.62632 20.2843 5.35861 19.908 5.19083C19.4802 5.00009 18.9201 5.00009 17.8 5.00009H6.2C5.0799 5.00009 4.51984 5.00009 4.09202 5.19083C3.71569 5.35861 3.40973 5.62632 3.21799 5.95561C3 6.32995 3 6.82 3 7.80009V16.2001C3 17.1802 3 17.6702 3.21799 18.0446C3.40973 18.3739 3.71569 18.6416 4.09202 18.8094C4.51984 19.0001 5.07989 19.0001 6.2 19.0001Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
@ -1,65 +0,0 @@
|
||||
import { Tooltip } from '@affine/component';
|
||||
import { appSidebarOpenAtom } from '@affine/component/app-sidebar';
|
||||
import { getEnvironment } from '@affine/env';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { SidebarSwitchIcon } from './icons';
|
||||
import { StyledSidebarSwitch } from './style';
|
||||
type SidebarSwitchProps = {
|
||||
visible?: boolean;
|
||||
tooltipContent?: string;
|
||||
};
|
||||
|
||||
// fixme: the following code is not correct, SSR will fail because hydrate will not match the client side render
|
||||
// in `StyledSidebarSwitch` a component
|
||||
export const SidebarSwitch = ({
|
||||
visible = true,
|
||||
tooltipContent,
|
||||
...props
|
||||
}: SidebarSwitchProps) => {
|
||||
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
||||
const [tooltipVisible, setTooltipVisible] = useState(false);
|
||||
const t = useAFFiNEI18N();
|
||||
const checkIsMac = () => {
|
||||
const env = getEnvironment();
|
||||
return env.isBrowser && env.isMacOs;
|
||||
};
|
||||
const [isMac, setIsMac] = useState(false);
|
||||
const collapseKeyboardShortcuts = isMac ? ' ⌘+/' : ' Ctrl+/';
|
||||
|
||||
useEffect(() => {
|
||||
setIsMac(checkIsMac());
|
||||
}, []);
|
||||
|
||||
tooltipContent =
|
||||
tooltipContent || (open ? t['Collapse sidebar']() : t['Expand sidebar']());
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={tooltipContent + ' ' + collapseKeyboardShortcuts}
|
||||
placement="right"
|
||||
zIndex={1000}
|
||||
visible={tooltipVisible}
|
||||
>
|
||||
<StyledSidebarSwitch
|
||||
{...props}
|
||||
visible={visible}
|
||||
disabled={!visible}
|
||||
onClick={useCallback(() => {
|
||||
setOpen(open => !open);
|
||||
setTooltipVisible(false);
|
||||
}, [setOpen])}
|
||||
onMouseEnter={useCallback(() => {
|
||||
setTooltipVisible(true);
|
||||
}, [])}
|
||||
onMouseLeave={useCallback(() => {
|
||||
setTooltipVisible(false);
|
||||
}, [])}
|
||||
>
|
||||
<SidebarSwitchIcon />
|
||||
</StyledSidebarSwitch>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
import { IconButton, styled } from '@affine/component';
|
||||
|
||||
export const StyledSidebarSwitch = styled(IconButton, {
|
||||
shouldForwardProp(propName: PropertyKey) {
|
||||
return propName !== 'visible';
|
||||
},
|
||||
})<{ visible: boolean }>(({ visible }) => {
|
||||
return {
|
||||
opacity: visible ? 1 : 0,
|
||||
WebkitAppRegion: visible ? 'no-drag' : 'drag',
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
};
|
||||
});
|
@ -3,7 +3,7 @@ import {
|
||||
appSidebarFloatingAtom,
|
||||
appSidebarOpenAtom,
|
||||
} from '@affine/component/app-sidebar';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { SidebarSwitch } from '@affine/component/app-sidebar/sidebar-header';
|
||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||
import { CloseIcon, MinusIcon, RoundedRectangleIcon } from '@blocksuite/icons';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
@ -11,15 +11,7 @@ import { affinePluginsAtom } from '@toeverything/plugin-infra/manager';
|
||||
import type { PluginUIAdapter } from '@toeverything/plugin-infra/type';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import type { FC, HTMLAttributes, PropsWithChildren, ReactNode } from 'react';
|
||||
import {
|
||||
forwardRef,
|
||||
lazy,
|
||||
memo,
|
||||
Suspense,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { forwardRef, memo, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { guideDownloadClientTipAtom } from '../../../atoms/guide';
|
||||
import { contentLayoutAtom } from '../../../atoms/layout';
|
||||
@ -35,12 +27,6 @@ import UserAvatar from './header-right-items/user-avatar';
|
||||
import * as styles from './styles.css';
|
||||
import { OSWarningMessage, shouldShowWarning } from './utils';
|
||||
|
||||
const SidebarSwitch = lazy(() =>
|
||||
import('../../affine/sidebar-switch').then(module => ({
|
||||
default: module.SidebarSwitch,
|
||||
}))
|
||||
);
|
||||
|
||||
export type BaseHeaderProps<
|
||||
Workspace extends AffineOfficialWorkspace = AffineOfficialWorkspace
|
||||
> = {
|
||||
@ -205,8 +191,6 @@ export const Header = forwardRef<
|
||||
setShowGuideDownloadClientTip(shouldShowGuideDownloadClientTip);
|
||||
}, [shouldShowGuideDownloadClientTip]);
|
||||
const open = useAtomValue(appSidebarOpenAtom);
|
||||
const t = useAFFiNEI18N();
|
||||
|
||||
const appSidebarFloating = useAtomValue(appSidebarFloatingAtom);
|
||||
|
||||
const mode = useCurrentMode();
|
||||
@ -237,16 +221,10 @@ export const Header = forwardRef<
|
||||
data-testid="editor-header-items"
|
||||
data-is-edgeless={mode === 'edgeless'}
|
||||
>
|
||||
<Suspense>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<SidebarSwitch
|
||||
visible={!open}
|
||||
tooltipContent={t['Expand sidebar']()}
|
||||
data-testid="sliderBar-arrowButton-expand"
|
||||
/>
|
||||
{props.leftSlot}
|
||||
</div>
|
||||
</Suspense>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
{!open && <SidebarSwitch />}
|
||||
{props.leftSlot}
|
||||
</div>
|
||||
|
||||
{props.children}
|
||||
<div className={styles.headerRightSide}>
|
||||
|
@ -1,15 +1,12 @@
|
||||
import { getEnvironment } from '@affine/env/config';
|
||||
import {
|
||||
ArrowLeftSmallIcon,
|
||||
ArrowRightSmallIcon,
|
||||
SidebarIcon,
|
||||
} from '@blocksuite/icons';
|
||||
import { useAtom } from 'jotai';
|
||||
import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons';
|
||||
import { useAtomValue } from 'jotai';
|
||||
|
||||
import { IconButton } from '../../..';
|
||||
import type { History } from '..';
|
||||
import { navHeaderStyle, sidebarButtonStyle } from '../index.css';
|
||||
import { navHeaderStyle } from '../index.css';
|
||||
import { appSidebarOpenAtom } from '../index.jotai';
|
||||
import { SidebarSwitch } from './sidebar-switch';
|
||||
|
||||
export type SidebarHeaderProps = {
|
||||
router?: {
|
||||
@ -20,7 +17,7 @@ export type SidebarHeaderProps = {
|
||||
};
|
||||
|
||||
export const SidebarHeader = (props: SidebarHeaderProps) => {
|
||||
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
||||
const open = useAtomValue(appSidebarOpenAtom);
|
||||
const environment = getEnvironment();
|
||||
return (
|
||||
<div className={navHeaderStyle} data-open={open}>
|
||||
@ -57,13 +54,9 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
|
||||
{!environment.isMacOs && <div style={{ flex: 1 }} />}
|
||||
</>
|
||||
)}
|
||||
<IconButton
|
||||
data-testid="app-sidebar-arrow-button-collapse"
|
||||
className={sidebarButtonStyle}
|
||||
onClick={() => setOpen(open => !open)}
|
||||
>
|
||||
<SidebarIcon width={24} height={24} />
|
||||
</IconButton>
|
||||
{open && <SidebarSwitch />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export * from './sidebar-switch';
|
||||
|
@ -0,0 +1,31 @@
|
||||
import { IconButton, Tooltip } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { SidebarIcon } from '@blocksuite/icons';
|
||||
import { useAtom } from 'jotai';
|
||||
|
||||
import { sidebarButtonStyle } from '../index.css';
|
||||
import { appSidebarOpenAtom } from '../index.jotai';
|
||||
|
||||
export const SidebarSwitch = () => {
|
||||
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
||||
const t = useAFFiNEI18N();
|
||||
const tooltipContent = open ? t['Collapse sidebar']() : t['Expand sidebar']();
|
||||
const collapseKeyboardShortcuts =
|
||||
environment.isBrowser && environment.isMacOs ? ' ⌘+/' : ' Ctrl+/';
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={tooltipContent + ' ' + collapseKeyboardShortcuts}
|
||||
placement="right"
|
||||
zIndex={1000}
|
||||
>
|
||||
<IconButton
|
||||
data-testid={`app-sidebar-arrow-button-${open ? 'collapse' : 'expand'}`}
|
||||
className={sidebarButtonStyle}
|
||||
onClick={() => setOpen(open => !open)}
|
||||
>
|
||||
<SidebarIcon width={24} height={24} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
@ -19,7 +19,7 @@ test('Expand Sidebar', async ({ page }) => {
|
||||
const sliderBarArea = page.getByTestId('sliderBar-inner');
|
||||
await expect(sliderBarArea).not.toBeInViewport();
|
||||
|
||||
await page.getByTestId('sliderBar-arrowButton-expand').click();
|
||||
await page.getByTestId('app-sidebar-arrow-button-expand').click();
|
||||
await expect(sliderBarArea).toBeInViewport();
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user