);
+ onCancel?: () => void;
cancelText?: string;
cancelButtonOptions?: ButtonProps;
+ reverseFooter?: boolean;
}
export const ConfirmModal = ({
@@ -20,7 +24,9 @@ export const ConfirmModal = ({
// FIXME: we need i18n
cancelText = 'Cancel',
cancelButtonOptions,
+ reverseFooter,
onConfirm,
+ onCancel,
width = 480,
...props
}: ConfirmModalProps) => {
@@ -36,13 +42,92 @@ export const ConfirmModal = ({
-
+
);
};
+
+interface ConfirmModalContextProps {
+ modalProps: ConfirmModalProps;
+ openConfirmModal: (props?: ConfirmModalProps) => void;
+ closeConfirmModal: () => void;
+}
+const ConfirmModalContext = createContext({
+ modalProps: { open: false },
+ openConfirmModal: () => {},
+ closeConfirmModal: () => {},
+});
+export const ConfirmModalProvider = ({ children }: PropsWithChildren) => {
+ const [modalProps, setModalProps] = useState({
+ open: false,
+ });
+
+ const setLoading = useCallback((value: boolean) => {
+ setModalProps(prev => ({
+ ...prev,
+ confirmButtonOptions: {
+ ...prev.confirmButtonOptions,
+ loading: value,
+ },
+ }));
+ }, []);
+
+ const closeConfirmModal = useCallback(() => {
+ setModalProps({ open: false });
+ }, []);
+
+ const openConfirmModal = useCallback(
+ (props?: ConfirmModalProps) => {
+ if (!props) {
+ setModalProps({ open: true });
+ return;
+ }
+
+ const { onConfirm: _onConfirm, ...otherProps } = props;
+
+ const onConfirm = () => {
+ setLoading(true);
+ _onConfirm?.()
+ ?.catch(console.error)
+ ?.finally(() => closeConfirmModal());
+ };
+ setModalProps({ ...otherProps, onConfirm, open: true });
+ },
+ [closeConfirmModal, setLoading]
+ );
+
+ const onOpenChange = useCallback((open: boolean) => {
+ setModalProps(props => ({ ...props, open }));
+ }, []);
+
+ return (
+
+ {children}
+ {/* TODO: multi-instance support(unnecessary for now) */}
+
+
+ );
+};
+export const useConfirmModal = () => {
+ const context = useContext(ConfirmModalContext);
+ if (!context) {
+ throw new Error(
+ 'useConfirmModal must be used within a ConfirmModalProvider'
+ );
+ }
+ return {
+ openConfirmModal: context.openConfirmModal,
+ closeConfirmModal: context.closeConfirmModal,
+ };
+};
diff --git a/packages/frontend/component/src/ui/modal/styles.css.ts b/packages/frontend/component/src/ui/modal/styles.css.ts
index b3a8d44e3..6372d9bef 100644
--- a/packages/frontend/component/src/ui/modal/styles.css.ts
+++ b/packages/frontend/component/src/ui/modal/styles.css.ts
@@ -65,6 +65,10 @@ export const modalFooter = style({
'&.modalFooterWithChildren': {
paddingTop: '20px',
},
+ '&.reverse': {
+ flexDirection: 'row-reverse',
+ justifyContent: 'flex-start',
+ },
},
});
export const confirmModalContent = style({
diff --git a/packages/frontend/core/src/components/affine/enable-affine-cloud-modal/index.tsx b/packages/frontend/core/src/components/affine/enable-affine-cloud-modal/index.tsx
index bd33049e6..c1efc7c1c 100644
--- a/packages/frontend/core/src/components/affine/enable-affine-cloud-modal/index.tsx
+++ b/packages/frontend/core/src/components/affine/enable-affine-cloud-modal/index.tsx
@@ -11,7 +11,7 @@ import { useCurrentLoginStatus } from '../../../hooks/affine/use-current-login-s
export const EnableAffineCloudModal = ({
onConfirm: propsOnConfirm,
...props
-}: ConfirmModalProps) => {
+}: Omit & { onConfirm: () => void }) => {
const t = useAFFiNEI18N();
const loginStatus = useCurrentLoginStatus();
const setAuthAtom = useSetAtom(authAtom);
diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/modals.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/modals.tsx
index 9df712e6b..ea613c5d5 100644
--- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/modals.tsx
+++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/modals.tsx
@@ -55,7 +55,7 @@ export const ConfirmLoadingModal = ({
onOpenChange={onOpenChange}
onConfirm={() => {
confirmed.current = true;
- onConfirm?.();
+ onConfirm?.()?.catch(console.error);
}}
{...props}
>
diff --git a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/delete-leave-workspace/delete/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/delete-leave-workspace/delete/index.tsx
index 51542bdf3..0631ea444 100644
--- a/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/delete-leave-workspace/delete/index.tsx
+++ b/packages/frontend/core/src/components/affine/setting-modal/workspace-setting/new-workspace-setting-detail/delete-leave-workspace/delete/index.tsx
@@ -13,6 +13,7 @@ import * as styles from './style.css';
interface WorkspaceDeleteProps extends ConfirmModalProps {
workspaceMetadata: WorkspaceMetadata;
+ onConfirm?: () => void;
}
export const WorkspaceDeleteModal = ({