diff --git a/packages/frontend/component/package.json b/packages/frontend/component/package.json index 559903154..24562700c 100644 --- a/packages/frontend/component/package.json +++ b/packages/frontend/component/package.json @@ -65,6 +65,7 @@ "react-is": "^18.2.0", "react-paginate": "^8.2.0", "react-router-dom": "^6.22.1", + "react-transition-state": "^2.1.1", "react-virtuoso": "~4.6.3", "rxjs": "^7.8.1", "swr": "^2.2.5", diff --git a/packages/frontend/component/src/components/resize-panel/resize-panel.css.ts b/packages/frontend/component/src/components/resize-panel/resize-panel.css.ts index bc3198c1a..655524ac8 100644 --- a/packages/frontend/component/src/components/resize-panel/resize-panel.css.ts +++ b/packages/frontend/component/src/components/resize-panel/resize-panel.css.ts @@ -5,6 +5,7 @@ export const resizeHandleOffsetVar = createVar('resize-handle-offset'); export const resizeHandleVerticalPadding = createVar( 'resize-handle-vertical-padding' ); +export const animationTimeout = createVar(); export const root = style({ vars: { [panelWidthVar]: '256px', @@ -30,13 +31,14 @@ export const root = style({ marginRight: `calc(${panelWidthVar} * -1)`, }, '&[data-enable-animation="true"]': { - transition: 'margin-left .3s .05s, margin-right .3s .05s, width .3s .05s', + transition: `margin-left ${animationTimeout} .05s, margin-right ${animationTimeout} .05s, width ${animationTimeout} .05s`, }, '&[data-is-floating="false"][data-transparent=true]': { backgroundColor: 'transparent', }, - '&[data-enable-animation="false"][data-open="false"]': { - display: 'none', + '&[data-transition-state="exited"]': { + // avoid focus on hidden panel + visibility: 'hidden', }, }, }); diff --git a/packages/frontend/component/src/components/resize-panel/resize-panel.tsx b/packages/frontend/component/src/components/resize-panel/resize-panel.tsx index 42584bfc8..33599cb10 100644 --- a/packages/frontend/component/src/components/resize-panel/resize-panel.tsx +++ b/packages/frontend/component/src/components/resize-panel/resize-panel.tsx @@ -2,6 +2,7 @@ import { assertExists } from '@blocksuite/global/utils'; import { assignInlineVars } from '@vanilla-extract/dynamic'; import clsx from 'clsx'; import { forwardRef, useCallback, useEffect, useRef, useState } from 'react'; +import { useTransition } from 'react-transition-state'; import * as styles from './resize-panel.css'; @@ -116,6 +117,7 @@ const ResizeHandle = ({ ); }; +// delay initial animation to avoid flickering function useEnableAnimation() { const [enable, setEnable] = useState(false); useEffect(() => { @@ -126,6 +128,8 @@ function useEnableAnimation() { return enable; } +const animationTimeout = 300; + export const ResizePanel = forwardRef( function ResizePanel( { @@ -150,15 +154,23 @@ export const ResizePanel = forwardRef( ) { const enableAnimation = useEnableAnimation() && _enableAnimation; const safeWidth = Math.min(maxWidth, Math.max(minWidth, width)); + const [{ status }, toggle] = useTransition({ + timeout: animationTimeout, + }); + useEffect(() => { + toggle(open); + }, [open]); return (
void; } -type ModalAnimationState = 'entering' | 'entered' | 'exiting' | 'exited'; - -function reduceAnimationState( - state: ModalAnimationState, - action: 'open' | 'close' | 'finish' -) { - switch (action) { - case 'open': - return state === 'entered' || state === 'entering' ? state : 'entering'; - case 'close': - return state === 'exited' || state === 'exiting' ? state : 'exiting'; - case 'finish': - return state === 'entering' ? 'entered' : 'exited'; - } -} +const animationTimeout = 120; export const CMDKModal = ({ onOpenChange, open, children, }: React.PropsWithChildren) => { - const [animationState, dispatch] = useReducer(reduceAnimationState, 'exited'); - + const [{ status }, toggle] = useTransition({ + timeout: animationTimeout, + }); useEffect(() => { - dispatch(open ? 'open' : 'close'); - const timeout = setTimeout(() => { - dispatch('finish'); - }, 120); - - return () => { - clearTimeout(timeout); - }; + toggle(open); }, [open]); - return ( - +
{children} diff --git a/yarn.lock b/yarn.lock index 65178ffb1..eac8622ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -269,6 +269,7 @@ __metadata: react-is: "npm:^18.2.0" react-paginate: "npm:^8.2.0" react-router-dom: "npm:^6.22.1" + react-transition-state: "npm:^2.1.1" react-virtuoso: "npm:~4.6.3" rxjs: "npm:^7.8.1" storybook: "npm:^7.6.17" @@ -381,6 +382,7 @@ __metadata: react-error-boundary: "npm:^4.0.12" react-is: "npm:18.2.0" react-router-dom: "npm:^6.22.1" + react-transition-state: "npm:^2.1.1" react-virtuoso: "npm:~4.6.3" rxjs: "npm:^7.8.1" ses: "npm:^1.3.0" @@ -30819,6 +30821,16 @@ __metadata: languageName: node linkType: hard +"react-transition-state@npm:^2.1.1": + version: 2.1.1 + resolution: "react-transition-state@npm:2.1.1" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10/992f6a44070c74bdcbeae4f6a2a5dd2429ab031e74a942822f9f2bd40b938e0efcdfbc0736f3f1a1003399191de9e5659397e99b4e901600cd03cc639579da54 + languageName: node + linkType: hard + "react-virtuoso@npm:~4.6.3": version: 4.6.3 resolution: "react-virtuoso@npm:4.6.3"