From d6ad7d566f6e68e9a2b840f5b729a76f060c4342 Mon Sep 17 00:00:00 2001 From: CatsJuice Date: Thu, 4 Jul 2024 07:00:17 +0000 Subject: [PATCH] chore(core): adjust ai onboarding dismiss logic, persist dialog and dismiss once closed (#7417) --- .../frontend/component/src/ui/modal/modal.tsx | 141 +++++++++++------- .../affine/ai-onboarding/general.dialog.tsx | 3 +- 2 files changed, 86 insertions(+), 58 deletions(-) diff --git a/packages/frontend/component/src/ui/modal/modal.tsx b/packages/frontend/component/src/ui/modal/modal.tsx index a10a578107..5c2710b033 100644 --- a/packages/frontend/component/src/ui/modal/modal.tsx +++ b/packages/frontend/component/src/ui/modal/modal.tsx @@ -10,7 +10,7 @@ import * as VisuallyHidden from '@radix-ui/react-visually-hidden'; import { assignInlineVars } from '@vanilla-extract/dynamic'; import clsx from 'clsx'; import type { CSSProperties } from 'react'; -import { forwardRef } from 'react'; +import { forwardRef, useCallback } from 'react'; import type { IconButtonProps } from '../button'; import { IconButton } from '../button'; @@ -23,12 +23,20 @@ export interface ModalProps extends DialogProps { title?: React.ReactNode; description?: React.ReactNode; withoutCloseButton?: boolean; + /** + * __Click outside__ or __Press `Esc`__ won't close the modal + * @default false + */ + persistent?: boolean; portalOptions?: DialogPortalProps; contentOptions?: DialogContentProps; overlayOptions?: DialogOverlayProps; closeButtonOptions?: IconButtonProps; } +type PointerDownOutsideEvent = Parameters< + Exclude +>[0]; const getVar = (style: number | string = '', defaultValue = '') => { return style @@ -48,11 +56,14 @@ export const Modal = forwardRef( description, withoutCloseButton = false, modal, + persistent, portalOptions, contentOptions: { style: contentStyle, className: contentClassName, + onPointerDownOutside, + onEscapeKeyDown, ...otherContentOptions } = {}, overlayOptions: { @@ -64,63 +75,79 @@ export const Modal = forwardRef( ...props }, ref - ) => ( - - - -
- - {withoutCloseButton ? null : ( - - - - - - )} - {title ? ( - - {title} - - ) : ( - // Refer: https://www.radix-ui.com/primitives/docs/components/dialog#title - // If you want to hide the title, wrap it inside our Visually Hidden utility like this . - - - - )} - {description ? ( - - {description} - - ) : null} + ) => { + return ( + + + +
+ { + onPointerDownOutside?.(e); + persistent && e.preventDefault(); + }, + [onPointerDownOutside, persistent] + )} + onEscapeKeyDown={useCallback( + (e: KeyboardEvent) => { + onEscapeKeyDown?.(e); + persistent && e.preventDefault(); + }, + [onEscapeKeyDown, persistent] + )} + className={clsx(styles.modalContent, contentClassName)} + style={{ + ...assignInlineVars({ + [styles.widthVar]: getVar(width, '50vw'), + [styles.heightVar]: getVar(height, 'unset'), + [styles.minHeightVar]: getVar(minHeight, '26px'), + }), + ...contentStyle, + }} + {...otherContentOptions} + ref={ref} + > + {withoutCloseButton ? null : ( + + + + + + )} + {title ? ( + + {title} + + ) : ( + // Refer: https://www.radix-ui.com/primitives/docs/components/dialog#title + // If you want to hide the title, wrap it inside our Visually Hidden utility like this . + + + + )} + {description ? ( + + {description} + + ) : null} - {children} - -
-
-
- ) + {children} +
+
+
+
+ ); + } ); Modal.displayName = 'Modal'; diff --git a/packages/frontend/core/src/components/affine/ai-onboarding/general.dialog.tsx b/packages/frontend/core/src/components/affine/ai-onboarding/general.dialog.tsx index b1033b1a4f..8bba8cfcb4 100644 --- a/packages/frontend/core/src/components/affine/ai-onboarding/general.dialog.tsx +++ b/packages/frontend/core/src/components/affine/ai-onboarding/general.dialog.tsx @@ -184,10 +184,11 @@ export const AIOnboardingGeneral = () => { return readyToOpen ? ( { showAIOnboardingGeneral$.next(v); - if (!v && isLast) toggleGeneralAIOnboarding(false); + if (!v) toggleGeneralAIOnboarding(false); }} contentOptions={{ className: styles.dialog }} overlayOptions={{ className: baseStyles.dialogOverlay }}