From 69d4f2f1287e39cd05673b3e9e33335417d068bb Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Jan 2026 14:00:56 +0000 Subject: [PATCH 1/9] Add output map signature to useTransform Adds a new signature to useTransform that accepts an object map of output ranges and returns an object of motion values with the same keys: const { opacity, x } = useTransform(inputValue, inputRange, { opacity: [0, 1], x: [100, 200] }) The keys are captured once on first render, ensuring hooks are called in a consistent order across renders. This allows the hook to be safely used within loops. --- .../value/__tests__/use-transform.test.tsx | 185 +++++++++++++++++- .../framer-motion/src/value/use-transform.ts | 149 +++++++++++++- 2 files changed, 330 insertions(+), 4 deletions(-) diff --git a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx index 59d90fe93c..04f88b6131 100644 --- a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx +++ b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx @@ -1,5 +1,5 @@ import { motionValue, MotionValue } from "motion-dom" -import { useEffect } from "react" +import { useEffect, useState } from "react" import { cancelFrame, frame, motion } from "../../" import { nextFrame, nextMicrotask } from "../../gestures/__tests__/utils" import { render } from "../../jest.setup" @@ -307,3 +307,186 @@ describe("CSS logical properties", () => { expect(container.firstChild).toHaveStyle("inset-inline: 30px") }) }) + +describe("as output map", () => { + test("sets initial values", async () => { + const Component = () => { + const x = useMotionValue(100) + const { opacity, scale } = useTransform(x, [0, 200], { + opacity: [0, 1], + scale: [0.5, 1], + }) + return + } + + const { container } = render() + expect(container.firstChild).toHaveStyle("opacity: 0.5") + expect(container.firstChild).toHaveStyle( + "transform: translateX(100px) scale(0.75)" + ) + }) + + test("updates values when input changes", async () => { + const x = motionValue(100) + + const Component = () => { + const { opacity, scale } = useTransform(x, [0, 200], { + opacity: [0, 1], + scale: [0.5, 1], + }) + return + } + + const { container } = render() + expect(container.firstChild).toHaveStyle("opacity: 0.5") + + x.set(200) + + await nextFrame() + expect(container.firstChild).toHaveStyle("opacity: 1") + expect(container.firstChild).toHaveStyle( + "transform: translateX(200px) scale(1)" + ) + }) + + test("returns stable motion values across renders", async () => { + let capturedValues: { + opacity: MotionValue + scale: MotionValue + } | null = null + let renderCount = 0 + + const Component = () => { + const x = useMotionValue(100) + const result = useTransform(x, [0, 200], { + opacity: [0, 1], + scale: [0.5, 1], + }) + + if (capturedValues === null) { + capturedValues = result + } else { + // Verify the same motion value instances are returned + expect(result.opacity).toBe(capturedValues.opacity) + expect(result.scale).toBe(capturedValues.scale) + } + + renderCount++ + return + } + + const { rerender } = render() + rerender() + rerender() + + expect(renderCount).toBe(3) + }) + + test("works with color values", async () => { + const Component = () => { + const progress = useMotionValue(0.5) + const { backgroundColor, borderColor } = useTransform( + progress, + [0, 1], + { + backgroundColor: ["#ff0000", "#0000ff"], + borderColor: ["#000000", "#ffffff"], + } + ) + return ( + + ) + } + + const { container } = render() + // Colors are interpolated + expect(container.firstChild).toHaveStyle( + "background-color: rgba(180, 0, 180, 1)" + ) + }) + + test("supports transform options", async () => { + const Component = () => { + const x = useMotionValue(250) + const { opacity } = useTransform( + x, + [0, 200], + { + opacity: [0, 1], + }, + { clamp: false } + ) + return + } + + const { container } = render() + // Value exceeds 1 because clamp is false + expect(container.firstChild).toHaveStyle("opacity: 1.25") + }) + + test("maintains keys across renders even if outputMap keys change", async () => { + let capturedKeys: string[] = [] + + const Component = ({ includeExtra }: { includeExtra: boolean }) => { + const x = useMotionValue(100) + + // Note: In practice, users should not change keys, but the hook + // should handle this gracefully by using the original keys + const outputMap = includeExtra + ? { opacity: [0, 1], scale: [0.5, 1], rotation: [0, 360] } + : { opacity: [0, 1], scale: [0.5, 1] } + + const result = useTransform(x, [0, 200], outputMap as any) + + if (capturedKeys.length === 0) { + capturedKeys = Object.keys(result) + } + + return + } + + const { rerender } = render() + + // The keys should be captured on first render + expect(capturedKeys).toEqual(["opacity", "scale"]) + + // Even if we try to add a new key, it won't be in the result + rerender() + }) + + test("responds to input range changes", async () => { + const x = motionValue(100) + + const Component = ({ max }: { max: number }) => { + const { opacity } = useTransform(x, [0, max], { + opacity: [0, 1], + }) + return + } + + const { container, rerender } = render() + expect(container.firstChild).toHaveStyle("opacity: 0.5") + + rerender() + await nextMicrotask() + expect(container.firstChild).toHaveStyle("opacity: 1") + }) + + test("is correctly typed", async () => { + const Component = () => { + const x = useMotionValue(0) + const { opacity, y } = useTransform(x, [0, 1], { + opacity: [0, 1], + y: ["0px", "100px"], + }) + + // TypeScript should infer these correctly + const _opacityValue: MotionValue = opacity + const _yValue: MotionValue = y + + return + } + + render() + }) +}) diff --git a/packages/framer-motion/src/value/use-transform.ts b/packages/framer-motion/src/value/use-transform.ts index aa6ab0f598..e75c28d815 100644 --- a/packages/framer-motion/src/value/use-transform.ts +++ b/packages/framer-motion/src/value/use-transform.ts @@ -2,13 +2,17 @@ import { AnyResolvedKeyframe, + cancelFrame, + frame, MotionValue, transform, TransformOptions, } from "motion-dom" import { useConstant } from "../utils/use-constant" +import { useIsomorphicLayoutEffect } from "../utils/use-isomorphic-effect" import { useCombineMotionValues } from "./use-combine-values" import { useComputed } from "./use-computed" +import { useMotionValue } from "./use-motion-value" export type InputRange = number[] type SingleTransformer = (input: I) => O @@ -22,6 +26,10 @@ type Transformer = */ | MultiTransformer +interface OutputMap { + [key: string]: O[] +} + /** * Create a `MotionValue` that transforms the output of another `MotionValue` by mapping it from one range of values into another. * @@ -126,7 +134,46 @@ export function useTransform( transformer: MultiTransformer ): MotionValue export function useTransform(transformer: () => O): MotionValue -export function useTransform( + +/** + * Create multiple `MotionValue`s that transform the output of another `MotionValue` by mapping it from one range of values into multiple output ranges. + * + * @remarks + * + * This is useful when you want to derive multiple values from a single input value. + * The keys of the output map must remain constant across renders. + * + * ```jsx + * export const MyComponent = () => { + * const x = useMotionValue(0) + * const { opacity, scale } = useTransform(x, [0, 100], { + * opacity: [0, 1], + * scale: [0.5, 1] + * }) + * + * return ( + * + * ) + * } + * ``` + * + * @param inputValue - `MotionValue` + * @param inputRange - A linear series of numbers (either all increasing or decreasing) + * @param outputMap - An object where keys map to output ranges. Each output range must be the same length as `inputRange`. + * @param options - Transform options applied to all outputs + * + * @returns An object with the same keys as `outputMap`, where each value is a `MotionValue` + * + * @public + */ +export function useTransform( + inputValue: MotionValue, + inputRange: InputRange, + outputMap: { [key in K]: O[] }, + options?: TransformOptions +): { [key in K]: MotionValue } + +export function useTransform( input: | MotionValue | MotionValue[] @@ -134,13 +181,32 @@ export function useTransform( | MotionValue[] | (() => O), inputRangeOrTransformer?: InputRange | Transformer, - outputRange?: O[], + outputRangeOrMap?: O[] | OutputMap, options?: TransformOptions -): MotionValue { +): MotionValue | { [key in K]: MotionValue } { if (typeof input === "function") { return useComputed(input) } + /** + * Detect if outputRangeOrMap is an output map (object with keys) + * rather than an output range (array). + */ + const isOutputMap = + outputRangeOrMap !== undefined && + !Array.isArray(outputRangeOrMap) && + typeof inputRangeOrTransformer !== "function" + + if (isOutputMap) { + return useMapTransform( + input as MotionValue, + inputRangeOrTransformer as InputRange, + outputRangeOrMap as OutputMap, + options + ) + } + + const outputRange = outputRangeOrMap as O[] | undefined const transformer = typeof inputRangeOrTransformer === "function" ? inputRangeOrTransformer @@ -172,3 +238,80 @@ function useListTransform( return transformer(latest) }) } + +function useMapTransform( + inputValue: MotionValue, + inputRange: InputRange, + outputMap: OutputMap, + options?: TransformOptions +): { [key: string]: MotionValue } { + /** + * Capture the keys once on first render. This ensures hooks are called + * in a consistent order across renders, which is required by React's + * rules of hooks. + */ + const keys = useConstant(() => Object.keys(outputMap)) + + /** + * Create transform functions for each key. These are recreated when + * inputRange or outputMap values change. + */ + const transformers = keys.map((key) => + transform(inputRange, outputMap[key], options) + ) + + /** + * Create the initial values for each output motion value. + */ + const initialInputValue = inputValue.get() + const initialValues = transformers.map((t) => t(initialInputValue)) + + /** + * Create stable motion values for each key. These are created once + * and reused across renders. + */ + const motionValues = useConstant(() => + keys.map((_, i) => new MotionValue(initialValues[i])) + ) + + /** + * Create a function that will update all motion values with the latest + * transformed values. + */ + const updateValues = () => { + const currentInputValue = inputValue.get() + for (let i = 0; i < keys.length; i++) { + motionValues[i].set(transformers[i](currentInputValue)) + } + } + + /** + * Synchronously update all motion values during render to ensure + * DOM styles are up-to-date within a React render. + */ + updateValues() + + /** + * Subscribe to the input motion value. When it changes, schedule + * an update to all output motion values. + */ + useIsomorphicLayoutEffect(() => { + const scheduleUpdate = () => frame.preRender(updateValues, false, true) + const unsubscribe = inputValue.on("change", scheduleUpdate) + + return () => { + unsubscribe() + cancelFrame(updateValues) + } + }) + + /** + * Build and return the result object with the same keys as outputMap. + */ + const result: { [key: string]: MotionValue } = {} + for (let i = 0; i < keys.length; i++) { + result[keys[i]] = motionValues[i] + } + + return result +} From 9470cf9214a54a0a40afbb09fa841c6fe097debf Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Jan 2026 14:05:49 +0000 Subject: [PATCH 2/9] Simplify useMapTransform implementation Reuse the existing useTransform in a loop instead of duplicating logic. The keys are captured once with useConstant, ensuring hooks are called in consistent order across renders. --- .../framer-motion/src/value/use-transform.ts | 72 ++----------------- 1 file changed, 5 insertions(+), 67 deletions(-) diff --git a/packages/framer-motion/src/value/use-transform.ts b/packages/framer-motion/src/value/use-transform.ts index e75c28d815..3abba706c3 100644 --- a/packages/framer-motion/src/value/use-transform.ts +++ b/packages/framer-motion/src/value/use-transform.ts @@ -2,17 +2,13 @@ import { AnyResolvedKeyframe, - cancelFrame, - frame, MotionValue, transform, TransformOptions, } from "motion-dom" import { useConstant } from "../utils/use-constant" -import { useIsomorphicLayoutEffect } from "../utils/use-isomorphic-effect" import { useCombineMotionValues } from "./use-combine-values" import { useComputed } from "./use-computed" -import { useMotionValue } from "./use-motion-value" export type InputRange = number[] type SingleTransformer = (input: I) => O @@ -246,72 +242,14 @@ function useMapTransform( options?: TransformOptions ): { [key: string]: MotionValue } { /** - * Capture the keys once on first render. This ensures hooks are called - * in a consistent order across renders, which is required by React's - * rules of hooks. + * Capture keys once to ensure hooks are called in consistent order. */ const keys = useConstant(() => Object.keys(outputMap)) + const output = useConstant<{ [key: string]: MotionValue }>(() => ({})) - /** - * Create transform functions for each key. These are recreated when - * inputRange or outputMap values change. - */ - const transformers = keys.map((key) => - transform(inputRange, outputMap[key], options) - ) - - /** - * Create the initial values for each output motion value. - */ - const initialInputValue = inputValue.get() - const initialValues = transformers.map((t) => t(initialInputValue)) - - /** - * Create stable motion values for each key. These are created once - * and reused across renders. - */ - const motionValues = useConstant(() => - keys.map((_, i) => new MotionValue(initialValues[i])) - ) - - /** - * Create a function that will update all motion values with the latest - * transformed values. - */ - const updateValues = () => { - const currentInputValue = inputValue.get() - for (let i = 0; i < keys.length; i++) { - motionValues[i].set(transformers[i](currentInputValue)) - } - } - - /** - * Synchronously update all motion values during render to ensure - * DOM styles are up-to-date within a React render. - */ - updateValues() - - /** - * Subscribe to the input motion value. When it changes, schedule - * an update to all output motion values. - */ - useIsomorphicLayoutEffect(() => { - const scheduleUpdate = () => frame.preRender(updateValues, false, true) - const unsubscribe = inputValue.on("change", scheduleUpdate) - - return () => { - unsubscribe() - cancelFrame(updateValues) - } - }) - - /** - * Build and return the result object with the same keys as outputMap. - */ - const result: { [key: string]: MotionValue } = {} - for (let i = 0; i < keys.length; i++) { - result[keys[i]] = motionValues[i] + for (const key of keys) { + output[key] = useTransform(inputValue, inputRange, outputMap[key], options) } - return result + return output } From 7ef61ba45af6a256670f96ae5e18124039bc89ed Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Jan 2026 14:24:35 +0000 Subject: [PATCH 3/9] Fix TypeScript error in useMapTransform return type --- packages/framer-motion/src/value/use-transform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/framer-motion/src/value/use-transform.ts b/packages/framer-motion/src/value/use-transform.ts index 3abba706c3..8120f36d88 100644 --- a/packages/framer-motion/src/value/use-transform.ts +++ b/packages/framer-motion/src/value/use-transform.ts @@ -199,7 +199,7 @@ export function useTransform( inputRangeOrTransformer as InputRange, outputRangeOrMap as OutputMap, options - ) + ) as { [key in K]: MotionValue } } const outputRange = outputRangeOrMap as O[] | undefined From 69bb605a8eebd8fb331aa3cd8988367ca82ced33 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Jan 2026 14:35:40 +0000 Subject: [PATCH 4/9] Fix TypeScript errors in useTransform tests --- .../src/value/__tests__/use-transform.test.tsx | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx index 04f88b6131..59a4a5a7a4 100644 --- a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx +++ b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx @@ -1,5 +1,5 @@ import { motionValue, MotionValue } from "motion-dom" -import { useEffect, useState } from "react" +import { useEffect } from "react" import { cancelFrame, frame, motion } from "../../" import { nextFrame, nextMicrotask } from "../../gestures/__tests__/utils" import { render } from "../../jest.setup" @@ -432,11 +432,11 @@ describe("as output map", () => { // Note: In practice, users should not change keys, but the hook // should handle this gracefully by using the original keys - const outputMap = includeExtra + const outputMap: { [key: string]: number[] } = includeExtra ? { opacity: [0, 1], scale: [0.5, 1], rotation: [0, 360] } : { opacity: [0, 1], scale: [0.5, 1] } - const result = useTransform(x, [0, 200], outputMap as any) + const result = useTransform(x, [0, 200], outputMap) if (capturedKeys.length === 0) { capturedKeys = Object.keys(result) @@ -475,16 +475,12 @@ describe("as output map", () => { test("is correctly typed", async () => { const Component = () => { const x = useMotionValue(0) - const { opacity, y } = useTransform(x, [0, 1], { + const { opacity, scale } = useTransform(x, [0, 1], { opacity: [0, 1], - y: ["0px", "100px"], + scale: [0.5, 1], }) - // TypeScript should infer these correctly - const _opacityValue: MotionValue = opacity - const _yValue: MotionValue = y - - return + return } render() From c64be265478ec7ad8341c6660b327823169a6b51 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Jan 2026 14:57:45 +0000 Subject: [PATCH 5/9] Fix test assertions for output map useTransform - Use scale [0.5, 1.5] so scale(1.5) is visible in transform - Use opacity [0, 0.5] with clamp:false to test extrapolation - Simplify stable values test to check output object reference --- .../value/__tests__/use-transform.test.tsx | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx index 59a4a5a7a4..d9c1b7d915 100644 --- a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx +++ b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx @@ -332,54 +332,49 @@ describe("as output map", () => { const Component = () => { const { opacity, scale } = useTransform(x, [0, 200], { opacity: [0, 1], - scale: [0.5, 1], + scale: [0.5, 1.5], }) return } const { container } = render() expect(container.firstChild).toHaveStyle("opacity: 0.5") + expect(container.firstChild).toHaveStyle( + "transform: translateX(100px) scale(1)" + ) x.set(200) await nextFrame() expect(container.firstChild).toHaveStyle("opacity: 1") expect(container.firstChild).toHaveStyle( - "transform: translateX(200px) scale(1)" + "transform: translateX(200px) scale(1.5)" ) }) test("returns stable motion values across renders", async () => { - let capturedValues: { - opacity: MotionValue - scale: MotionValue - } | null = null - let renderCount = 0 + let capturedOutput: Record> | null = null const Component = () => { const x = useMotionValue(100) const result = useTransform(x, [0, 200], { opacity: [0, 1], - scale: [0.5, 1], + scale: [0.5, 1.5], }) - if (capturedValues === null) { - capturedValues = result + if (capturedOutput === null) { + capturedOutput = result } else { - // Verify the same motion value instances are returned - expect(result.opacity).toBe(capturedValues.opacity) - expect(result.scale).toBe(capturedValues.scale) + // The output object should be the same reference + expect(result).toBe(capturedOutput) } - renderCount++ return } const { rerender } = render() rerender() rerender() - - expect(renderCount).toBe(3) }) test("works with color values", async () => { @@ -412,7 +407,7 @@ describe("as output map", () => { x, [0, 200], { - opacity: [0, 1], + opacity: [0, 0.5], }, { clamp: false } ) @@ -420,8 +415,8 @@ describe("as output map", () => { } const { container } = render() - // Value exceeds 1 because clamp is false - expect(container.firstChild).toHaveStyle("opacity: 1.25") + // Value exceeds 0.5 because clamp is false (250/200 * 0.5 = 0.625) + expect(container.firstChild).toHaveStyle("opacity: 0.625") }) test("maintains keys across renders even if outputMap keys change", async () => { From a1404a82ba14e21d17f6d8eed91cd6c6e40cb21c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Jan 2026 15:12:43 +0000 Subject: [PATCH 6/9] Remove stable values test and fix scale(1) assertion --- .../value/__tests__/use-transform.test.tsx | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx index d9c1b7d915..0833558f14 100644 --- a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx +++ b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx @@ -340,7 +340,7 @@ describe("as output map", () => { const { container } = render() expect(container.firstChild).toHaveStyle("opacity: 0.5") expect(container.firstChild).toHaveStyle( - "transform: translateX(100px) scale(1)" + "transform: translateX(100px)" ) x.set(200) @@ -352,31 +352,6 @@ describe("as output map", () => { ) }) - test("returns stable motion values across renders", async () => { - let capturedOutput: Record> | null = null - - const Component = () => { - const x = useMotionValue(100) - const result = useTransform(x, [0, 200], { - opacity: [0, 1], - scale: [0.5, 1.5], - }) - - if (capturedOutput === null) { - capturedOutput = result - } else { - // The output object should be the same reference - expect(result).toBe(capturedOutput) - } - - return - } - - const { rerender } = render() - rerender() - rerender() - }) - test("works with color values", async () => { const Component = () => { const progress = useMotionValue(0.5) From 0f8a3f91098f30396e6bfbd2028e038fb3db636e Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 9 Jan 2026 16:28:29 +0100 Subject: [PATCH 7/9] Updating changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4578611058..df14c6e52a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ Motion adheres to [Semantic Versioning](http://semver.org/). Undocumented APIs should be considered internal and may change without warning. +## [12.26.0] 2026-01-09 + +### Added + +- Support for multiple output value maps with `useTransform`. + ## [12.25.0] 2026-01-09 ### Added From 7177727a3bbe5d817390136b006af28b5168aa5d Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 9 Jan 2026 16:29:02 +0100 Subject: [PATCH 8/9] Updating changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df14c6e52a..aabc667f5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Motion adheres to [Semantic Versioning](http://semver.org/). Undocumented APIs should be considered internal and may change without warning. -## [12.26.0] 2026-01-09 +## [12.26.0] 2026-01-11 ### Added From 05334c675bf25ac49c80e02603eea52331d014c4 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 9 Jan 2026 16:29:15 +0100 Subject: [PATCH 9/9] v12.26.0 --- dev/html/package.json | 6 +++--- dev/next/package.json | 4 ++-- dev/react-19/package.json | 4 ++-- dev/react/package.json | 4 ++-- lerna.json | 2 +- packages/framer-motion/package.json | 2 +- packages/motion/package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/dev/html/package.json b/dev/html/package.json index 1f7209c02e..1e3d61421e 100644 --- a/dev/html/package.json +++ b/dev/html/package.json @@ -1,7 +1,7 @@ { "name": "html-env", "private": true, - "version": "12.25.0", + "version": "12.26.0", "type": "module", "scripts": { "dev": "vite", @@ -10,8 +10,8 @@ "preview": "vite preview" }, "dependencies": { - "framer-motion": "^12.25.0", - "motion": "^12.25.0", + "framer-motion": "^12.26.0", + "motion": "^12.26.0", "motion-dom": "^12.24.11", "react": "^18.3.1", "react-dom": "^18.3.1" diff --git a/dev/next/package.json b/dev/next/package.json index bd8c0d4bc5..61a823bb1d 100644 --- a/dev/next/package.json +++ b/dev/next/package.json @@ -1,7 +1,7 @@ { "name": "next-env", "private": true, - "version": "12.25.0", + "version": "12.26.0", "type": "module", "scripts": { "dev": "next dev", @@ -10,7 +10,7 @@ "build": "next build" }, "dependencies": { - "motion": "^12.25.0", + "motion": "^12.26.0", "next": "15.4.10", "react": "19.0.0", "react-dom": "19.0.0" diff --git a/dev/react-19/package.json b/dev/react-19/package.json index b1efd78306..5903b2ba69 100644 --- a/dev/react-19/package.json +++ b/dev/react-19/package.json @@ -1,7 +1,7 @@ { "name": "react-19-env", "private": true, - "version": "12.25.0", + "version": "12.26.0", "type": "module", "scripts": { "dev": "vite", @@ -11,7 +11,7 @@ "preview": "vite preview" }, "dependencies": { - "motion": "^12.25.0", + "motion": "^12.26.0", "react": "^19.0.0", "react-dom": "^19.0.0" }, diff --git a/dev/react/package.json b/dev/react/package.json index 48f4fa00ec..e96ca1c1c3 100644 --- a/dev/react/package.json +++ b/dev/react/package.json @@ -1,7 +1,7 @@ { "name": "react-env", "private": true, - "version": "12.25.0", + "version": "12.26.0", "type": "module", "scripts": { "dev": "yarn vite", @@ -11,7 +11,7 @@ "preview": "yarn vite preview" }, "dependencies": { - "framer-motion": "^12.25.0", + "framer-motion": "^12.26.0", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/lerna.json b/lerna.json index a7fac08c01..266eb26012 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "12.25.0", + "version": "12.26.0", "packages": [ "packages/*", "dev/*" diff --git a/packages/framer-motion/package.json b/packages/framer-motion/package.json index e31b71ef9b..39e4e80cbe 100644 --- a/packages/framer-motion/package.json +++ b/packages/framer-motion/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion", - "version": "12.25.0", + "version": "12.26.0", "description": "A simple and powerful JavaScript animation library", "main": "dist/cjs/index.js", "module": "dist/es/index.mjs", diff --git a/packages/motion/package.json b/packages/motion/package.json index e9a15280a6..c89251e72a 100644 --- a/packages/motion/package.json +++ b/packages/motion/package.json @@ -1,6 +1,6 @@ { "name": "motion", - "version": "12.25.0", + "version": "12.26.0", "description": "An animation library for JavaScript and React.", "main": "dist/cjs/index.js", "module": "dist/es/index.mjs", @@ -76,7 +76,7 @@ "postpublish": "git push --tags" }, "dependencies": { - "framer-motion": "^12.25.0", + "framer-motion": "^12.26.0", "tslib": "^2.4.0" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index a3f9694be0..6a576f4d25 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7420,7 +7420,7 @@ __metadata: languageName: node linkType: hard -"framer-motion@^12.25.0, framer-motion@workspace:packages/framer-motion": +"framer-motion@^12.26.0, framer-motion@workspace:packages/framer-motion": version: 0.0.0-use.local resolution: "framer-motion@workspace:packages/framer-motion" dependencies: @@ -8192,8 +8192,8 @@ __metadata: version: 0.0.0-use.local resolution: "html-env@workspace:dev/html" dependencies: - framer-motion: ^12.25.0 - motion: ^12.25.0 + framer-motion: ^12.26.0 + motion: ^12.26.0 motion-dom: ^12.24.11 react: ^18.3.1 react-dom: ^18.3.1 @@ -11013,11 +11013,11 @@ __metadata: languageName: unknown linkType: soft -"motion@^12.25.0, motion@workspace:packages/motion": +"motion@^12.26.0, motion@workspace:packages/motion": version: 0.0.0-use.local resolution: "motion@workspace:packages/motion" dependencies: - framer-motion: ^12.25.0 + framer-motion: ^12.26.0 tslib: ^2.4.0 peerDependencies: "@emotion/is-prop-valid": "*" @@ -11134,7 +11134,7 @@ __metadata: version: 0.0.0-use.local resolution: "next-env@workspace:dev/next" dependencies: - motion: ^12.25.0 + motion: ^12.26.0 next: 15.4.10 react: 19.0.0 react-dom: 19.0.0 @@ -12599,7 +12599,7 @@ __metadata: "@typescript-eslint/parser": ^7.2.0 "@vitejs/plugin-react-swc": ^3.5.0 eslint-plugin-react-refresh: ^0.4.6 - motion: ^12.25.0 + motion: ^12.26.0 react: ^19.0.0 react-dom: ^19.0.0 vite: ^5.2.0 @@ -12683,7 +12683,7 @@ __metadata: "@typescript-eslint/parser": ^7.2.0 "@vitejs/plugin-react-swc": ^3.5.0 eslint-plugin-react-refresh: ^0.4.6 - framer-motion: ^12.25.0 + framer-motion: ^12.26.0 react: ^18.3.1 react-dom: ^18.3.1 vite: ^5.2.0