feat: new setting modal (#2834)

Co-authored-by: Alex Yang <himself65@outlook.com>
This commit is contained in:
Qi
2023-06-21 19:57:59 +08:00
committed by GitHub
parent 9a90ce694c
commit aa86d3a2ee
64 changed files with 1911 additions and 159 deletions
@@ -0,0 +1,126 @@
import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
import type {
AffineLegacyCloudWorkspace,
LocalWorkspace,
} from '@affine/env/workspace';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
import clsx from 'clsx';
import type {
GeneralSettingKeys,
GeneralSettingList,
} from '../general-setting';
import type { Workspace } from '../type';
import {
accountButton,
settingSlideBar,
sidebarItemsWrapper,
sidebarSelectItem,
sidebarSubtitle,
sidebarTitle,
} from './style.css';
export const SettingSidebar = ({
generalSettingList,
onGeneralSettingClick,
currentWorkspace,
workspaceList,
onWorkspaceSettingClick,
selectedWorkspace,
selectedGeneralKey,
onAccountSettingClick,
}: {
generalSettingList: GeneralSettingList;
onGeneralSettingClick: (key: GeneralSettingKeys) => void;
currentWorkspace: Workspace;
workspaceList: Workspace[];
onWorkspaceSettingClick: (
workspace: AffineLegacyCloudWorkspace | LocalWorkspace
) => void;
selectedWorkspace: Workspace | null;
selectedGeneralKey: string | null;
onAccountSettingClick: () => void;
}) => {
return (
<div className={settingSlideBar}>
<div className={sidebarTitle}>Settings</div>
<div className={sidebarSubtitle}>General</div>
<div className={sidebarItemsWrapper}>
{generalSettingList.map(({ title, icon, key }) => {
return (
<div
className={clsx(sidebarSelectItem, {
active: key === selectedGeneralKey,
})}
key={key}
title={title}
onClick={() => {
onGeneralSettingClick(key);
}}
>
{icon({ className: 'icon' })}
<span className="setting-name">{title}</span>
</div>
);
})}
</div>
<div className={sidebarSubtitle}>Workspace</div>
<div className={clsx(sidebarItemsWrapper, 'scroll')}>
{workspaceList.map(workspace => {
return (
<WorkspaceListItem
key={workspace.id}
workspace={workspace}
onClick={() => {
onWorkspaceSettingClick(workspace);
}}
isCurrent={workspace.id === currentWorkspace.id}
isActive={workspace.id === selectedWorkspace?.id}
/>
);
})}
</div>
<div className={accountButton} onClick={onAccountSettingClick}>
<div className="avatar"></div>
<div className="content">
<div className="name" title="xxx">
Account NameAccount Name
</div>
<div className="email" title="xxx">
xxxxxxxx@gmail.comxxxxxxxx@gmail.com
</div>
</div>
</div>
</div>
);
};
const WorkspaceListItem = ({
workspace,
onClick,
isCurrent,
isActive,
}: {
workspace: AffineLegacyCloudWorkspace | LocalWorkspace;
onClick: () => void;
isCurrent: boolean;
isActive: boolean;
}) => {
const [workspaceName] = useBlockSuiteWorkspaceName(
workspace.blockSuiteWorkspace ?? null
);
return (
<div
className={clsx(sidebarSelectItem, { active: isActive })}
title={workspaceName}
onClick={onClick}
>
<WorkspaceAvatar size={14} workspace={workspace} className="icon" />
<span className="setting-name">{workspaceName}</span>
{isCurrent ? <div className="current-label">Current</div> : null}
</div>
);
};
@@ -0,0 +1,138 @@
import { globalStyle, style } from '@vanilla-extract/css';
export const settingSlideBar = style({
width: '25%',
maxWidth: '242px',
// TODO: use color variable
// background: 'var(--affine-background-secondary-color)',
backgroundColor: '#F4F4F5',
padding: '20px 16px',
height: '100%',
flexShrink: 0,
display: 'flex',
flexDirection: 'column',
});
export const sidebarTitle = style({
fontSize: 'var(--affine-font-h-6)',
fontWeight: '600',
lineHeight: 'var(--affine-line-height)',
paddingLeft: '8px',
});
export const sidebarSubtitle = style({
fontSize: 'var(--affine-font-sm)',
lineHeight: 'var(--affine-line-height)',
color: 'var(--affine-text-secondary-color)',
paddingLeft: '8px',
marginTop: '20px',
marginBottom: '4px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
});
export const sidebarItemsWrapper = style({
selectors: {
'&.scroll': {
flexGrow: 1,
},
},
});
export const sidebarSelectItem = style({
display: 'flex',
alignItems: 'center',
padding: '0 8px',
height: '30px',
marginBottom: '4px',
fontSize: 'var(--affine-font-sm)',
borderRadius: '8px',
cursor: 'pointer',
userSelect: 'none',
':hover': {
background: 'var(--affine-hover-color)',
},
selectors: {
'&.active': {
background: 'var(--affine-hover-color)',
},
[`${sidebarItemsWrapper} &:last-of-type`]: {
marginBottom: 0,
},
},
});
globalStyle(`${settingSlideBar} .icon`, {
width: '16px',
height: '16px',
marginRight: '10px',
flexShrink: 0,
});
globalStyle(`${settingSlideBar} .setting-name`, {
minWidth: 0,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
flexGrow: 1,
});
globalStyle(`${settingSlideBar} .current-label`, {
height: '20px',
borderRadius: '8px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: '0 5px',
// TODO: use color variable
background: '#1E96EB',
fontSize: 'var(--affine-font-xs)',
fontWeight: '600',
color: 'var(--affine-white)',
marginLeft: '10px',
flexShrink: 0,
});
export const accountButton = style({
height: '42px',
padding: '4px 8px',
borderRadius: '8px',
cursor: 'pointer',
userSelect: 'none',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
':hover': {
background: 'var(--affine-hover-color)',
},
});
globalStyle(`${accountButton} .avatar`, {
width: '28px',
height: '28px',
border: '1px solid',
borderColor: 'var(--affine-white)',
borderRadius: '14px',
flexShrink: '0',
marginRight: '10px',
background: 'red',
});
globalStyle(`${accountButton} .content`, {
flexGrow: '1',
minWidth: 0,
});
globalStyle(`${accountButton} .name`, {
fontSize: 'var(--affine-font-sm)',
fontWeight: 600,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
flexGrow: 1,
});
globalStyle(`${accountButton} .email`, {
fontSize: 'var(--affine-font-xs)',
color: 'var(--affine-text-secondary-color)',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
flexGrow: 1,
});