feat: replace modal with new design (#4324)

Co-authored-by: Peng Xiao <pengxiao@outlook.com>
This commit is contained in:
Qi
2023-09-13 16:05:19 +08:00
committed by GitHub
parent 49e0172316
commit 0b1ba6bf43
58 changed files with 637 additions and 1404 deletions

View File

@@ -1,14 +1,9 @@
import {
Input,
Modal,
ModalCloseButton,
ModalWrapper,
toast,
} from '@affine/component';
import { Input, toast } from '@affine/component';
import { DebugLogger } from '@affine/debug';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { HelpIcon } from '@blocksuite/icons';
import { Button } from '@toeverything/components/button';
import { Modal } from '@toeverything/components/modal';
import { Tooltip } from '@toeverything/components/tooltip';
import type {
LoadDBFileResult,
@@ -386,16 +381,28 @@ export const CreateWorkspaceModal = ({
/>
) : null;
const onOpenChange = useCallback(
(open: boolean) => {
if (!open) {
onClose();
}
},
[onClose]
);
return (
<Modal open={mode !== false && !!step} onClose={onClose}>
<ModalWrapper width={560} style={{ padding: '10px' }}>
<div className={style.header}>
<ModalCloseButton top={6} right={6} onClick={onClose} />
</div>
{nameWorkspaceNode}
{setDBLocationNode}
{setSyncingModeNode}
</ModalWrapper>
<Modal
open={mode !== false && !!step}
width={560}
onOpenChange={onOpenChange}
contentOptions={{
style: { padding: '10px' },
}}
>
<div className={style.header}></div>
{nameWorkspaceNode}
{setDBLocationNode}
{setSyncingModeNode}
</Modal>
);
};

View File

@@ -1,33 +1,26 @@
import { Modal, ModalWrapper } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon } from '@blocksuite/icons';
import { Button, IconButton } from '@toeverything/components/button';
import {
ConfirmModal,
type ConfirmModalProps,
} from '@toeverything/components/modal';
import { useSetAtom } from 'jotai';
import { useCallback } from 'react';
import { authAtom } from '../../../atoms';
import { setOnceSignedInEventAtom } from '../../../atoms/event';
import { useCurrentLoginStatus } from '../../../hooks/affine/use-current-login-status';
import { ButtonContainer, Content, Header, StyleTips, Title } from './style';
interface EnableAffineCloudModalProps {
open: boolean;
onConfirm: () => void;
onClose: () => void;
}
export const EnableAffineCloudModal = ({
onConfirm: propsOnConfirm,
open,
onClose,
}: EnableAffineCloudModalProps) => {
...props
}: ConfirmModalProps) => {
const t = useAFFiNEI18N();
const loginStatus = useCurrentLoginStatus();
const setAuthAtom = useSetAtom(authAtom);
const setOnceSignedInEvent = useSetAtom(setOnceSignedInEventAtom);
const confirm = useCallback(async () => {
return propsOnConfirm();
return propsOnConfirm?.();
}, [propsOnConfirm]);
const onConfirm = useCallback(() => {
@@ -39,42 +32,29 @@ export const EnableAffineCloudModal = ({
setOnceSignedInEvent(confirm);
}
if (loginStatus === 'authenticated') {
return propsOnConfirm();
return propsOnConfirm?.();
}
}, [confirm, loginStatus, propsOnConfirm, setAuthAtom, setOnceSignedInEvent]);
return (
<Modal open={open} onClose={onClose} data-testid="logout-modal">
<ModalWrapper width={480}>
<Header>
<Title>{t['Enable AFFiNE Cloud']()}</Title>
<IconButton onClick={onClose}>
<CloseIcon />
</IconButton>
</Header>
<Content>
<StyleTips>{t['Enable AFFiNE Cloud Description']()}</StyleTips>
<ButtonContainer>
<div>
<Button onClick={onClose} block>
{t['com.affine.enableAffineCloudModal.button.cancel']()}
</Button>
</div>
<div>
<Button
data-testid="confirm-enable-affine-cloud-button"
type="primary"
block
onClick={onConfirm}
>
{loginStatus === 'authenticated'
? t['Enable']()
: t['Sign in and Enable']()}
</Button>
</div>
</ButtonContainer>
</Content>
</ModalWrapper>
</Modal>
<ConfirmModal
width={480}
title={t['Enable AFFiNE Cloud']()}
description={t['Enable AFFiNE Cloud Description']()}
cancelText={t['com.affine.enableAffineCloudModal.button.cancel']()}
onConfirm={onConfirm}
confirmButtonOptions={{
type: 'primary',
['data-testid' as string]: 'confirm-enable-affine-cloud-button',
children:
loginStatus === 'authenticated'
? t['Enable']()
: t['Sign in and Enable'](),
}}
contentOptions={{
['data-testid' as string]: 'enable-cloud-modal',
}}
{...props}
/>
);
};

View File

@@ -1,35 +0,0 @@
import { styled } from '@affine/component';
export const Header = styled('div')({
display: 'flex',
justifyContent: 'space-between',
paddingRight: '20px',
paddingTop: '20px',
paddingLeft: '24px',
alignItems: 'center',
});
export const Content = styled('div')({
padding: '12px 24px 20px 24px',
});
export const Title = styled('div')({
fontSize: 'var(--affine-font-h6)',
lineHeight: '26px',
fontWeight: 600,
});
export const StyleTips = styled('div')(() => {
return {
userSelect: 'none',
marginBottom: '20px',
};
});
export const ButtonContainer = styled('div')(() => {
return {
display: 'flex',
justifyContent: 'flex-end',
gap: '20px',
paddingTop: '20px',
};
});

View File

@@ -1,33 +1,24 @@
import { Input, Modal, ModalCloseButton } from '@affine/component';
import { Input } from '@affine/component';
import type { AffineOfficialWorkspace } from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Button } from '@toeverything/components/button';
import {
ConfirmModal,
type ConfirmModalProps,
} from '@toeverything/components/modal';
import { useBlockSuiteWorkspaceName } from '@toeverything/hooks/use-block-suite-workspace-name';
import { useState } from 'react';
import {
StyledButtonContent,
StyledInputContent,
StyledModalHeader,
StyledModalWrapper,
StyledTextContent,
StyledWorkspaceName,
} from './style';
import { StyledInputContent, StyledWorkspaceName } from './style';
interface WorkspaceDeleteProps {
open: boolean;
onClose: () => void;
interface WorkspaceDeleteProps extends ConfirmModalProps {
workspace: AffineOfficialWorkspace;
onConfirm: () => void;
}
export const WorkspaceDeleteModal = ({
open,
onClose,
onConfirm,
workspace,
...props
}: WorkspaceDeleteProps) => {
const [workspaceName] = useBlockSuiteWorkspaceName(
workspace.blockSuiteWorkspace
@@ -37,65 +28,50 @@ export const WorkspaceDeleteModal = ({
const t = useAFFiNEI18N();
return (
<Modal open={open} onClose={onClose}>
<StyledModalWrapper>
<ModalCloseButton onClick={onClose} />
<StyledModalHeader>
{t['com.affine.workspaceDelete.title']()}?
</StyledModalHeader>
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
<StyledTextContent>
<Trans i18nKey="com.affine.workspaceDelete.description">
Deleting (
<StyledWorkspaceName>
{{ workspace: workspaceName } as any}
</StyledWorkspaceName>
) cannot be undone, please proceed with caution. All contents will
be lost.
</Trans>
</StyledTextContent>
) : (
<StyledTextContent>
<Trans i18nKey="com.affine.workspaceDelete.description2">
Deleting (
<StyledWorkspaceName>
{{ workspace: workspaceName } as any}
</StyledWorkspaceName>
) will delete both local and cloud data, this operation cannot be
undone, please proceed with caution.
</Trans>
</StyledTextContent>
)}
<StyledInputContent>
<Input
ref={ref => {
if (ref) {
window.setTimeout(() => ref.focus(), 0);
}
}}
onChange={setDeleteStr}
data-testid="delete-workspace-input"
placeholder={t['com.affine.workspaceDelete.placeholder']()}
width={315}
height={42}
/>
</StyledInputContent>
<StyledButtonContent>
<Button onClick={onClose} size="large">
{t['com.affine.workspaceDelete.button.cancel']()}
</Button>
<Button
data-testid="delete-workspace-confirm-button"
disabled={!allowDelete}
onClick={onConfirm}
size="large"
type="error"
style={{ marginLeft: '24px' }}
>
{t['com.affine.workspaceDelete.button.delete']()}
</Button>
</StyledButtonContent>
</StyledModalWrapper>
</Modal>
<ConfirmModal
title={`${t['com.affine.workspaceDelete.title']()}?`}
cancelText={t['com.affine.workspaceDelete.button.cancel']()}
confirmButtonOptions={{
type: 'error',
disabled: !allowDelete,
['data-testid' as string]: 'delete-workspace-confirm-button',
children: t['com.affine.workspaceDelete.button.delete'](),
}}
{...props}
>
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
<Trans i18nKey="com.affine.workspaceDelete.description">
Deleting (
<StyledWorkspaceName>
{{ workspace: workspaceName } as any}
</StyledWorkspaceName>
) cannot be undone, please proceed with caution. All contents will be
lost.
</Trans>
) : (
<Trans i18nKey="com.affine.workspaceDelete.description2">
Deleting (
<StyledWorkspaceName>
{{ workspace: workspaceName } as any}
</StyledWorkspaceName>
) will delete both local and cloud data, this operation cannot be
undone, please proceed with caution.
</Trans>
)}
<StyledInputContent>
<Input
ref={ref => {
if (ref) {
window.setTimeout(() => ref.focus(), 0);
}
}}
onChange={setDeleteStr}
data-testid="delete-workspace-input"
placeholder={t['com.affine.workspaceDelete.placeholder']()}
width={315}
height={42}
/>
</StyledInputContent>
</ConfirmModal>
);
};

