Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e3c1b1e
refactor(motion, Slide): rename fromX/toX params to outX/inX
robertpenner Dec 18, 2025
655391e
refactor(motion, Fade): rename fromOpacity/toOpacity params to outOpa…
robertpenner Dec 18, 2025
dadbf7b
refactor(motion, Scale): rename fromScale/toScale params to outScale/…
robertpenner Dec 19, 2025
c0f8b5e
refactor(motion): update parameter descriptions for clarity in Fade, …
robertpenner Dec 19, 2025
dbff41b
refactor(motion, Rotate): rename fromAngle/toAngle params to outAngle…
robertpenner Dec 19, 2025
6266d50
refactor(motion, Blur): rename fromRadius/toRadius params to outRadiu…
robertpenner Dec 19, 2025
37bbb7a
refactor(motion, Collapse): rename fromSize parameter to outSize and …
robertpenner Dec 19, 2025
fb2eb5c
refactor(motion): replace "in the [in|out] state" with "for the..."
robertpenner Dec 19, 2025
4a081c0
chore: yarn change
robertpenner Dec 19, 2025
ab6af20
chore: update .api.md
robertpenner Dec 19, 2025
54290f3
refactor(motion, SlideCardsDemo): simplify spring settle and anticipa…
robertpenner Dec 19, 2025
1fe8259
refactor(motion, RotateCardFlip): update exit easing to use anticipat…
robertpenner Dec 19, 2025
f7f6c3a
refactor(motion, SlideDirections): update prop names from "fromX" and…
robertpenner Dec 19, 2025
06352a3
fix(react-drawer): update slide atom param from "fromX" to "outX"
robertpenner Dec 19, 2025
6d28c45
fix(react-message-bar): update slide atom param from "fromY" to "outY"
robertpenner Dec 19, 2025
82aa61a
chore: yarn change
robertpenner Dec 19, 2025
679b56f
chore: Prettier
robertpenner Dec 19, 2025
b378184
refactor(motion): rename prop "fromScale" to "outScale" for consistency
robertpenner Dec 19, 2025
344bd02
fix(react-dialog): update Scale param from "fromScale" to "outScale"
robertpenner Dec 19, 2025
ac3343d
chore: yarn change
robertpenner Dec 19, 2025
acdd6ca
fix(react-nav): update Rotate param from "fromAngle" to "outAngle"
robertpenner Dec 19, 2025
d49b400
refactor(motion): rename prop "fromSize" to "outSize" for consistency
robertpenner Dec 19, 2025
0f3f795
refactor(blur): rename prop "fromRadius" to "outRadius" for consistency
robertpenner Dec 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix(react-dialog): update Scale param from \"fromScale\" to \"outScale\"",
"packageName": "@fluentui/react-dialog",
"email": "robertpenner@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix(react-message-bar): update slide atom param from \"fromY\" to \"outY\"",
"packageName": "@fluentui/react-message-bar",
"email": "robertpenner@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "refactor(motion-components): improve parameter naming from 'from/to' to 'out/in'",
"packageName": "@fluentui/react-motion-components-preview",
"email": "robertpenner@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix(react-nav): update Rotate param from \"fromAngle\" to \"outAngle\"",
"packageName": "@fluentui/react-nav",
"email": "robertpenner@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createPresenceComponentVariant, motionTokens } from '@fluentui/react-mo
import { Scale } from '@fluentui/react-motion-components-preview';

