Skip to content

Commit

Permalink
refactor(MessageBarGroup): wrap conditional rendering in new MessageB…
Browse files Browse the repository at this point in the history
…arMotion 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
  • Loading branch information
robertpenner committed Dec 19, 2024
1 parent dad61fb commit 834480d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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 {
Expand All @@ -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
<SlideInFadeOut>{children}</SlideInFadeOut>
) : (
// no enter motion; exit with fade
<FadeOut>{children}</FadeOut>
);
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -15,15 +15,11 @@ export const renderMessageBarGroup_unstable = (state: MessageBarGroupState) => {
return (
<state.root>
<PresenceGroup>
{state.children.map(child =>
state.animate === 'both' ? (
// enter with slide and fade; exit with fade
<SlideInFadeOut key={child.key}>{child}</SlideInFadeOut>
) : (
// no enter motion; exit with fade
<FadeOut key={child.key}>{child}</FadeOut>
),
)}
{state.children.map(child => (
<MessageBarMotion key={child.key} animate={state.animate}>
{child}
</MessageBarMotion>
))}
</PresenceGroup>
</state.root>
);
Expand Down

0 comments on commit 834480d

Please sign in to comment.