View File

@@ -21,20 +21,6 @@ export const StyledModalHeader = styled('div')(() => {
};
});
// export const StyledModalContent = styled('div')(({ theme }) => {});
export const StyledTextContent = styled('div')(() => {
return {
margin: 'auto',
width: '425px',
fontStyle: 'normal',
fontWeight: '400',
fontSize: '18px',
lineHeight: '26px',
textAlign: 'left',
};
});
export const StyledInputContent = styled('div')(() => {
return {
display: 'flex',
@@ -45,31 +31,8 @@ export const StyledInputContent = styled('div')(() => {
};
});
export const StyledButtonContent = styled('div')(() => {
return {
marginBottom: '42px',
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
};
});
export const StyledWorkspaceName = styled('span')(() => {
return {
fontWeight: '600',
};
});
// export const StyledCancelButton = styled(Button)(({ theme }) => {
// return {
// width: '100px',
// justifyContent: 'center',
// };
// });
// export const StyledDeleteButton = styled(Button)(({ theme }) => {
// return {
// width: '100px',
// justifyContent: 'center',
// };
// });

View File

@@ -1,9 +1,9 @@
import { ConfirmModal } from '@affine/component';
import { SettingRow } from '@affine/component/setting-components';
import type { AffineOfficialWorkspace } from '@affine/env/workspace';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ArrowRightSmallIcon } from '@blocksuite/icons';
import { ConfirmModal } from '@toeverything/components/modal';
import { useCallback, useState } from 'react';
import type { WorkspaceSettingDetailProps } from '../types';
@@ -33,10 +33,6 @@ export const DeleteLeaveWorkspace = ({
}
}, [isOwner]);
const onCloseLeaveModal = useCallback(() => {
setShowLeave(false);
}, []);
const onLeaveConfirm = useCallback(() => {
return onLeaveWorkspace();
}, [onLeaveWorkspace]);
@@ -71,21 +67,21 @@ export const DeleteLeaveWorkspace = ({
<WorkspaceDeleteModal
onConfirm={onDeleteConfirm}
open={showDelete}
onClose={() => {
setShowDelete(false);
}}
onOpenChange={setShowDelete}
workspace={workspace}
/>
) : (
<ConfirmModal
open={showLeave}
cancelText={t['com.affine.confirmModal.button.cancel']()}
onConfirm={onLeaveConfirm}
onCancel={onCloseLeaveModal}
onClose={onCloseLeaveModal}
onOpenChange={setShowLeave}
title={`${t['com.affine.deleteLeaveWorkspace.leave']()}?`}
content={t['com.affine.deleteLeaveWorkspace.leaveDescription']()}
confirmType="warning"
confirmText={t['Leave']()}
description={t['com.affine.deleteLeaveWorkspace.leaveDescription']()}
confirmButtonOptions={{
type: 'warning',
children: t['Leave'](),
}}
/>
)}
</>

