mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
chore(core): adjust ai onboarding dismiss logic, persist dialog and dismiss once closed (#7417)
This commit is contained in:
@@ -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<DialogContentProps['onPointerDownOutside'], undefined>
|
||||
>[0];
|
||||
|
||||
const getVar = (style: number | string = '', defaultValue = '') => {
|
||||
return style
|
||||
@@ -48,11 +56,14 @@ export const Modal = forwardRef<HTMLDivElement, ModalProps>(
|
||||
description,
|
||||
withoutCloseButton = false,
|
||||
modal,
|
||||
persistent,
|
||||
|
||||
portalOptions,
|
||||
contentOptions: {
|
||||
style: contentStyle,
|
||||
className: contentClassName,
|
||||
onPointerDownOutside,
|
||||
onEscapeKeyDown,
|
||||
...otherContentOptions
|
||||
} = {},
|
||||
overlayOptions: {
|
||||
@@ -64,63 +75,79 @@ export const Modal = forwardRef<HTMLDivElement, ModalProps>(
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => (
|
||||
<Dialog.Root modal={modal} {...props}>
|
||||
<Dialog.Portal {...portalOptions}>
|
||||
<Dialog.Overlay
|
||||
className={clsx(styles.modalOverlay, overlayClassName)}
|
||||
{...otherOverlayOptions}
|
||||
/>
|
||||
<div data-modal={modal} className={clsx(styles.modalContentWrapper)}>
|
||||
<Dialog.Content
|
||||
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 : (
|
||||
<Dialog.Close asChild>
|
||||
<IconButton
|
||||
className={styles.closeButton}
|
||||
aria-label="Close"
|
||||
type="plain"
|
||||
data-testid="modal-close-button"
|
||||
{...closeButtonOptions}
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Dialog.Close>
|
||||
)}
|
||||
{title ? (
|
||||
<Dialog.Title className={styles.modalHeader}>
|
||||
{title}
|
||||
</Dialog.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 <VisuallyHidden asChild>.
|
||||
<VisuallyHidden.Root asChild>
|
||||
<Dialog.Title></Dialog.Title>
|
||||
</VisuallyHidden.Root>
|
||||
)}
|
||||
{description ? (
|
||||
<Dialog.Description className={styles.modalDescription}>
|
||||
{description}
|
||||
</Dialog.Description>
|
||||
) : null}
|
||||
) => {
|
||||
return (
|
||||
<Dialog.Root modal={modal} {...props}>
|
||||
<Dialog.Portal {...portalOptions}>
|
||||
<Dialog.Overlay
|
||||
className={clsx(styles.modalOverlay, overlayClassName)}
|
||||
{...otherOverlayOptions}
|
||||
/>
|
||||
<div data-modal={modal} className={clsx(styles.modalContentWrapper)}>
|
||||
<Dialog.Content
|
||||
onPointerDownOutside={useCallback(
|
||||
(e: PointerDownOutsideEvent) => {
|
||||
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 : (
|
||||
<Dialog.Close asChild>
|
||||
<IconButton
|
||||
className={styles.closeButton}
|
||||
aria-label="Close"
|
||||
type="plain"
|
||||
data-testid="modal-close-button"
|
||||
{...closeButtonOptions}
|
||||
>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Dialog.Close>
|
||||
)}
|
||||
{title ? (
|
||||
<Dialog.Title className={styles.modalHeader}>
|
||||
{title}
|
||||
</Dialog.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 <VisuallyHidden asChild>.
|
||||
<VisuallyHidden.Root asChild>
|
||||
<Dialog.Title></Dialog.Title>
|
||||
</VisuallyHidden.Root>
|
||||
)}
|
||||
{description ? (
|
||||
<Dialog.Description className={styles.modalDescription}>
|
||||
{description}
|
||||
</Dialog.Description>
|
||||
) : null}
|
||||
|
||||
{children}
|
||||
</Dialog.Content>
|
||||
</div>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
)
|
||||
{children}
|
||||
</Dialog.Content>
|
||||
</div>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Modal.displayName = 'Modal';
|
||||
|
||||
@@ -184,10 +184,11 @@ export const AIOnboardingGeneral = () => {
|
||||
|
||||
return readyToOpen ? (
|
||||
<Modal
|
||||
persistent
|
||||
open={open}
|
||||
onOpenChange={v => {
|
||||
showAIOnboardingGeneral$.next(v);
|
||||
if (!v && isLast) toggleGeneralAIOnboarding(false);
|
||||
if (!v) toggleGeneralAIOnboarding(false);
|
||||
}}
|
||||
contentOptions={{ className: styles.dialog }}
|
||||
overlayOptions={{ className: baseStyles.dialogOverlay }}
|
||||
|
||||
Reference in New Issue
Block a user