Skip to content

feat: React 19 support #2349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 25 commits into from
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2843b31
feat!: React 19 support
CodyJasonBennett Jan 2, 2025
8f36899
fix: remaining type errors
CodyJasonBennett Jan 2, 2025
4053dcc
chore: cleanup
CodyJasonBennett Jan 2, 2025
a3bd26d
docs: add missing react-use-measure dep
CodyJasonBennett Jan 2, 2025
a0652aa
chore: resolve conflicts
CodyJasonBennett Jan 8, 2025
f1b2617
docs: add missing use-gesture dep
CodyJasonBennett Jan 8, 2025
6cdab5e
chore: prefer JSX.IntrinsicElements for backwards compat
CodyJasonBennett Jan 8, 2025
a7fd0ac
chore: keep PropsWithRef for React 18
CodyJasonBennett Jan 8, 2025
f201223
chore(SpringContext): add React 18 backwards compat
CodyJasonBennett Jan 8, 2025
f25225d
fix(SpringContext): swap mutation target
CodyJasonBennett Jan 8, 2025
f3cef19
fix(SpringContext): typo
CodyJasonBennett Jan 8, 2025
9b12ea6
fix(SpringContext): feature check renderable context for consumer
CodyJasonBennett Jan 9, 2025
cafa5b8
chore: cleanup
CodyJasonBennett Jan 9, 2025
97b33db
experiment: revert dep upgrade
CodyJasonBennett Jan 9, 2025
20c7df5
experiment: restore dep upgrade
CodyJasonBennett Jan 9, 2025
6c06950
experiment: keep MutableRefObject
CodyJasonBennett Jan 10, 2025
33364f8
experiment: revert deps upgrade
CodyJasonBennett Jan 10, 2025
51312c3
Revert "experiment: keep MutableRefObject"
CodyJasonBennett Jan 10, 2025
59579e2
fix: add annotation for 18.3 immutable useRef
CodyJasonBennett Jan 10, 2025
a61d9e7
experiment: keep MutableRefObject
CodyJasonBennett Jan 10, 2025
983ca3f
experiment: upgrade deps to React 19
CodyJasonBennett Jan 10, 2025
c30d8a0
chore: upgrade to rc.2
CodyJasonBennett Jan 10, 2025
efda668
chore: cleanup
CodyJasonBennett Jan 10, 2025
7c57dff
experiment: test suite fixes
CodyJasonBennett Feb 19, 2025
3aaa957
chore: use R3F v9 stable
CodyJasonBennett Feb 21, 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
Empty file modified .yarn/releases/yarn-3.8.7.cjs
100755 → 100644
Empty file.
2 changes: 2 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
"@remix-run/serve": "2.15.2",
"@remix-run/server-runtime": "2.15.2",
"@supabase/supabase-js": "2.47.10",
"@use-gesture/react": "^10.3.1",
"@vanilla-extract/css": "1.17.0",
"@vanilla-extract/dynamic": "2.1.2",
"@vanilla-extract/recipes": "0.5.5",
@@ -44,6 +45,7 @@
"react": "18.3.1",
"react-dom": "18.3.1",
"react-select": "5.9.0",
"react-use-measure": "^2.1.1",
"zod": "3.24.1"
},
"devDependencies": {
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@
"@changesets/cli": "2.27.11",
"@commitlint/cli": "19.6.1",
"@commitlint/config-conventional": "19.6.0",
"@react-three/fiber": "8.17.10",
"@react-three/fiber": "^9.0.4",
"@remix-run/dev": "2.15.2",
"@simonsmith/cypress-image-snapshot": "9.1.0",
"@swc/core": "1.10.4",
@@ -79,8 +79,8 @@
"@types/jest": "29.5.14",
"@types/lodash.clamp": "4.0.9",
"@types/lodash.shuffle": "4.2.9",
"@types/react": "18.3.18",
"@types/react-dom": "18.3.5",
"@types/react": "19.0.2",
"@types/react-dom": "19.0.2",
"@types/react-lazyload": "3.2.3",
"@types/react-native": "0.73.0",
"@types/styled-components": "5.1.34",
@@ -95,8 +95,8 @@
"mock-raf": "npm:@react-spring/[email protected]",
"prettier": "3.4.2",
"pretty-quick": "4.0.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-konva": "18.2.10",
"react-native": "0.76.5",
"react-zdog": "1.2.2",
14 changes: 12 additions & 2 deletions packages/animated/src/withAnimated.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import * as React from 'react'
import { forwardRef, useRef, Ref, useCallback, useEffect } from 'react'
import {
forwardRef,
useRef,
Ref,
useCallback,
useEffect,
MutableRefObject,
} from 'react'
import {
is,
each,
@@ -66,7 +73,10 @@ export const withAnimated = (Component: any, host: HostConfig) => {

const observer = new PropsObserver(callback, deps)

const observerRef = useRef<PropsObserver>()
// NOTE: useRef is bugged as immutable in 18.3 types
const observerRef = useRef<PropsObserver>(
null
) as MutableRefObject<PropsObserver | null>
useIsomorphicLayoutEffect(() => {
observerRef.current = observer

65 changes: 43 additions & 22 deletions packages/core/src/SpringContext.tsx
Original file line number Diff line number Diff line change
@@ -13,33 +13,54 @@ export interface SpringContext {
immediate?: boolean
}

export const SpringContext = ({
children,
...props
}: PropsWithChildren<SpringContext>) => {
const inherited = useContext(ctx)
export const SpringContext = makeRenderableContext<
SpringContext,
PropsWithChildren<SpringContext>
>(
Context =>
({ children, ...props }) => {
const inherited = useContext(Context)

// Inherited values are dominant when truthy.
const pause = props.pause || !!inherited.pause,
immediate = props.immediate || !!inherited.immediate
// Inherited values are dominant when truthy.
const pause = props.pause || !!inherited.pause
const immediate = props.immediate || !!inherited.immediate

// Memoize the context to avoid unwanted renders.
props = useMemoOne(() => ({ pause, immediate }), [pause, immediate])
// Memoize the context to avoid unwanted renders.
props = useMemoOne(() => ({ pause, immediate }), [pause, immediate])

const { Provider } = ctx
return <Provider value={props}>{children}</Provider>
return <Context.Provider value={props}>{children}</Context.Provider>
},
{} as SpringContext
)

interface RenderableContext<T, P> extends React.ProviderExoticComponent<P> {
Provider: RenderableContext<T, P>
Consumer: React.Consumer<T>
displayName?: string
}

const ctx = makeContext(SpringContext, {} as SpringContext)
/** Make the `target` compatible with `useContext` */
function makeRenderableContext<T, P>(
target: (context: React.Context<T>) => React.FunctionComponent<P>,
init: T
): RenderableContext<T, P> {
let context = React.createContext(init)
context = Object.assign(target(context), context)

// https://github.com/facebook/react/pull/28226
if ('_context' in context.Provider) {
context.Provider._context = context
} else {
// @ts-ignore React 18 types disallow this
context.Provider = context
}

// Allow `useContext(SpringContext)` in TypeScript.
SpringContext.Provider = ctx.Provider
SpringContext.Consumer = ctx.Consumer
if ('_context' in context.Consumer) {
context.Consumer._context = context
} else {
// @ts-expect-error
context.Consumer = context
}

/** Make the `target` compatible with `useContext` */
function makeContext<T>(target: any, init: T): React.Context<T> {
Object.assign(target, React.createContext(init))
target.Provider._context = target
target.Consumer._context = target
return target
return context as unknown as RenderableContext<T, P>
}
1 change: 1 addition & 0 deletions packages/core/src/components/Spring.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { JSX } from 'react'
import { NoInfer, UnknownProps } from '@react-spring/types'
import { useSpring, UseSpringProps } from '../hooks/useSpring'
import { SpringValues, SpringToFn, SpringChain } from '../types'
1 change: 1 addition & 0 deletions packages/core/src/components/Transition.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { JSX } from 'react'
import { Valid } from '../types/common'
import { TransitionComponentProps } from '../types'
import { useTransition } from '../hooks'
2 changes: 1 addition & 1 deletion packages/core/src/hooks/useInView.ts
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ export function useInView<TElement extends HTMLElement>(
args?: IntersectionArgs
) {
const [isInView, setIsInView] = useState(false)
const ref = useRef<TElement>()
const ref = useRef<TElement>(null)

const propsFn = is.fun(props) && props

4 changes: 2 additions & 2 deletions packages/core/src/hooks/useSpring.test.tsx
Original file line number Diff line number Diff line change
@@ -115,7 +115,7 @@ interface TestContext extends SpringContext {
}

function createUpdater(Component: React.ComponentType<{ args: [any, any?] }>) {
let prevElem: JSX.Element | undefined
let prevElem: React.JSX.Element | undefined
let result: RenderResult | undefined

const context: TestContext = {
@@ -139,7 +139,7 @@ function createUpdater(Component: React.ComponentType<{ args: [any, any?] }>) {
}
})

function renderWithContext(elem: JSX.Element) {
function renderWithContext(elem: React.JSX.Element) {
const wrapped = <SpringContext {...context}>{elem}</SpringContext>
if (result) result.rerender(wrapped)
else result = render(wrapped)
13 changes: 9 additions & 4 deletions packages/core/src/hooks/useSprings.ts
Original file line number Diff line number Diff line change
@@ -82,7 +82,7 @@
// Create a local ref if a props function or deps array is ever passed.
const ref = useMemo(
() => (propsFn || arguments.length == 3 ? SpringRef() : void 0),
[]

Check warning on line 85 in packages/core/src/hooks/useSprings.ts

GitHub Actions / Style Checks

React Hook useMemo has a missing dependency: 'propsFn'. Either include it or remove the dependency array
)

interface State {
@@ -124,11 +124,12 @@
})
},
}),
[]

Check warning on line 127 in packages/core/src/hooks/useSprings.ts

GitHub Actions / Style Checks

React Hook useMemo has a missing dependency: 'forceUpdate'. Either include it or remove the dependency array
)

const ctrls = useRef([...state.ctrls])
const updates: any[] = []
const updates = useRef<any[]>(null!)
updates.current ??= []

// Cache old controllers to dispose in the commit phase.
const prevLength = usePrev(length) || 0
@@ -144,13 +145,13 @@
ctrls.current.length = length

declareUpdates(prevLength, length)
}, [length])

Check warning on line 148 in packages/core/src/hooks/useSprings.ts

GitHub Actions / Style Checks

React Hook useMemo has missing dependencies: 'declareUpdates', 'prevLength', and 'ref'. Either include them or remove the dependency array

// Update existing controllers when "deps" are changed.
useMemo(() => {
declareUpdates(0, Math.min(prevLength, length))
// @ts-expect-error – we want to allow passing undefined to useMemo
}, deps)

Check warning on line 154 in packages/core/src/hooks/useSprings.ts

GitHub Actions / Style Checks

React Hook useMemo was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies

Check warning on line 154 in packages/core/src/hooks/useSprings.ts

GitHub Actions / Style Checks

React Hook useMemo has missing dependencies: 'declareUpdates', 'length', and 'prevLength'. Either include them or remove the dependency array

/** Fill the `updates` array with declarative updates for the given index range. */
function declareUpdates(startIndex: number, endIndex: number) {
@@ -164,15 +165,17 @@
: (props as any)[i]

if (update) {
updates[i] = declareUpdate(update)
updates.current[i] = declareUpdate(update)
}
}
}

// New springs are created during render so users can pass them to
// their animated components, but new springs aren't cached until the
// commit phase (see the `useIsomorphicLayoutEffect` callback below).
const springs = ctrls.current.map((ctrl, i) => getSprings(ctrl, updates[i]))
const springs = ctrls.current.map((ctrl, i) =>
getSprings(ctrl, updates.current[i])
)

const context = useContext(SpringContext)
const prevContext = usePrev(context)
@@ -202,7 +205,7 @@
}

// Apply updates created during render.
const update = updates[i]
const update = updates.current[i]
if (update) {
// Update the injected ref if needed.
replaceRef(ctrl, update.ref)
@@ -214,6 +217,8 @@
} else {
ctrl.start(update)
}

updates.current[i] = null
}
})
})
2 changes: 1 addition & 1 deletion packages/core/src/types/transition.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react'
import { ReactNode, JSX } from 'react'
import {
Lookup,
ObjectFromUnion,
7 changes: 2 additions & 5 deletions packages/core/test/setup.ts
Original file line number Diff line number Diff line change
@@ -60,9 +60,6 @@ beforeEach(() => {
requestAnimationFrame: global.mockRaf.raf,
colors,
skipAnimation: false,
// This lets our useTransition hook force its component
// to update from within an "onRest" handler.
batchedUpdates: act,
})
})

