feat: add animation to mode switch when hover (#1489)

Co-authored-by: Yifeng Wang <doodlewind@toeverything.info>
Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
Qi
2023-03-10 14:44:33 +08:00
committed by GitHub
parent afd113b1f1
commit 7eeff9d470
9 changed files with 143 additions and 13 deletions

View File

@@ -22,6 +22,9 @@ import { useWorkspacesHelper } from '../../hooks/use-workspaces';
import { ThemeProvider } from '../../providers/ThemeProvider';
import { pathGenerator, RemWorkspaceFlavour } from '../../shared';
import { WorkSpaceSliderBar } from '../pure/workspace-slider-bar';
vi.mock('react-lottie', () => ({
default: (props: React.PropsWithChildren) => <>{props.children}</>,
}));
const fetchMocker = createFetchMock(vi);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,4 @@
import { toast } from '@affine/component';
import { EdgelessIcon, PaperIcon } from '@blocksuite/icons';
import { assertExists } from '@blocksuite/store';
import { CSSProperties } from 'react';
@@ -8,7 +7,8 @@ import {
usePageMetaHelper,
} from '../../../../hooks/use-page-meta';
import { BlockSuiteWorkspace } from '../../../../shared';
import { StyledEditorModeSwitch, StyledSwitchItem } from './style';
import { StyledEditorModeSwitch } from './style';
import { EdgelessSwitchItem, PageSwitchItem } from './switch-items';
export type EditorModeSwitchProps = {
// todo(himself65): combine these two properties
@@ -35,7 +35,7 @@ export const EditorModeSwitch = ({
switchLeft={mode === 'page'}
showAlone={trash}
>
<StyledSwitchItem
<PageSwitchItem
data-testid="switch-page-mode-button"
active={mode === 'page'}
hide={trash && mode !== 'page'}
@@ -43,10 +43,8 @@ export const EditorModeSwitch = ({
setPageMeta(pageId, { mode: 'page' });
toast('Page mode');
}}
>
<PaperIcon />
</StyledSwitchItem>
<StyledSwitchItem
/>
<EdgelessSwitchItem
data-testid="switch-edgeless-mode-button"
active={mode === 'edgeless'}
hide={trash && mode !== 'edgeless'}
@@ -54,9 +52,7 @@ export const EditorModeSwitch = ({
setPageMeta(pageId, { mode: 'edgeless' });
toast('Edgeless mode');
}}
>
<EdgelessIcon />
</StyledSwitchItem>
/>
</StyledEditorModeSwitch>
);
};

View File

@@ -40,9 +40,9 @@ export const StyledEditorModeSwitch = styled('div')<{
});
export const StyledSwitchItem = styled('button')<{
active: boolean;
active?: boolean;
hide?: boolean;
}>(({ theme, active, hide = false }) => {
}>(({ theme, active = false, hide = false }) => {
return {
width: '24px',
height: '24px',
@@ -54,5 +54,8 @@ export const StyledSwitchItem = styled('button')<{
position: 'relative',
zIndex: 2,
fontSize: '20px',
path: {
fill: 'currentColor',
},
};
});

View File

@@ -0,0 +1,79 @@
import React, { cloneElement, HTMLAttributes, useState } from 'react';
import Lottie from 'react-lottie';
import * as edgelessHoverAnimationData from './animation-data/edgeless-hover.json';
import * as pageHoverAnimationData from './animation-data/page-hover.json';
import { StyledSwitchItem } from './style';
type HoverAnimateControllerProps = {
active?: boolean;
hide?: boolean;
children: React.ReactElement;
} & HTMLAttributes<HTMLButtonElement>;
const HoverAnimateController = ({
active,
hide,
children,
...props
}: HoverAnimateControllerProps) => {
const [startAnimate, setStartAnimate] = useState(false);
return (
<StyledSwitchItem
hide={hide}
active={active}
onMouseEnter={() => {
setStartAnimate(true);
}}
onMouseLeave={() => {
setStartAnimate(false);
}}
{...props}
>
{cloneElement(children, {
isStopped: !startAnimate,
speed: 5,
width: 20,
height: 20,
})}
</StyledSwitchItem>
);
};
export const PageSwitchItem = (
props: Omit<HoverAnimateControllerProps, 'children'>
) => {
return (
<HoverAnimateController {...props}>
<Lottie
options={{
loop: false,
autoplay: false,
animationData: pageHoverAnimationData,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
}}
/>
</HoverAnimateController>
);
};
export const EdgelessSwitchItem = (
props: Omit<HoverAnimateControllerProps, 'children'>
) => {
return (
<HoverAnimateController {...props}>
<Lottie
options={{
loop: false,
autoplay: false,
animationData: edgelessHoverAnimationData,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
}}
/>
</HoverAnimateController>
);
};

View File

@@ -42,6 +42,9 @@ import {
useSyncRouterWithCurrentWorkspaceAndPage,
} from '../use-sync-router-with-current-workspace-and-page';
import { useWorkspaces, useWorkspacesHelper } from '../use-workspaces';
vi.mock('react-lottie', () => ({
default: (props: React.PropsWithChildren) => <>{props.children}</>,
}));
let blockSuiteWorkspace: BlockSuiteWorkspace;
beforeAll(() => {