diff --git a/.yarn/releases/yarn-3.8.7.cjs b/.yarn/releases/yarn-3.8.7.cjs old mode 100755 new mode 100644 diff --git a/docs/package.json b/docs/package.json index 032793171e..3ced67a027 100644 --- a/docs/package.json +++ b/docs/package.json @@ -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": { diff --git a/package.json b/package.json index 6429c5e7f2..aacc19b7ea 100644 --- a/package.json +++ b/package.json @@ -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.0-rc.2", "@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/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", diff --git a/packages/animated/src/withAnimated.tsx b/packages/animated/src/withAnimated.tsx index ba715d8dde..cbfb3715a5 100644 --- a/packages/animated/src/withAnimated.tsx +++ b/packages/animated/src/withAnimated.tsx @@ -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() + // NOTE: useRef is bugged as immutable in 18.3 types + const observerRef = useRef( + null + ) as MutableRefObject useIsomorphicLayoutEffect(() => { observerRef.current = observer diff --git a/packages/core/src/SpringContext.tsx b/packages/core/src/SpringContext.tsx index 8e0a48d6fe..0667c310a5 100644 --- a/packages/core/src/SpringContext.tsx +++ b/packages/core/src/SpringContext.tsx @@ -13,33 +13,54 @@ export interface SpringContext { immediate?: boolean } -export const SpringContext = ({ - children, - ...props -}: PropsWithChildren) => { - const inherited = useContext(ctx) +export const SpringContext = makeRenderableContext< + SpringContext, + PropsWithChildren +>( + 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 {children} + return {children} + }, + {} as SpringContext +) + +interface RenderableContext extends React.ProviderExoticComponent

