Skip to content

Commit 30a407f

Browse files
committed
Split out motion token raw values
This makes it possible to use them in Framer Motion components, which need numeric values.
1 parent 3cac39b commit 30a407f

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

static/app/components/core/principles/motion/motion.mdx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,21 @@ const theme = useTheme();
5959
theme.motion.smooth.moderate;
6060
```
6161

62+
If you need to use the tokens with [Framer Motion](https://motion.dev) you can access the Bézier curve control points values and durations directly.
63+
64+
```jsx
65+
const theme = useTheme();
66+
67+
<motion.div
68+
animate={{opacity: 0}}
69+
transition={{
70+
type: 'tween',
71+
ease: theme.motionControlPoints.enter,
72+
duration: theme.motionDurations.slow,
73+
}}
74+
></motion.div>;
75+
```
76+
6277
## Easing
6378

6479
The easing curve of an animation drastically changes our perception of it. These easing tokens have been chosen to provide snappy, natural motion to interactions.

static/app/utils/theme/theme.tsx

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -252,20 +252,42 @@ const generateTokens = (colors: Colors) => ({
252252
},
253253
});
254254

255-
const generateMotion = () => {
255+
type Curve = 'smooth' | 'snap' | 'enter' | 'exit';
256+
type ControlPoints = [number, number, number, number];
257+
258+
const BEZIER_CONTROL_POINTS: Record<Curve, ControlPoints> = {
259+
smooth: [0.72, 0, 0.16, 1],
260+
snap: [0.8, -0.4, 0.5, 1],
261+
enter: [0.24, 1, 0.32, 1],
262+
exit: [0.64, 0, 0.8, 0],
263+
};
264+
265+
function formatBezierCurve(points: ControlPoints): string {
266+
return `cubic-bezier(${points.join(', ')})`;
267+
}
268+
269+
type AnimationDuration = 'fast' | 'moderate' | 'slow';
270+
271+
const MOTION_DURATIONS: Record<AnimationDuration, number> = {
272+
fast: 0.12,
273+
moderate: 0.16,
274+
slow: 0.24,
275+
};
276+
277+
const withDuration = (easing: string) => {
256278
return {
257-
smooth: withDuration('cubic-bezier(0.72, 0, 0.16, 1)'),
258-
snap: withDuration('cubic-bezier(0.8, -0.4, 0.5, 1)'),
259-
enter: withDuration('cubic-bezier(0.24, 1, 0.32, 1)'),
260-
exit: withDuration('cubic-bezier(0.64, 0, 0.8, 0)'),
279+
fast: `${MOTION_DURATIONS.fast}s ${easing}`,
280+
moderate: `${MOTION_DURATIONS.moderate}s ${easing}`,
281+
slow: `${MOTION_DURATIONS.slow}s ${easing}`,
261282
};
262283
};
263284

264-
const withDuration = (easing: string) => {
285+
const generateMotion = () => {
265286
return {
266-
fast: `120ms ${easing}`,
267-
moderate: `160ms ${easing}`,
268-
slow: `240ms ${easing}`,
287+
smooth: withDuration(formatBezierCurve(BEZIER_CONTROL_POINTS.smooth)),
288+
snap: withDuration(formatBezierCurve(BEZIER_CONTROL_POINTS.snap)),
289+
enter: withDuration(formatBezierCurve(BEZIER_CONTROL_POINTS.enter)),
290+
exit: withDuration(formatBezierCurve(BEZIER_CONTROL_POINTS.exit)),
269291
};
270292
};
271293

@@ -1152,6 +1174,8 @@ const commonTheme = {
11521174

11531175
space,
11541176
motion: generateMotion(),
1177+
motionControlPoints: BEZIER_CONTROL_POINTS,
1178+
motionDurations: MOTION_DURATIONS,
11551179

11561180
// Icons
11571181
iconSizes,

0 commit comments

Comments
 (0)