From 564ab94ffbe34095608d3e1256ee9c76a2cca06a Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Mon, 12 Jan 2026 10:19:54 +0100 Subject: [PATCH 1/4] Updating changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aabc667f5a..945d4d7c06 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-11 +## [12.26.0] 2026-01-12 ### Added From e7a5d9f44340cff559f7b483f33bf15ad0d1c52e Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Mon, 12 Jan 2026 11:05:09 +0100 Subject: [PATCH 2/4] Updating useTransform types --- CHANGELOG.md | 6 ++ .../value/__tests__/use-transform.test.tsx | 29 +++++++ .../framer-motion/src/value/use-transform.ts | 76 +++++++++---------- 3 files changed, 73 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 945d4d7c06..eab08b889f 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.1] 2026-01-12 + +### Fixed + +- Improve overload selection for `useTransform`. + ## [12.26.0] 2026-01-12 ### Added 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 0833558f14..c565eb7ac2 100644 --- a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx +++ b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx @@ -455,4 +455,33 @@ describe("as output map", () => { render() }) + + test("works with mixed types (string and number outputs)", async () => { + const progress = motionValue(50) + + const Component = () => { + const { filter, scale, opacity } = useTransform( + progress, + [0, 100], + { + filter: ["blur(10px)", "blur(0px)"], + scale: [0.5, 1], + opacity: [0.5, 1], + } + ) + return + } + + const { container } = render() + expect(container.firstChild).toHaveStyle("filter: blur(5px)") + expect(container.firstChild).toHaveStyle("opacity: 0.75") + expect(container.firstChild).toHaveStyle("transform: scale(0.75)") + + progress.set(0) + + await nextFrame() + expect(container.firstChild).toHaveStyle("filter: blur(10px)") + expect(container.firstChild).toHaveStyle("opacity: 0.5") + expect(container.firstChild).toHaveStyle("transform: scale(0.5)") + }) }) diff --git a/packages/framer-motion/src/value/use-transform.ts b/packages/framer-motion/src/value/use-transform.ts index 8120f36d88..9c68569e55 100644 --- a/packages/framer-motion/src/value/use-transform.ts +++ b/packages/framer-motion/src/value/use-transform.ts @@ -26,6 +26,44 @@ interface OutputMap { [key: string]: O[] } +/** + * 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: T, + options?: TransformOptions +): { [K in keyof T]: MotionValue } + /** * Create a `MotionValue` that transforms the output of another `MotionValue` by mapping it from one range of values into another. * @@ -131,44 +169,6 @@ export function useTransform( ): MotionValue export function useTransform(transformer: () => O): MotionValue -/** - * 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 From e4141d2284a4a7a6f89ae250ea50c5ac346755fd Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Mon, 12 Jan 2026 11:05:23 +0100 Subject: [PATCH 3/4] v12.26.1 --- 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 1e3d61421e..7a5c24ee08 100644 --- a/dev/html/package.json +++ b/dev/html/package.json @@ -1,7 +1,7 @@ { "name": "html-env", "private": true, - "version": "12.26.0", + "version": "12.26.1", "type": "module", "scripts": { "dev": "vite", @@ -10,8 +10,8 @@ "preview": "vite preview" }, "dependencies": { - "framer-motion": "^12.26.0", - "motion": "^12.26.0", + "framer-motion": "^12.26.1", + "motion": "^12.26.1", "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 61a823bb1d..fe11184992 100644 --- a/dev/next/package.json +++ b/dev/next/package.json @@ -1,7 +1,7 @@ { "name": "next-env", "private": true, - "version": "12.26.0", + "version": "12.26.1", "type": "module", "scripts": { "dev": "next dev", @@ -10,7 +10,7 @@ "build": "next build" }, "dependencies": { - "motion": "^12.26.0", + "motion": "^12.26.1", "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 5903b2ba69..409580702e 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.26.0", + "version": "12.26.1", "type": "module", "scripts": { "dev": "vite", @@ -11,7 +11,7 @@ "preview": "vite preview" }, "dependencies": { - "motion": "^12.26.0", + "motion": "^12.26.1", "react": "^19.0.0", "react-dom": "^19.0.0" }, diff --git a/dev/react/package.json b/dev/react/package.json index e96ca1c1c3..20fd792163 100644 --- a/dev/react/package.json +++ b/dev/react/package.json @@ -1,7 +1,7 @@ { "name": "react-env", "private": true, - "version": "12.26.0", + "version": "12.26.1", "type": "module", "scripts": { "dev": "yarn vite", @@ -11,7 +11,7 @@ "preview": "yarn vite preview" }, "dependencies": { - "framer-motion": "^12.26.0", + "framer-motion": "^12.26.1", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/lerna.json b/lerna.json index 266eb26012..d5f40fe3d6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "12.26.0", + "version": "12.26.1", "packages": [ "packages/*", "dev/*" diff --git a/packages/framer-motion/package.json b/packages/framer-motion/package.json index 39e4e80cbe..6334abd71c 100644 --- a/packages/framer-motion/package.json +++ b/packages/framer-motion/package.json @@ -1,6 +1,6 @@ { "name": "framer-motion", - "version": "12.26.0", + "version": "12.26.1", "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 c89251e72a..45118f678b 100644 --- a/packages/motion/package.json +++ b/packages/motion/package.json @@ -1,6 +1,6 @@ { "name": "motion", - "version": "12.26.0", + "version": "12.26.1", "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.26.0", + "framer-motion": "^12.26.1", "tslib": "^2.4.0" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index 6a576f4d25..84f9dccd2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7420,7 +7420,7 @@ __metadata: languageName: node linkType: hard -"framer-motion@^12.26.0, framer-motion@workspace:packages/framer-motion": +"framer-motion@^12.26.1, 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.26.0 - motion: ^12.26.0 + framer-motion: ^12.26.1 + motion: ^12.26.1 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.26.0, motion@workspace:packages/motion": +"motion@^12.26.1, motion@workspace:packages/motion": version: 0.0.0-use.local resolution: "motion@workspace:packages/motion" dependencies: - framer-motion: ^12.26.0 + framer-motion: ^12.26.1 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.26.0 + motion: ^12.26.1 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.26.0 + motion: ^12.26.1 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.26.0 + framer-motion: ^12.26.1 react: ^18.3.1 react-dom: ^18.3.1 vite: ^5.2.0 From 08701027b0e22135e036dd4871b26761ff7f8c37 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Mon, 12 Jan 2026 11:47:50 +0100 Subject: [PATCH 4/4] Removing unused command --- .claude/commands/fix-close.md | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 .claude/commands/fix-close.md diff --git a/.claude/commands/fix-close.md b/.claude/commands/fix-close.md deleted file mode 100644 index 6b25c5b5b1..0000000000 --- a/.claude/commands/fix-close.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -description: Remove current worktree and return to main repo -allowed-tools: Bash(git worktree:*), Bash(pwd:*), Bash(basename:*) ---- - -Close the current git worktree and return to the main repository. - -## Steps - -1. List all worktrees to identify the main repo: `git worktree list` -2. Get the current directory: `pwd` -3. Determine the main repo path (first entry in worktree list) -4. Tell me to close Claude and run these commands from outside: - -```bash -cd -git worktree remove -claude -``` - -Note: You cannot remove a worktree while inside it, so I need to close Claude first.