refactor(core): replace the Modal of the FindInPage component with Dialog (#7149)

In order to customize the opening and closing styles, the Modal were replaced.

https://github.com/toeverything/AFFiNE/assets/102217452/ece774ea-634c-4723-bace-7926f003497c
This commit is contained in:
JimmFly
2024-06-18 07:46:22 +00:00
parent b3ec3a2b3e
commit ea718d30e9
2 changed files with 149 additions and 77 deletions

View File

@@ -1,17 +1,73 @@
import { cssVar } from '@toeverything/theme'; import { cssVar } from '@toeverything/theme';
import { style } from '@vanilla-extract/css'; import { createVar, keyframes, style } from '@vanilla-extract/css';
export const container = style({ export const animationTimeout = createVar();
const contentShow = keyframes({
from: {
opacity: 0,
transform: 'translateY(-2%) scale(0.96)',
},
to: {
opacity: 1,
transform: 'translateY(0) scale(1)',
},
});
const contentHide = keyframes({
to: {
opacity: 0,
transform: 'translateY(-2%) scale(0.96)',
},
from: {
opacity: 1,
transform: 'translateY(0) scale(1)',
},
});
export const modalOverlay = style({
position: 'fixed',
inset: 0,
backgroundColor: 'transparent',
zIndex: cssVar('zIndexModal'),
});
export const modalContentWrapper = style({
position: 'fixed',
inset: 0,
display: 'flex',
alignItems: 'flex-start',
justifyContent: 'flex-end',
zIndex: cssVar('zIndexModal'),
right: '28px',
top: '80px',
});
export const modalContent = style({
width: 400,
height: 48,
backgroundColor: cssVar('backgroundOverlayPanelColor'),
borderRadius: '8px',
boxShadow: cssVar('shadow3'),
minHeight: 48,
// :focus-visible will set outline
outline: 'none',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'space-between', justifyContent: 'space-between',
padding: '8px 12px 8px 8px',
position: 'fixed',
right: '28px',
top: '80px',
borderRadius: '8px',
boxShadow: cssVar('shadow3'),
border: `0.5px solid ${cssVar('borderColor')}`, border: `0.5px solid ${cssVar('borderColor')}`,
padding: '8px 12px 8px 8px',
zIndex: cssVar('zIndexModal'),
willChange: 'transform, opacity',
selectors: {
'&[data-state=entered], &[data-state=entering]': {
animation: `${contentShow} ${animationTimeout} cubic-bezier(0.42, 0, 0.58, 1)`,
animationFillMode: 'forwards',
},
'&[data-state=exited], &[data-state=exiting]': {
animation: `${contentHide} ${animationTimeout} cubic-bezier(0.42, 0, 0.58, 1)`,
animationFillMode: 'forwards',
},
},
}); });
export const leftContent = style({ export const leftContent = style({

View File

@@ -1,11 +1,13 @@
import { Button, IconButton, Modal } from '@affine/component'; import { Button, IconButton } from '@affine/component';
import { import {
ArrowDownSmallIcon, ArrowDownSmallIcon,
ArrowUpSmallIcon, ArrowUpSmallIcon,
CloseIcon, CloseIcon,
SearchIcon, SearchIcon,
} from '@blocksuite/icons'; } from '@blocksuite/icons';
import * as Dialog from '@radix-ui/react-dialog';
import { useLiveData, useService } from '@toeverything/infra'; import { useLiveData, useService } from '@toeverything/infra';
import { assignInlineVars } from '@vanilla-extract/dynamic';
import clsx from 'clsx'; import clsx from 'clsx';
import { import {
type KeyboardEventHandler, type KeyboardEventHandler,
@@ -14,10 +16,13 @@ import {
useRef, useRef,
useState, useState,
} from 'react'; } from 'react';
import { useTransition } from 'react-transition-state';
import { FindInPageService } from '../services/find-in-page'; import { FindInPageService } from '../services/find-in-page';
import * as styles from './find-in-page-modal.css'; import * as styles from './find-in-page-modal.css';
const animationTimeout = 120;
const drawText = (canvas: HTMLCanvasElement, text: string) => { const drawText = (canvas: HTMLCanvasElement, text: string) => {
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
if (!ctx) { if (!ctx) {
@@ -81,6 +86,14 @@ export const FindInPageModal = () => {
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [active, setActive] = useState(false); const [active, setActive] = useState(false);
const [{ status }, toggle] = useTransition({
timeout: animationTimeout,
});
useEffect(() => {
toggle(visible);
}, [visible]);
const handleValueChange = useCallback( const handleValueChange = useCallback(
(v: string) => { (v: string) => {
setValue(v); setValue(v);
@@ -164,16 +177,16 @@ export const FindInPageModal = () => {
); );
return ( return (
<Modal <Dialog.Root modal open={status !== 'exited'}>
open={visible} <Dialog.Portal>
modal={false} <Dialog.Overlay className={styles.modalOverlay} />
withoutCloseButton <div className={styles.modalContentWrapper}>
width={400} <Dialog.Content
height={48} style={assignInlineVars({
minHeight={48} [styles.animationTimeout]: `${animationTimeout}ms`,
contentOptions={{ })}
className: styles.container, className={styles.modalContent}
}} data-state={status}
> >
<div className={styles.leftContent}> <div className={styles.leftContent}>
<div <div
@@ -232,6 +245,9 @@ export const FindInPageModal = () => {
> >
<CloseIcon /> <CloseIcon />
</IconButton> </IconButton>
</Modal> </Dialog.Content>
</div>
</Dialog.Portal>
</Dialog.Root>
); );
}; };