@@ -138,7 +135,7 @@ global.advanceUntil = async test => {
willAdvance: observe,
})

jest.advanceTimersByTime(1000 / 60)
await act(() => jest.advanceTimersByTimeAsync(1000 / 60))
global.mockRaf.step()

// Stop observing after the frame is processed.
@@ -147,7 +144,7 @@ global.advanceUntil = async test => {
}

// Ensure pending effects are flushed.
await flushMicroTasks()
await act(() => flushMicroTasks())

// Prevent infinite recursion.
if (++steps > 1e3) {
6 changes: 3 additions & 3 deletions packages/parallax/src/index.tsx
Original file line number Diff line number Diff line change
@@ -143,7 +143,7 @@ export const ParallaxLayer = React.memo(

React.useImperativeHandle(ref, () => layer)

const layerRef = useRef<any>()
const layerRef = useRef<any>(null)

const setSticky = (height: number, scrollTop: number) => {
const start = layer.sticky!.start! * height
@@ -229,8 +229,8 @@ export const Parallax = React.memo(
...rest
} = props

const containerRef = useRef<any>()
const contentRef = useRef<any>()
const containerRef = useRef<any>(null)
const contentRef = useRef<any>(null)

const state: IParallax = useMemoOne(
() => ({
5 changes: 3 additions & 2 deletions packages/shared/src/hooks/useMemoOne.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react'
import { useEffect, useRef, useState, MutableRefObject } from 'react'

type Cache<T> = {
inputs?: any[]
@@ -14,7 +14,8 @@ export function useMemoOne<T>(getResult: () => T, inputs?: any[]): T {
})
)

const committed = useRef<Cache<T>>()
// NOTE: useRef is bugged as immutable in 18.3 types
const committed = useRef<Cache<T>>(null) as MutableRefObject<Cache<T> | null>
const prevCache = committed.current

let cache = prevCache
2 changes: 1 addition & 1 deletion packages/shared/src/hooks/usePrev.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { useEffect, useRef } from 'react'

/** Use a value from the previous render */
export function usePrev<T>(value: T): T | undefined {
const prevRef = useRef<any>()
const prevRef = useRef<any>(null)
useEffect(() => {
prevRef.current = value
})
2 changes: 1 addition & 1 deletion targets/three/src/animated.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { CSSProperties, ForwardRefExoticComponent, FC } from 'react'
import { CSSProperties, ForwardRefExoticComponent, FC, JSX } from 'react'
import {
AssignableKeys,
ComponentPropsWithRef,
2 changes: 1 addition & 1 deletion targets/three/src/index.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ addEffect(() => {
})

const host = createHost(primitives, {
// @ts-expect-error r3f related
// @ts-ignore related to R3F v8
applyAnimatedValues: applyProps,
})

2 changes: 1 addition & 1 deletion targets/three/src/primitives.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as THREE from 'three'
import '@react-three/fiber'
import { JSX } from 'react'

export type Primitives = keyof JSX.IntrinsicElements

2 changes: 2 additions & 0 deletions targets/web/src/primitives.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { JSX } from 'react'

export type Primitives = keyof JSX.IntrinsicElements
export const primitives: Primitives[] = [
'a',
176 changes: 164 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -4682,6 +4682,7 @@ __metadata:
"@remix-run/serve": 2.15.2
"@remix-run/server-runtime": 2.15.2
"@supabase/supabase-js": 2.47.10
"@use-gesture/react": ^10.3.1
"@vanilla-extract/css": 1.17.0
"@vanilla-extract/dynamic": 2.1.2
"@vanilla-extract/recipes": 0.5.5
@@ -4702,6 +4703,7 @@ __metadata:
react: 18.3.1
react-dom: 18.3.1
react-select: 5.9.0
react-use-measure: ^2.1.1
refractor: 4.8.1
rehype-autolink-headings: 7.1.0
rehype-parse: 9.0.1
@@ -4908,6 +4910,48 @@ __metadata:
languageName: node
linkType: hard

"@react-three/fiber@npm:^9.0.4":
version: 9.0.4
resolution: "@react-three/fiber@npm:9.0.4"
dependencies:
"@babel/runtime": ^7.17.8
"@types/react-reconciler": ^0.28.9
"@types/webxr": "*"
base64-js: ^1.5.1
buffer: ^6.0.3
its-fine: ^2.0.0
react-reconciler: ^0.31.0
react-use-measure: ^2.1.7
scheduler: ^0.25.0
suspend-react: ^0.1.3
use-sync-external-store: ^1.4.0
zustand: ^5.0.3
peerDependencies:
expo: ">=43.0"
expo-asset: ">=8.4"
expo-file-system: ">=11.0"
expo-gl: ">=11.0"
react: ^19.0.0
react-dom: ^19.0.0
react-native: ">=0.78"
three: ">=0.156"
peerDependenciesMeta:
expo:
optional: true
expo-asset:
optional: true
expo-file-system:
optional: true
expo-gl:
optional: true
react-dom:
optional: true
react-native:
optional: true
checksum: 222d90d1d108c5abd0b568222835062e0add08a49ee5fadf23681a91251fa7f8c1b048854c21169a25f162abf6fe6371858040307a1e8fbcc917614e22204dd2
languageName: node
linkType: hard

"@remix-run/dev@npm:2.15.2":
version: 2.15.2
resolution: "@remix-run/dev@npm:2.15.2"
@@ -6047,12 +6091,12 @@ __metadata:
languageName: node
linkType: hard

"@types/react-dom@npm:18.3.5":
version: 18.3.5
resolution: "@types/react-dom@npm:18.3.5"
"@types/react-dom@npm:19.0.2":
version: 19.0.2
resolution: "@types/react-dom@npm:19.0.2"
peerDependencies:
"@types/react": ^18.0.0
checksum: 95c757684f71e761515c5a11299e5feec550c72bb52975487f360e6f0d359b26454c26eaf2ce45dd22748205aa9b2c2fe0abe7005ebcbd233a7615283ac39a7d
"@types/react": ^19.0.0
checksum: d2ae81ec0b8eee7a4bf31918796fdaa34e8db68f69682163bc212d759de76783e6ffcc02c02722dcf508429067148841e6da81414cc730ca2a28c9c2b350c880
languageName: node
linkType: hard

@@ -6092,6 +6136,15 @@ __metadata:
languageName: node
linkType: hard

"@types/react-reconciler@npm:^0.28.9":
version: 0.28.9
resolution: "@types/react-reconciler@npm:0.28.9"
peerDependencies:
"@types/react": "*"
checksum: 06257f693c7b148a4258c0d0a958288116100014e7b3c21ceaea2d55a668c71718f79b4105a9a0f35b480f3729e46960b40026d685719f9386b4ed63108dda09
languageName: node
linkType: hard

"@types/react-transition-group@npm:^4.4.0":
version: 4.4.10
resolution: "@types/react-transition-group@npm:4.4.10"
@@ -6101,7 +6154,7 @@ __metadata:
languageName: node
linkType: hard

"@types/react@npm:*, @types/react@npm:18.3.18":
"@types/react@npm:*":
version: 18.3.18
resolution: "@types/react@npm:18.3.18"
dependencies:
@@ -6111,6 +6164,15 @@ __metadata:
languageName: node
linkType: hard

"@types/react@npm:19.0.2":
version: 19.0.2
resolution: "@types/react@npm:19.0.2"
dependencies:
csstype: ^3.0.2
checksum: 2f12c2a84b778283884d41560c723d815153d88c56cacf25c0166329e9099c35c82c602a21d8831a381e2ef5574434ebd7bf09a636fe073558919474b0b3c9ed
languageName: node
linkType: hard

"@types/semver@npm:^7.5.0":
version: 7.5.6
resolution: "@types/semver@npm:7.5.6"
@@ -12519,6 +12581,17 @@ __metadata:
languageName: node
linkType: hard

"its-fine@npm:^2.0.0":
version: 2.0.0
resolution: "its-fine@npm:2.0.0"
dependencies:
"@types/react-reconciler": ^0.28.9
peerDependencies:
react: ^19.0.0
checksum: 887ff10d8dfe8558683d5f68ad963c72a28c6df027c5039de7ec57978e5071c564ef4b00b14ef41e7706e5839a5584cbd480a79a3880f78d7ff826931e5dc22a
languageName: node
linkType: hard

"jackspeak@npm:^3.1.2":
version: 3.4.3
resolution: "jackspeak@npm:3.4.3"
@@ -16886,6 +16959,17 @@ __metadata:
languageName: node
linkType: hard

"react-dom@npm:19.0.0":
version: 19.0.0
resolution: "react-dom@npm:19.0.0"
dependencies:
scheduler: ^0.25.0
peerDependencies:
react: ^19.0.0
checksum: 009cc6e575263a0d1906f9dd4aa6532d2d3d0d71e4c2b7777c8fe4de585fa06b5b77cdc2e0fbaa2f3a4a5e5d3305c189ba152153f358ee7da4d9d9ba5d3a8975
languageName: node
linkType: hard

"react-dropzone@npm:^12.0.0":
version: 12.1.0
resolution: "react-dropzone@npm:12.1.0"
@@ -17013,6 +17097,17 @@ __metadata:
languageName: node
linkType: hard

"react-reconciler@npm:^0.31.0":
version: 0.31.0
resolution: "react-reconciler@npm:0.31.0"
dependencies:
scheduler: ^0.25.0
peerDependencies:
react: ^19.0.0
checksum: 820c4e4003c5615849bf0cda97d8a55b99af2bb59cc0825882b727f0ad0c4bf4581bb3d25e00beca1164203dbc172f0a8c4725e7aa2fb85e025938722384a84e
languageName: node
linkType: hard

"react-reconciler@npm:~0.29.0":
version: 0.29.0
resolution: "react-reconciler@npm:0.29.0"
@@ -17125,7 +17220,7 @@ __metadata:
"@changesets/cli": 2.27.11
"@commitlint/cli": 19.6.1
"@commitlint/config-conventional": 19.6.0
"@react-three/fiber": 8.17.10
"@react-three/fiber": ^9.0.4
"@remix-run/dev": 2.15.2
"@simonsmith/cypress-image-snapshot": 9.1.0
"@swc/core": 1.10.4
@@ -17138,8 +17233,8 @@ __metadata:
"@types/jest": 29.5.14
"@types/lodash.clamp": 4.0.9
"@types/lodash.shuffle": 4.2.9
"@types/react": 18.3.18
"@types/react-dom": 18.3.5
"@types/react": 19.0.2
"@types/react-dom": 19.0.2
"@types/react-lazyload": 3.2.3
"@types/react-native": 0.73.0
"@types/styled-components": 5.1.34
@@ -17154,8 +17249,8 @@ __metadata:
mock-raf: "npm:@react-spring/mock-raf@1.1.1"
prettier: 3.4.2
pretty-quick: 4.0.0
react: 18.3.1
react-dom: 18.3.1
react: 19.0.0
react-dom: 19.0.0
react-konva: 18.2.10
react-native: 0.76.5
react-zdog: 1.2.2
@@ -17226,7 +17321,7 @@ __metadata:
languageName: node
linkType: hard

"react-use-measure@npm:2.1.1":
"react-use-measure@npm:2.1.1, react-use-measure@npm:^2.1.1":
version: 2.1.1
resolution: "react-use-measure@npm:2.1.1"
dependencies:
@@ -17238,6 +17333,19 @@ __metadata:
languageName: node
linkType: hard

"react-use-measure@npm:^2.1.7":
version: 2.1.7
resolution: "react-use-measure@npm:2.1.7"
peerDependencies:
react: ">=16.13"
react-dom: ">=16.13"
peerDependenciesMeta:
react-dom:
optional: true
checksum: 5f00c14cf50b0710cdbd27b63a005be20283099d2fa2723a97f3a1cf0b2daedddd67249520c21e49e95348f56428689f3229c343dcb9ed37da58f9c227d29bee
languageName: node
linkType: hard

"react-zdog@npm:1.2.2":
version: 1.2.2
resolution: "react-zdog@npm:1.2.2"
@@ -17269,6 +17377,13 @@ __metadata:
languageName: node
linkType: hard

"react@npm:19.0.0":
version: 19.0.0
resolution: "react@npm:19.0.0"
checksum: 86de15d85b2465feb40297a90319c325cb07cf27191a361d47bcfe8c6126c973d660125aa67b8f4cbbe39f15a2f32efd0c814e98196d8e5b68c567ba40a399c6
languageName: node
linkType: hard

"read-yaml-file@npm:^1.1.0":
version: 1.1.0
resolution: "read-yaml-file@npm:1.1.0"
@@ -18053,6 +18168,13 @@ __metadata:
languageName: node
linkType: hard

"scheduler@npm:^0.25.0":
version: 0.25.0
resolution: "scheduler@npm:0.25.0"
checksum: b7bb9fddbf743e521e9aaa5198a03ae823f5e104ebee0cb9ec625392bb7da0baa1c28ab29cee4b1e407a94e76acc6eee91eeb749614f91f853efda2613531566
languageName: node
linkType: hard

"section-matter@npm:^1.0.0":
version: 1.0.0
resolution: "section-matter@npm:1.0.0"
@@ -20138,6 +20260,15 @@ __metadata:
languageName: node
linkType: hard

"use-sync-external-store@npm:^1.4.0":
version: 1.4.0
resolution: "use-sync-external-store@npm:1.4.0"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: dc3843a1b59ac8bd01417bd79498d4c688d5df8bf4801be50008ef4bfaacb349058c0b1605b5b43c828e0a2d62722d7e861573b3f31cea77a7f23e8b0fc2f7e3
languageName: node
linkType: hard

"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1":
version: 1.0.2
resolution: "util-deprecate@npm:1.0.2"
@@ -21075,6 +21206,27 @@ __metadata:
languageName: node
linkType: hard

"zustand@npm:^5.0.3":
version: 5.0.3
resolution: "zustand@npm:5.0.3"
peerDependencies:
"@types/react": ">=18.0.0"
immer: ">=9.0.6"
react: ">=18.0.0"
use-sync-external-store: ">=1.2.0"
peerDependenciesMeta:
"@types/react":
optional: true
immer:
optional: true
react:
optional: true
use-sync-external-store:
optional: true
checksum: 72da39ac3017726c3562c615a0f76cee0c9ea678d664f82ee7669f8cb5e153ee81059363473094e4154d73a2935ee3459f6792d1ec9d08d2e72ebe641a16a6ba
languageName: node
linkType: hard

"zwitch@npm:^2.0.0, zwitch@npm:^2.0.4":
version: 2.0.4
resolution: "zwitch@npm:2.0.4"

Unchanged files with check annotations Beta

}
// The animated prop value of a React element
type AnimatedProp<T> = [T, T] extends [infer T, infer DT]

Check warning on line 31 in targets/zdog/src/animated.ts

GitHub Actions / Style Checks

'T' is defined but never used. Allowed unused vars must match /^_/u
? [DT] extends [never]
? never
: DT extends void
: never
// An animated object of style attributes
type AnimatedStyle<T> = [T, T] extends [infer T, infer DT]

Check warning on line 42 in targets/zdog/src/animated.ts

GitHub Actions / Style Checks

'T' is defined but never used. Allowed unused vars must match /^_/u
? DT extends void
? undefined
: [DT] extends [never]
config: { mass: 20, tension: 150, friction: 50 }
}))
React.useEffect(() => void setInterval(() => api.start((i) => ({ ...random(i), delay: i * 40 })), 3000), [])

Check warning on line 34 in demo/src/sandboxes/springy-boxes/src/App.tsx

GitHub Actions / Style Checks

React Hook React.useEffect has a missing dependency: 'api'. Either include it or remove the dependency array
return (
<>
// Return a `SpringRef` if a deps array was passed.
const ref = useMemo(
() => (propsFn || arguments.length == 3 ? SpringRef() : void 0),
[]

Check warning on line 94 in packages/core/src/hooks/useTransition.tsx

GitHub Actions / Style Checks

React Hook useMemo has a missing dependency: 'propsFn'. Either include it or remove the dependency array
)
// Every item has its own transition.
(start: StartFn<T>, stop: StopFn<T>): Promise<any> | void
}
type StartFn<T> = InferTarget<T> extends { start: infer T } ? T : never

Check warning on line 35 in packages/core/src/types/functions.ts

GitHub Actions / Style Checks

'T' is defined but never used. Allowed unused vars must match /^_/u
type StopFn<T> = InferTarget<T> extends { stop: infer T } ? T : never
/**