mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 01:09:54 +08:00
fix: some style issues to sidebar and switch (#4046)
Co-authored-by: Alex Yang <himself65@outlook.com>
This commit is contained in:
@@ -49,7 +49,7 @@ export const fontStyleOptions = [
|
|||||||
}[];
|
}[];
|
||||||
|
|
||||||
const appSettingBaseAtom = atomWithStorage<AppSetting>('affine-settings', {
|
const appSettingBaseAtom = atomWithStorage<AppSetting>('affine-settings', {
|
||||||
clientBorder: globalThis.platform !== 'win32',
|
clientBorder: environment.isDesktop ? !environment.isWindows : false,
|
||||||
fullWidthLayout: false,
|
fullWidthLayout: false,
|
||||||
windowFrameStyle: 'frameless',
|
windowFrameStyle: 'frameless',
|
||||||
fontStyle: 'Sans',
|
fontStyle: 'Sans',
|
||||||
|
|||||||
@@ -11,7 +11,11 @@ export const AppContainer = (props: WorkspaceRootProps) => {
|
|||||||
return (
|
return (
|
||||||
<AppContainerWithoutSettings
|
<AppContainerWithoutSettings
|
||||||
useNoisyBackground={appSettings.enableNoisyBackground}
|
useNoisyBackground={appSettings.enableNoisyBackground}
|
||||||
useBlurBackground={!appSettings.enableBlurBackground}
|
useBlurBackground={
|
||||||
|
appSettings.enableBlurBackground &&
|
||||||
|
environment.isDesktop &&
|
||||||
|
environment.isMacOs
|
||||||
|
}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
+13
-11
@@ -212,17 +212,19 @@ export const AppearanceSettings = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
<SettingRow
|
{environment.isMacOs && (
|
||||||
name={t['com.affine.settings.translucent-style']()}
|
<SettingRow
|
||||||
desc={t['com.affine.settings.translucent-style-description']()}
|
name={t['com.affine.settings.translucent-style']()}
|
||||||
>
|
desc={t['com.affine.settings.translucent-style-description']()}
|
||||||
<Switch
|
>
|
||||||
checked={appSettings.enableBlurBackground}
|
<Switch
|
||||||
onChange={checked =>
|
checked={appSettings.enableBlurBackground}
|
||||||
changeSwitch('enableBlurBackground', checked)
|
onChange={checked =>
|
||||||
}
|
changeSwitch('enableBlurBackground', checked)
|
||||||
/>
|
}
|
||||||
</SettingRow>
|
/>
|
||||||
|
</SettingRow>
|
||||||
|
)}
|
||||||
</SettingWrapper>
|
</SettingWrapper>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ globalStyle(`${accountButton} .avatar.not-sign`, {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderColor: 'var(--affine-border-color)',
|
borderColor: 'var(--affine-icon-secondary)',
|
||||||
color: 'var(--affine-border-color)',
|
color: 'var(--affine-icon-secondary)',
|
||||||
background: 'var(--affine-white)',
|
background: 'var(--affine-white)',
|
||||||
});
|
});
|
||||||
globalStyle(`${accountButton} .content`, {
|
globalStyle(`${accountButton} .content`, {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { Wrapper } from '@affine/component';
|
|
||||||
import {
|
import {
|
||||||
appSidebarFloatingAtom,
|
appSidebarFloatingAtom,
|
||||||
appSidebarOpenAtom,
|
appSidebarOpenAtom,
|
||||||
@@ -66,12 +65,8 @@ export const Header = forwardRef<HTMLDivElement, HeaderPros>(function Header(
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div className={clsx(style.headerItem, 'top-item')}>
|
<div className={clsx(style.headerItem, 'top-item')}>
|
||||||
<div ref={sidebarSwitchRef}>
|
<div ref={sidebarSwitchRef} style={{ marginRight: open ? 0 : 20 }}>
|
||||||
{!open && (
|
<SidebarSwitch show={!open} />
|
||||||
<Wrapper marginRight={20}>
|
|
||||||
<SidebarSwitch />
|
|
||||||
</Wrapper>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={clsx(style.headerItem, 'left')}>
|
<div className={clsx(style.headerItem, 'left')}>
|
||||||
|
|||||||
@@ -77,10 +77,10 @@ export const collapsibleContent = style({
|
|||||||
marginTop: '4px',
|
marginTop: '4px',
|
||||||
selectors: {
|
selectors: {
|
||||||
'&[data-state="open"]': {
|
'&[data-state="open"]': {
|
||||||
animation: `${slideDown} 0.2s ease-out`,
|
animation: `${slideDown} 0.2s ease-in-out`,
|
||||||
},
|
},
|
||||||
'&[data-state="closed"]': {
|
'&[data-state="closed"]': {
|
||||||
animation: `${slideUp} 0.2s ease-out`,
|
animation: `${slideUp} 0.2s ease-in-out`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -155,7 +155,13 @@ export const RootAppSidebar = ({
|
|||||||
<>
|
<>
|
||||||
<AppSidebar
|
<AppSidebar
|
||||||
router={router}
|
router={router}
|
||||||
hasBackground={!appSettings.enableBlurBackground}
|
hasBackground={
|
||||||
|
!(
|
||||||
|
appSettings.enableBlurBackground &&
|
||||||
|
environment.isDesktop &&
|
||||||
|
environment.isMacOs
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<SidebarContainer>
|
<SidebarContainer>
|
||||||
<NoSsr>
|
<NoSsr>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
AppSidebar,
|
AppSidebar,
|
||||||
AppSidebarFallback,
|
AppSidebarFallback,
|
||||||
appSidebarOpenAtom,
|
appSidebarOpenAtom,
|
||||||
|
SidebarSwitch,
|
||||||
} from '@affine/component/app-sidebar';
|
} from '@affine/component/app-sidebar';
|
||||||
import { AddPageButton } from '@affine/component/app-sidebar';
|
import { AddPageButton } from '@affine/component/app-sidebar';
|
||||||
import { CategoryDivider } from '@affine/component/app-sidebar';
|
import { CategoryDivider } from '@affine/component/app-sidebar';
|
||||||
@@ -12,13 +13,8 @@ import {
|
|||||||
SidebarContainer,
|
SidebarContainer,
|
||||||
SidebarScrollableContainer,
|
SidebarScrollableContainer,
|
||||||
} from '@affine/component/app-sidebar';
|
} from '@affine/component/app-sidebar';
|
||||||
import {
|
import { DeleteTemporarilyIcon, SettingsIcon } from '@blocksuite/icons';
|
||||||
DeleteTemporarilyIcon,
|
|
||||||
SettingsIcon,
|
|
||||||
SidebarIcon,
|
|
||||||
} from '@blocksuite/icons';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
import type { Meta, StoryFn } from '@storybook/react';
|
||||||
import { IconButton } from '@toeverything/components/button';
|
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { type PropsWithChildren, useState } from 'react';
|
import { type PropsWithChildren, useState } from 'react';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
@@ -45,20 +41,11 @@ const Container = ({ children }: PropsWithChildren) => (
|
|||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
const Main = () => {
|
const Main = () => {
|
||||||
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
const [open] = useAtom(appSidebarOpenAtom);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={navHeaderStyle}>
|
<div className={navHeaderStyle}>
|
||||||
{!open && (
|
<SidebarSwitch show={!open} />
|
||||||
<IconButton
|
|
||||||
size="large"
|
|
||||||
onClick={() => {
|
|
||||||
setOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SidebarIcon width={24} height={24} />
|
|
||||||
</IconButton>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const navWrapperStyle = style({
|
|||||||
marginLeft: `calc(${navWidthVar} * -1)`,
|
marginLeft: `calc(${navWidthVar} * -1)`,
|
||||||
},
|
},
|
||||||
'&[data-enable-animation="true"]': {
|
'&[data-enable-animation="true"]': {
|
||||||
transition: 'margin-left .3s, width .3s',
|
transition: 'margin-left .3s .05s, width .3s .05s',
|
||||||
},
|
},
|
||||||
'&.has-background': {
|
'&.has-background': {
|
||||||
backgroundColor: 'var(--affine-white-60)',
|
backgroundColor: 'var(--affine-white-60)',
|
||||||
|
|||||||
@@ -102,8 +102,10 @@ export function AppSidebar(props: AppSidebarProps): ReactElement {
|
|||||||
(environment.isDesktop && props.hasBackground),
|
(environment.isDesktop && props.hasBackground),
|
||||||
})}
|
})}
|
||||||
data-open={open}
|
data-open={open}
|
||||||
|
data-testid="app-sidebar-wrapper"
|
||||||
data-is-macos-electron={isMacosDesktop}
|
data-is-macos-electron={isMacosDesktop}
|
||||||
data-is-floating={appSidebarFloating}
|
data-is-floating={appSidebarFloating}
|
||||||
|
data-has-background={props.hasBackground}
|
||||||
data-enable-animation={enableAnimation && !isResizing}
|
data-enable-animation={enableAnimation && !isResizing}
|
||||||
>
|
>
|
||||||
<nav className={navStyle} ref={navRef} data-testid="app-sidebar">
|
<nav className={navStyle} ref={navRef} data-testid="app-sidebar">
|
||||||
|
|||||||
@@ -19,10 +19,13 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
|
|||||||
const open = useAtomValue(appSidebarOpenAtom);
|
const open = useAtomValue(appSidebarOpenAtom);
|
||||||
return (
|
return (
|
||||||
<div className={navHeaderStyle} data-open={open}>
|
<div className={navHeaderStyle} data-open={open}>
|
||||||
<div style={{ flex: 1 }} />
|
{environment.isDesktop && environment.isMacOs && (
|
||||||
{open && <SidebarSwitch />}
|
<div style={{ flex: 1 }} />
|
||||||
|
)}
|
||||||
|
<SidebarSwitch show={open} />
|
||||||
{environment.isDesktop && (
|
{environment.isDesktop && (
|
||||||
<>
|
<>
|
||||||
|
{!environment.isMacOs && <div style={{ flex: 1 }} />}
|
||||||
<IconButton
|
<IconButton
|
||||||
data-testid="app-sidebar-arrow-button-back"
|
data-testid="app-sidebar-arrow-button-back"
|
||||||
disabled={props.router?.history.current === 0}
|
disabled={props.router?.history.current === 0}
|
||||||
@@ -47,8 +50,6 @@ export const SidebarHeader = (props: SidebarHeaderProps) => {
|
|||||||
>
|
>
|
||||||
<ArrowRightSmallIcon />
|
<ArrowRightSmallIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
{!environment.isMacOs && <div style={{ flex: 1 }} />}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
export const sidebarSwitch = style({
|
||||||
|
opacity: 0,
|
||||||
|
width: 0,
|
||||||
|
overflow: 'hidden',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
transition: 'opacity .3s ease-in-out',
|
||||||
|
selectors: {
|
||||||
|
'&[data-show=true]': {
|
||||||
|
opacity: 1,
|
||||||
|
width: '32px',
|
||||||
|
pointerEvents: 'auto',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -6,8 +6,9 @@ import { useAtom } from 'jotai';
|
|||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
|
|
||||||
import { appSidebarOpenAtom } from '../index.jotai';
|
import { appSidebarOpenAtom } from '../index.jotai';
|
||||||
|
import * as styles from './sidebar-switch.css';
|
||||||
|
|
||||||
export const SidebarSwitch = () => {
|
export const SidebarSwitch = ({ show }: { show: boolean }) => {
|
||||||
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
const [open, setOpen] = useAtom(appSidebarOpenAtom);
|
||||||
const t = useAFFiNEI18N();
|
const t = useAFFiNEI18N();
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
@@ -18,12 +19,14 @@ export const SidebarSwitch = () => {
|
|||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={tooltipContent + ' ' + collapseKeyboardShortcuts}
|
content={tooltipContent + ' ' + collapseKeyboardShortcuts}
|
||||||
side="right"
|
side={open ? 'bottom' : 'right'}
|
||||||
portalOptions={{
|
portalOptions={{
|
||||||
container: ref.current,
|
container: ref.current,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
className={styles.sidebarSwitch}
|
||||||
|
data-show={show}
|
||||||
size="large"
|
size="large"
|
||||||
data-testid={`app-sidebar-arrow-button-${open ? 'collapse' : 'expand'}`}
|
data-testid={`app-sidebar-arrow-button-${open ? 'collapse' : 'expand'}`}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ export const appStyle = style({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexGrow: '1',
|
flexGrow: '1',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
backgroundColor: 'var(--affine-background-primary-color)',
|
||||||
selectors: {
|
selectors: {
|
||||||
'&[data-is-resizing="true"]': {
|
'&[data-is-resizing="true"]': {
|
||||||
cursor: 'col-resize',
|
cursor: 'col-resize',
|
||||||
},
|
},
|
||||||
'&.blur-background': {
|
'&.blur-background': {
|
||||||
backgroundColor: 'var(--affine-background-primary-color)',
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
'&.noisy-background::before': {
|
'&.noisy-background::before': {
|
||||||
content: '""',
|
content: '""',
|
||||||
@@ -70,7 +71,7 @@ export const mainContainerStyle = style({
|
|||||||
backgroundColor: 'var(--affine-background-primary-color)',
|
backgroundColor: 'var(--affine-background-primary-color)',
|
||||||
selectors: {
|
selectors: {
|
||||||
'&[data-show-padding="true"]': {
|
'&[data-show-padding="true"]': {
|
||||||
margin: '8px 8px 8px 0',
|
margin: '8px',
|
||||||
borderRadius: '5px',
|
borderRadius: '5px',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
boxShadow: 'var(--affine-shadow-1)',
|
boxShadow: 'var(--affine-shadow-1)',
|
||||||
@@ -119,6 +120,17 @@ globalStyle(`${mainContainerStyle} > div[data-panel-group] > div[data-panel]`, {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Hack margin so that it works normally when sidebar is closed
|
||||||
|
globalStyle(
|
||||||
|
`[data-testid=app-sidebar-wrapper][data-open=true][data-is-floating=false][data-has-background=false]
|
||||||
|
~ ${mainContainerStyle}[data-show-padding="true"]`,
|
||||||
|
{
|
||||||
|
// transition added here to prevent the transition from being applied on page load
|
||||||
|
transition: 'margin-left .3s ease-in-out',
|
||||||
|
marginLeft: '0',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export const toolStyle = style({
|
export const toolStyle = style({
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
right: '30px',
|
right: '30px',
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import { expect } from '@playwright/test';
|
|||||||
test('Collapse Sidebar', async ({ page }) => {
|
test('Collapse Sidebar', async ({ page }) => {
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await waitEditorLoad(page);
|
await waitEditorLoad(page);
|
||||||
await page.getByTestId('app-sidebar-arrow-button-collapse').click();
|
await page
|
||||||
|
.locator('[data-testid=app-sidebar-arrow-button-collapse][data-show=true]')
|
||||||
|
.click();
|
||||||
const sliderBarArea = page.getByTestId('app-sidebar');
|
const sliderBarArea = page.getByTestId('app-sidebar');
|
||||||
await expect(sliderBarArea).not.toBeInViewport();
|
await expect(sliderBarArea).not.toBeInViewport();
|
||||||
});
|
});
|
||||||
@@ -14,11 +16,15 @@ test('Collapse Sidebar', async ({ page }) => {
|
|||||||
test('Expand Sidebar', async ({ page }) => {
|
test('Expand Sidebar', async ({ page }) => {
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await waitEditorLoad(page);
|
await waitEditorLoad(page);
|
||||||
await page.getByTestId('app-sidebar-arrow-button-collapse').click();
|
await page
|
||||||
|
.locator('[data-testid=app-sidebar-arrow-button-collapse][data-show=true]')
|
||||||
|
.click();
|
||||||
const sliderBarArea = page.getByTestId('sliderBar-inner');
|
const sliderBarArea = page.getByTestId('sliderBar-inner');
|
||||||
await expect(sliderBarArea).not.toBeInViewport();
|
await expect(sliderBarArea).not.toBeInViewport();
|
||||||
|
|
||||||
await page.getByTestId('app-sidebar-arrow-button-expand').click();
|
await page
|
||||||
|
.locator('[data-testid=app-sidebar-arrow-button-expand][data-show=true]')
|
||||||
|
.click();
|
||||||
await expect(sliderBarArea).toBeInViewport();
|
await expect(sliderBarArea).toBeInViewport();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import { expect } from '@playwright/test';
|
|||||||
test('Create subpage', async ({ page }) => {
|
test('Create subpage', async ({ page }) => {
|
||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await waitEditorLoad(page);
|
await waitEditorLoad(page);
|
||||||
await page.getByTestId('app-sidebar-arrow-button-collapse').click();
|
await page
|
||||||
|
.locator('[data-testid=app-sidebar-arrow-button-collapse][data-show=true]')
|
||||||
|
.click();
|
||||||
const sliderBarArea = page.getByTestId('sliderBar-inner');
|
const sliderBarArea = page.getByTestId('sliderBar-inner');
|
||||||
await expect(sliderBarArea).not.toBeInViewport();
|
await expect(sliderBarArea).not.toBeInViewport();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user