View File

@@ -142,9 +142,7 @@ const PublishPanelLocal = ({
{runtimeConfig.enableCloud ? (
<EnableAffineCloudModal
open={open}
onClose={() => {
setOpen(false);
}}
onOpenChange={setOpen}
onConfirm={() => {
onTransferWorkspace(
WorkspaceFlavour.LOCAL,
@@ -155,12 +153,7 @@ const PublishPanelLocal = ({
}}
/>
) : (
<TmpDisableAffineCloudModal
open={open}
onClose={() => {
setOpen(false);
}}
/>
<TmpDisableAffineCloudModal open={open} onOpenChange={setOpen} />
)}
</>
);

View File

@@ -8,12 +8,16 @@ import { guideOnboardingAtom } from '../../atoms/guide';
export const OnboardingModal = memo(function OnboardingModal() {
const [open, setOpen] = useAtom(openOnboardingModalAtom);
const [guideOpen, setShowOnboarding] = useAtom(guideOnboardingAtom);
const onCloseTourModal = useCallback(() => {
setShowOnboarding(false);
setOpen(false);
}, [setOpen, setShowOnboarding]);
const onOpenChange = useCallback(
(open: boolean) => {
if (open) return;
setShowOnboarding(false);
setOpen(false);
},
[setOpen, setShowOnboarding]
);
return (
<TourModal open={!open ? guideOpen : open} onClose={onCloseTourModal} />
<TourModal open={!open ? guideOpen : open} onOpenChange={onOpenChange} />
);
});

View File

@@ -1,10 +1,7 @@
import {
SettingModal as SettingModalBase,
type SettingModalProps as SettingModalBaseProps,
WorkspaceDetailSkeleton,
} from '@affine/component/setting-components';
import { WorkspaceDetailSkeleton } from '@affine/component/setting-components';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ContactWithUsIcon } from '@blocksuite/icons';
import { Modal, type ModalProps } from '@toeverything/components/modal';
import { Suspense, useCallback } from 'react';
import { useCurrentLoginStatus } from '../../../hooks/affine/use-current-login-status';
@@ -20,7 +17,7 @@ import { WorkspaceSetting } from './workspace-setting';
type ActiveTab = GeneralSettingKeys | 'workspace' | 'account';
export interface SettingProps {
export interface SettingProps extends ModalProps {
activeTab: ActiveTab;
workspaceId: string | null;
onSettingClick: (params: {
@@ -29,15 +26,12 @@ export interface SettingProps {
}) => void;
}
type SettingModalProps = SettingModalBaseProps & SettingProps;
export const SettingModal = ({
open,
setOpen,
activeTab = 'appearance',
workspaceId = null,
onSettingClick,
}: SettingModalProps) => {
...modalProps
}: SettingProps) => {
const t = useAFFiNEI18N();
const loginStatus = useCurrentLoginStatus();
@@ -66,7 +60,21 @@ export const SettingModal = ({
}, [onSettingClick]);
return (
<SettingModalBase open={open} setOpen={setOpen}>
<Modal
width={1080}
height={760}
contentOptions={{
['data-testid' as string]: 'setting-modal',
style: {
maxHeight: '85vh',
maxWidth: '70vw',
padding: 0,
overflow: 'hidden',
display: 'flex',
},
}}
{...modalProps}
>
<SettingSidebar
generalSettingList={generalSettingList}
onGeneralSettingClick={onGeneralSettingClick}
@@ -105,6 +113,6 @@ export const SettingModal = ({
</div>
</div>
</div>
</SettingModalBase>
</Modal>
);
};

View File

@@ -30,9 +30,7 @@ export const SharePageModal = ({ workspace, page }: SharePageModalProps) => {
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
<EnableAffineCloudModal
open={open}
onClose={() => {
setOpen(false);
}}
onOpenChange={setOpen}
onConfirm={() => {
onTransformWorkspace(
WorkspaceFlavour.LOCAL,

View File

@@ -1,79 +1,61 @@
import { Empty, Modal, ModalWrapper } from '@affine/component';
import { Empty } from '@affine/component';
import { Trans } from '@affine/i18n';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon } from '@blocksuite/icons';
import { IconButton } from '@toeverything/components/button';
import { Modal, type ModalProps } from '@toeverything/components/modal';
import { useCallback } from 'react';
import {
Content,
ContentTitle,
Header,
StyleButton,
StyleButtonContainer,
StyleImage,
StyleTips,
} from './style';
interface TmpDisableAffineCloudModalProps {
open: boolean;
onClose: () => void;
}
export const TmpDisableAffineCloudModal = ({
open,
onClose,
}: TmpDisableAffineCloudModalProps) => {
export const TmpDisableAffineCloudModal = (props: ModalProps) => {
const t = useAFFiNEI18N();
const onClose = useCallback(() => {
props.onOpenChange?.(false);
}, [props]);
return (
<Modal
data-testid="disable-affine-cloud-modal"
open={open}
onClose={onClose}
title={t['com.affine.cloudTempDisable.title']()}
contentOptions={{
['data-testid' as string]: 'disable-affine-cloud-modal',
}}
width={480}
{...props}
>
<ModalWrapper width={480}>
<Header>
<IconButton onClick={onClose}>
<CloseIcon />
</IconButton>
</Header>
<Content>
<ContentTitle>
{t['com.affine.cloudTempDisable.title']()}
</ContentTitle>
<StyleTips>
<Trans i18nKey="com.affine.cloudTempDisable.description">
We are upgrading the AFFiNE Cloud service and it is temporarily
unavailable on the client side. If you wish to stay updated on the
progress and be notified on availability, you can fill out the
<a
href="https://6dxre9ihosp.typeform.com/to/B8IHwuyy"
rel="noreferrer"
target="_blank"
style={{
color: 'var(--affine-link-color)',
}}
>
AFFiNE Cloud Signup
</a>
.
</Trans>
</StyleTips>
<StyleImage>
<Empty
containerStyle={{
width: '200px',
height: '112px',
}}
/>
</StyleImage>
<StyleButtonContainer>
<StyleButton type="primary" onClick={onClose}>
{t['Got it']()}
</StyleButton>
</StyleButtonContainer>
</Content>
</ModalWrapper>
<StyleTips>
<Trans i18nKey="com.affine.cloudTempDisable.description">
We are upgrading the AFFiNE Cloud service and it is temporarily
unavailable on the client side. If you wish to stay updated on the
progress and be notified on availability, you can fill out the
<a
href="https://6dxre9ihosp.typeform.com/to/B8IHwuyy"
rel="noreferrer"
target="_blank"
style={{
color: 'var(--affine-link-color)',
}}
>
AFFiNE Cloud Signup
</a>
.
</Trans>
</StyleTips>
<StyleImage>
<Empty
containerStyle={{
width: '200px',
height: '112px',
}}
/>
</StyleImage>
<StyleButtonContainer>
<StyleButton type="primary" onClick={onClose}>
{t['Got it']()}
</StyleButton>
</StyleButtonContainer>
</Modal>
);
};

View File

@@ -16,6 +16,7 @@ export const Content = styled('div')({
export const ContentTitle = styled('h1')(() => {
return {
marginTop: 44,
fontSize: 'var(--affine-font-h6)',
lineHeight: '28px',
fontWeight: 600,
@@ -24,8 +25,7 @@ export const ContentTitle = styled('h1')(() => {
export const StyleTips = styled('div')(() => {
return {
userSelect: 'none',
margin: '20px 0',
margin: '0 0 20px 0',
a: {
color: 'var(--affine-primary-color)',
},
@@ -35,7 +35,6 @@ export const StyleTips = styled('div')(() => {
export const StyleButton = styled(Button)(() => {
return {
textAlign: 'center',
margin: '20px 0',
borderRadius: '8px',
backgroundColor: 'var(--affine-primary-color)',
span: {
@@ -46,11 +45,12 @@ export const StyleButton = styled(Button)(() => {
export const StyleButtonContainer = styled('div')(() => {
return {
width: '100%',
marginTop: 20,
...displayFlex('flex-end', 'center'),
};
});
export const StyleImage = styled('div')(() => {
return {
width: '100%',
...displayFlex('center', 'center'),
};
});

View File

@@ -1,58 +0,0 @@
import { Modal, ModalWrapper } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon } from '@blocksuite/icons';
import { IconButton } from '@toeverything/components/button';
import { Content, ContentTitle, Header, StyleButton, StyleTips } from './style';
export interface TransformWorkspaceToAffineModalProps {
open: boolean;
onClose: () => void;
onConform: () => void;
}
export const TransformWorkspaceToAffineModal = ({
open,
onClose,
onConform,
}: TransformWorkspaceToAffineModalProps) => {
const t = useAFFiNEI18N();
return (
<Modal
open={open}
onClose={onClose}
data-testid="enable-affine-cloud-modal"
>
<ModalWrapper width={560} height={292}>
<Header>
<IconButton onClick={onClose}>
<CloseIcon />
</IconButton>
</Header>
<Content>
<ContentTitle>{t['Enable AFFiNE Cloud']()}?</ContentTitle>
<StyleTips>{t['Enable AFFiNE Cloud Description']()}</StyleTips>
{/* <StyleTips>{t('Retain cached cloud data')}</StyleTips> */}
<div>
<StyleButton
data-testid="confirm-enable-cloud-button"
type="primary"
onClick={onConform}
>
{t['Sign in and Enable']()}
</StyleButton>
<StyleButton
shape="round"
onClick={() => {
onClose();
}}
>
{t['Not now']()}
</StyleButton>
</div>
</Content>
</ModalWrapper>
</Modal>
);
};

View File

@@ -1,41 +0,0 @@
import { styled } from '@affine/component';
import { Button } from '@toeverything/components/button';
export const Header = styled('div')({
height: '44px',
display: 'flex',
flexDirection: 'row-reverse',
paddingRight: '10px',
paddingTop: '10px',
flexShrink: 0,
});
export const Content = styled('div')({
textAlign: 'center',
});
export const ContentTitle = styled('h1')({
fontSize: '20px',
lineHeight: '28px',
fontWeight: 600,
textAlign: 'center',
});
export const StyleTips = styled('div')(() => {
return {
userSelect: 'none',
width: '400px',
margin: 'auto',
marginBottom: '32px',
marginTop: '12px',
};
});
export const StyleButton = styled(Button)(() => {
return {
width: '284px',
display: 'block',
margin: 'auto',
marginTop: '16px',
};
});

View File

@@ -225,9 +225,7 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
open={openConfirm}
title={pageMeta.title}
onConfirm={handleOnConfirm}
onCancel={() => {
setOpenConfirm(false);
}}
onOpenChange={setOpenConfirm}
/>
</FlexWrapper>
</>

View File

@@ -1,5 +1,5 @@
import { Modal, ModalWrapper } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Modal } from '@toeverything/components/modal';
import { Command } from 'cmdk';
import { startTransition, Suspense } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
@@ -75,93 +75,86 @@ export const QuickSearchModal = ({
return (
<Modal
open={open}
onClose={handleClose}
wrapperPosition={['top', 'center']}
data-testid="quickSearch"
>
<ModalWrapper
width={608}
style={{
onOpenChange={setOpen}
width={608}
contentOptions={{
['data-testid' as string]: 'quickSearch',
style: {
maxHeight: '80vh',
minHeight: '412px',
top: '80px',
overflow: 'hidden',
transform: 'translateX(-50%)',
},
}}
>
<Command
shouldFilter={false}
//Handle KeyboardEvent conflicts with blocksuite
onKeyDown={(e: React.KeyboardEvent) => {
if (
e.key === 'ArrowDown' ||
e.key === 'ArrowUp' ||
e.key === 'ArrowLeft' ||
e.key === 'ArrowRight'
) {
e.stopPropagation();
}
}}
>
{/* <NavigationPath
blockSuiteWorkspace={blockSuiteWorkspace}
onJumpToPage={() => {
setOpen(false);
}}
/> */}
<Command
shouldFilter={false}
//Handle KeyboardEvent conflicts with blocksuite
onKeyDown={(e: React.KeyboardEvent) => {
if (
e.key === 'ArrowDown' ||
e.key === 'ArrowUp' ||
e.key === 'ArrowLeft' ||
e.key === 'ArrowRight'
) {
e.stopPropagation();
}
}}
>
<StyledModalHeader>
<SearchInput
ref={inputRef}
onValueChange={value => {
setQuery(value);
}}
onKeyDown={e => {
// Avoid triggering the cmdk onSelect event when the input method is in use
if (e.nativeEvent.isComposing) {
e.stopPropagation();
return;
}
}}
placeholder={t['Quick search placeholder']()}
/>
<StyledShortcut>
{environment.isBrowser && environment.isMacOs
? '⌘ + K'
: 'Ctrl + K'}
</StyledShortcut>
</StyledModalHeader>
<StyledModalDivider />
<Command.List>
<StyledContent>
<Suspense
fallback={
<StyledNotFound>
<span>{t['com.affine.loading']()}</span>
</StyledNotFound>
}
>
<Results
<StyledModalHeader>
<SearchInput
ref={inputRef}
onValueChange={value => {
setQuery(value);
}}
onKeyDown={e => {
// Avoid triggering the cmdk onSelect event when the input method is in use
if (e.nativeEvent.isComposing) {
e.stopPropagation();
return;
}
}}
placeholder={t['Quick search placeholder']()}
/>
<StyledShortcut>
{environment.isBrowser && environment.isMacOs
? '⌘ + K'
: 'Ctrl + K'}
</StyledShortcut>
</StyledModalHeader>
<StyledModalDivider />
<Command.List>
<StyledContent>
<Suspense
fallback={
<StyledNotFound>
<span>{t['com.affine.loading']()}</span>
</StyledNotFound>
}
>
<Results
query={query}
onClose={handleClose}
workspace={workspace}
setShowCreatePage={setShowCreatePage}
/>
</Suspense>
</StyledContent>
{showCreatePage ? (
<>
<StyledModalDivider />
<StyledModalFooter>
<Footer
query={query}
onClose={handleClose}
workspace={workspace}
setShowCreatePage={setShowCreatePage}
blockSuiteWorkspace={blockSuiteWorkspace}
/>
</Suspense>
</StyledContent>
{showCreatePage ? (
<>
<StyledModalDivider />
<StyledModalFooter>
<Footer
query={query}
onClose={handleClose}
blockSuiteWorkspace={blockSuiteWorkspace}
/>
</StyledModalFooter>
</>
) : null}
</Command.List>
</Command>
</ModalWrapper>
</StyledModalFooter>
</>
) : null}
</Command.List>
</Command>
</Modal>
);
};

View File

@@ -1,9 +1,7 @@
import {
ModalCloseButton,
MuiClickAwayListener,
MuiSlide,
} from '@affine/component';
import { MuiClickAwayListener, MuiSlide } from '@affine/component';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { CloseIcon } from '@blocksuite/icons';
import { IconButton } from '@toeverything/components/button';
import {
type ShortcutsInfo,
@@ -14,13 +12,7 @@ import {
} from '../../../hooks/affine/use-shortcuts';
import { KeyboardIcon } from './icons';
import * as styles from './style.css';
// import {
// StyledListItem,
// StyledModalHeader,
// StyledShortcutsModal,
// StyledSubTitle,
// StyledTitle,
// } from './style';
type ModalProps = {
open: boolean;
onClose: () => void;
@@ -81,12 +73,16 @@ export const ShortcutsModal = ({ open, onClose }: ModalProps) => {
{t['Shortcuts']()}
</div>
<ModalCloseButton
top={6}
right={6}
<IconButton
style={{
position: 'absolute',
right: 6,
top: 6,
}}
onClick={() => {
onClose();
}}
icon={<CloseIcon />}
/>
</div>
<ShortcutsPanel shortcutsInfo={generalShortcutsInfo} />

View File

@@ -1,8 +1,8 @@
import { Confirm } from '@affine/component';
import { WorkspaceSubPath } from '@affine/env/workspace';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { assertExists } from '@blocksuite/global/utils';
import { Button } from '@toeverything/components/button';
import { ConfirmModal } from '@toeverything/components/modal';
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
import { currentPageIdAtom } from '@toeverything/infra/atom';
import { useAtomValue } from 'jotai';
@@ -61,23 +61,21 @@ export const TrashButtonGroup = () => {
{t['com.affine.trashOperation.deletePermanently']()}
</Button>
</div>
<Confirm
<ConfirmModal
title={t['com.affine.trashOperation.delete.title']()}
content={t['com.affine.trashOperation.delete.description']()}
confirmText={t['com.affine.trashOperation.delete']()}
confirmType="error"
cancelText={t['com.affine.confirmModal.button.cancel']()}
description={t['com.affine.trashOperation.delete.description']()}
confirmButtonOptions={{
type: 'error',
children: t['com.affine.trashOperation.delete'](),
}}
open={open}
onConfirm={useCallback(() => {
jumpToSubPath(workspace.id, WorkspaceSubPath.ALL);
blockSuiteWorkspace.removePage(pageId);
toast(t['com.affine.toastMessage.permanentlyDeleted']());
}, [blockSuiteWorkspace, jumpToSubPath, pageId, workspace.id, t])}
onCancel={() => {
setOpen(false);
}}
onClose={() => {
setOpen(false);
}}
onOpenChange={setOpen}
/>
</div>
);

View File

@@ -177,6 +177,7 @@ export const WorkspaceListModal = ({
const localWorkspaces = workspaces.filter(
({ flavour }) => flavour === WorkspaceFlavour.LOCAL
) as (AffineCloudWorkspace | LocalWorkspace)[];
// FIXME: replace mui popover
return (
<Popover
sx={{
@@ -209,6 +210,7 @@ export const WorkspaceListModal = ({
openModal: true,
}));
}
onClose();
}}
data-testid="cloud-signin-button"
>

View File

@@ -1,5 +1,5 @@
import {
EditCollectionModel,
EditCollectionModal,
useCollectionManager,
} from '@affine/component/page-list';
import type { Collection } from '@affine/env/filter';
@@ -46,12 +46,12 @@ export const AddCollectionButton = ({
<PlusIcon />
</IconButton>
<EditCollectionModel
<EditCollectionModal
propertiesMeta={workspace.meta.properties}
getPageInfo={getPageInfo}
onConfirm={setting.saveCollection}
open={show}
onClose={() => showUpdateCollection(false)}
onOpenChange={showUpdateCollection}
title={t['com.affine.editCollection.saveCollection']()}
init={defaultCollection}
/>

View File

@@ -1,6 +1,6 @@
import { MenuItem as CollectionItem } from '@affine/component/app-sidebar';
import {
EditCollectionModel,
EditCollectionModal,
useCollectionManager,
useSavedCollections,
} from '@affine/component/page-list';
@@ -203,13 +203,13 @@ const CollectionRenderer = ({
return (
<Collapsible.Root open={!collapsed}>
<EditCollectionModel
<EditCollectionModal
propertiesMeta={workspace.meta.properties}
getPageInfo={getPageInfo}
init={collection}
onConfirm={setting.saveCollection}
open={show}
onClose={() => showUpdateCollection(false)}
onOpenChange={showUpdateCollection}
/>
<CollectionItem
data-testid="collection-item"

View File

@@ -53,14 +53,14 @@ export type RootAppSidebarProps = {
};
const RouteMenuLinkItem = React.forwardRef<
HTMLButtonElement,
HTMLDivElement,
{
currentPath: string; // todo: pass through useRouter?
path: string;
icon: ReactElement;
children?: ReactElement;
isDraggedOver?: boolean;
} & React.HTMLAttributes<HTMLButtonElement>
} & React.HTMLAttributes<HTMLDivElement>
>(({ currentPath, path, icon, children, isDraggedOver, ...props }, ref) => {
// Force active style when a page is dragged over
const active = isDraggedOver || currentPath === path;