feat: move theme switch and language switch to editor option menu (#2025)

Co-authored-by: himself65 <himself65@outlook.com>
This commit is contained in:
JimmFly
2023-04-28 04:28:51 -05:00
committed by GitHub
co-authored by himself65
parent 903b6eaf30
commit 2ff5ef9d5d
12 changed files with 347 additions and 193 deletions
+1
View File
@@ -51,6 +51,7 @@ test('app theme', async () => {
await page.screenshot({ await page.screenshot({
path: resolve(testResultDir, 'affine-light-theme-electron.png'), path: resolve(testResultDir, 'affine-light-theme-electron.png'),
}); });
await page.getByTestId('editor-option-menu').click();
await page.getByTestId('change-theme-dark').click(); await page.getByTestId('change-theme-dark').click();
await page.waitForTimeout(50); await page.waitForTimeout(50);
{ {
@@ -14,6 +14,7 @@ import {
usePageMetaHelper, usePageMetaHelper,
} from '@toeverything/hooks/use-block-suite-page-meta'; } from '@toeverything/hooks/use-block-suite-page-meta';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import { useRouter } from 'next/router';
import { useState } from 'react'; import { useState } from 'react';
import { workspacePreferredModeAtom } from '../../../../atoms'; import { workspacePreferredModeAtom } from '../../../../atoms';
@@ -22,10 +23,41 @@ import { useCurrentPageId } from '../../../../hooks/current/use-current-page-id'
import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace'; import { useCurrentWorkspace } from '../../../../hooks/current/use-current-workspace';
import { toast } from '../../../../utils'; import { toast } from '../../../../utils';
import { Export, MoveToTrash } from '../../../affine/operation-menu-items'; import { Export, MoveToTrash } from '../../../affine/operation-menu-items';
import { MenuThemeModeSwitch } from '../header-right-items/theme-mode-switch';
export const EditorOptionMenu = () => { import {
StyledHorizontalDivider,
StyledHorizontalDividerContainer,
} from '../styles';
import { LanguageMenu } from './LanguageMenu';
const CommonMenu = () => {
const content = (
<div
onClick={e => {
e.stopPropagation();
}}
>
<MenuThemeModeSwitch />
<LanguageMenu />
</div>
);
return (
<FlexWrapper alignItems="center" justifyContent="center">
<Menu
width={276}
content={content}
// placement="bottom-end"
disablePortal={true}
trigger="click"
>
<IconButton data-testid="editor-option-menu" iconSize={[24, 24]}>
<MoreVerticalIcon />
</IconButton>
</Menu>
</FlexWrapper>
);
};
const PageMenu = () => {
const { t } = useTranslation(); const { t } = useTranslation();
// fixme(himself65): remove these hooks ASAP // fixme(himself65): remove these hooks ASAP
const [workspace] = useCurrentWorkspace(); const [workspace] = useCurrentWorkspace();
const [pageId] = useCurrentPageId(); const [pageId] = useCurrentPageId();
@@ -35,55 +67,70 @@ export const EditorOptionMenu = () => {
const pageMeta = useBlockSuitePageMeta(blockSuiteWorkspace).find( const pageMeta = useBlockSuitePageMeta(blockSuiteWorkspace).find(
meta => meta.id === pageId meta => meta.id === pageId
); );
assertExists(pageMeta);
const [record, set] = useAtom(workspacePreferredModeAtom); const [record, set] = useAtom(workspacePreferredModeAtom);
const mode = record[pageId] ?? 'page'; const mode = record[pageId] ?? 'page';
assertExists(pageMeta);
const { favorite } = pageMeta; const favorite = pageMeta.favorite ?? false;
const { setPageMeta } = usePageMetaHelper(blockSuiteWorkspace); const { setPageMeta } = usePageMetaHelper(blockSuiteWorkspace);
const [openConfirm, setOpenConfirm] = useState(false); const [openConfirm, setOpenConfirm] = useState(false);
const { removeToTrash } = useBlockSuiteMetaHelper(blockSuiteWorkspace); const { removeToTrash } = useBlockSuiteMetaHelper(blockSuiteWorkspace);
const EditMenu = ( const EditMenu = (
<> <>
<MenuItem <>
data-testid="editor-option-menu-favorite" <MenuItem
onClick={() => { data-testid="editor-option-menu-favorite"
setPageMeta(pageId, { favorite: !favorite }); onClick={() => {
toast( setPageMeta(pageId, { favorite: !favorite });
favorite ? t('Removed from Favorites') : t('Added to Favorites') toast(
); favorite ? t('Removed from Favorites') : t('Added to Favorites')
}} );
icon={
favorite ? (
<FavoritedIcon style={{ color: 'var(--affine-primary-color)' }} />
) : (
<FavoriteIcon />
)
}
>
{favorite ? t('Remove from favorites') : t('Add to Favorites')}
</MenuItem>
<MenuItem
icon={mode === 'page' ? <EdgelessIcon /> : <PageIcon />}
data-testid="editor-option-menu-edgeless"
onClick={() => {
set(record => ({
...record,
[pageId]: mode === 'page' ? 'edgeless' : 'page',
}));
}}
>
{t('Convert to ')}
{mode === 'page' ? t('Edgeless') : t('Page')}
</MenuItem>
<Export />
{!pageMeta.isRootPinboard && (
<MoveToTrash
testId="editor-option-menu-delete"
onItemClick={() => {
setOpenConfirm(true);
}} }}
/> icon={
)} favorite ? (
<FavoritedIcon style={{ color: 'var(--affine-primary-color)' }} />
) : (
<FavoriteIcon />
)
}
>
{favorite ? t('Remove from favorites') : t('Add to Favorites')}
</MenuItem>
<MenuItem
icon={mode === 'page' ? <EdgelessIcon /> : <PageIcon />}
data-testid="editor-option-menu-edgeless"
onClick={() => {
set(record => ({
...record,
[pageId]: mode === 'page' ? 'edgeless' : 'page',
}));
}}
>
{t('Convert to ')}
{mode === 'page' ? t('Edgeless') : t('Page')}
</MenuItem>
<Export />
{!pageMeta.isRootPinboard && (
<MoveToTrash
testId="editor-option-menu-delete"
onItemClick={() => {
setOpenConfirm(true);
}}
/>
)}
<StyledHorizontalDividerContainer>
<StyledHorizontalDivider />
</StyledHorizontalDividerContainer>
</>
<div
onClick={e => {
e.stopPropagation();
}}
>
<MenuThemeModeSwitch />
<LanguageMenu />
</div>
</> </>
); );
@@ -116,3 +163,7 @@ export const EditorOptionMenu = () => {
</> </>
); );
}; };
export const EditorOptionMenu = () => {
const router = useRouter();
return router.query.pageId ? <PageMenu /> : <CommonMenu />;
};
@@ -0,0 +1,133 @@
import { Button, displayFlex, Menu, MenuItem, styled } from '@affine/component';
import { LOCALES } from '@affine/i18n';
import { useTranslation } from '@affine/i18n';
import { ArrowDownSmallIcon, PublishIcon } from '@blocksuite/icons';
import type { FC, ReactElement } from 'react';
import { useCallback } from 'react';
const LanguageMenuContent: FC = () => {
const { i18n } = useTranslation();
const changeLanguage = useCallback(
(event: string) => {
i18n.changeLanguage(event);
},
[i18n]
);
return (
<>
{LOCALES.map(option => {
return (
<StyledListItem
key={option.name}
title={option.name}
onClick={() => {
changeLanguage(option.tag);
}}
>
{option.originalName}
</StyledListItem>
);
})}
</>
);
};
export const LanguageMenu: React.FC = () => {
const { i18n } = useTranslation();
const currentLanguage = LOCALES.find(item => item.tag === i18n.language);
return (
<StyledContainer>
<StyledIconContainer>
<PublishIcon />
</StyledIconContainer>
<StyledButtonContainer>
<Menu
content={(<LanguageMenuContent />) as ReactElement}
placement="bottom"
trigger="click"
disablePortal={true}
>
<StyledButton
icon={
<StyledArrowDownContainer>
<ArrowDownSmallIcon />
</StyledArrowDownContainer>
}
iconPosition="end"
noBorder={true}
data-testid="language-menu-button"
>
<StyledCurrentLanguage>
{currentLanguage?.originalName}
</StyledCurrentLanguage>
</StyledButton>
</Menu>
</StyledButtonContainer>
</StyledContainer>
);
};
const StyledListItem = styled(MenuItem)(() => ({
width: '132px',
height: '38px',
fontSize: 'var(--affine-font-base)',
textTransform: 'capitalize',
}));
const StyledContainer = styled('div')(() => {
return {
width: '100%',
height: '48px',
backgroundColor: 'transparent',
...displayFlex('flex-start', 'center'),
padding: '0 14px',
};
});
const StyledIconContainer = styled('div')(() => {
return {
width: '20px',
height: '20px',
color: 'var(--affine-icon-color)',
fontSize: '20px',
...displayFlex('flex-start', 'center'),
};
});
const StyledButtonContainer = styled('div')(() => {
return {
width: '100%',
height: '32px',
borderRadius: '4px',
border: `1px solid var(--affine-border-color)`,
backgroundColor: 'transparent',
...displayFlex('flex-start', 'center'),
marginLeft: '12px',
};
});
const StyledButton = styled(Button)(() => {
return {
width: '100%',
height: '32px',
borderRadius: '4px',
backgroundColor: 'transparent',
...displayFlex('space-between', 'center'),
textTransform: 'capitalize',
padding: '0',
};
});
const StyledArrowDownContainer = styled('div')(() => {
return {
height: '32px',
borderLeft: `1px solid var(--affine-border-color)`,
backgroundColor: 'transparent',
...displayFlex('flex-start', 'center'),
padding: '4px 6px',
fontSize: '24px',
};
});
const StyledCurrentLanguage = styled('div')(() => {
return {
marginLeft: '12px',
color: 'var(--affine-text-color)',
};
});
@@ -1,50 +1,65 @@
import { DarkModeIcon, LightModeIcon } from '@blocksuite/icons'; import { DarkModeIcon, LightModeIcon } from '@blocksuite/icons';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { useEffect, useState } from 'react'; import { useEffect } from 'react';
import { StyledSwitchItem, StyledThemeModeSwitch } from './style'; import {
export const ThemeModeSwitch = () => { StyledSwitchItem,
const { setTheme, resolvedTheme } = useTheme(); StyledThemeButton,
StyledThemeButtonContainer,
StyledThemeModeContainer,
StyledThemeModeSwitch,
StyledVerticalDivider,
} from './style';
export const MenuThemeModeSwitch = () => {
const { setTheme, resolvedTheme, theme } = useTheme();
useEffect(() => { useEffect(() => {
if (environment.isDesktop) { if (environment.isDesktop) {
window.apis?.onThemeChange(resolvedTheme === 'dark' ? 'dark' : 'light'); window.apis?.onThemeChange(resolvedTheme === 'dark' ? 'dark' : 'light');
} }
}, [resolvedTheme]); }, [resolvedTheme]);
const [isHover, setIsHover] = useState(false);
return ( return (
<StyledThemeModeSwitch <StyledThemeModeContainer>
data-testid="change-theme-container" <StyledThemeModeSwitch data-testid="change-theme-container" inMenu={true}>
onMouseEnter={() => { <StyledSwitchItem active={resolvedTheme === 'light'} inMenu={true}>
setIsHover(true); <LightModeIcon />
}} </StyledSwitchItem>
onMouseLeave={() => { <StyledSwitchItem active={resolvedTheme === 'dark'} inMenu={true}>
setIsHover(false); <DarkModeIcon />
}} </StyledSwitchItem>
> </StyledThemeModeSwitch>
<StyledSwitchItem <StyledThemeButtonContainer>
data-testid="change-theme-light" <StyledThemeButton
active={resolvedTheme === 'light'} data-testid="change-theme-light"
isHover={isHover} active={theme === 'light'}
onClick={() => { onClick={() => {
setTheme('light'); setTheme('light');
}} }}
> >
<LightModeIcon /> light
</StyledSwitchItem> </StyledThemeButton>
<StyledSwitchItem <StyledVerticalDivider />
data-testid="change-theme-dark" <StyledThemeButton
active={resolvedTheme === 'dark'} data-testid="change-theme-dark"
isHover={isHover} active={theme === 'dark'}
onClick={() => { onClick={() => {
setTheme('dark'); setTheme('dark');
}} }}
> >
<DarkModeIcon /> dark
</StyledSwitchItem> </StyledThemeButton>
</StyledThemeModeSwitch> <StyledVerticalDivider />
<StyledThemeButton
active={theme === 'system'}
onClick={() => {
setTheme('system');
}}
>
system
</StyledThemeButton>
</StyledThemeButtonContainer>
</StyledThemeModeContainer>
); );
}; };
export default ThemeModeSwitch; export default MenuThemeModeSwitch;
@@ -3,24 +3,63 @@ import { css, displayFlex, keyframes, styled } from '@affine/component';
import spring, { toString } from 'css-spring'; import spring, { toString } from 'css-spring';
const ANIMATE_DURATION = 400; const ANIMATE_DURATION = 400;
export const StyledThemeModeContainer = styled('div')(() => {
export const StyledThemeModeSwitch = styled('button')(() => {
return { return {
width: '32px', width: '100%',
height: '48px',
borderRadius: '6px',
backgroundColor: 'transparent',
color: 'var(--affine-icon-color)',
fontSize: '16px',
...displayFlex('flex-start', 'center'),
padding: '0 14px',
};
});
export const StyledThemeButtonContainer = styled('div')(() => {
return {
border: `1px solid var(--affine-border-color)`,
borderRadius: '4px',
cursor: 'pointer',
...displayFlex('space-evenly', 'center'),
flexGrow: 1,
marginLeft: '12px',
};
});
export const StyledThemeButton = styled('button')<{
active: boolean;
}>(({ active }) => {
return {
cursor: 'pointer',
color: active ? 'var(--affine-primary-color)' : 'var(--affine-icon-color)',
};
});
export const StyledVerticalDivider = styled('div')(() => {
return {
width: '1px',
height: '32px', height: '32px',
borderLeft: `1px solid var(--affine-border-color)`,
};
});
export const StyledThemeModeSwitch = styled('button')<{
inMenu?: boolean;
}>(({ inMenu }) => {
return {
width: inMenu ? '20px' : '32px',
height: inMenu ? '20px' : '32px',
borderRadius: '6px', borderRadius: '6px',
overflow: 'hidden', overflow: 'hidden',
WebkitAppRegion: 'no-drag', WebkitAppRegion: 'no-drag',
backgroundColor: 'transparent', backgroundColor: 'transparent',
position: 'relative', position: 'relative',
color: 'var(--affine-icon-color)', color: 'var(--affine-icon-color)',
fontSize: '24px', fontSize: inMenu ? '20px' : '24px',
}; };
}); });
export const StyledSwitchItem = styled('div')<{ export const StyledSwitchItem = styled('div')<{
active: boolean; active: boolean;
isHover: boolean; isHover?: boolean;
}>(({ active, isHover }) => { inMenu?: boolean;
}>(({ active, isHover, inMenu }) => {
const activeRaiseAnimate = toString( const activeRaiseAnimate = toString(
spring({ top: '0' }, { top: '-100%' }, { preset: 'gentle' }) spring({ top: '0' }, { top: '-100%' }, { preset: 'gentle' })
); );
@@ -58,8 +97,8 @@ export const StyledSwitchItem = styled('div')<{
}; };
return css` return css`
${css(displayFlex('center', 'center'))} ${css(displayFlex('center', 'center'))}
width: 32px; width:${inMenu ? '20px' : '32px'} ;
height: 32px; height: ${inMenu ? '20px' : '32px'} ;
position: absolute; position: absolute;
left: 0; left: 0;
cursor: pointer; cursor: pointer;
@@ -19,7 +19,6 @@ import { EditorOptionMenu } from './header-right-items/EditorOptionMenu';
import EditPage from './header-right-items/EditPage'; import EditPage from './header-right-items/EditPage';
import { HeaderShareMenu } from './header-right-items/ShareMenu'; import { HeaderShareMenu } from './header-right-items/ShareMenu';
import SyncUser from './header-right-items/SyncUser'; import SyncUser from './header-right-items/SyncUser';
import ThemeModeSwitch from './header-right-items/theme-mode-switch';
import TrashButtonGroup from './header-right-items/TrashButtonGroup'; import TrashButtonGroup from './header-right-items/TrashButtonGroup';
import UserAvatar from './header-right-items/UserAvatar'; import UserAvatar from './header-right-items/UserAvatar';
import { import {
@@ -66,7 +65,6 @@ export type BaseHeaderProps<
export const enum HeaderRightItemName { export const enum HeaderRightItemName {
EditorOptionMenu = 'editorOptionMenu', EditorOptionMenu = 'editorOptionMenu',
TrashButtonGroup = 'trashButtonGroup', TrashButtonGroup = 'trashButtonGroup',
ThemeModeSwitch = 'themeModeSwitch',
SyncUser = 'syncUser', SyncUser = 'syncUser',
ShareMenu = 'shareMenu', ShareMenu = 'shareMenu',
EditPage = 'editPage', EditPage = 'editPage',
@@ -98,12 +96,6 @@ const HeaderRightItems: Record<HeaderRightItemName, HeaderItem> = {
return !isPublic && !isPreview; return !isPublic && !isPreview;
}, },
}, },
[HeaderRightItemName.ThemeModeSwitch]: {
Component: ThemeModeSwitch,
availableWhen: (_, currentPage) => {
return currentPage?.meta.trash !== true;
},
},
[HeaderRightItemName.ShareMenu]: { [HeaderRightItemName.ShareMenu]: {
Component: HeaderShareMenu, Component: HeaderShareMenu,
availableWhen: (workspace, currentPage) => { availableWhen: (workspace, currentPage) => {
@@ -125,7 +117,7 @@ const HeaderRightItems: Record<HeaderRightItemName, HeaderItem> = {
[HeaderRightItemName.EditorOptionMenu]: { [HeaderRightItemName.EditorOptionMenu]: {
Component: EditorOptionMenu, Component: EditorOptionMenu,
availableWhen: (_, currentPage, { isPublic, isPreview }) => { availableWhen: (_, currentPage, { isPublic, isPreview }) => {
return !!currentPage && !isPublic && !isPreview; return !isPublic && !isPreview;
}, },
}, },
}; };
@@ -167,3 +167,16 @@ export const StyledQuickSearchTipContent = styled('div')(() => {
flexDirection: 'column', flexDirection: 'column',
}; };
}); });
export const StyledHorizontalDivider = styled('div')(() => {
return {
width: '100%',
borderTop: `1px solid var(--affine-border-color)`,
};
});
export const StyledHorizontalDividerContainer = styled('div')(() => {
return {
width: '100%',
padding: '14px',
};
});
@@ -15,7 +15,6 @@ import { useCallback } from 'react';
import type { AllWorkspace } from '../../../shared'; import type { AllWorkspace } from '../../../shared';
import { Footer } from '../footer'; import { Footer } from '../footer';
import { LanguageMenu } from './language-menu';
import { import {
StyledCreateWorkspaceCard, StyledCreateWorkspaceCard,
StyledHelperContainer, StyledHelperContainer,
@@ -24,7 +23,6 @@ import {
StyledModalHeaderLeft, StyledModalHeaderLeft,
StyledModalTitle, StyledModalTitle,
StyledOperationWrapper, StyledOperationWrapper,
StyledSplitLine,
StyleWorkspaceAdd, StyleWorkspaceAdd,
StyleWorkspaceInfo, StyleWorkspaceInfo,
StyleWorkspaceTitle, StyleWorkspaceTitle,
@@ -86,8 +84,6 @@ export const WorkspaceListModal = ({
</StyledModalHeaderLeft> </StyledModalHeaderLeft>
<StyledOperationWrapper> <StyledOperationWrapper>
<LanguageMenu />
<StyledSplitLine />
<ModalCloseButton <ModalCloseButton
data-testid="close-workspace-modal" data-testid="close-workspace-modal"
onClick={() => { onClick={() => {
@@ -1,64 +0,0 @@
import { Button, Menu, MenuItem, styled } from '@affine/component';
import { LOCALES } from '@affine/i18n';
import { useTranslation } from '@affine/i18n';
import { ArrowDownSmallIcon } from '@blocksuite/icons';
import type { FC, ReactElement } from 'react';
import { useCallback } from 'react';
const LanguageMenuContent: FC = () => {
const { i18n } = useTranslation();
const changeLanguage = useCallback(
(event: string) => {
i18n.changeLanguage(event);
},
[i18n]
);
return (
<>
{LOCALES.map(option => {
return (
<ListItem
key={option.name}
title={option.name}
onClick={() => {
changeLanguage(option.tag);
}}
>
{option.originalName}
</ListItem>
);
})}
</>
);
};
export const LanguageMenu: React.FC = () => {
const { i18n } = useTranslation();
const currentLanguage = LOCALES.find(item => item.tag === i18n.language);
return (
<Menu
content={(<LanguageMenuContent />) as ReactElement}
placement="bottom"
trigger="click"
disablePortal={true}
>
<Button
icon={<ArrowDownSmallIcon />}
iconPosition="end"
noBorder={true}
style={{ textTransform: 'capitalize', padding: '0 12px' }}
data-testid="language-menu-button"
>
{currentLanguage?.originalName}
</Button>
</Menu>
);
};
const ListItem = styled(MenuItem)(() => ({
height: '38px',
fontSize: 'var(--affine-font-base)',
textTransform: 'capitalize',
padding: '0 24px',
}));
+1 -2
View File
@@ -9,7 +9,7 @@ test('Switch to edgeless by switch edgeless item', async ({ page }) => {
await waitMarkdownImported(page); await waitMarkdownImported(page);
const btn = await page.getByTestId('switch-edgeless-mode-button'); const btn = await page.getByTestId('switch-edgeless-mode-button');
await btn.click(); await btn.click();
await page.waitForTimeout(100);
const edgeless = page.locator('affine-edgeless-page'); const edgeless = page.locator('affine-edgeless-page');
expect(await edgeless.isVisible()).toBe(true); expect(await edgeless.isVisible()).toBe(true);
@@ -27,7 +27,6 @@ test('Convert to edgeless by editor header items', async ({ page }) => {
await clickPageMoreActions(page); await clickPageMoreActions(page);
const menusEdgelessItem = page.getByTestId('editor-option-menu-edgeless'); const menusEdgelessItem = page.getByTestId('editor-option-menu-edgeless');
await menusEdgelessItem.click({ delay: 100 }); await menusEdgelessItem.click({ delay: 100 });
const edgeless = page.locator('affine-edgeless-page'); const edgeless = page.locator('affine-edgeless-page');
expect(await edgeless.isVisible()).toBe(true); expect(await edgeless.isVisible()).toBe(true);
}); });
@@ -3,7 +3,6 @@ import { expect } from '@playwright/test';
import { openHomePage } from '../libs/load-page'; import { openHomePage } from '../libs/load-page';
import { waitMarkdownImported } from '../libs/page-logic'; import { waitMarkdownImported } from '../libs/page-logic';
import { clickSideBarCurrentWorkspaceBanner } from '../libs/sidebar';
import { assertCurrentWorkspaceFlavour } from '../libs/workspace'; import { assertCurrentWorkspaceFlavour } from '../libs/workspace';
test('preset workspace name', async ({ page }) => { test('preset workspace name', async ({ page }) => {
@@ -24,7 +23,9 @@ test('preset workspace name', async ({ page }) => {
test('Open language switch menu', async ({ page }) => { test('Open language switch menu', async ({ page }) => {
await openHomePage(page); await openHomePage(page);
await waitMarkdownImported(page); await waitMarkdownImported(page);
await clickSideBarCurrentWorkspaceBanner(page); const editorOptionMenuButton = page.getByTestId('editor-option-menu');
await expect(editorOptionMenuButton).toBeVisible();
await editorOptionMenuButton.click();
const languageMenuButton = page.getByTestId('language-menu-button'); const languageMenuButton = page.getByTestId('language-menu-button');
await expect(languageMenuButton).toBeVisible(); await expect(languageMenuButton).toBeVisible();
const actual = await languageMenuButton.innerText(); const actual = await languageMenuButton.innerText();
+1 -23
View File
@@ -22,32 +22,10 @@ test('default white', async ({ browser }) => {
await page.screenshot({ await page.screenshot({
path: resolve(testResultDir, 'affine-light-theme.png'), path: resolve(testResultDir, 'affine-light-theme.png'),
}); });
await page.getByTestId('editor-option-menu').click();
await page.getByTestId('change-theme-dark').click(); await page.getByTestId('change-theme-dark').click();
await page.waitForTimeout(50); await page.waitForTimeout(50);
await page.screenshot({ await page.screenshot({
path: resolve(testResultDir, 'affine-dark-theme.png'), path: resolve(testResultDir, 'affine-dark-theme.png'),
}); });
}); });
// test('change theme to dark', async ({ page }) => {
// const changeThemeContainer = page.locator(
// '[data-testid=change-theme-container]'
// );
// const box = await changeThemeContainer.boundingBox();
// expect(box?.x).not.toBeUndefined();
//
// await page.mouse.move((box?.x ?? 0) + 5, (box?.y ?? 0) + 5);
// await page.waitForTimeout(1000);
// const darkButton = page.locator('[data-testid=change-theme-dark]');
// const darkButtonPositionTop = await darkButton.evaluate(
// element => element.getBoundingClientRect().y
// );
// expect(darkButtonPositionTop).toBe(box?.y);
//
// await page.mouse.click((box?.x ?? 0) + 5, (box?.y ?? 0) + 5);
// const root = page.locator('html');
// const themeMode = await root.evaluate(element =>
// element.getAttribute('data-theme')
// );
// expect(themeMode).toBe('dark');
// });