export const DialogSurfaceMotion = createPresenceComponentVariant(Scale, {
fromScale: 0.85,
outScale: 0.85,
easing: motionTokens.curveDecelerateMid,
duration: motionTokens.durationGentle,
exitEasing: motionTokens.curveAccelerateMin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,14 @@ const useStyles = makeStyles({
const BodyPresenceMotion = createPresenceComponent<{ level: 1 | 2 }>(({ level }) => {
const duration = motionTokens.durationNormal;
const easing = motionTokens.curveEasyEase;
const fromX = level === 1 ? '-100%' : '100%';
const outX = level === 1 ? '-100%' : '100%';

return {
enter: [
fadeAtom({ direction: 'enter', duration, easing }),
slideAtom({ direction: 'enter', duration, easing, fromX }),
],
exit: [
fadeAtom({ direction: 'exit', duration, easing }),
slideAtom({ direction: 'exit', duration, easing, fromX }),
slideAtom({ direction: 'enter', duration, easing, outX }),
],
exit: [fadeAtom({ direction: 'exit', duration, easing }), slideAtom({ direction: 'exit', duration, easing, outX })],
};
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const MessageBarMotion = createPresenceComponent<{ animate?: MessageBarGr
enter:
animate === 'both'
? // enter with slide and fade
[fadeAtom({ direction: 'enter', duration }), slideAtom({ direction: 'enter', fromY: '-100%', duration })]
[fadeAtom({ direction: 'enter', duration }), slideAtom({ direction: 'enter', outY: '-100%', duration })]
: [], // no enter motion

// Always exit with a fade
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import * as React_2 from 'react';
export const Blur: PresenceComponent<BlurParams>;

// @public
export const blurAtom: ({ direction, duration, easing, delay, fromRadius, toRadius, }: BlurAtomParams) => AtomMotion;
export const blurAtom: ({ direction, duration, easing, delay, outRadius, inRadius, }: BlurAtomParams) => AtomMotion;

// @public (undocumented)
export type BlurParams = BasePresenceParams & AnimateOpacity & {
fromRadius?: string;
toRadius?: string;
outRadius?: string;
inRadius?: string;
};

// @public
Expand All @@ -39,7 +39,7 @@ export type CollapseDurations = {
// @public (undocumented)
export type CollapseParams = BasePresenceParams & AnimateOpacity & CollapseDurations & {
orientation?: CollapseOrientation;
fromSize?: string;
outSize?: string;
staggerDelay?: number;
exitStaggerDelay?: number;
};
Expand All @@ -54,12 +54,12 @@ export const CollapseSnappy: PresenceComponent<CollapseParams>;
export const Fade: PresenceComponent<FadeParams>;

// @public
export const fadeAtom: ({ direction, duration, easing, delay, fromOpacity, toOpacity, }: FadeAtomParams) => AtomMotion;
export const fadeAtom: ({ direction, duration, easing, delay, outOpacity, inOpacity, }: FadeAtomParams) => AtomMotion;

// @public (undocumented)
export type FadeParams = BasePresenceParams & {
fromOpacity?: number;
toOpacity?: number;
outOpacity?: number;
inOpacity?: number;
};

// @public (undocumented)
Expand All @@ -72,25 +72,25 @@ export const FadeSnappy: PresenceComponent<FadeParams>;
export const Rotate: PresenceComponent<RotateParams>;

// @public
export const rotateAtom: ({ direction, duration, easing, delay, axis, fromAngle, toAngle, }: RotateAtomParams) => AtomMotion;
export const rotateAtom: ({ direction, duration, easing, delay, axis, outAngle, inAngle, }: RotateAtomParams) => AtomMotion;

// @public (undocumented)
export type RotateParams = BasePresenceParams & AnimateOpacity & {
axis?: Axis3D;
fromAngle?: number;
toAngle?: number;
outAngle?: number;
inAngle?: number;
};

// @public
export const Scale: PresenceComponent<ScaleParams>;

// @public
export const scaleAtom: ({ direction, duration, easing, delay, fromScale, toScale, }: ScaleAtomParams) => AtomMotion;
export const scaleAtom: ({ direction, duration, easing, delay, outScale, inScale, }: ScaleAtomParams) => AtomMotion;

// @public (undocumented)
export type ScaleParams = BasePresenceParams & AnimateOpacity & {
fromScale?: number;
toScale?: number;
outScale?: number;
inScale?: number;
};

// @public (undocumented)
Expand All @@ -103,14 +103,14 @@ export const ScaleSnappy: PresenceComponent<ScaleParams>;
export const Slide: PresenceComponent<SlideParams>;

// @public
export const slideAtom: ({ direction, duration, easing, delay, fromX, fromY, toX, toY, }: SlideAtomParams) => AtomMotion;
export const slideAtom: ({ direction, duration, easing, delay, outX, outY, inX, inY, }: SlideAtomParams) => AtomMotion;

// @public (undocumented)
export type SlideParams = BasePresenceParams & AnimateOpacity & {
fromX?: string;
fromY?: string;
toX?: string;
toY?: string;
outX?: string;
outY?: string;
inX?: string;
inY?: string;
};

// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('blurAtom', () => {
direction: 'enter',
duration: 300,
easing: motionTokens.curveEasyEase,
fromRadius: '20px',
outRadius: '20px',
});

expect(atom).toMatchObject({
Expand All @@ -22,7 +22,7 @@ describe('blurAtom', () => {
direction: 'exit',
duration: 250,
easing: motionTokens.curveAccelerateMin,
fromRadius: '15px',
outRadius: '15px',
});

expect(atom).toMatchObject({
Expand All @@ -32,18 +32,18 @@ describe('blurAtom', () => {
});
});

it('applies custom toRadius values', () => {
it('applies custom inRadius values', () => {
const atom = blurAtom({
direction: 'enter',
duration: 300,
fromRadius: '20px',
toRadius: '5px',
outRadius: '20px',
inRadius: '5px',
});

expect(atom.keyframes).toEqual([{ filter: 'blur(20px)' }, { filter: 'blur(5px)' }]);
});

it('uses default fromRadius when not provided', () => {
it('uses default outRadius when not provided', () => {
const atom = blurAtom({
direction: 'enter',
duration: 300,
Expand All @@ -56,25 +56,25 @@ describe('blurAtom', () => {
const atom = blurAtom({
direction: 'enter',
duration: 300,
fromRadius: '5px',
outRadius: '5px',
});

expect(atom.easing).toBe(motionTokens.curveLinear);
});

it('handles different CSS units for fromRadius and toRadius', () => {
it('handles different CSS units for outRadius and inRadius', () => {
const atomPx = blurAtom({
direction: 'enter',
duration: 300,
fromRadius: '8px',
toRadius: '2px',
outRadius: '8px',
inRadius: '2px',
});

const atomRem = blurAtom({
direction: 'enter',
duration: 300,
fromRadius: '1rem',
toRadius: '0.5rem',
outRadius: '1rem',
inRadius: '0.5rem',
});

expect(atomPx.keyframes[0]).toEqual({ filter: 'blur(8px)' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ import { AtomMotion, motionTokens } from '@fluentui/react-motion';
import { BaseAtomParams } from '../types';

interface BlurAtomParams extends BaseAtomParams {
fromRadius?: string;
toRadius?: string;
/** Blur radius for the out state (exited). Defaults to '10px'. */
outRadius?: string;
/** Blur radius for the in state (entered). Defaults to '0px'. */
inRadius?: string;
}

/**
* Generates a motion atom object for a blur-in or blur-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 fromRadius - The blur radius value with units (e.g., '20px', '1rem'). Defaults to '10px'.
* @param toRadius - The ending blur radius value with units (e.g., '0px', '5px'). Defaults to '0px'.
* @param outRadius - Blur radius for the out state (exited) with units (e.g., '20px', '1rem'). Defaults to '10px'.
* @param inRadius - Blur radius for the in state (entered) with units (e.g., '0px', '5px'). Defaults to '0px'.
* @param delay - Time (ms) to delay the animation. Defaults to 0.
* @returns A motion atom object with filter blur keyframes and the supplied duration and easing.
*/
Expand All @@ -21,10 +23,10 @@ export const blurAtom = ({
duration,
easing = motionTokens.curveLinear,
delay = 0,
fromRadius = '10px',
toRadius = '0px',
outRadius = '10px',
inRadius = '0px',
}: BlurAtomParams): AtomMotion => {
const keyframes = [{ filter: `blur(${fromRadius})` }, { filter: `blur(${toRadius})` }];
const keyframes = [{ filter: `blur(${outRadius})` }, { filter: `blur(${inRadius})` }];
if (direction === 'exit') {
keyframes.reverse();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import {
function expectFadeAtom(
atom: import('@fluentui/react-motion').AtomMotion,
direction: 'enter' | 'exit',
fromOpacity: number = 0,
toOpacity: number = 1,
outOpacity: number = 0,
inOpacity: number = 1,
) {
expectValidAtomMotion(atom);

if (direction === 'enter') {
expectKeyframeProperty(atom, 'opacity', [fromOpacity, toOpacity]);
expectKeyframeProperty(atom, 'opacity', [outOpacity, inOpacity]);
} else {
expectKeyframeProperty(atom, 'opacity', [toOpacity, fromOpacity]);
expectKeyframeProperty(atom, 'opacity', [inOpacity, outOpacity]);
}
}

Expand All @@ -44,8 +44,8 @@ describe('fadeAtom', () => {
const atom = fadeAtom({
direction: 'enter',
duration: 300,
fromOpacity: 0.5,
toOpacity: 0.8,
outOpacity: 0.5,
inOpacity: 0.8,
});

expect(atom.keyframes).toEqual([{ opacity: 0.5 }, { opacity: 0.8 }]);
Expand Down Expand Up @@ -110,8 +110,8 @@ describe('fadeAtom', () => {
});

it('validates custom opacity values with test utility', () => {
const enterAtom = fadeAtom({ direction: 'enter', duration: 300, fromOpacity: 0.2, toOpacity: 0.7 });
const exitAtom = fadeAtom({ direction: 'exit', duration: 300, fromOpacity: 0.3, toOpacity: 0.8 });
const enterAtom = fadeAtom({ direction: 'enter', duration: 300, outOpacity: 0.2, inOpacity: 0.7 });
const exitAtom = fadeAtom({ direction: 'exit', duration: 300, outOpacity: 0.3, inOpacity: 0.8 });

expectFadeAtom(enterAtom, 'enter', 0.2, 0.7);
expectFadeAtom(exitAtom, 'exit', 0.3, 0.8);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ interface FadeAtomParams extends BaseAtomParams {
/** Defines how values are applied before and after execution. Defaults to 'both'. */
fill?: FillMode;

/** The starting opacity value. Defaults to 0. */
fromOpacity?: number;
/** Opacity for the out state (exited). Defaults to 0. */
outOpacity?: number;

/** The ending opacity value. Defaults to 1. */
toOpacity?: number;
/** Opacity for the in state (entered). Defaults to 1. */
inOpacity?: number;
}

/**
Expand All @@ -18,19 +18,19 @@ interface FadeAtomParams extends BaseAtomParams {
* @param duration - The duration of the motion in milliseconds.
* @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`.
* @param delay - The delay before the motion starts. Defaults to 0.
* @param fromOpacity - The starting opacity value. Defaults to 0.
* @param toOpacity - The ending opacity value. Defaults to 1.
* @param outOpacity - Opacity for the out state (exited). Defaults to 0.
* @param inOpacity - Opacity for the in state (entered). Defaults to 1.
* @returns A motion atom object with opacity keyframes and the supplied duration and easing.
*/
export const fadeAtom = ({
direction,
duration,
easing = motionTokens.curveLinear,
delay = 0,
fromOpacity = 0,
toOpacity = 1,
outOpacity = 0,
inOpacity = 1,
}: FadeAtomParams): AtomMotion => {
const keyframes = [{ opacity: fromOpacity }, { opacity: toOpacity }];
const keyframes = [{ opacity: outOpacity }, { opacity: inOpacity }];
if (direction === 'exit') {
keyframes.reverse();
}
Expand Down
Loading