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
+1 -1
View File
@@ -39,7 +39,7 @@
"@mui/material": "^5.14.7",
"@radix-ui/react-select": "^1.2.2",
"@react-hookz/web": "^23.1.0",
"@toeverything/components": "^0.0.34",
"@toeverything/components": "^0.0.38",
"async-call-rpc": "^6.3.1",
"cmdk": "^0.2.0",
"css-spring": "^4.1.0",
@@ -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>
);
};
@@ -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}
/>
);
};
@@ -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',
};
});
@@ -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>
);
};
@@ -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',
// };
// });
@@ -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'](),
}}
/>
)}
</>
@@ -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} />
)}
</>
);
@@ -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} />
);
});
@@ -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>
);
};
@@ -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,
@@ -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>
);
};
@@ -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'),
};
});
@@ -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>
);
};
@@ -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',
};
});
@@ -225,9 +225,7 @@ export const PageMenu = ({ rename, pageId }: PageMenuProps) => {
open={openConfirm}
title={pageMeta.title}
onConfirm={handleOnConfirm}
onCancel={() => {
setOpenConfirm(false);
}}
onOpenChange={setOpenConfirm}
/>
</FlexWrapper>
</>
@@ -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>
);
};
@@ -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} />
@@ -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>
);
@@ -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"
>
@@ -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}
/>
@@ -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"
@@ -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;
+3 -5
View File
@@ -86,8 +86,8 @@ export const Setting = () => {
activeTab={activeTab}
workspaceId={workspaceId}
onSettingClick={onSettingClick}
setOpen={useCallback(
open => {
onOpenChange={useCallback(
(open: boolean) => {
setOpenSettingModalAtom(prev => ({ ...prev, open }));
},
[setOpenSettingModalAtom]
@@ -147,9 +147,7 @@ export function CurrentWorkspaceModals() {
<Suspense>
<TmpDisableAffineCloudModal
open={openDisableCloudAlertModal}
onClose={useCallback(() => {
setOpenDisableCloudAlertModal(false);
}, [setOpenDisableCloudAlertModal])}
onOpenChange={setOpenDisableCloudAlertModal}
/>
</Suspense>
{environment.isDesktop && (
@@ -11,7 +11,7 @@ export default {
} satisfies Meta;
export const Basic: StoryFn = () => {
return <TourModal open={true} onClose={() => {}} />;
return <TourModal open={true} />;
};
Basic.args = {
logoSrc: '/imgs/affine-text-logo.png',
@@ -136,11 +136,11 @@ export const DisableModal: StoryFn = () => {
</StyledDisableButton>
<PublicLinkDisableModal
open={open}
onConfirmDisable={() => {
onConfirm={() => {
toast('Disabled');
setOpen(false);
}}
onClose={() => setOpen(false)}
onOpenChange={setOpen}
/>
</>
);
@@ -6,7 +6,7 @@ import { Link } from 'react-router-dom';
import * as styles from './index.css';
export interface MenuItemProps extends React.HTMLAttributes<HTMLButtonElement> {
export interface MenuItemProps extends React.HTMLAttributes<HTMLDivElement> {
icon?: React.ReactElement;
active?: boolean;
disabled?: boolean;
@@ -25,7 +25,7 @@ const stopPropagation: React.MouseEventHandler = e => {
e.stopPropagation();
};
export const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(
export const MenuItem = React.forwardRef<HTMLDivElement, MenuItemProps>(
(
{
onClick,
@@ -42,7 +42,7 @@ export const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(
) => {
const collapsible = onCollapsedChange !== undefined;
return (
<button
<div
ref={ref}
{...props}
onClick={onClick}
@@ -82,22 +82,21 @@ export const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(
{postfix}
</div>
) : null}
</button>
</div>
);
}
);
MenuItem.displayName = 'MenuItem';
export const MenuLinkItem = React.forwardRef<
HTMLButtonElement,
MenuLinkItemProps
>(({ to, ...props }, ref) => {
return (
<Link to={to} className={styles.linkItemRoot}>
{/* The <a> element rendered by Link does not generate display box due to `display: contents` style */}
{/* Thus ref is passed to MenuItem instead of Link */}
<MenuItem ref={ref} {...props}></MenuItem>
</Link>
);
});
export const MenuLinkItem = React.forwardRef<HTMLDivElement, MenuLinkItemProps>(
({ to, ...props }, ref) => {
return (
<Link to={to} className={styles.linkItemRoot}>
{/* The <a> element rendered by Link does not generate display box due to `display: contents` style */}
{/* Thus ref is passed to MenuItem instead of Link */}
<MenuItem ref={ref} {...props}></MenuItem>
</Link>
);
}
);
MenuLinkItem.displayName = 'MenuLinkItem';
@@ -1,5 +1,5 @@
import clsx from 'clsx';
import type { FC } from 'react';
import type { FC, HTMLAttributes } from 'react';
import { Input, type InputProps } from '../../ui/input';
import { authInputWrapper, formHint } from './share.css';
@@ -9,6 +9,7 @@ export type AuthInputProps = InputProps & {
errorHint?: string;
withoutHint?: boolean;
onEnter?: () => void;
wrapperProps?: HTMLAttributes<HTMLDivElement>;
};
export const AuthInput: FC<AuthInputProps> = ({
label,
@@ -16,13 +17,15 @@ export const AuthInput: FC<AuthInputProps> = ({
errorHint,
withoutHint = false,
onEnter,
wrapperProps: { className, ...otherWrapperProps } = {},
...inputProps
}) => {
return (
<div
className={clsx(authInputWrapper, {
className={clsx(authInputWrapper, className, {
'without-hint': withoutHint,
})}
{...otherWrapperProps}
>
{label ? <label>{label}</label> : null}
<Input
@@ -1,6 +1,5 @@
import { Modal, ModalCloseButton, ModalWrapper } from '@affine/component';
import { Modal } from '@toeverything/components/modal';
import type { FC, PropsWithChildren } from 'react';
import { useCallback } from 'react';
export type AuthModalProps = {
open: boolean;
@@ -12,32 +11,18 @@ export const AuthModal: FC<PropsWithChildren<AuthModalProps>> = ({
open,
setOpen,
}) => {
const handleClose = useCallback(() => {
setOpen(false);
}, [setOpen]);
return (
<Modal
open={open}
onClose={handleClose}
wrapperPosition={['center', 'center']}
data-testid="auth-modal"
onOpenChange={setOpen}
width={400}
height={468}
contentOptions={{
['data-testid' as string]: 'auth-modal',
style: { padding: '44px 40px 0' },
}}
>
<ModalWrapper
width={1080}
height={760}
style={{
height: '468px',
width: '400px',
overflow: 'hidden',
backgroundColor: 'var(--affine-white)',
boxShadow: 'var(--affine-popover-shadow)',
padding: '44px 40px 0',
}}
>
<ModalCloseButton top={20} right={20} onClick={handleClose} />
{children}
</ModalWrapper>
{children}
</Modal>
);
};
@@ -1,13 +1,14 @@
import {
CloseIcon,
ExportToHtmlIcon,
ExportToMarkdownIcon,
HelpIcon,
NewIcon,
NotionIcon,
} from '@blocksuite/icons';
import { IconButton } from '@toeverything/components/button';
import { Tooltip } from '@toeverything/components/tooltip';
import { ModalCloseButton } from '../../ui/modal';
import { BlockCard } from '../card/block-card';
import {
importPageBodyStyle,
@@ -27,7 +28,17 @@ export const ImportPage = ({
onClose: () => void;
}) => (
<div className={importPageContainerStyle}>
<ModalCloseButton top={6} right={6} onClick={onClose} />
<IconButton
style={{
position: 'absolute',
right: 6,
top: 6,
}}
onClick={() => {
onClose();
}}
icon={<CloseIcon />}
/>
<div className={importPageBodyStyle}>
<div className="title">Import</div>
<span>
@@ -1,12 +1,10 @@
import { Permission } from '@affine/graphql';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Button } from '@toeverything/components/button';
import { ConfirmModal } from '@toeverything/components/modal';
import { useCallback, useEffect, useState } from 'react';
import { Modal, ModalCloseButton, ModalWrapper } from '../../ui/modal';
import { AuthInput } from '..//auth-components';
import { emailRegex } from '..//auth-components/utils';
import * as styles from './styles.css';
export interface InviteModalProps {
open: boolean;
@@ -26,10 +24,6 @@ export const InviteModal = ({
const [permission] = useState(Permission.Write);
const [isValidEmail, setIsValidEmail] = useState(true);
const handleCancel = useCallback(() => {
setOpen(false);
}, [setOpen]);
const handleConfirm = useCallback(() => {
if (!emailRegex.test(inviteEmail)) {
setIsValidEmail(false);
@@ -51,47 +45,41 @@ export const InviteModal = ({
}, [open]);
return (
<Modal
wrapperPosition={['center', 'center']}
data-testid="invite-modal"
<ConfirmModal
open={open}
>
<ModalWrapper
width={480}
height={254}
style={{
onOpenChange={setOpen}
width={480}
title={t['Invite Members']()}
description={t['Invite Members Message']()}
cancelText={t['com.affine.inviteModal.button.cancel']()}
contentOptions={{
['data-testid' as string]: 'invite-modal',
style: {
padding: '20px 26px',
},
}}
confirmButtonOptions={{
loading: isMutating,
type: 'primary',
['data-testid' as string]: 'confirm-enable-affine-cloud-button',
children: t['Invite'](),
}}
onConfirm={handleConfirm}
>
{/*TODO: check email & add placeholder*/}
<AuthInput
disabled={isMutating}
placeholder="email@example.com"
value={inviteEmail}
onChange={setInviteEmail}
error={!isValidEmail}
errorHint={isValidEmail ? '' : t['com.affine.auth.sign.email.error']()}
onEnter={handleConfirm}
wrapperProps={{
style: { padding: 0 },
}}
>
<ModalCloseButton top={20} right={20} onClick={handleCancel} />
<div className={styles.inviteModalTitle}>{t['Invite Members']()}</div>
<div className={styles.inviteModalContent}>
{t['Invite Members Message']()}
{/*TODO: check email & add placeholder*/}
<AuthInput
disabled={isMutating}
placeholder="email@example.com"
value={inviteEmail}
onChange={setInviteEmail}
error={!isValidEmail}
errorHint={
isValidEmail ? '' : t['com.affine.auth.sign.email.error']()
}
onEnter={handleConfirm}
style={{ marginTop: 20 }}
size="large"
/>
</div>
<div className={styles.inviteModalButtonContainer}>
<Button style={{ marginRight: 20 }} onClick={handleCancel}>
{t['com.affine.inviteModal.button.cancel']()}
</Button>
<Button type="primary" onClick={handleConfirm} loading={isMutating}>
{t['Invite']()}
</Button>
</div>
</ModalWrapper>
</Modal>
size="large"
/>
</ConfirmModal>
);
};
@@ -10,10 +10,11 @@ import {
} from '@blocksuite/icons';
import { IconButton } from '@toeverything/components/button';
import { Menu, MenuIcon, MenuItem } from '@toeverything/components/menu';
import { ConfirmModal } from '@toeverything/components/modal';
import { Tooltip } from '@toeverything/components/tooltip';
import { useState } from 'react';
import { Confirm, FlexWrapper } from '../../..';
import { FlexWrapper } from '../../..';
import { DisablePublicSharing, MoveToTrash } from './operation-menu-items';
export interface OperationCellProps {
@@ -106,19 +107,12 @@ export const OperationCell = ({
onRemoveToTrash();
setOpen(false);
}}
onClose={() => {
setOpen(false);
}}
onCancel={() => {
setOpen(false);
}}
onOpenChange={setOpen}
/>
<DisablePublicSharing.DisablePublicSharingModal
onConfirmDisable={onDisablePublicSharing}
onConfirm={onDisablePublicSharing}
open={openDisableShared}
onClose={() => {
setOpenDisableShared(false);
}}
onOpenChange={setOpenDisableShared}
/>
</>
);
@@ -161,22 +155,20 @@ export const TrashOperationCell = ({
<DeletePermanentlyIcon />
</IconButton>
</Tooltip>
<Confirm
<ConfirmModal
title={`${t['com.affine.trashOperation.deletePermanently']()}?`}
content={t['com.affine.trashOperation.deleteDescription']()}
confirmText={t['com.affine.trashOperation.delete']()}
confirmType="error"
description={t['com.affine.trashOperation.deleteDescription']()}
cancelText={t['com.affine.confirmModal.button.cancel']()}
confirmButtonOptions={{
type: 'error',
children: t['com.affine.trashOperation.delete'](),
}}
open={open}
onOpenChange={setOpen}
onConfirm={() => {
onPermanentlyDeletePage();
setOpen(false);
}}
onClose={() => {
setOpen(false);
}}
onCancel={() => {
setOpen(false);
}}
/>
</FlexWrapper>
);
@@ -5,9 +5,10 @@ import {
MenuItem,
type MenuItemProps,
} from '@toeverything/components/menu';
import type { ConfirmProps } from '../../..';
import { Confirm } from '../../..';
import {
ConfirmModal,
type ConfirmModalProps,
} from '@toeverything/components/modal';
export const MoveToTrash = (props: MenuItemProps) => {
const t = useAFFiNEI18N();
@@ -27,26 +28,29 @@ export const MoveToTrash = (props: MenuItemProps) => {
);
};
const ConfirmModal = ({
const MoveToTrashConfirm = ({
title,
...confirmModalProps
}: {
title: string;
} & ConfirmProps) => {
} & ConfirmModalProps) => {
const t = useAFFiNEI18N();
return (
<Confirm
<ConfirmModal
title={t['com.affine.moveToTrash.confirmModal.title']()}
content={t['com.affine.moveToTrash.confirmModal.description']({
description={t['com.affine.moveToTrash.confirmModal.description']({
title: title || 'Untitled',
})}
confirmButtonTestId="confirm-delete-page"
confirmText={t.Delete()}
confirmType="error"
cancelText={t['com.affine.confirmModal.button.cancel']()}
confirmButtonOptions={{
['data-testid' as string]: 'confirm-delete-page',
type: 'error',
children: t.Delete(),
}}
{...confirmModalProps}
/>
);
};
MoveToTrash.ConfirmModal = ConfirmModal;
MoveToTrash.ConfirmModal = MoveToTrashConfirm;
@@ -5,14 +5,14 @@ import { ViewLayersIcon } from '@blocksuite/icons';
import { Button } from '@toeverything/components/button';
import { Tooltip } from '@toeverything/components/tooltip';
import clsx from 'clsx';
import { useCallback, useState } from 'react';
import { useState } from 'react';
import {
type CollectionsAtom,
useCollectionManager,
} from '../use-collection-manager';
import * as styles from './collection-bar.css';
import { EditCollectionModel } from './create-collection';
import { EditCollectionModal } from './create-collection';
import { useActions } from './use-action';
interface CollectionBarProps {
@@ -33,21 +33,20 @@ export const CollectionBar = (props: CollectionBarProps) => {
setting,
openEdit: () => setOpen(true),
});
const onClose = useCallback(() => setOpen(false), []);
return !setting.isDefault ? (
<tr style={{ userSelect: 'none' }}>
<td>
<div className={styles.view}>
<EditCollectionModel
<EditCollectionModal
propertiesMeta={propertiesMeta}
getPageInfo={getPageInfo}
init={collection}
open={open}
onClose={onClose}
onOpenChange={setOpen}
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onConfirm={setting.updateCollection}
></EditCollectionModel>
/>
<ViewLayersIcon
style={{
height: 20,
@@ -14,7 +14,7 @@ import { useCallback, useRef, useState } from 'react';
import { CreateFilterMenu } from '../filter/vars';
import type { useCollectionManager } from '../use-collection-manager';
import * as styles from './collection-list.css';
import { EditCollectionModel } from './create-collection';
import { EditCollectionModal } from './create-collection';
import { useActions } from './use-action';
const CollectionOption = ({
@@ -126,14 +126,16 @@ export const CollectionList = ({
},
[setting]
);
const closeUpdateCollectionModal = useCallback(
() => setCollection(undefined),
[]
);
const closeUpdateCollectionModal = useCallback((open: boolean) => {
if (!open) {
setCollection(undefined);
}
}, []);
const onConfirm = useCallback(
async (view: Collection) => {
await setting.updateCollection(view);
closeUpdateCollectionModal();
closeUpdateCollectionModal(false);
},
[closeUpdateCollectionModal, setting]
);
@@ -214,14 +216,14 @@ export const CollectionList = ({
{t['com.affine.filter']()}
</Button>
</Menu>
<EditCollectionModel
<EditCollectionModal
propertiesMeta={propertiesMeta}
getPageInfo={getPageInfo}
init={collection}
open={!!collection}
onClose={closeUpdateCollectionModal}
onOpenChange={closeUpdateCollectionModal}
onConfirm={onConfirm}
></EditCollectionModel>
/>
</FlexWrapper>
);
};
@@ -10,72 +10,69 @@ import {
} from '@blocksuite/icons';
import { uuidv4 } from '@blocksuite/store';
import { Button } from '@toeverything/components/button';
import { Modal } from '@toeverything/components/modal';
import { useCallback, useMemo, useState } from 'react';
import {
Input,
Modal,
ModalCloseButton,
ModalWrapper,
ScrollableContainer,
} from '../../..';
import { Input, ScrollableContainer } from '../../..';
import { FilterList } from '../filter';
import * as styles from './collection-list.css';
interface EditCollectionModelProps {
interface EditCollectionModalProps {
init?: Collection;
title?: string;
open: boolean;
getPageInfo: GetPageInfoById;
propertiesMeta: PropertiesMeta;
onClose: () => void;
onOpenChange: (open: boolean) => void;
onConfirm: (view: Collection) => Promise<void>;
}
export const EditCollectionModel = ({
export const EditCollectionModal = ({
init,
onConfirm,
open,
onClose,
onOpenChange,
getPageInfo,
propertiesMeta,
title,
}: EditCollectionModelProps) => {
}: EditCollectionModalProps) => {
const t = useAFFiNEI18N();
const onConfirmOnCollection = useCallback(
(view: Collection) => {
onConfirm(view)
.then(() => {
onClose();
onOpenChange(false);
})
.catch(err => {
console.error(err);
});
},
[onClose, onConfirm]
[onConfirm, onOpenChange]
);
const onCancel = useCallback(() => {
onOpenChange(false);
}, [onOpenChange]);
return (
<Modal open={open} onClose={onClose}>
<ModalWrapper
width={600}
style={{
padding: '40px',
background: 'var(--affine-background-primary-color)',
}}
>
<ModalCloseButton top={12} right={12} onClick={onClose} />
{init ? (
<EditCollection
propertiesMeta={propertiesMeta}
title={title}
onConfirmText={t['com.affine.editCollection.save']()}
init={init}
getPageInfo={getPageInfo}
onCancel={onClose}
onConfirm={onConfirmOnCollection}
/>
) : null}
</ModalWrapper>
<Modal
open={open}
onOpenChange={onOpenChange}
width={600}
contentOptions={{
style: { padding: '40px' },
}}
>
{init ? (
<EditCollection
propertiesMeta={propertiesMeta}
title={title}
onConfirmText={t['com.affine.editCollection.save']()}
init={init}
getPageInfo={getPageInfo}
onCancel={onCancel}
onConfirm={onConfirmOnCollection}
/>
) : null}
</Modal>
);
};
@@ -301,14 +298,14 @@ export const SaveCollectionButton = ({
>
{t['com.affine.editCollection.saveCollection']()}
</Button>
<EditCollectionModel
<EditCollectionModal
title={t['com.affine.editCollection.saveCollection']()}
propertiesMeta={propertiesMeta}
init={init}
onConfirm={onConfirm}
open={show}
getPageInfo={getPageInfo}
onClose={() => changeShow(false)}
onOpenChange={changeShow}
/>
</>
);
@@ -1,4 +1,3 @@
export { SettingModal, type SettingModalProps } from './modal';
export { SettingHeader } from './setting-header';
export { SettingRow } from './setting-row';
export * from './storage-progess';
@@ -1,43 +0,0 @@
import { Modal, ModalCloseButton, ModalWrapper } from '@affine/component';
import type { PropsWithChildren } from 'react';
import { useCallback } from 'react';
export interface SettingModalProps {
open: boolean;
setOpen: (value: boolean) => void;
}
export const SettingModal = ({
children,
open,
setOpen,
}: PropsWithChildren<SettingModalProps>) => {
const handleClose = useCallback(() => {
setOpen(false);
}, [setOpen]);
return (
<Modal
open={open}
onClose={handleClose}
wrapperPosition={['center', 'center']}
data-testid="setting-modal"
>
<ModalWrapper
width={1080}
height={760}
style={{
maxHeight: '85vh',
maxWidth: '70vw',
overflow: 'hidden',
display: 'flex',
backgroundColor: 'var(--affine-background-overlay-panel-color)',
boxShadow: 'var(--affine-popover-shadow)',
}}
>
<ModalCloseButton top={16} right={20} onClick={handleClose} />
{children}
</ModalWrapper>
</Modal>
);
};
@@ -1,57 +1,24 @@
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 { Modal, ModalWrapper } from '../../..';
import { ButtonContainer, Content, Header, StyleTips, Title } from './style';
export type PublicLinkDisableProps = {
open: boolean;
onConfirmDisable: () => void;
onClose: () => void;
};
export const PublicLinkDisableModal = ({
open,
onConfirmDisable,
onClose,
}: PublicLinkDisableProps) => {
export const PublicLinkDisableModal = (props: ConfirmModalProps) => {
const t = useAFFiNEI18N();
return (
<Modal open={open} onClose={onClose}>
<ModalWrapper width={480}>
<Header>
<Title>{t['com.affine.publicLinkDisableModal.title']()}</Title>
<IconButton onClick={onClose}>
<CloseIcon />
</IconButton>
</Header>
<Content>
<StyleTips>
{t['com.affine.publicLinkDisableModal.description']()}
</StyleTips>
<ButtonContainer>
<div>
<Button onClick={onClose} block>
{t['com.affine.publicLinkDisableModal.button.cancel']()}
</Button>
</div>
<div>
<Button
data-testid="confirm-enable-affine-cloud-button"
type="error"
block
onClick={() => {
onConfirmDisable();
onClose();
}}
>
{t['com.affine.publicLinkDisableModal.button.disable']()}
</Button>
</div>
</ButtonContainer>
</Content>
</ModalWrapper>
</Modal>
<ConfirmModal
width={480}
title={t['com.affine.publicLinkDisableModal.title']()}
description={t['com.affine.publicLinkDisableModal.description']()}
cancelText={t['com.affine.publicLinkDisableModal.button.cancel']()}
confirmButtonOptions={{
type: 'error',
['data-testid' as string]: 'confirm-enable-affine-cloud-button',
children: t['com.affine.publicLinkDisableModal.button.disable'](),
}}
{...props}
/>
);
};
@@ -1,35 +0,0 @@
import { styled } from '../../..';
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',
};
});
@@ -208,7 +208,10 @@ export const AffineSharePage = (props: ShareMenuProps) => {
block
type="danger"
className={styles.menuItemStyle}
onClick={() => setShowDisable(true)}
onSelect={e => {
e.preventDefault();
setShowDisable(true);
}}
>
<div className={styles.disableSharePage}>
{t['Disable Public Link']()}
@@ -216,10 +219,8 @@ export const AffineSharePage = (props: ShareMenuProps) => {
</MenuItem>
<PublicLinkDisableModal
open={showDisable}
onConfirmDisable={onDisablePublic}
onClose={() => {
setShowDisable(false);
}}
onConfirm={onDisablePublic}
onOpenChange={setShowDisable}
/>
</>
) : null}
@@ -231,7 +232,11 @@ export const SharePage = (props: ShareMenuProps) => {
if (props.workspace.flavour === WorkspaceFlavour.LOCAL) {
return <LocalSharePage {...props} />;
} else if (props.workspace.flavour === WorkspaceFlavour.AFFINE_CLOUD) {
return <AffineSharePage {...props} />;
return (
<>
<AffineSharePage {...props} />
</>
);
}
throw new Error('Unreachable');
};
@@ -5,7 +5,6 @@ export const modalStyle = style({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
position: 'relative',
backgroundColor: 'var(--affine-background-secondary-color)',
borderRadius: '16px',
overflow: 'hidden',
@@ -1,9 +1,9 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { ArrowLeftSmallIcon, ArrowRightSmallIcon } from '@blocksuite/icons';
import { Modal, type ModalProps } from '@toeverything/components/modal';
import clsx from 'clsx';
import { useState } from 'react';
import { Modal, ModalCloseButton, ModalWrapper } from '../..';
import {
arrowStyle,
buttonDisableStyle,
@@ -25,140 +25,133 @@ import {
videoStyle,
} from './index.css';
export interface TourModalProps {
open: boolean;
onClose: () => void;
}
export const TourModal = ({ open, onClose }: TourModalProps) => {
export const TourModal = (props: ModalProps) => {
const t = useAFFiNEI18N();
const [step, setStep] = useState(-1);
const handleClose = () => {
setStep(-1);
onClose();
};
return (
<Modal
open={open}
onClose={handleClose}
wrapperPosition={['center', 'center']}
hideBackdrop
width={545}
contentOptions={{
['data-testid' as string]: 'onboarding-modal',
style: {
minHeight: '480px',
padding: 0,
},
}}
overlayOptions={{
style: {
background: 'transparent',
},
}}
closeButtonOptions={{
// @ts-expect-error - fix upstream type
'data-testid': 'onboarding-modal-close-button',
}}
{...props}
>
<ModalWrapper
width={545}
style={{ minHeight: '480px' }}
data-testid="onboarding-modal"
>
<ModalCloseButton
top={6}
right={10}
onClick={handleClose}
data-testid="onboarding-modal-close-button"
/>
<div className={modalStyle}>
<div className={titleContainerStyle}>
{step !== -1 && (
<div
className={clsx(titleStyle, {
[slideToRightStyle]: step === 0,
[formSlideToLeftStyle]: step === 1,
})}
>
{t['com.affine.onboarding.title2']()}
</div>
)}
<div className={modalStyle}>
<div className={titleContainerStyle}>
{step !== -1 && (
<div
className={clsx(titleStyle, {
[slideToLeftStyle]: step === 1,
[formSlideToRightStyle]: step === 0,
[slideToRightStyle]: step === 0,
[formSlideToLeftStyle]: step === 1,
})}
>
{t['com.affine.onboarding.title1']()}
{t['com.affine.onboarding.title2']()}
</div>
)}
<div
className={clsx(titleStyle, {
[slideToLeftStyle]: step === 1,
[formSlideToRightStyle]: step === 0,
})}
>
{t['com.affine.onboarding.title1']()}
</div>
</div>
<div className={containerStyle}>
<div
className={clsx(arrowStyle, { [buttonDisableStyle]: step !== 1 })}
onClick={() => step === 1 && setStep(0)}
data-testid="onboarding-modal-pre-button"
>
<ArrowLeftSmallIcon />
</div>
<div className={videoContainerStyle}>
<div className={videoSlideStyle}>
{step !== -1 && (
<video
autoPlay
muted
loop
className={clsx(videoStyle, {
[slideToRightStyle]: step === 0,
[formSlideToLeftStyle]: step === 1,
})}
data-testid="onboarding-modal-editing-video"
>
<source src="/editingVideo.mp4" type="video/mp4" />
<source src="/editingVideo.webm" type="video/webm" />
</video>
)}
<div className={containerStyle}>
<div
className={clsx(arrowStyle, { [buttonDisableStyle]: step !== 1 })}
onClick={() => step === 1 && setStep(0)}
data-testid="onboarding-modal-pre-button"
>
<ArrowLeftSmallIcon />
</div>
<div className={videoContainerStyle}>
<div className={videoSlideStyle}>
{step !== -1 && (
<video
autoPlay
muted
loop
className={clsx(videoStyle, {
[slideToLeftStyle]: step === 1,
[formSlideToRightStyle]: step === 0,
[slideToRightStyle]: step === 0,
[formSlideToLeftStyle]: step === 1,
})}
data-testid="onboarding-modal-switch-video"
data-testid="onboarding-modal-editing-video"
>
<source src="/switchVideo.mp4" type="video/mp4" />
<source src="/switchVideo.webm" type="video/webm" />
<source src="/editingVideo.mp4" type="video/mp4" />
<source src="/editingVideo.webm" type="video/webm" />
</video>
</div>
</div>
<div
className={clsx(arrowStyle, { [buttonDisableStyle]: step === 1 })}
onClick={() => setStep(1)}
data-testid="onboarding-modal-next-button"
>
<ArrowRightSmallIcon />
)}
<video
autoPlay
muted
loop
className={clsx(videoStyle, {
[slideToLeftStyle]: step === 1,
[formSlideToRightStyle]: step === 0,
})}
data-testid="onboarding-modal-switch-video"
>
<source src="/switchVideo.mp4" type="video/mp4" />
<source src="/switchVideo.webm" type="video/webm" />
</video>
</div>
</div>
<ul className={tabContainerStyle}>
<li
className={clsx(tabStyle, {
[tabActiveStyle]: step !== 1,
})}
onClick={() => setStep(0)}
></li>
<li
className={clsx(tabStyle, { [tabActiveStyle]: step === 1 })}
onClick={() => setStep(1)}
></li>
</ul>
<div className={descriptionContainerStyle}>
{step !== -1 && (
<div
className={clsx(descriptionStyle, {
[slideToRightStyle]: step === 0,
[formSlideToLeftStyle]: step === 1,
})}
>
{t['com.affine.onboarding.videoDescription2']()}
</div>
)}
<div
className={clsx(descriptionStyle, {
[slideToLeftStyle]: step === 1,
[formSlideToRightStyle]: step === 0,
})}
>
{t['com.affine.onboarding.videoDescription1']()}
</div>
<div
className={clsx(arrowStyle, { [buttonDisableStyle]: step === 1 })}
onClick={() => setStep(1)}
data-testid="onboarding-modal-next-button"
>
<ArrowRightSmallIcon />
</div>
</div>
</ModalWrapper>
<ul className={tabContainerStyle}>
<li
className={clsx(tabStyle, {
[tabActiveStyle]: step !== 1,
})}
onClick={() => setStep(0)}
></li>
<li
className={clsx(tabStyle, { [tabActiveStyle]: step === 1 })}
onClick={() => setStep(1)}
></li>
</ul>
<div className={descriptionContainerStyle}>
{step !== -1 && (
<div
className={clsx(descriptionStyle, {
[slideToRightStyle]: step === 0,
[formSlideToLeftStyle]: step === 1,
})}
>
{t['com.affine.onboarding.videoDescription2']()}
</div>
)}
<div
className={clsx(descriptionStyle, {
[slideToLeftStyle]: step === 1,
[formSlideToRightStyle]: step === 0,
})}
>
{t['com.affine.onboarding.videoDescription1']()}
</div>
</div>
</div>
</Modal>
);
};
-2
View File
@@ -2,12 +2,10 @@ export * from './components/list-skeleton';
export * from './styles';
export * from './ui/breadcrumbs';
export * from './ui/button';
export * from './ui/confirm';
export * from './ui/empty';
export * from './ui/input';
export * from './ui/layout';
export * from './ui/menu';
export * from './ui/modal';
export * from './ui/mui';
export * from './ui/popper';
export * from './ui/scrollbar';
@@ -1,110 +0,0 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Button } from '@toeverything/components/button';
import { useCallback, useMemo } from 'react';
import type { ModalProps } from '../modal';
import { Modal, ModalCloseButton } from '../modal';
import {
StyledColumnButtonWrapper,
StyledConfirmContent,
StyledConfirmTitle,
StyledModalWrapper,
StyledRowButtonWrapper,
} from './styles';
export type ConfirmProps = {
title?: string;
content?: string;
confirmText?: string;
cancelText?: string;
// TODO: Confirm button's color should depend on confirm type
confirmType?: 'primary' | 'warning' | 'error';
buttonDirection?: 'row' | 'column';
onConfirm?: () => void;
onCancel?: () => void;
cancelButtonTestId?: string;
confirmButtonTestId?: string;
} & Omit<ModalProps, 'children'>;
export const Confirm = ({
title,
content,
confirmText,
confirmType,
onConfirm,
onCancel,
buttonDirection = 'row',
cancelText = 'Cancel',
open,
cancelButtonTestId = '',
confirmButtonTestId = '',
}: ConfirmProps) => {
const t = useAFFiNEI18N();
const cancelText_ = useMemo<string>(() => {
return cancelText === 'Cancel'
? t['com.affine.confirmModal.button.cancel']()
: cancelText;
}, [cancelText, t]);
const handleCancel = useCallback(() => {
onCancel?.();
}, [onCancel]);
const handleConfirm = useCallback(() => {
onConfirm?.();
}, [onConfirm]);
return (
<Modal open={open} disablePortal={false}>
<StyledModalWrapper>
<ModalCloseButton onClick={handleCancel} />
<StyledConfirmTitle>{title}</StyledConfirmTitle>
<StyledConfirmContent>{content}</StyledConfirmContent>
{buttonDirection === 'row' ? (
<StyledRowButtonWrapper>
<Button
onClick={handleCancel}
size="large"
style={{ marginRight: '24px' }}
data-testid={cancelButtonTestId}
>
{cancelText_}
</Button>
<Button
type={confirmType}
onClick={handleConfirm}
size="large"
data-testid={confirmButtonTestId}
>
{confirmText}
</Button>
</StyledRowButtonWrapper>
) : (
<StyledColumnButtonWrapper>
<Button
type={confirmType}
onClick={handleConfirm}
style={{ width: '284px', height: '38px', textAlign: 'center' }}
data-testid={confirmButtonTestId}
>
{confirmText}
</Button>
<Button
onClick={handleCancel}
style={{
marginTop: '16px',
width: '284px',
height: '38px',
textAlign: 'center',
}}
data-testid={cancelButtonTestId}
>
{cancelText_}
</Button>
</StyledColumnButtonWrapper>
)}
</StyledModalWrapper>
</Modal>
);
};
export default Confirm;
@@ -1 +0,0 @@
export * from './confirm';
@@ -1,46 +0,0 @@
import { displayFlex, styled } from '../../styles';
import { ModalWrapper } from '../modal';
export const StyledModalWrapper = styled(ModalWrapper)(() => {
return {
minWidth: '460px',
maxWidth: '560px',
maxHeight: '292px',
padding: '44px 84px 32px 84px',
overflow: 'auto',
};
});
export const StyledConfirmTitle = styled('div')(() => {
return {
fontSize: 'var(--affine-font-h6)',
fontWeight: 600,
textAlign: 'center',
lineHeight: '28px',
};
});
export const StyledConfirmContent = styled('div')(() => {
return {
fontSize: 'var(--affine-font-base)',
textAlign: 'center',
marginTop: '12px',
color: 'var(--affine-text-primary-color)',
lineHeight: '26px',
};
});
export const StyledColumnButtonWrapper = styled('div')(() => {
return {
...displayFlex('center', 'center'),
flexDirection: 'column',
marginTop: '32px',
};
});
export const StyledRowButtonWrapper = styled('div')(() => {
return {
...displayFlex('center', 'center'),
flexDirection: 'row',
marginTop: '32px',
};
});
@@ -1,72 +0,0 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Button, type ButtonType } from '@toeverything/components/button';
import { useCallback } from 'react';
import { Modal, type ModalProps } from './modal';
import { ModalCloseButton } from './modal-close-button';
import { ModalWrapper } from './modal-wrapper';
import {
StyledModalContent,
StyledModalFooter,
StyledModalTitle,
} from './styles';
export interface BaseModalProps
extends Omit<ModalProps, 'onClose' | 'children'> {
title?: string;
content?: string;
confirmText?: string;
confirmType?: ButtonType;
onClose: () => void;
onCancel: () => void;
onConfirm: () => void;
}
export const ConfirmModal = ({
open,
onClose,
confirmText,
confirmType = 'primary',
onCancel,
onConfirm,
title,
content,
}: BaseModalProps) => {
const t = useAFFiNEI18N();
const handleClose = useCallback(() => {
onClose();
}, [onClose]);
return (
<Modal
open={open}
onClose={handleClose}
wrapperPosition={['center', 'center']}
data-testid="auth-modal"
>
<ModalWrapper
width={480}
minHeight={194}
style={{
overflow: 'hidden',
backgroundColor: 'var(--affine-white)',
boxShadow: 'var(--affine-popover-shadow)',
padding: '20px 24px 0',
}}
>
<ModalCloseButton top={22} right={20} onClick={handleClose} />
<StyledModalTitle>{title}</StyledModalTitle>
<StyledModalContent>{content}</StyledModalContent>
<StyledModalFooter>
<Button onClick={onCancel} style={{ marginRight: 20 }}>
{t['com.affine.confirmModal.button.cancel']()}
</Button>
<Button type={confirmType} onClick={onConfirm}>
{confirmText || t['Confirm']()}
</Button>
</StyledModalFooter>
</ModalWrapper>
</Modal>
);
};
@@ -1,8 +0,0 @@
import Modal from './modal';
export * from './confirm-modal';
export * from './modal';
export * from './modal-close-button';
export * from './modal-wrapper';
export default Modal;
@@ -1,39 +0,0 @@
import { CloseIcon } from '@blocksuite/icons';
import {
IconButton,
type IconButtonProps,
} from '@toeverything/components/button';
import type { HTMLAttributes } from 'react';
export type ModalCloseButtonProps = {
top?: number;
right?: number;
absolute?: boolean;
} & Omit<IconButtonProps, 'children'> &
HTMLAttributes<HTMLButtonElement>;
export const ModalCloseButton = ({
absolute = true,
right,
top,
...props
}: ModalCloseButtonProps) => {
return (
<IconButton
style={
absolute
? {
position: 'absolute',
top: top ?? 24,
right: right ?? 40,
zIndex: 1,
}
: {}
}
data-testid="modal-close-button"
{...props}
>
<CloseIcon />
</IconButton>
);
};
@@ -1,22 +0,0 @@
import type { CSSProperties } from 'react';
import { styled } from '../../styles';
export const ModalWrapper = styled('div')<{
width?: CSSProperties['width'];
height?: CSSProperties['height'];
minHeight?: CSSProperties['minHeight'];
}>(({ width, height, minHeight }) => {
return {
width,
height,
minHeight,
backgroundColor: 'var(--affine-background-overlay-panel-color)',
boxShadow: 'var(--affine-shadow-3)',
borderRadius: '12px',
position: 'relative',
maxHeight: 'calc(100vh - 32px)',
};
});
export default ModalWrapper;
-59
View File
@@ -1,59 +0,0 @@
import type { ModalProps as ModalUnstyledOwnProps } from '@mui/base/Modal';
import Fade from '@mui/material/Fade';
import { StyledBackdrop, StyledModal } from './styles';
const Backdrop = ({
open,
...other
}: {
open?: boolean;
className: string;
}) => {
return (
<Fade in={open}>
<StyledBackdrop {...other} />
</Fade>
);
};
export type ModalProps = {
wrapperPosition?: ['top' | 'bottom' | 'center', 'left' | 'right' | 'center'];
} & ModalUnstyledOwnProps;
const transformConfig = {
top: 'flex-start',
bottom: 'flex-end',
center: 'center',
left: 'flex-start',
right: 'flex-end',
};
export const Modal = (props: ModalProps) => {
const {
wrapperPosition = ['center', 'center'],
open,
children,
...otherProps
} = props;
const [vertical, horizontal] = wrapperPosition;
// Fixme: This is a workaround for Mui bug
// Refs: https://github.com/mui/material-ui/issues/33748
if (!open) {
return null;
}
return (
<StyledModal
{...otherProps}
open={open}
slots={{ backdrop: Backdrop }}
alignItems={transformConfig[vertical]}
justifyContent={transformConfig[horizontal]}
disableEnforceFocus
>
<Fade in={open}>{children}</Fade>
</StyledModal>
);
};
export default Modal;
-65
View File
@@ -1,65 +0,0 @@
import { Modal as ModalUnstyled } from '@mui/base/Modal';
import type { CSSProperties } from 'react';
import { styled } from '../../styles';
export const StyledBackdrop = styled('div')(() => {
return {
zIndex: '-1',
position: 'fixed',
right: '0',
bottom: '0',
top: '0',
left: '0',
backgroundColor: 'var(--affine-background-modal-color)',
};
});
export const StyledModal = styled(ModalUnstyled, {
shouldForwardProp: prop => {
return !['justifyContent', 'alignItems'].includes(prop as string);
},
})<{
alignItems: CSSProperties['alignItems'];
justifyContent: CSSProperties['justifyContent'];
}>(({ alignItems, justifyContent }) => {
return {
width: '100vw',
height: '100vh',
display: 'flex',
alignItems,
justifyContent,
position: 'fixed',
left: '0',
top: '0',
zIndex: 'var(--affine-z-index-modal)',
WebkitAppRegion: 'no-drag',
'*': {
WebkitTapHighlightColor: 'transparent',
outline: 'none',
},
};
});
export const StyledModalFooter = styled('div')(() => {
return {
marginTop: 40,
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
};
});
export const StyledModalTitle = styled('div')(() => {
return {
fontWeight: 600,
fontSize: 'var(--affine-font-h-6)',
};
});
export const StyledModalContent = styled('div')(() => {
return {
fontSize: 'var(--affine-font-base)',
lineHeight: '24px',
marginTop: '12px',
};
});
+1 -1
View File
@@ -16,7 +16,7 @@
"dependencies": {
"@affine/component": "workspace:*",
"@affine/sdk": "workspace:*",
"@toeverything/components": "^0.0.34",
"@toeverything/components": "^0.0.38",
"idb": "^7.1.1",
"langchain": "^0.0.138",
"marked": "^7.0.5",
+1 -1
View File
@@ -18,7 +18,7 @@
"@affine/component": "workspace:*",
"@affine/sdk": "workspace:*",
"@blocksuite/icons": "^2.1.33",
"@toeverything/components": "^0.0.34"
"@toeverything/components": "^0.0.38"
},
"devDependencies": {
"@affine/plugin-cli": "workspace:*"
+1 -1
View File
@@ -17,7 +17,7 @@
"@affine/component": "workspace:*",
"@affine/sdk": "workspace:*",
"@blocksuite/icons": "^2.1.33",
"@toeverything/components": "^0.0.34",
"@toeverything/components": "^0.0.38",
"@toeverything/theme": "^0.7.15",
"clsx": "^2.0.0",
"foxact": "^0.2.20",
+1 -1
View File
@@ -18,7 +18,7 @@
"@affine/component": "workspace:*",
"@affine/sdk": "workspace:*",
"@blocksuite/icons": "^2.1.33",
"@toeverything/components": "^0.0.34"
"@toeverything/components": "^0.0.38"
},
"devDependencies": {
"@affine/plugin-cli": "workspace:*",
+43 -9
View File
@@ -231,7 +231,7 @@ __metadata:
"@affine/component": "workspace:*"
"@affine/plugin-cli": "workspace:*"
"@affine/sdk": "workspace:*"
"@toeverything/components": ^0.0.34
"@toeverything/components": ^0.0.38
"@types/marked": ^5.0.1
idb: ^7.1.1
jotai: ^2.4.1
@@ -282,7 +282,7 @@ __metadata:
"@sentry/webpack-plugin": ^2.7.0
"@svgr/webpack": ^8.1.0
"@swc/core": ^1.3.81
"@toeverything/components": ^0.0.34
"@toeverything/components": ^0.0.38
"@types/lodash-es": ^4.17.9
"@types/webpack-env": ^1.18.1
async-call-rpc: ^6.3.1
@@ -458,7 +458,7 @@ __metadata:
"@affine/plugin-cli": "workspace:*"
"@affine/sdk": "workspace:*"
"@blocksuite/icons": ^2.1.33
"@toeverything/components": ^0.0.34
"@toeverything/components": ^0.0.38
languageName: unknown
linkType: soft
@@ -484,7 +484,7 @@ __metadata:
"@affine/plugin-cli": "workspace:*"
"@affine/sdk": "workspace:*"
"@blocksuite/icons": ^2.1.33
"@toeverything/components": ^0.0.34
"@toeverything/components": ^0.0.38
"@toeverything/theme": ^0.7.15
clsx: ^2.0.0
foxact: ^0.2.20
@@ -580,7 +580,7 @@ __metadata:
"@affine/plugin-cli": "workspace:*"
"@affine/sdk": "workspace:*"
"@blocksuite/icons": ^2.1.33
"@toeverything/components": ^0.0.34
"@toeverything/components": ^0.0.38
jotai: ^2.4.1
react: 18.2.0
react-dom: 18.2.0
@@ -9108,6 +9108,39 @@ __metadata:
languageName: node
linkType: hard
"@radix-ui/react-dialog@npm:^1.0.4":
version: 1.0.4
resolution: "@radix-ui/react-dialog@npm:1.0.4"
dependencies:
"@babel/runtime": ^7.13.10
"@radix-ui/primitive": 1.0.1
"@radix-ui/react-compose-refs": 1.0.1
"@radix-ui/react-context": 1.0.1
"@radix-ui/react-dismissable-layer": 1.0.4
"@radix-ui/react-focus-guards": 1.0.1
"@radix-ui/react-focus-scope": 1.0.3
"@radix-ui/react-id": 1.0.1
"@radix-ui/react-portal": 1.0.3
"@radix-ui/react-presence": 1.0.1
"@radix-ui/react-primitive": 1.0.3
"@radix-ui/react-slot": 1.0.2
"@radix-ui/react-use-controllable-state": 1.0.1
aria-hidden: ^1.1.1
react-remove-scroll: 2.5.5
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 01ad549a3685e221628950e6fbec306494170aa3b92cbe00732b1531c16e1cf681138cd4a79d658f4f97d4096676a40d08642090fdea1675d0b7dc78df66d962
languageName: node
linkType: hard
"@radix-ui/react-direction@npm:1.0.0":
version: 1.0.0
resolution: "@radix-ui/react-direction@npm:1.0.0"
@@ -12447,11 +12480,12 @@ __metadata:
languageName: node
linkType: hard
"@toeverything/components@npm:^0.0.34":
version: 0.0.34
resolution: "@toeverything/components@npm:0.0.34"
"@toeverything/components@npm:^0.0.38":
version: 0.0.38
resolution: "@toeverything/components@npm:0.0.38"
dependencies:
"@blocksuite/icons": ^2.1.33
"@radix-ui/react-dialog": ^1.0.4
"@radix-ui/react-dropdown-menu": ^2.0.5
"@radix-ui/react-tooltip": ^1.0.6
peerDependencies:
@@ -12459,7 +12493,7 @@ __metadata:
clsx: ^2
react: ^18
react-dom: ^18
checksum: 240fadd8101d92eb2da6700372a2cb87516479999943628c7d422d3cfeb3f330a15096eed470d650d207bd1a132e4115e1277b13d59a6f4994827e231e9cf5f3
checksum: 8771f0439be2db0acffa1d6f73a2c49155acf35c5a0538c3391f98f5dfc7961f6e88e48dfc9e5dae2847b3a31a720a58dc79075db024758b74b72bcfe15eadd0
languageName: node
linkType: hard