From a905fddf661bc610dfd089348e08bf88c34c2eba Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 6 Dec 2024 15:25:09 -0500 Subject: [PATCH] refactor(Toast): replace custom motion component with CollapseDelayed (#33405) --- ...-19d4910b-6f0a-4f0f-a0c4-d668280c25c9.json | 7 ++++ ...-d5b54519-be81-485d-af06-6b728958fd45.json | 7 ++++ .../src/components/Collapse/collapse-atoms.ts | 36 +++++++++++++------ .../react-toast/library/package.json | 1 + .../ToastContainer/ToastContainer.test.tsx | 4 +-- .../ToastContainer/ToastContainerMotion.tsx | 33 ----------------- .../ToastContainer/renderToastContainer.tsx | 6 ++-- 7 files changed, 45 insertions(+), 49 deletions(-) create mode 100644 change/@fluentui-react-motion-components-preview-19d4910b-6f0a-4f0f-a0c4-d668280c25c9.json create mode 100644 change/@fluentui-react-toast-d5b54519-be81-485d-af06-6b728958fd45.json delete mode 100644 packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainerMotion.tsx diff --git a/change/@fluentui-react-motion-components-preview-19d4910b-6f0a-4f0f-a0c4-d668280c25c9.json b/change/@fluentui-react-motion-components-preview-19d4910b-6f0a-4f0f-a0c4-d668280c25c9.json new file mode 100644 index 0000000000000..5cfb15acfe47f --- /dev/null +++ b/change/@fluentui-react-motion-components-preview-19d4910b-6f0a-4f0f-a0c4-d668280c25c9.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat(Collapse): add margin to whitespace animation", + "packageName": "@fluentui/react-motion-components-preview", + "email": "robertpenner@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-toast-d5b54519-be81-485d-af06-6b728958fd45.json b/change/@fluentui-react-toast-d5b54519-be81-485d-af06-6b728958fd45.json new file mode 100644 index 0000000000000..daa10478e96d6 --- /dev/null +++ b/change/@fluentui-react-toast-d5b54519-be81-485d-af06-6b728958fd45.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "refactor(Toast): replace custom component with CollapseDelayed", + "packageName": "@fluentui/react-toast", + "email": "robertpenner@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts b/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts index 777223f5ddd35..0ce27aa7d91c8 100644 --- a/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts +++ b/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts @@ -68,16 +68,28 @@ export const sizeExitAtom = ({ // ----- WHITESPACE ----- -// Whitespace animation currently includes padding, but could be extended to handle margin. +// Whitespace animation includes padding and margin. const whitespaceValuesForOrientation = (orientation: CollapseOrientation) => { - const paddingStart = orientation === 'horizontal' ? 'paddingLeft' : 'paddingTop'; - const paddingEnd = orientation === 'horizontal' ? 'paddingRight' : 'paddingBottom'; - return { paddingStart, paddingEnd }; + // horizontal whitespace collapse + if (orientation === 'horizontal') { + return { + paddingStart: 'paddingInlineStart', + paddingEnd: 'paddingInlineEnd', + marginStart: 'marginInlineStart', + marginEnd: 'marginInlineEnd', + }; + } + // vertical whitespace collapse + return { + paddingStart: 'paddingBlockStart', + paddingEnd: 'paddingBlockEnd', + marginStart: 'marginBlockStart', + marginEnd: 'marginBlockEnd', + }; }; -// Because a height of zero does not eliminate padding, -// we will create keyframes to animate it to zero. -// TODO: consider collapsing margin, perhaps as an option. +// Because a height of zero does not eliminate padding or margin, +// we will create keyframes to animate them to zero. export const whitespaceEnterAtom = ({ orientation, duration, @@ -87,9 +99,10 @@ export const whitespaceEnterAtom = ({ duration: number; easing: string; }): AtomMotion => { - const { paddingStart, paddingEnd } = whitespaceValuesForOrientation(orientation); + const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation); return { - keyframes: [{ [paddingStart]: '0', [paddingEnd]: '0', offset: 0 }], + // Animate from whitespace of zero to the current whitespace, by omitting the ending keyframe. + keyframes: [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset: 0 }], duration, easing, }; @@ -106,9 +119,10 @@ export const whitespaceExitAtom = ({ easing: string; delay?: number; }): AtomMotion => { - const { paddingStart, paddingEnd } = whitespaceValuesForOrientation(orientation); + const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation); return { - keyframes: [{ [paddingStart]: '0', [paddingEnd]: '0', offset: 1 }], + // Animate from the current whitespace to whitespace of zero, by using offset 1 and omitting the starting keyframe. + keyframes: [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset: 1 }], duration, easing, fill: 'forwards', diff --git a/packages/react-components/react-toast/library/package.json b/packages/react-components/react-toast/library/package.json index 1eeebf77473f9..4322eae0675fd 100644 --- a/packages/react-components/react-toast/library/package.json +++ b/packages/react-components/react-toast/library/package.json @@ -25,6 +25,7 @@ "@fluentui/react-icons": "^2.0.245", "@fluentui/react-jsx-runtime": "^9.0.47", "@fluentui/react-motion": "^9.6.3", + "@fluentui/react-motion-components-preview": "^0.3.1", "@fluentui/react-portal": "^9.4.39", "@fluentui/react-shared-contexts": "^9.21.1", "@fluentui/react-tabster": "^9.23.1", diff --git a/packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainer.test.tsx b/packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainer.test.tsx index c3a3522b3abc5..6358a47de9553 100644 --- a/packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainer.test.tsx +++ b/packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainer.test.tsx @@ -35,9 +35,9 @@ const pausedTimerSelector = '[data-timer-status="paused"]'; const FAKE_MOTION_DURATION = 500; -jest.mock('./ToastContainerMotion', () => ({ +jest.mock('@fluentui/react-motion-components-preview', () => ({ // eslint-disable-next-line @typescript-eslint/naming-convention - ToastContainerMotion: (props: PresenceComponentProps) => { + CollapseDelayed: (props: PresenceComponentProps) => { const { children, onMotionFinish, visible } = props; React.useEffect(() => { diff --git a/packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainerMotion.tsx b/packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainerMotion.tsx deleted file mode 100644 index 20de9134cb2c8..0000000000000 --- a/packages/react-components/react-toast/library/src/components/ToastContainer/ToastContainerMotion.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { createPresenceComponent } from '@fluentui/react-motion'; - -export const ToastContainerMotion = createPresenceComponent(({ element }) => ({ - enter: [ - { - keyframes: [ - { marginTop: 0, minHeight: 0, maxHeight: 0, opacity: 0 }, - { marginTop: '16px', minHeight: 44, maxHeight: `${element.scrollHeight}px`, opacity: 0 }, - ], - duration: 200, - }, - { - keyframes: [{ opacity: 0 }, { opacity: 1 }], - delay: 200, - duration: 400, - }, - ], - - exit: [ - { - keyframes: [ - { marginTop: '16px', minHeight: 44, maxHeight: `${element.scrollHeight}px` }, - { marginTop: 0, minHeight: 0, maxHeight: 0 }, - ], - delay: 400, - duration: 200, - }, - { - keyframes: [{ opacity: 1 }, { opacity: 0 }], - duration: 400, - }, - ], -})); diff --git a/packages/react-components/react-toast/library/src/components/ToastContainer/renderToastContainer.tsx b/packages/react-components/react-toast/library/src/components/ToastContainer/renderToastContainer.tsx index 025e41113ae03..b3aa10f91ff7c 100644 --- a/packages/react-components/react-toast/library/src/components/ToastContainer/renderToastContainer.tsx +++ b/packages/react-components/react-toast/library/src/components/ToastContainer/renderToastContainer.tsx @@ -3,7 +3,7 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { ToastContainerState, ToastContainerSlots, ToastContainerContextValues } from './ToastContainer.types'; import { ToastContainerContextProvider } from '../../contexts/toastContainerContext'; -import { ToastContainerMotion } from './ToastContainerMotion'; +import { CollapseDelayed } from '@fluentui/react-motion-components-preview'; /** * Render the final JSX of ToastContainer @@ -17,12 +17,12 @@ export const renderToastContainer_unstable = ( return ( - + {state.root.children} - + ); };