{ + Provider: RenderableContext + Consumer: React.Consumer + displayName?: string } -const ctx = makeContext(SpringContext, {} as SpringContext) +/** Make the `target` compatible with `useContext` */ +function makeRenderableContext( + target: (context: React.Context) => React.FunctionComponent

, + init: T +): RenderableContext { + 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(target: any, init: T): React.Context { - Object.assign(target, React.createContext(init)) - target.Provider._context = target - target.Consumer._context = target - return target + return context as unknown as RenderableContext } diff --git a/packages/core/src/components/Spring.tsx b/packages/core/src/components/Spring.tsx index e835c2d482..c902dd2e64 100644 --- a/packages/core/src/components/Spring.tsx +++ b/packages/core/src/components/Spring.tsx @@ -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' diff --git a/packages/core/src/components/Transition.tsx b/packages/core/src/components/Transition.tsx index 7b2a3bd337..ce7fbe7203 100644 --- a/packages/core/src/components/Transition.tsx +++ b/packages/core/src/components/Transition.tsx @@ -1,3 +1,4 @@ +import { JSX } from 'react' import { Valid } from '../types/common' import { TransitionComponentProps } from '../types' import { useTransition } from '../hooks' diff --git a/packages/core/src/hooks/useInView.ts b/packages/core/src/hooks/useInView.ts index 7d26d2c3d2..90dc6c9067 100644 --- a/packages/core/src/hooks/useInView.ts +++ b/packages/core/src/hooks/useInView.ts @@ -35,7 +35,7 @@ export function useInView( args?: IntersectionArgs ) { const [isInView, setIsInView] = useState(false) - const ref = useRef() + const ref = useRef(null) const propsFn = is.fun(props) && props diff --git a/packages/core/src/hooks/useSpring.test.tsx b/packages/core/src/hooks/useSpring.test.tsx index c5bd8892c8..68935ce676 100644 --- a/packages/core/src/hooks/useSpring.test.tsx +++ b/packages/core/src/hooks/useSpring.test.tsx @@ -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 = {elem} if (result) result.rerender(wrapped) else result = render(wrapped) diff --git a/packages/core/src/types/transition.ts b/packages/core/src/types/transition.ts index 8fe1344e0a..7ae3acf69e 100644 --- a/packages/core/src/types/transition.ts +++ b/packages/core/src/types/transition.ts @@ -1,4 +1,4 @@ -import { ReactNode } from 'react' +import { ReactNode, JSX } from 'react' import { Lookup, ObjectFromUnion, diff --git a/packages/parallax/src/index.tsx b/packages/parallax/src/index.tsx index 74e05932a5..9594c852bd 100644 --- a/packages/parallax/src/index.tsx +++ b/packages/parallax/src/index.tsx @@ -143,7 +143,7 @@ export const ParallaxLayer = React.memo( React.useImperativeHandle(ref, () => layer) - const layerRef = useRef() + const layerRef = useRef(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() - const contentRef = useRef() + const containerRef = useRef(null) + const contentRef = useRef(null) const state: IParallax = useMemoOne( () => ({ diff --git a/packages/shared/src/hooks/useMemoOne.ts b/packages/shared/src/hooks/useMemoOne.ts index 4d02743845..7d5cef54f1 100644 --- a/packages/shared/src/hooks/useMemoOne.ts +++ b/packages/shared/src/hooks/useMemoOne.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { useEffect, useRef, useState, MutableRefObject } from 'react' type Cache = { inputs?: any[] @@ -14,7 +14,8 @@ export function useMemoOne(getResult: () => T, inputs?: any[]): T { }) ) - const committed = useRef>() + // NOTE: useRef is bugged as immutable in 18.3 types + const committed = useRef>(null) as MutableRefObject | null> const prevCache = committed.current let cache = prevCache diff --git a/packages/shared/src/hooks/usePrev.ts b/packages/shared/src/hooks/usePrev.ts index 9c97e064c8..bf44a12d3a 100644 --- a/packages/shared/src/hooks/usePrev.ts +++ b/packages/shared/src/hooks/usePrev.ts @@ -2,7 +2,7 @@ import { useEffect, useRef } from 'react' /** Use a value from the previous render */ export function usePrev(value: T): T | undefined { - const prevRef = useRef() + const prevRef = useRef(null) useEffect(() => { prevRef.current = value }) diff --git a/targets/three/src/animated.ts b/targets/three/src/animated.ts index 39f100b5e4..230837381b 100644 --- a/targets/three/src/animated.ts +++ b/targets/three/src/animated.ts @@ -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, diff --git a/targets/three/src/index.ts b/targets/three/src/index.ts index 7840ae51ad..a8c4a9410a 100644 --- a/targets/three/src/index.ts +++ b/targets/three/src/index.ts @@ -19,7 +19,7 @@ addEffect(() => { }) const host = createHost(primitives, { - // @ts-expect-error r3f related + // @ts-ignore related to R3F v8 applyAnimatedValues: applyProps, }) diff --git a/targets/three/src/primitives.ts b/targets/three/src/primitives.ts index 16c36921b0..228d5bf1bc 100644 --- a/targets/three/src/primitives.ts +++ b/targets/three/src/primitives.ts @@ -1,5 +1,5 @@ import * as THREE from 'three' -import '@react-three/fiber' +import { JSX } from 'react' export type Primitives = keyof JSX.IntrinsicElements diff --git a/targets/web/src/primitives.ts b/targets/web/src/primitives.ts index a77a1f3d70..23edb245fa 100644 --- a/targets/web/src/primitives.ts +++ b/targets/web/src/primitives.ts @@ -1,3 +1,5 @@ +import { JSX } from 'react' + export type Primitives = keyof JSX.IntrinsicElements export const primitives: Primitives[] = [ 'a', diff --git a/yarn.lock b/yarn.lock index c0fdc04aab..4ed4a9c261 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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.0-rc.2": + version: 9.0.0-rc.2 + resolution: "@react-three/fiber@npm:9.0.0-rc.2" + dependencies: + "@babel/runtime": ^7.17.8 + "@types/debounce": ^1.2.1 + "@types/react-reconciler": ^0.28.8 + "@types/webxr": "*" + base64-js: ^1.5.1 + buffer: ^6.0.3 + debounce: ^1.2.1 + its-fine: ^1.2.5 + react-reconciler: 0.31.0 + scheduler: 0.25.0 + suspend-react: ^0.1.3 + zustand: ^4.1.2 + 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.69" + 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: efb7af039705b10fa456c3e90338e0d5fdaba50238901c84e3b7ddc59cc9b07f178900077625a628a53b9cc2013eca804bd5268b5f28883718b13e13ad85d4af + 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.8": + 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" @@ -12508,7 +12570,7 @@ __metadata: languageName: node linkType: hard -"its-fine@npm:^1.0.6, its-fine@npm:^1.1.1": +"its-fine@npm:^1.0.6, its-fine@npm:^1.1.1, its-fine@npm:^1.2.5": version: 1.2.5 resolution: "its-fine@npm:1.2.5" dependencies: @@ -16886,6 +16948,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" @@ -17001,6 +17074,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.27.0": version: 0.27.0 resolution: "react-reconciler@npm:0.27.0" @@ -17125,7 +17209,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.0-rc.2 "@remix-run/dev": 2.15.2 "@simonsmith/cypress-image-snapshot": 9.1.0 "@swc/core": 1.10.4 @@ -17138,8 +17222,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 +17238,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 +17310,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: @@ -17269,6 +17353,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" @@ -18035,6 +18126,13 @@ __metadata: languageName: node linkType: hard +"scheduler@npm:0.25.0, scheduler@npm:^0.25.0": + version: 0.25.0 + resolution: "scheduler@npm:0.25.0" + checksum: b7bb9fddbf743e521e9aaa5198a03ae823f5e104ebee0cb9ec625392bb7da0baa1c28ab29cee4b1e407a94e76acc6eee91eeb749614f91f853efda2613531566 + languageName: node + linkType: hard + "scheduler@npm:^0.21.0": version: 0.21.0 resolution: "scheduler@npm:0.21.0" @@ -20138,6 +20236,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.2.2": + 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" @@ -21034,6 +21141,26 @@ __metadata: languageName: node linkType: hard +"zustand@npm:^4.1.2": + version: 4.5.6 + resolution: "zustand@npm:4.5.6" + dependencies: + use-sync-external-store: ^1.2.2 + peerDependencies: + "@types/react": ">=16.8" + immer: ">=9.0.6" + react: ">=16.8" + peerDependenciesMeta: + "@types/react": + optional: true + immer: + optional: true + react: + optional: true + checksum: c4e9c809c92195fa2f9e8e0cd6631b6830fc9676343c8584c20cf26d402f220c54ae0479a299dbcd5e1cdfc5977f116838f1b5f39d6a4997ff727c6cebe60d3f + languageName: node + linkType: hard + "zustand@npm:^4.3.2": version: 4.5.5 resolution: "zustand@npm:4.5.5"