Skip to content

Commit

Permalink
refactor(Collapse): change atom functions to named arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
robertpenner committed Dec 18, 2024
1 parent 5cf1291 commit fca343d
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
import { PresenceDirection, motionTokens } from '@fluentui/react-motion';
import { AtomMotion, PresenceDirection, motionTokens } from '@fluentui/react-motion';

export const fadeAtom = (direction: PresenceDirection, duration: number, easing: string = motionTokens.curveLinear) => {
const keyframes = [{ opacity: 0 }, { opacity: 1 }];
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.
*/
export const fadeAtom = ({
direction,
duration,
easing = motionTokens.curveLinear,
fromValue = 0,
}: FadeAtomParams): AtomMotion => {
const keyframes = [{ opacity: fromValue }, { opacity: 1 }];
if (direction === 'exit') {
keyframes.reverse();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,35 @@ export const createCollapseDelayedPresence: PresenceMotionFnCreator<
// ----- ENTER -----
// The enter transition is an array of up to 3 motion atoms: size, whitespace and opacity.
const enterAtoms: AtomMotion[] = [
sizeEnterAtom(orientation, enterSizeDuration, enterEasing, element),
whitespaceAtom('enter', orientation, enterSizeDuration, enterEasing),
sizeEnterAtom({ orientation, duration: enterSizeDuration, easing: enterEasing, element }),
whitespaceAtom({ direction: 'enter', orientation, duration: enterSizeDuration, easing: enterEasing }),
];
// Fade in only if animateOpacity is true. Otherwise, leave opacity unaffected.
if (animateOpacity) {
enterAtoms.push({ ...fadeAtom('enter', enterOpacityDuration, enterEasing), delay: enterDelay, fill: 'both' });
enterAtoms.push({
...fadeAtom({ direction: 'enter', duration: enterOpacityDuration, easing: enterEasing }),
delay: enterDelay,
fill: 'both',
});
}

// ----- EXIT -----
// The exit transition is an array of up to 3 motion atoms: opacity, size and whitespace.
const exitAtoms: AtomMotion[] = [];
// Fade out only if animateOpacity is true. Otherwise, leave opacity unaffected.
if (animateOpacity) {
exitAtoms.push(fadeAtom('exit', exitOpacityDuration, exitEasing));
exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitOpacityDuration, easing: exitEasing }));
}
exitAtoms.push(sizeExitAtom(orientation, exitSizeDuration, exitEasing, element, exitDelay));
exitAtoms.push(whitespaceAtom('exit', orientation, exitSizeDuration, exitEasing, exitDelay));
exitAtoms.push(
sizeExitAtom({ orientation, duration: exitSizeDuration, easing: exitEasing, element, delay: exitDelay }),
whitespaceAtom({
direction: 'exit',
orientation,
duration: exitSizeDuration,
easing: exitEasing,
delay: exitDelay,
}),
);

return {
enter: enterAtoms,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AtomMotion, motionTokens, PresenceDirection } from '@fluentui/react-motion';
import { AtomMotion, PresenceDirection } from '@fluentui/react-motion';
import { CollapseOrientation } from './collapse-types';

// ----- SIZE -----
Expand All @@ -11,13 +11,21 @@ const sizeValuesForOrientation = (orientation: CollapseOrientation, element: Ele
return { sizeName, overflowName, toSize };
};

export const sizeEnterAtom = (
orientation: CollapseOrientation,
duration: number,
easing: string,
element: HTMLElement,
fromSize: string = '0',
): AtomMotion => {
interface SizeEnterAtomParams {
orientation: CollapseOrientation;
duration: number;
easing: string;
element: HTMLElement;
fromSize?: string;
}

export const sizeEnterAtom = ({
orientation,
duration,
easing,
element,
fromSize = '0',
}: SizeEnterAtomParams): AtomMotion => {
const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);

return {
Expand All @@ -31,14 +39,18 @@ export const sizeEnterAtom = (
};
};

export const sizeExitAtom = (
orientation: CollapseOrientation,
duration: number,
easing: string,
element: HTMLElement,
delay: number = 0,
fromSize: string = '0',
): AtomMotion => {
interface SizeExitAtomParams extends SizeEnterAtomParams {
delay?: number;
}

export const sizeExitAtom = ({
orientation,
duration,
easing,
element,
delay = 0,
fromSize = '0',
}: SizeExitAtomParams): AtomMotion => {
const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element);

return {
Expand Down Expand Up @@ -75,15 +87,21 @@ const whitespaceValuesForOrientation = (orientation: CollapseOrientation) => {
};
};

// Because a height of zero does not eliminate padding or margin,
// we will create keyframes to animate them to zero.
export const whitespaceAtom = (
direction: PresenceDirection,
orientation: CollapseOrientation,
duration: number,
easing: string,
delay: number = 0,
): AtomMotion => {
interface WhitespaceAtomParams {
direction: PresenceDirection;
orientation: CollapseOrientation;
duration: number;
easing: string;
delay?: number;
}

export const whitespaceAtom = ({
direction,
orientation,
duration,
easing,
delay = 0,
}: WhitespaceAtomParams): AtomMotion => {
const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation);
// The keyframe with zero whitespace is at the start for enter and at the end for exit.
const offset = direction === 'enter' ? 0 : 1;
Expand Down

0 comments on commit fca343d

Please sign in to comment.