Skip to content

React 19, framer-motion 12, tanstack query 5.72 #12841

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 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 15 additions & 7 deletions app/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,25 @@
"lint": "eslint ./src --cache --max-warnings=0"
},
"peerDependencies": {
"@tanstack/query-core": "5.59.20",
"@tanstack/vue-query": "5.59.20",
"zod": "^3.23.0"
"@tanstack/query-core": "5.72.2",
"@tanstack/vue-query": "5.73.0",
"zod": "^3.24.1",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"@internationalized/date": "3.7.0"
},
"dependencies": {
"@internationalized/date": "3.7.0",
"@tanstack/query-persist-client-core": "5.59.20",
"@tanstack/vue-query": "5.59.20",
"@tanstack/query-persist-client-core": "5.73.1",
"@types/node": "^20.11.21",
"lib0": "^0.2.99",
"react": "^18.3.1",
"vitest": "3.0.5"
},
"devDependencies": {
"@internationalized/date": "3.7.0",
"@types/react": "^19.1.1",
"@types/react-dom": "^19.1.2",
"@tanstack/vue-query": "5.73.0",
"react": "^19.1.0",
"react-dom": "^19.1.0"
}
}
47 changes: 22 additions & 25 deletions app/gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,33 +68,32 @@
"@lexical/markdown": "^0.21.0",
"@lezer/common": "^1.2.3",
"@lezer/highlight": "^1.2.1",
"@monaco-editor/react": "4.6.0",
"@monaco-editor/react": "4.7.0",
"@noble/hashes": "^1.6.1",
"@react-aria/collections": "3.0.0-alpha.7",
"@react-aria/interactions": "3.23.0",
"@sentry/vue": "^7.120.2",
"@sentry/vite-plugin": "^2.22.7",
"@stripe/react-stripe-js": "^2.9.0",
"@stripe/stripe-js": "^3.5.0",
"@tanstack/react-query": "5.59.20",
"@tanstack/vue-query": "5.59.20",
"@sentry/vue": "9.12.0",
"@sentry/vite-plugin": "3.3.1",
"@stripe/react-stripe-js": "3.6.0",
"@stripe/stripe-js": "7.0.0",
"@tanstack/react-query": "5.72.2",
"@tanstack/vue-query": "5.73.0",
"@vueuse/core": "^13.0.0",
"@vueuse/gesture": "^2.0.0",
"ag-grid-community": "^32.3.3",
"ag-grid-enterprise": "^32.3.3",
"ajv": "^8.17.1",
"amazon-cognito-identity-js": "6.3.6",
"babel-plugin-react-compiler": "19.0.0-beta-63e3235-20250105",
"clsx": "^2.1.1",
"babel-plugin-react-compiler": "19.0.0-beta-e993439-20250405",
"codemirror": "^6.0.1",
"culori": "^3.3.0",
"dotenv": "^16.4.7",
"enso-common": "workspace:*",
"events": "^3.3.0",
"framer-motion": "11.3.0",
"framer-motion": "12.6.5",
"hash-sum": "^2.0.0",
"idb-keyval": "^6.2.1",
"input-otp": "1.2.4",
"input-otp": "1.4.2",
"install": "^0.13.0",
"is-network-error": "^1.1.0",
"lexical": "^0.21.0",
Expand All @@ -107,15 +106,14 @@
"papaparse": "^5.4.1",
"postcss-inline-svg": "^6.0.0",
"postcss-nesting": "^12.1.5",
"qrcode.react": "3.1.0",
"react": "^18.3.1",
"qrcode.react": "4.2.0",
"react": "^19.1.0",
"react-aria": "3.37.0",
"react-aria-components": "1.6.0",
"react-compiler-runtime": "19.0.0-beta-decd7b8-20250118",
"react-dom": "^18.3.1",
"react-error-boundary": "4.0.13",
"react-keyed-flatten-children": "5.0.0",
"react-dom": "^19.1.0",
"react-error-boundary": "5.0.0",
"react-hook-form": "^7.54.2",
"react-keyed-flatten-children": "3.0.2",
"react-stately": "3.35.0",
"react-toastify": "^9.1.3",
"sucrase": "^3.35.0",
Expand All @@ -124,7 +122,7 @@
"tiny-invariant": "^1.3.3",
"ts-results": "^3.3.0",
"validator": "^13.12.0",
"veaury": "=2.4.4",
"veaury": "2.6.2",
"motion-v": "^1.0.0-beta.1",
"vue": "^3.5.13",
"vue-router": "^4.5.0",
Expand All @@ -135,7 +133,7 @@
"ydoc-shared": "workspace:*",
"yjs": "^13.6.21",
"zod": "^3.24.1",
"zustand": "^4.5.5"
"zustand": "5.0.3"
},
"devDependencies": {
"@babel/plugin-syntax-import-attributes": "^7.26.0",
Expand All @@ -155,11 +153,10 @@
"@storybook/test": "8.5.0",
"@storybook/vue3": "8.5.0",
"@storybook/vue3-vite": "8.5.0",
"@tanstack/react-query-devtools": "5.59.20",
"@tanstack/react-query-devtools": "5.72.2",
"@testing-library/jest-dom": "6.6.3",
"@testing-library/react": "16.0.1",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/user-event": "14.5.2",
"@testing-library/react": "16.3.0",
"@testing-library/user-event": "14.6.1",
"@tsconfig/node20": "^20.1.4",
"@types/css.escape": "^1.5.2",
"@types/culori": "^2.1.1",
Expand All @@ -169,8 +166,8 @@
"@types/mapbox-gl": "^3.4.1",
"@types/node": "^22.10.4",
"@types/papaparse": "^5.3.15",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@types/react": "^19.1.1",
"@types/react-dom": "^19.1.2",
"@types/shuffle-seed": "^1.1.3",
"@types/tar": "^6.1.13",
"@types/validator": "^13.12.2",
Expand Down
8 changes: 6 additions & 2 deletions app/gui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ import { registerAutoBlurHandler, registerGlobalBlurHandler } from '@/util/autoB
import { baseConfig, configValue, mergeConfig, type ApplicationConfigValue } from '@/util/config'
import { urlParams } from '@/util/urlParams'
import { useQueryClient } from '@tanstack/vue-query'
import { applyPureReactInVue } from 'veaury'
import { createRoot } from 'react-dom/client'
import { applyPureReactInVue, setVeauryOptions } from 'veaury'
import { computed, onMounted } from 'vue'
import { ComponentProps } from 'vue-component-type-helpers'

setVeauryOptions({ react: { createRoot } })

const ReactRootInVue = applyPureReactInVue(ReactRoot)

const { projectViewOnly, onAuthenticated } = defineProps<{
// Used in Project View integration tests. Once both test projects will be merged, this should be
// removed
Expand All @@ -43,7 +48,6 @@ const appConfig = computed(() =>
)
const appConfigValue = computed((): ApplicationConfigValue => configValue(appConfig.value))

const ReactRootWrapper = applyPureReactInVue(ReactRoot)
const queryClient = useQueryClient()

provideKeyboard()
Expand Down
43 changes: 21 additions & 22 deletions app/gui/src/ReactRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import HttpClient from '#/utilities/HttpClient'
import { QueryClientProvider } from '@tanstack/react-query'
import { QueryClient } from '@tanstack/vue-query'
import { IS_DEV_MODE, isOnElectron, isOnLinux } from 'enso-common/src/detect'
import { PropsWithChildren, StrictMode } from 'react'
import { PropsWithChildren } from 'react'
import invariant from 'tiny-invariant'

interface ReactRootProps {
queryClient: QueryClient
classSet: Map<string, number>
onAuthenticated: (accessToken: string | null) => void
classSet?: Map<string, number>
}

function generateSessionID() {
Expand Down Expand Up @@ -57,30 +57,29 @@ export default function ReactRoot(props: PropsWithChildren<ReactRootProps>) {
const isCloudBuild = $config.CLOUD_BUILD === 'true'

return (
<StrictMode>
<QueryClientProvider client={queryClient}>
<QueryClientProvider client={queryClient}>
<UIProviders locale="en-US" portalRoot={portalRoot} appRoot={appRoot}>
<ErrorBoundary>
<UIProviders locale="en-US" portalRoot={portalRoot} appRoot={appRoot}>
<Suspense fallback={<LoadingScreen />}>
<OfflineNotificationManager>
<LoggerProvider logger={console}>
<HttpClientProvider httpClient={httpClient}>
<App
supportsDeepLinks={supportsDeepLinks}
supportsLocalBackend={!isCloudBuild}
onAuthenticated={onAuthenticated}
>
<Suspense fallback={<LoadingScreen />}>
<OfflineNotificationManager>
<LoggerProvider logger={console}>
<HttpClientProvider httpClient={httpClient}>
<App
supportsDeepLinks={supportsDeepLinks}
supportsLocalBackend={!isCloudBuild}

onAuthenticated={onAuthenticated}
>
{children}
</App>
</HttpClientProvider>
</LoggerProvider>
</OfflineNotificationManager>
</Suspense>
</HttpClientProvider>
</LoggerProvider>
</OfflineNotificationManager>
</Suspense>

<ReactQueryDevtools />
</UIProviders>
<ReactQueryDevtools />
</ErrorBoundary>
</QueryClientProvider>
</StrictMode>
</UIProviders>
</QueryClientProvider>
)
}
10 changes: 5 additions & 5 deletions app/gui/src/dashboard/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ export default function App(props: React.PropsWithChildren<AppProps>) {
projectManagerInstance: new ProjectManager(config.projectManagerUrl, rootDirectory),
projectManagerRootDirectory: rootDirectory,
}
} else {
return {
projectManagerInstance: null,
projectManagerRootDirectory: null,
}
}

return {
projectManagerInstance: null,
projectManagerRootDirectory: null,
}
},
})
Expand Down
11 changes: 6 additions & 5 deletions app/gui/src/dashboard/components/Activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
* This component is used to suspend the rendering of a subtree until a promise is resolved.
*/
import { unsafeWriteValue } from '#/utilities/write'
import { startTransition, Suspense, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { useAwait } from './Await'
import { startTransition, Suspense, use, useEffect, useLayoutEffect, useRef, useState } from 'react'

/**
* Props for {@link Activity}
Expand Down Expand Up @@ -88,8 +87,10 @@ interface ActivityInnerProps {
function ActivityInner(props: ActivityInnerProps) {
const { promise, children } = props

// Suspend the subtree
useAwait(promise)
if (promise != null) {
// Suspend the subtree
use(promise)
}

return children
}
Expand All @@ -98,7 +99,7 @@ function ActivityInner(props: ActivityInnerProps) {
* Props for {@link UnhideSuspendedTree}
*/
interface UnhideSuspendedTreeProps {
readonly contentRef: React.RefObject<HTMLDivElement>
readonly contentRef: React.RefObject<HTMLDivElement | null>
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/** @file Alert component. */
import { type ForwardedRef, type HTMLAttributes, type PropsWithChildren } from 'react'
import { type HTMLAttributes, type PropsWithChildren } from 'react'

import { forwardRef } from '#/utilities/react'
import { tv, type VariantProps } from '#/utilities/tailwindVariants'
import { Icon } from '../../Icon'
import type { IconProp } from '../types'
import type { IconProp, PropsWithRef } from '../types'

// eslint-disable-next-line react-refresh/only-export-components
export const ALERT_STYLES = tv({
base: 'flex items-stretch gap-2',
Expand Down Expand Up @@ -51,16 +51,14 @@ export const ALERT_STYLES = tv({
export interface AlertProps<IconType extends string = string>
extends PropsWithChildren,
VariantProps<typeof ALERT_STYLES>,
PropsWithRef<HTMLDivElement>,
HTMLAttributes<HTMLDivElement> {
/** The icon to display in the Alert */
readonly icon?: IconProp<IconType> | null | undefined
}

/** Alert component. */
export const Alert = forwardRef(function Alert<IconType extends string = string>(
props: AlertProps<IconType>,
ref: ForwardedRef<HTMLDivElement>,
) {
export function Alert<IconType extends string = string>(props: AlertProps<IconType>) {
const {
children,
className,
Expand All @@ -72,6 +70,7 @@ export const Alert = forwardRef(function Alert<IconType extends string = string>
variants = ALERT_STYLES,
tabIndex: rawTabIndex,
role: rawRole,
ref,
...containerProps
} = props

Expand All @@ -98,4 +97,4 @@ export const Alert = forwardRef(function Alert<IconType extends string = string>
<div className={classes.children()}>{children}</div>
</div>
)
})
}
Loading
Loading