Skip to content

Commit

Permalink
refactor(Fade): migrate to new variant structure (#33080)
Browse files Browse the repository at this point in the history
Co-authored-by: Alexander Katrukhin <[email protected]>
  • Loading branch information
robertpenner and pixel-perfectionist authored Oct 22, 2024
1 parent 5001626 commit 39269ba
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "refactor: migrate Fade motion component to new variant structure",
"packageName": "@fluentui/react-motion-components-preview",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import type { MotionParam } from '@fluentui/react-motion';
import { PresenceComponent } from '@fluentui/react-motion';
import type { PresenceMotion } from '@fluentui/react-motion';
import type { PresenceMotionFn } from '@fluentui/react-motion';

// @public
Expand All @@ -26,6 +27,9 @@ export const createCollapseDelayedPresence: PresenceMotionFnCreator<CollapseDela
// @public
export const createCollapsePresence: PresenceMotionFnCreator<CollapseVariantParams, CollapseRuntimeParams>;

// @public
export const createFadePresence: PresenceMotionCreator<FadeVariantParams>;

// @public
export const Fade: PresenceComponent< {}>;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import {
motionTokens,
PresenceMotion,
createPresenceComponent,
createPresenceComponentVariant,
} from '@fluentui/react-motion';
import { motionTokens, createPresenceComponent } from '@fluentui/react-motion';
import type { PresenceMotionCreator } from '../../types';

const duration = motionTokens.durationNormal;
const easing = motionTokens.curveEasyEase;
type FadeVariantParams = {
/** Time (ms) for the enter transition (fade-in). Defaults to the `durationNormal` value (200 ms). */
enterDuration?: number;

/** Define a presence motion for fade in/out */
const fadeMotion: PresenceMotion = {
enter: { duration, easing, keyframes: [{ opacity: 0 }, { opacity: 1 }] },
exit: { duration, easing, keyframes: [{ opacity: 1 }, { opacity: 0 }] },
/** Easing curve for the enter transition (fade-in). Defaults to the `easeEase` value. */
enterEasing?: string;

/** Time (ms) for the exit transition (fade-out). Defaults to the `enterDuration` param for symmetry. */
exitDuration?: number;

/** Easing curve for the exit transition (fade-out). Defaults to the `enterEasing` param for symmetry. */
exitEasing?: string;
};

/** Define a presence motion for fade in/out */
export const createFadePresence: PresenceMotionCreator<FadeVariantParams> = ({
enterDuration = motionTokens.durationNormal,
enterEasing = motionTokens.curveEasyEase,
exitDuration = enterDuration,
exitEasing = enterEasing,
} = {}) => ({
enter: { duration: enterDuration, easing: enterEasing, keyframes: [{ opacity: 0 }, { opacity: 1 }] },
exit: { duration: exitDuration, easing: exitEasing, keyframes: [{ opacity: 1 }, { opacity: 0 }] },
});

/** A React component that applies fade in/out transitions to its children. */
export const Fade = createPresenceComponent(fadeMotion);
export const Fade = createPresenceComponent(createFadePresence());

export const FadeSnappy = createPresenceComponentVariant(Fade, { all: { duration: motionTokens.durationFast } });
export const FadeSnappy = createPresenceComponent(createFadePresence({ enterDuration: motionTokens.durationFast }));

export const FadeExaggerated = createPresenceComponentVariant(Fade, { all: { duration: motionTokens.durationGentle } });
export const FadeExaggerated = createPresenceComponent(
createFadePresence({ enterDuration: motionTokens.durationGentle }),
);
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export {
createCollapsePresence,
createCollapseDelayedPresence,
} from './components/Collapse';
export { Fade, FadeSnappy, FadeExaggerated } from './components/Fade';
export { Fade, FadeSnappy, FadeExaggerated, createFadePresence } from './components/Fade';
export { Scale, ScaleSnappy, ScaleExaggerated } from './components/Scale';
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import type { MotionParam, PresenceMotionFn } from '@fluentui/react-motion';
import type { MotionParam, PresenceMotion, PresenceMotionFn } from '@fluentui/react-motion';

/**
* This is a factory function that generates a motion object from variant params, e.g. duration, easing, etc.
* The generated object defines a presence motion with `enter` and `exit` transitions.
* This motion object is declarative, i.e. data without side effects,
* and it is framework-independent, i.e. non-React.
* It can be turned into a React component using `createPresenceComponent`.
*/
// TODO: move to @fluentui/react-motion when stable
export type PresenceMotionCreator<MotionVariantParams extends Record<string, MotionParam> = {}> = (
variantParams?: MotionVariantParams,
) => PresenceMotion;

/**
* This is a factory function that generates a motion function, which has variant params bound into it.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
- `duration` and `easing` can be customized for each transition separately using `createPresenceComponentVariant()`.
- A fade variant can be created with the factory function `createFadePresence()`, then converting the result to a React component using `createPresenceComponent()`:

```tsx
import { motionTokens, createPresenceComponentVariant } from '@fluentui/react-components';
import { Fade } from '@fluentui/react-motion-components-preview';
import { motionTokens } from '@fluentui/react-components';

const CustomFadeVariant = createPresenceComponentVariant(Fade, {
enter: { duration: motionTokens.durationSlow, easing: motionTokens.curveEasyEaseMax },
exit: { duration: motionTokens.durationNormal, easing: motionTokens.curveEasyEaseMax },
});
const CustomFadeVariant = createPresenceComponent(
createFadePresence({
enterDuration: motionTokens.durationSlow,
enterEasing: motionTokens.curveEasyEaseMax,
exitDuration: motionTokens.durationNormal,
}),
);

const CustomFade = ({ visible }) => (
<CustomFadeVariant unmountOnExit visible={visible}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import {
createPresenceComponentVariant,
createPresenceComponent,
Field,
makeStyles,
mergeClasses,
Expand All @@ -10,7 +10,7 @@ import {
Switch,
tokens,
} from '@fluentui/react-components';
import { Fade } from '@fluentui/react-motion-components-preview';
import { createFadePresence } from '@fluentui/react-motion-components-preview';

import description from './FadeCustomization.stories.md';

Expand Down Expand Up @@ -54,10 +54,13 @@ const useClasses = makeStyles({
},
});

const CustomFadeVariant = createPresenceComponentVariant(Fade, {
enter: { duration: motionTokens.durationSlow, easing: motionTokens.curveEasyEaseMax },
exit: { duration: motionTokens.durationNormal, easing: motionTokens.curveEasyEaseMax },
});
const CustomFadeVariant = createPresenceComponent(
createFadePresence({
enterDuration: motionTokens.durationSlow,
enterEasing: motionTokens.curveEasyEaseMax,
exitDuration: motionTokens.durationNormal,
}),
);

const LoremIpsum = () => (
<>
Expand Down

0 comments on commit 39269ba

Please sign in to comment.