From 8f8483ab5c10e3338371488b254b0eb98215e638 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 00:28:43 +0000 Subject: [PATCH 01/18] refactor(MessageBar): migrate slide to motion component --- .../react-message-bar/library/package.json | 2 + .../MessageBarGroup/renderMessageBarGroup.tsx | 71 +++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/packages/react-components/react-message-bar/library/package.json b/packages/react-components/react-message-bar/library/package.json index 15788570dd1342..84657813e67633 100644 --- a/packages/react-components/react-message-bar/library/package.json +++ b/packages/react-components/react-message-bar/library/package.json @@ -21,6 +21,8 @@ "@fluentui/react-button": "^9.3.97", "@fluentui/react-icons": "^2.0.245", "@fluentui/react-jsx-runtime": "^9.0.47", + "@fluentui/react-motion": "^9.6.4", + "@fluentui/react-motion-components-preview": "^0.4.0", "@fluentui/react-shared-contexts": "^9.21.1", "@fluentui/react-link": "^9.3.4", "@fluentui/react-theme": "^9.1.23", diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx index ddd4c6d29760d5..88e5707d23780c 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx @@ -3,8 +3,65 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { MessageBarGroupState, MessageBarGroupSlots } from './MessageBarGroup.types'; -import { TransitionGroup } from 'react-transition-group'; -import { MessageBarTransition } from './MessageBarTransition'; +// import { TransitionGroup } from 'react-transition-group'; +// import { MessageBarTransition } from './MessageBarTransition'; +// import { Fade, Collapse } from '@fluentui/react-motion-components-preview'; +import { createPresenceComponent, PresenceGroup, motionTokens, PresenceDirection } from '@fluentui/react-motion'; + +const opacityAtom = (direction: PresenceDirection, duration: number, easing: string = motionTokens.curveLinear) => { + const keyframes = [{ opacity: 0 }, { opacity: 1 }]; + if (direction === 'exit') { + keyframes.reverse(); + } + return { + keyframes, + duration, + easing, + }; +}; + +/** + * A horizontal or vertical translation, from a specified distance to zero. + * @param distance - The distance to slide; it can be a percentage or pixels. + */ +const slideAtom = ( + direction: PresenceDirection, + axis: 'X' | 'Y', + distance: string, + duration: number, + enterEasing: string = motionTokens.curveDecelerateMid, + exitEasing: string = motionTokens.curveAccelerateMid, +) => { + const keyframes = [{ transform: `translate${axis}(${distance})` }, { transform: 'translate${axis}(0)' }]; + let easing = enterEasing; + if (direction === 'exit') { + keyframes.reverse(); + easing = exitEasing; + } + return { + keyframes, + duration, + easing, + }; +}; + +const SlideInFadeOut = createPresenceComponent(({ element }) => { + const duration = motionTokens.durationGentle; + + return { + enter: [ + opacityAtom('enter', duration), + slideAtom('enter', 'Y', '-100%', duration), + // { + // keyframes: [{ transform: 'translateY(-100%)' }, { transform: 'translateY(0)' }], + // duration, + // easing: motionTokens.curveDecelerateMid, + // }, + ], + + exit: opacityAtom('exit', duration), + }; +}); /** * Render the final JSX of MessageBarGroup @@ -14,7 +71,13 @@ export const renderMessageBarGroup_unstable = (state: MessageBarGroupState) => { return ( - + + {state.children.map(child => ( + {child} + ))} + + + {/* {state.children.map(child => ( { {child} ))} - + */} ); }; From 67e6aaf954d2f7644de18ae1d4bcc1e8c124dad2 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 15:54:07 +0000 Subject: [PATCH 02/18] refactor(MessageBar): move motions to own file --- .../MessageBarGroup.motions.tsx | 70 +++++++++++++++ .../MessageBarGroup/renderMessageBarGroup.tsx | 86 +++---------------- 2 files changed, 81 insertions(+), 75 deletions(-) create mode 100644 packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx new file mode 100644 index 00000000000000..8dd5590cbf8aa1 --- /dev/null +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx @@ -0,0 +1,70 @@ +import { motionTokens, createPresenceComponent, PresenceDirection, AtomMotion } from '@fluentui/react-motion'; + +// TODO: move these atoms to react-motion-components-preview + +/** + * + * @param direction - The functional direction of the motion: 'enter' or 'exit'. + * @param duration - The duration of the motion in milliseconds. + * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`. + * @returns + */ +const opacityAtom = ( + direction: PresenceDirection, + duration: number, + easing: string = motionTokens.curveLinear, +): AtomMotion => { + const keyframes = [{ opacity: 0 }, { opacity: 1 }]; + if (direction === 'exit') { + keyframes.reverse(); + } + return { + keyframes, + duration, + easing, + }; +}; + +/** + * Generates a motion atom object for an X or Y translation, from a specified distance to zero. + * @param direction - The functional direction of the motion: 'enter' or 'exit'. + * @param axis - The axis of the translation: 'X' or 'Y'. + * @param distance - The distance to slide; it can be a percentage or pixels. + * @param duration - The duration of the motion in milliseconds. + * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveDecelerateMid`. + */ +const slideAtom = ( + direction: PresenceDirection, + axis: 'X' | 'Y', + distance: string, + duration: number, + easing: string = motionTokens.curveDecelerateMid, +): AtomMotion => { + const keyframes = [{ transform: `translate${axis}(${distance})` }, { transform: 'translate${axis}(0)' }]; + if (direction === 'exit') { + keyframes.reverse(); + } + return { + keyframes, + duration, + easing, + }; +}; + +export const SlideInFadeOut = createPresenceComponent(() => { + const duration = motionTokens.durationGentle; + + return { + enter: [opacityAtom('enter', duration), slideAtom('enter', 'Y', '-100%', duration)], + + exit: opacityAtom('exit', duration), + }; +}); + +export const FadeOut = createPresenceComponent(() => { + return { + enter: [], + + exit: opacityAtom('exit', motionTokens.durationGentle), + }; +}); diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx index 88e5707d23780c..f9f4ac8e507800 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx @@ -3,65 +3,8 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { MessageBarGroupState, MessageBarGroupSlots } from './MessageBarGroup.types'; -// import { TransitionGroup } from 'react-transition-group'; -// import { MessageBarTransition } from './MessageBarTransition'; -// import { Fade, Collapse } from '@fluentui/react-motion-components-preview'; -import { createPresenceComponent, PresenceGroup, motionTokens, PresenceDirection } from '@fluentui/react-motion'; - -const opacityAtom = (direction: PresenceDirection, duration: number, easing: string = motionTokens.curveLinear) => { - const keyframes = [{ opacity: 0 }, { opacity: 1 }]; - if (direction === 'exit') { - keyframes.reverse(); - } - return { - keyframes, - duration, - easing, - }; -}; - -/** - * A horizontal or vertical translation, from a specified distance to zero. - * @param distance - The distance to slide; it can be a percentage or pixels. - */ -const slideAtom = ( - direction: PresenceDirection, - axis: 'X' | 'Y', - distance: string, - duration: number, - enterEasing: string = motionTokens.curveDecelerateMid, - exitEasing: string = motionTokens.curveAccelerateMid, -) => { - const keyframes = [{ transform: `translate${axis}(${distance})` }, { transform: 'translate${axis}(0)' }]; - let easing = enterEasing; - if (direction === 'exit') { - keyframes.reverse(); - easing = exitEasing; - } - return { - keyframes, - duration, - easing, - }; -}; - -const SlideInFadeOut = createPresenceComponent(({ element }) => { - const duration = motionTokens.durationGentle; - - return { - enter: [ - opacityAtom('enter', duration), - slideAtom('enter', 'Y', '-100%', duration), - // { - // keyframes: [{ transform: 'translateY(-100%)' }, { transform: 'translateY(0)' }], - // duration, - // easing: motionTokens.curveDecelerateMid, - // }, - ], - - exit: opacityAtom('exit', duration), - }; -}); +import { PresenceGroup } from '@fluentui/react-motion'; +import { SlideInFadeOut, FadeOut } from './MessageBarGroup.motions'; /** * Render the final JSX of MessageBarGroup @@ -72,23 +15,16 @@ export const renderMessageBarGroup_unstable = (state: MessageBarGroupState) => { return ( - {state.children.map(child => ( - {child} - ))} + {state.children.map(child => + state.animate === 'both' ? ( + // enter with slide and fade; exit with fade + {child} + ) : ( + // no enter motion; exit with fade + {child} + ), + )} - - {/* - {state.children.map(child => ( - - {child} - - ))} - */} ); }; From 0d1b177ec29c1efb771fab91d94abbf140d670b6 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 15:56:15 +0000 Subject: [PATCH 03/18] chore: `yarn nx generate-api` --- .../library/etc/react-message-bar.api.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md b/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md index f542397433e674..cc6f80e27fdeb8 100644 --- a/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md +++ b/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md @@ -144,13 +144,13 @@ export type MessageBarTitleSlots = { // @public export type MessageBarTitleState = ComponentState; -// @internal (undocumented) +// @internal @deprecated (undocumented) export const messageBarTransitionContextDefaultValue: MessageBarTransitionContextValue; -// @internal +// @internal @deprecated export const MessageBarTransitionContextProvider: React_2.Provider; -// @public (undocumented) +// @public @deprecated (undocumented) export type MessageBarTransitionContextValue = { className: string; nodeRef: React_2.Ref; @@ -210,7 +210,7 @@ export const useMessageBarTitle_unstable: (props: MessageBarTitleProps, ref: Rea // @public export const useMessageBarTitleStyles_unstable: (state: MessageBarTitleState) => MessageBarTitleState; -// @internal (undocumented) +// @internal @deprecated (undocumented) export const useMessageBarTransitionContext: () => MessageBarTransitionContextValue; // (No @packageDocumentation comment for this package) From 7e48afe437a2f19701b614795ba9438f6e5e3859 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 15:56:38 +0000 Subject: [PATCH 04/18] chore(MessageBar): delete or deprecate unused code --- .../library/src/components/MessageBar/MessageBar.types.ts | 3 +++ .../src/components/MessageBar/useMessageBarStyles.styles.ts | 1 - .../src/components/MessageBarGroup/MessageBarTransition.tsx | 3 +++ .../library/src/contexts/messageBarTransitionContext.ts | 6 ++++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.types.ts b/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.types.ts index ac8dbb62040eee..95b0ee35ccf3db 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.types.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.types.ts @@ -48,5 +48,8 @@ export type MessageBarProps = ComponentProps & export type MessageBarState = ComponentState & Required> & Pick & { + /** + * @deprecated Code is unused, replaced by motion components + */ transitionClassName: string; }; diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBarStyles.styles.ts b/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBarStyles.styles.ts index 1a9f754e95e4f2..7a278362508736 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBarStyles.styles.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBarStyles.styles.ts @@ -114,7 +114,6 @@ export const useMessageBarStyles_unstable = (state: MessageBarState): MessageBar state.layout === 'multiline' && styles.rootMultiline, state.shape === 'square' && styles.square, rootIntentStyles[state.intent], - state.transitionClassName, state.root.className, ); diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx index a6e5c4ab95794d..afeaa6ecf1ded0 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx @@ -3,6 +3,7 @@ import { Transition, TransitionStatus } from 'react-transition-group'; import { MessageBarTransitionContextProvider } from '../../contexts/messageBarTransitionContext'; import { MessageBarGroupProps } from './MessageBarGroup.types'; +// TODO: delete this unused code to save bytes const getClassName = ( status: TransitionStatus, enterClassName: string, @@ -24,6 +25,7 @@ const getClassName = ( /** * Internal component that controls the animation transition for MessageBar components * @internal + * @deprecated Code is unused, replaced by motion components */ export const MessageBarTransition: React.FC<{ children: React.ReactElement; @@ -50,6 +52,7 @@ export const MessageBarTransition: React.FC<{ ); }; +// TODO: delete this unused code to save bytes const MessageBarTransitionInner: React.FC<{ children: React.ReactElement; enterClassName: string; diff --git a/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts b/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts index 0a023b4b0e46ca..ce0862601ee9d9 100644 --- a/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts +++ b/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts @@ -1,5 +1,8 @@ import * as React from 'react'; +/** + * @deprecated Code is unused, replaced by motion components + */ export type MessageBarTransitionContextValue = { className: string; nodeRef: React.Ref; @@ -9,6 +12,7 @@ const messageBarTransitionContext = React.createContext React.useContext(messageBarTransitionContext) ?? messageBarTransitionContextDefaultValue; From 3b9ff97615fde985ed7583120a1793cb89e1b801 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 15:57:32 +0000 Subject: [PATCH 05/18] chore: `yarn change` --- ...t-message-bar-72abc821-ab32-4cac-8dd2-4c8dce4c810e.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-message-bar-72abc821-ab32-4cac-8dd2-4c8dce4c810e.json diff --git a/change/@fluentui-react-message-bar-72abc821-ab32-4cac-8dd2-4c8dce4c810e.json b/change/@fluentui-react-message-bar-72abc821-ab32-4cac-8dd2-4c8dce4c810e.json new file mode 100644 index 00000000000000..45370fc286bc2a --- /dev/null +++ b/change/@fluentui-react-message-bar-72abc821-ab32-4cac-8dd2-4c8dce4c810e.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "refactor(MessageBar): migrate slide & fade to motion components", + "packageName": "@fluentui/react-message-bar", + "email": "robertpenner@microsoft.com", + "dependentChangeType": "patch" +} From d4bfcac43de97165a2914602c495c2649333ea2a Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 16:14:25 +0000 Subject: [PATCH 06/18] chore(MessageBar): delete unused MessageBarTransition.tsx --- .../react-message-bar/library/package.json | 3 +- .../MessageBarGroup/MessageBarTransition.tsx | 74 ------------------- 2 files changed, 1 insertion(+), 76 deletions(-) delete mode 100644 packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx diff --git a/packages/react-components/react-message-bar/library/package.json b/packages/react-components/react-message-bar/library/package.json index 84657813e67633..11a5362eb0cf1b 100644 --- a/packages/react-components/react-message-bar/library/package.json +++ b/packages/react-components/react-message-bar/library/package.json @@ -28,8 +28,7 @@ "@fluentui/react-theme": "^9.1.23", "@fluentui/react-utilities": "^9.18.18", "@griffel/react": "^1.5.22", - "@swc/helpers": "^0.5.1", - "react-transition-group": "^4.4.1" + "@swc/helpers": "^0.5.1" }, "peerDependencies": { "@types/react": ">=16.8.0 <19.0.0", diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx deleted file mode 100644 index afeaa6ecf1ded0..00000000000000 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarTransition.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import * as React from 'react'; -import { Transition, TransitionStatus } from 'react-transition-group'; -import { MessageBarTransitionContextProvider } from '../../contexts/messageBarTransitionContext'; -import { MessageBarGroupProps } from './MessageBarGroup.types'; - -// TODO: delete this unused code to save bytes -const getClassName = ( - status: TransitionStatus, - enterClassName: string, - exitClassName: string, - animate: MessageBarGroupProps['animate'], -) => { - switch (status) { - case 'entering': - case 'entered': - return animate === 'both' ? enterClassName : ''; - case 'exiting': - case 'exited': - return exitClassName; - default: - return ''; - } -}; - -/** - * Internal component that controls the animation transition for MessageBar components - * @internal - * @deprecated Code is unused, replaced by motion components - */ -export const MessageBarTransition: React.FC<{ - children: React.ReactElement; - enterClassName: string; - exitClassName: string; - animate: MessageBarGroupProps['animate']; -}> = ({ children, enterClassName, exitClassName, animate, ...rest }) => { - const nodeRef = React.useRef(null); - - return ( - - {state => ( - - {children} - - )} - - ); -}; - -// TODO: delete this unused code to save bytes -const MessageBarTransitionInner: React.FC<{ - children: React.ReactElement; - enterClassName: string; - exitClassName: string; - animate: MessageBarGroupProps['animate']; - nodeRef: React.Ref; - state: TransitionStatus; -}> = ({ children, state, enterClassName, exitClassName, animate, nodeRef }) => { - const className = getClassName(state, enterClassName, exitClassName, animate); - const context = React.useMemo( - () => ({ - className, - nodeRef, - }), - [className, nodeRef], - ); - - return {children}; -}; From 551a4a41188a142bbc1ef02913cc54e13ced405a Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 18:11:29 +0000 Subject: [PATCH 07/18] chore(MessageBar): roll back deprecations of MessageBarTransitionContext - based on code review --- .../library/etc/react-message-bar.api.md | 8 ++++---- .../src/contexts/messageBarTransitionContext.ts | 11 ++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md b/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md index cc6f80e27fdeb8..f542397433e674 100644 --- a/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md +++ b/packages/react-components/react-message-bar/library/etc/react-message-bar.api.md @@ -144,13 +144,13 @@ export type MessageBarTitleSlots = { // @public export type MessageBarTitleState = ComponentState; -// @internal @deprecated (undocumented) +// @internal (undocumented) export const messageBarTransitionContextDefaultValue: MessageBarTransitionContextValue; -// @internal @deprecated +// @internal export const MessageBarTransitionContextProvider: React_2.Provider; -// @public @deprecated (undocumented) +// @public (undocumented) export type MessageBarTransitionContextValue = { className: string; nodeRef: React_2.Ref; @@ -210,7 +210,7 @@ export const useMessageBarTitle_unstable: (props: MessageBarTitleProps, ref: Rea // @public export const useMessageBarTitleStyles_unstable: (state: MessageBarTitleState) => MessageBarTitleState; -// @internal @deprecated (undocumented) +// @internal (undocumented) export const useMessageBarTransitionContext: () => MessageBarTransitionContextValue; // (No @packageDocumentation comment for this package) diff --git a/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts b/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts index ce0862601ee9d9..5c1dea8f74f588 100644 --- a/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts +++ b/packages/react-components/react-message-bar/library/src/contexts/messageBarTransitionContext.ts @@ -1,9 +1,9 @@ import * as React from 'react'; -/** - * @deprecated Code is unused, replaced by motion components - */ export type MessageBarTransitionContextValue = { + /** + * @deprecated CSS className is no longer used for this transition, replaced by motion components + */ className: string; nodeRef: React.Ref; }; @@ -12,7 +12,6 @@ const messageBarTransitionContext = React.createContext React.useContext(messageBarTransitionContext) ?? messageBarTransitionContextDefaultValue; From 9805fc64b2cee468175f1ec814a105464d8025af Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 23:27:36 +0000 Subject: [PATCH 08/18] chore(MessageBar): ignore lint warning for newly deprecated className --- .../library/src/components/MessageBar/useMessageBar.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts b/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts index cb2e0e7f1bc256..1c6145749da4fa 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts @@ -21,6 +21,7 @@ export const useMessageBar_unstable = (props: MessageBarProps, ref: React.Ref(null); const bodyRef = React.useRef(null); From 426e4586940a77b1c1300fd53d5ca4175b7370b2 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 13 Dec 2024 23:39:06 +0000 Subject: [PATCH 09/18] chore(MessageBar): add todo comments --- .../src/components/MessageBarGroup/MessageBarGroup.types.ts | 1 + .../MessageBarGroup/useMessageBarGroupStyles.styles.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts index dc0cbc00b1a751..9fb97fca8e9c30 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts @@ -18,6 +18,7 @@ export type MessageBarGroupProps = ComponentProps & { */ export type MessageBarGroupState = ComponentState & Pick & { + // TODO: deprecate these 2 obsolete props? enterStyles: string; exitStyles: string; children: React.ReactElement[]; diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts index a7054fe773448c..82fd1a0fec3054 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts @@ -7,6 +7,7 @@ export const messageBarGroupClassNames: SlotClassNames = { root: 'fui-MessageBarGroup', }; +// TODO: delete this obsolete code to save bytes? /** * Styles for the root slot */ @@ -49,6 +50,7 @@ export const useMessageBarGroupStyles_unstable = (state: MessageBarGroupState): const styles = useStyles(); state.root.className = mergeClasses(messageBarGroupClassNames.root, state.root.className); + // TODO: delete these 2 lines to save bytes? state.enterStyles = mergeClasses(styles.base, styles.enter); state.exitStyles = mergeClasses(styles.base, styles.exit); return state; From 84168bc510aedff3cf0e945c80810e7c17795bb3 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Mon, 16 Dec 2024 18:39:38 +0000 Subject: [PATCH 10/18] refactor(MessageBar): rename opacityAtom to fadeAtom; add docs --- .../MessageBarGroup/MessageBarGroup.motions.tsx | 14 +++++++------- .../library/src/atoms/fade-atom.ts | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx index 8dd5590cbf8aa1..d8f983eaf3723f 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx @@ -1,15 +1,15 @@ import { motionTokens, createPresenceComponent, PresenceDirection, AtomMotion } from '@fluentui/react-motion'; -// TODO: move these atoms to react-motion-components-preview +// TODO: import these atoms from react-motion-components-preview once they're available there /** - * + * Generates a motion atom object for a fade in or fade out. * @param direction - The functional direction of the motion: 'enter' or 'exit'. * @param duration - The duration of the motion in milliseconds. * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`. - * @returns + * @returns A motion atom object with opacity keyframes and the supplied duration and easing. */ -const opacityAtom = ( +const fadeAtom = ( direction: PresenceDirection, duration: number, easing: string = motionTokens.curveLinear, @@ -55,9 +55,9 @@ export const SlideInFadeOut = createPresenceComponent(() => { const duration = motionTokens.durationGentle; return { - enter: [opacityAtom('enter', duration), slideAtom('enter', 'Y', '-100%', duration)], + enter: [fadeAtom('enter', duration), slideAtom('enter', 'Y', '-100%', duration)], - exit: opacityAtom('exit', duration), + exit: fadeAtom('exit', duration), }; }); @@ -65,6 +65,6 @@ export const FadeOut = createPresenceComponent(() => { return { enter: [], - exit: opacityAtom('exit', motionTokens.durationGentle), + exit: fadeAtom('exit', motionTokens.durationGentle), }; }); diff --git a/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts b/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts new file mode 100644 index 00000000000000..4b488fa8c63ba3 --- /dev/null +++ b/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts @@ -0,0 +1 @@ +import { PresenceDirection, motionTokens } from '@fluentui/react-motion'; From 56708e03ba76c82ef309e281b9f75235482bf531 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Tue, 17 Dec 2024 21:57:38 +0000 Subject: [PATCH 11/18] chore: remove fade-atom.ts WIP file which was accidentally committed --- .../library/src/atoms/fade-atom.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts diff --git a/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts b/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts deleted file mode 100644 index 4b488fa8c63ba3..00000000000000 --- a/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts +++ /dev/null @@ -1 +0,0 @@ -import { PresenceDirection, motionTokens } from '@fluentui/react-motion'; From ee1613c0bb662ad26468f3643fdd740ebcd0bc69 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Tue, 17 Dec 2024 22:00:23 +0000 Subject: [PATCH 12/18] refactor(MessageBar): delete and deprecate unused CSS animation code --- .../MessageBarGroup/MessageBarGroup.types.ts | 3 +- .../useMessageBarGroupStyles.styles.ts | 42 +------------------ 2 files changed, 3 insertions(+), 42 deletions(-) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts index 9fb97fca8e9c30..3892ffb59ac5ce 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.types.ts @@ -18,8 +18,9 @@ export type MessageBarGroupProps = ComponentProps & { */ export type MessageBarGroupState = ComponentState & Pick & { - // TODO: deprecate these 2 obsolete props? + /** @deprecated property is unused; these CSS animations were replaced by motion components */ enterStyles: string; + /** @deprecated property is unused; these CSS animations were replaced by motion components */ exitStyles: string; children: React.ReactElement[]; }; diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts index 82fd1a0fec3054..bdc96b5d9e631a 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/useMessageBarGroupStyles.styles.ts @@ -1,5 +1,4 @@ -import { makeStyles, mergeClasses } from '@griffel/react'; -import { tokens } from '@fluentui/react-theme'; +import { mergeClasses } from '@griffel/react'; import type { SlotClassNames } from '@fluentui/react-utilities'; import type { MessageBarGroupSlots, MessageBarGroupState } from './MessageBarGroup.types'; @@ -7,51 +6,12 @@ export const messageBarGroupClassNames: SlotClassNames = { root: 'fui-MessageBarGroup', }; -// TODO: delete this obsolete code to save bytes? -/** - * Styles for the root slot - */ -const useStyles = makeStyles({ - base: { - animationFillMode: 'forwards', - animationDuration: tokens.durationNormal, - }, - - enter: { - animationName: { - from: { - opacity: 0, - transform: 'translateY(-100%)', - }, - to: { - opacity: 1, - transform: 'translateY(0)', - }, - }, - }, - - exit: { - animationName: { - from: { - opacity: 1, - }, - to: { - opacity: 0, - }, - }, - }, -}); - /** * Apply styling to the MessageBarGroup slots based on the state */ export const useMessageBarGroupStyles_unstable = (state: MessageBarGroupState): MessageBarGroupState => { 'use no memo'; - const styles = useStyles(); state.root.className = mergeClasses(messageBarGroupClassNames.root, state.root.className); - // TODO: delete these 2 lines to save bytes? - state.enterStyles = mergeClasses(styles.base, styles.enter); - state.exitStyles = mergeClasses(styles.base, styles.exit); return state; }; From 925985d93b1b4af3ac36127cff759b7bd4de360f Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Wed, 18 Dec 2024 17:58:27 +0000 Subject: [PATCH 13/18] chore: remove trailing whitespace in package.json that was failing CI - yarn nx format:check --base origin/master --- .../react-components/react-message-bar/library/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-message-bar/library/package.json b/packages/react-components/react-message-bar/library/package.json index 4ec5f583a371d9..2f5ebe74b1a1b0 100644 --- a/packages/react-components/react-message-bar/library/package.json +++ b/packages/react-components/react-message-bar/library/package.json @@ -22,7 +22,7 @@ "@fluentui/react-icons": "^2.0.245", "@fluentui/react-jsx-runtime": "^9.0.48", "@fluentui/react-motion": "^9.6.4", - "@fluentui/react-motion-components-preview": "^0.4.0", + "@fluentui/react-motion-components-preview": "^0.4.0", "@fluentui/react-shared-contexts": "^9.21.2", "@fluentui/react-link": "^9.3.5", "@fluentui/react-theme": "^9.1.24", From e55b7bb95d90fee86ee3544ac2e5b38fe565938a Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Wed, 18 Dec 2024 17:58:42 +0000 Subject: [PATCH 14/18] refactor(Collapse): change atom functions to named arguments --- .../MessageBarGroup.motions.tsx | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx index d8f983eaf3723f..59d3fd94f4508b 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx @@ -2,19 +2,28 @@ import { motionTokens, createPresenceComponent, PresenceDirection, AtomMotion } // TODO: import these atoms from react-motion-components-preview once they're available there +interface FadeAtomParams { + direction: PresenceDirection; + duration: number; + easing?: string; + fromValue?: number; +} + /** * Generates a motion atom object for a fade in or fade out. * @param direction - The functional direction of the motion: 'enter' or 'exit'. * @param duration - The duration of the motion in milliseconds. * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`. + * @param fromValue - The starting opacity value. Defaults to 0. * @returns A motion atom object with opacity keyframes and the supplied duration and easing. */ -const fadeAtom = ( - direction: PresenceDirection, - duration: number, - easing: string = motionTokens.curveLinear, -): AtomMotion => { - const keyframes = [{ opacity: 0 }, { opacity: 1 }]; +const fadeAtom = ({ + direction, + duration, + easing = motionTokens.curveLinear, + fromValue = 0, +}: FadeAtomParams): AtomMotion => { + const keyframes = [{ opacity: fromValue }, { opacity: 1 }]; if (direction === 'exit') { keyframes.reverse(); } @@ -33,14 +42,20 @@ const fadeAtom = ( * @param duration - The duration of the motion in milliseconds. * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveDecelerateMid`. */ -const slideAtom = ( - direction: PresenceDirection, - axis: 'X' | 'Y', - distance: string, - duration: number, - easing: string = motionTokens.curveDecelerateMid, -): AtomMotion => { - const keyframes = [{ transform: `translate${axis}(${distance})` }, { transform: 'translate${axis}(0)' }]; +const slideAtom = ({ + direction, + axis, + distance, + duration, + easing = motionTokens.curveDecelerateMid, +}: { + direction: PresenceDirection; + axis: 'X' | 'Y'; + distance: string; + duration: number; + easing?: string; +}): AtomMotion => { + const keyframes = [{ transform: `translate${axis}(${distance})` }, { transform: `translate${axis}(0)` }]; if (direction === 'exit') { keyframes.reverse(); } @@ -55,9 +70,12 @@ export const SlideInFadeOut = createPresenceComponent(() => { const duration = motionTokens.durationGentle; return { - enter: [fadeAtom('enter', duration), slideAtom('enter', 'Y', '-100%', duration)], + enter: [ + fadeAtom({ direction: 'enter', duration }), + slideAtom({ direction: 'enter', axis: 'Y', distance: '-100%', duration }), + ], - exit: fadeAtom('exit', duration), + exit: fadeAtom({ direction: 'exit', duration }), }; }); @@ -65,6 +83,6 @@ export const FadeOut = createPresenceComponent(() => { return { enter: [], - exit: fadeAtom('exit', motionTokens.durationGentle), + exit: fadeAtom({ direction: 'exit', duration: motionTokens.durationGentle }), }; }); From d8fea767d37d08101ac52452547a38373c516f04 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Wed, 18 Dec 2024 18:07:21 +0000 Subject: [PATCH 15/18] refactor(MessageBarGroup): rename and add jsdoc to motion functions --- .../MessageBarGroup/MessageBarGroup.motions.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx index 59d3fd94f4508b..415e513d2346ab 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx @@ -38,24 +38,24 @@ const fadeAtom = ({ * Generates a motion atom object for an X or Y translation, from a specified distance to zero. * @param direction - The functional direction of the motion: 'enter' or 'exit'. * @param axis - The axis of the translation: 'X' or 'Y'. - * @param distance - The distance to slide; it can be a percentage or pixels. + * @param fromValue - The starting position of the slide; it can be a percentage or pixels. * @param duration - The duration of the motion in milliseconds. * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveDecelerateMid`. */ const slideAtom = ({ direction, axis, - distance, + fromValue, duration, easing = motionTokens.curveDecelerateMid, }: { direction: PresenceDirection; axis: 'X' | 'Y'; - distance: string; + fromValue: string; duration: number; easing?: string; }): AtomMotion => { - const keyframes = [{ transform: `translate${axis}(${distance})` }, { transform: `translate${axis}(0)` }]; + const keyframes = [{ transform: `translate${axis}(${fromValue})` }, { transform: `translate${axis}(0)` }]; if (direction === 'exit') { keyframes.reverse(); } @@ -66,19 +66,26 @@ const slideAtom = ({ }; }; +/** + * A presence motion component that enters by sliding in from the top and fading in, + * and exits by just fading out. + */ export const SlideInFadeOut = createPresenceComponent(() => { const duration = motionTokens.durationGentle; return { enter: [ fadeAtom({ direction: 'enter', duration }), - slideAtom({ direction: 'enter', axis: 'Y', distance: '-100%', duration }), + slideAtom({ direction: 'enter', axis: 'Y', fromValue: '-100%', duration }), ], exit: fadeAtom({ direction: 'exit', duration }), }; }); +/** + * A presence motion component with only an exit transition of fading out. + */ export const FadeOut = createPresenceComponent(() => { return { enter: [], From 834480dc679ed3f5e2a786ae50ca294096a51888 Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Thu, 19 Dec 2024 16:58:02 +0000 Subject: [PATCH 16/18] refactor(MessageBarGroup): wrap conditional rendering in new MessageBarMotion component - Otherwise, when state.animate changes, an elementType will change and React will remount a part of a tree, and children will loose their state --- .../MessageBarGroup.motions.tsx | 22 +++++++++++++++++-- .../MessageBarGroup/renderMessageBarGroup.tsx | 16 +++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx index 415e513d2346ab..9deeeecbb38d9b 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx @@ -1,4 +1,6 @@ +import * as React from 'react'; import { motionTokens, createPresenceComponent, PresenceDirection, AtomMotion } from '@fluentui/react-motion'; +import { MessageBarGroupProps } from './MessageBarGroup.types'; // TODO: import these atoms from react-motion-components-preview once they're available there @@ -70,7 +72,7 @@ const slideAtom = ({ * A presence motion component that enters by sliding in from the top and fading in, * and exits by just fading out. */ -export const SlideInFadeOut = createPresenceComponent(() => { +const SlideInFadeOut = createPresenceComponent(() => { const duration = motionTokens.durationGentle; return { @@ -86,10 +88,26 @@ export const SlideInFadeOut = createPresenceComponent(() => { /** * A presence motion component with only an exit transition of fading out. */ -export const FadeOut = createPresenceComponent(() => { +const FadeOut = createPresenceComponent(() => { return { enter: [], exit: fadeAtom({ direction: 'exit', duration: motionTokens.durationGentle }), }; }); + +/** + * A compound component that renders a `SlideInFadeOut` or `FadeOut` component, + * depending on the `animate` prop being `'both'` or not. + */ +export const MessageBarMotion: React.FC<{ + animate: MessageBarGroupProps['animate']; + children: React.ReactElement; +}> = ({ animate, children }) => + animate === 'both' ? ( + // enter with slide and fade; exit with fade + {children} + ) : ( + // no enter motion; exit with fade + {children} + ); diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx index f9f4ac8e507800..70e62632523c60 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/renderMessageBarGroup.tsx @@ -4,7 +4,7 @@ import { assertSlots } from '@fluentui/react-utilities'; import type { MessageBarGroupState, MessageBarGroupSlots } from './MessageBarGroup.types'; import { PresenceGroup } from '@fluentui/react-motion'; -import { SlideInFadeOut, FadeOut } from './MessageBarGroup.motions'; +import { MessageBarMotion } from './MessageBarGroup.motions'; /** * Render the final JSX of MessageBarGroup @@ -15,15 +15,11 @@ export const renderMessageBarGroup_unstable = (state: MessageBarGroupState) => { return ( - {state.children.map(child => - state.animate === 'both' ? ( - // enter with slide and fade; exit with fade - {child} - ) : ( - // no enter motion; exit with fade - {child} - ), - )} + {state.children.map(child => ( + + {child} + + ))} ); From 8fdaa1d60e024434e6dc6e8a0b75c928d9e4241d Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Thu, 19 Dec 2024 20:51:37 +0000 Subject: [PATCH 17/18] refactor(MessageBar): move conditional motion inside a single motion component - This helps the React tree reconciliation, by keeping the React element type from changing. --- .../MessageBarGroup.motions.tsx | 60 +++++++------------ 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx index 9deeeecbb38d9b..feff719a0669a2 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx @@ -69,45 +69,27 @@ const slideAtom = ({ }; /** - * A presence motion component that enters by sliding in from the top and fading in, - * and exits by just fading out. + * A presence component for a MessageBar to enter and exit from a MessageBarGroup. + * It has an optional enter transition of a slide-in and fade-in, + * when the `animate` prop is set to `'both'`. + * It always has an exit transition of a fade-out. */ -const SlideInFadeOut = createPresenceComponent(() => { - const duration = motionTokens.durationGentle; +export const MessageBarMotion = createPresenceComponent<{ animate?: MessageBarGroupProps['animate'] }>( + ({ animate }) => { + const duration = motionTokens.durationGentle; - return { - enter: [ - fadeAtom({ direction: 'enter', duration }), - slideAtom({ direction: 'enter', axis: 'Y', fromValue: '-100%', duration }), - ], - - exit: fadeAtom({ direction: 'exit', duration }), - }; -}); + return { + enter: + animate === 'both' + ? // enter with slide and fade + [ + fadeAtom({ direction: 'enter', duration }), + slideAtom({ direction: 'enter', axis: 'Y', fromValue: '-100%', duration }), + ] + : [], // no enter motion -/** - * A presence motion component with only an exit transition of fading out. - */ -const FadeOut = createPresenceComponent(() => { - return { - enter: [], - - exit: fadeAtom({ direction: 'exit', duration: motionTokens.durationGentle }), - }; -}); - -/** - * A compound component that renders a `SlideInFadeOut` or `FadeOut` component, - * depending on the `animate` prop being `'both'` or not. - */ -export const MessageBarMotion: React.FC<{ - animate: MessageBarGroupProps['animate']; - children: React.ReactElement; -}> = ({ animate, children }) => - animate === 'both' ? ( - // enter with slide and fade; exit with fade - {children} - ) : ( - // no enter motion; exit with fade - {children} - ); + // Always exit with a fade + exit: fadeAtom({ direction: 'exit', duration }), + }; + }, +); From 2a8fe3dd3275dfe691452d59daca5e58a56a62fe Mon Sep 17 00:00:00 2001 From: Robert Penner Date: Fri, 20 Dec 2024 19:22:05 +0000 Subject: [PATCH 18/18] chore(MessageBar): remove unused import --- .../src/components/MessageBarGroup/MessageBarGroup.motions.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx index feff719a0669a2..3df0dab15d1378 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBarGroup/MessageBarGroup.motions.tsx @@ -1,4 +1,3 @@ -import * as React from 'react'; import { motionTokens, createPresenceComponent, PresenceDirection, AtomMotion } from '@fluentui/react-motion'; import { MessageBarGroupProps } from './MessageBarGroup.types';