diff --git a/lib/makeWebpackConfig.js b/lib/makeWebpackConfig.js index 98698e16..2cd7d317 100644 --- a/lib/makeWebpackConfig.js +++ b/lib/makeWebpackConfig.js @@ -30,7 +30,7 @@ module.exports = async (playroomConfig, options) => { } ); const { version } = JSON.parse(pkgContents); - isLegacyReact = !(version.startsWith('18') || version.startsWith('0.0.0')); + isLegacyReact = !(version.startsWith('18') || version.startsWith('19') || version.startsWith('0.0.0')); } catch (e) { throw new Error('Unable to read `react-dom` package json'); } diff --git a/package.json b/package.json index 0f77b664..e5c14d29 100644 --- a/package.json +++ b/package.json @@ -73,8 +73,8 @@ "@types/base64-url": "^2.2.0", "@types/codemirror": "^5.60.5", "@types/prettier": "^2.7.1", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.9", + "@types/react": "19.0.8", + "@types/react-dom": "19.0.3", "@vanilla-extract/css": "^1.9.2", "@vanilla-extract/css-utils": "^0.1.3", "@vanilla-extract/dynamic": "^2.1.2", @@ -132,15 +132,15 @@ "husky": "^8.0.2", "jest": "^29.3.1", "lint-staged": "^15.2.2", - "react": "^18.0.1", - "react-dom": "^18.0.1", + "react": "19.0.0", + "react-dom": "19.0.0", "serve": "^14.1.2", "start-server-and-test": "^1.15.2", "surge": "^0.23.1" }, "peerDependencies": { - "react": "^17 || ^18", - "react-dom": "^17 || ^18" + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" }, "engines": { "node": ">=18.12.0" @@ -148,5 +148,10 @@ "packageManager": "pnpm@8.15.3", "volta": { "node": "18.19.1" + }, + "pnpm": { + "patchedDependencies": { + "react-use@17.4.0": "patches/react-use@17.4.0.patch" + } } } diff --git a/patches/react-use@17.4.0.patch b/patches/react-use@17.4.0.patch new file mode 100644 index 00000000..6e214d80 --- /dev/null +++ b/patches/react-use@17.4.0.patch @@ -0,0 +1,21 @@ +diff --git a/CHANGELOG.md b/CHANGELOG.md +deleted file mode 100644 +index 9b28df0e8aa4734af2c7006fd077ff17e2281db5..0000000000000000000000000000000000000000 +diff --git a/esm/useIntersection.d.ts b/esm/useIntersection.d.ts +index 9d3ac04942d2f3118e5fb5bf3c1758e4513d1fa5..62d128868aa774d80674896a3ce532a6125526aa 100644 +--- a/esm/useIntersection.d.ts ++++ b/esm/useIntersection.d.ts +@@ -1,3 +1,3 @@ + import { RefObject } from 'react'; +-declare const useIntersection: (ref: RefObject, options: IntersectionObserverInit) => IntersectionObserverEntry | null; ++declare const useIntersection: (ref: RefObject, options: IntersectionObserverInit) => IntersectionObserverEntry | null; + export default useIntersection; +diff --git a/lib/useIntersection.d.ts b/lib/useIntersection.d.ts +index 9d3ac04942d2f3118e5fb5bf3c1758e4513d1fa5..62d128868aa774d80674896a3ce532a6125526aa 100644 +--- a/lib/useIntersection.d.ts ++++ b/lib/useIntersection.d.ts +@@ -1,3 +1,3 @@ + import { RefObject } from 'react'; +-declare const useIntersection: (ref: RefObject, options: IntersectionObserverInit) => IntersectionObserverEntry | null; ++declare const useIntersection: (ref: RefObject, options: IntersectionObserverInit) => IntersectionObserverEntry | null; + export default useIntersection; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7fb7b6a0..317118cb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,11 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +patchedDependencies: + react-use@17.4.0: + hash: f42hight6xh6nh4xod5b2cx4ku + path: patches/react-use@17.4.0.patch + dependencies: '@babel/core': specifier: ^7.20.5 @@ -33,11 +38,11 @@ dependencies: specifier: ^2.7.1 version: 2.7.1 '@types/react': - specifier: ^18.0.26 - version: 18.0.26 + specifier: 19.0.8 + version: 19.0.8 '@types/react-dom': - specifier: ^18.0.9 - version: 18.0.9 + specifier: 19.0.3 + version: 19.0.3(@types/react@19.0.8) '@vanilla-extract/css': specifier: ^1.9.2 version: 1.14.1 @@ -121,19 +126,19 @@ dependencies: version: 15.8.1 re-resizable: specifier: ^6.10.0 - version: 6.10.0(react-dom@18.2.0)(react@18.2.0) + version: 6.10.0(react-dom@19.0.0)(react@19.0.0) react-docgen-typescript: specifier: ^2.2.2 version: 2.2.2(typescript@5.0.4) react-helmet: specifier: ^6.1.0 - version: 6.1.0(react@18.2.0) + version: 6.1.0(react@19.0.0) react-transition-group: specifier: ^4.4.5 - version: 4.4.5(react-dom@18.2.0)(react@18.2.0) + version: 4.4.5(react-dom@19.0.0)(react@19.0.0) react-use: specifier: ^17.4.0 - version: 17.4.0(react-dom@18.2.0)(react@18.2.0) + version: 17.4.0(patch_hash=f42hight6xh6nh4xod5b2cx4ku)(react-dom@19.0.0)(react@19.0.0) read-pkg-up: specifier: ^7.0.1 version: 7.0.1 @@ -148,7 +153,7 @@ dependencies: version: 5.0.4 use-debounce: specifier: ^10.0.0 - version: 10.0.0(react@18.2.0) + version: 10.0.0(react@19.0.0) webpack: specifier: ^5.75.0 version: 5.75.0 @@ -206,11 +211,11 @@ devDependencies: specifier: ^15.2.2 version: 15.2.2 react: - specifier: ^18.0.1 - version: 18.2.0 + specifier: 19.0.0 + version: 19.0.0 react-dom: - specifier: ^18.0.1 - version: 18.2.0(react@18.2.0) + specifier: 19.0.0 + version: 19.0.0(react@19.0.0) serve: specifier: ^14.1.2 version: 14.1.2 @@ -2849,9 +2854,6 @@ packages: /@types/prettier@2.7.1: resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} - /@types/prop-types@15.7.5: - resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} - /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} dev: false @@ -2860,38 +2862,35 @@ packages: resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} dev: false - /@types/react-dom@18.0.9: - resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} + /@types/react-dom@19.0.3(@types/react@19.0.8): + resolution: {integrity: sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==} + peerDependencies: + '@types/react': ^19.0.0 dependencies: - '@types/react': 18.0.26 + '@types/react': 19.0.8 dev: false /@types/react-helmet@6.1.11: resolution: {integrity: sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==} dependencies: - '@types/react': 18.0.26 + '@types/react': 19.0.8 dev: true /@types/react-transition-group@4.4.10: resolution: {integrity: sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==} dependencies: - '@types/react': 18.0.26 + '@types/react': 19.0.8 dev: true - /@types/react@18.0.26: - resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} + /@types/react@19.0.8: + resolution: {integrity: sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==} dependencies: - '@types/prop-types': 15.7.5 - '@types/scheduler': 0.16.2 csstype: 3.1.1 /@types/retry@0.12.2: resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} dev: false - /@types/scheduler@0.16.2: - resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - /@types/semver@6.2.3: resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} dev: true @@ -7815,7 +7814,7 @@ packages: thenify-all: 1.6.0 dev: false - /nano-css@5.3.5(react-dom@18.2.0)(react@18.2.0): + /nano-css@5.3.5(react-dom@19.0.0)(react@19.0.0): resolution: {integrity: sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==} peerDependencies: react: '*' @@ -7825,8 +7824,8 @@ packages: csstype: 3.1.1 fastest-stable-stringify: 2.0.2 inline-style-prefixer: 6.0.4 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) rtl-css-js: 1.16.0 sourcemap-codec: 1.4.8 stacktrace-js: 2.0.2 @@ -8548,14 +8547,14 @@ packages: strip-json-comments: 2.0.1 dev: true - /re-resizable@6.10.0(react-dom@18.2.0)(react@18.2.0): + /re-resizable@6.10.0(react-dom@19.0.0)(react@19.0.0): resolution: {integrity: sha512-hysSK0xmA5nz24HBVztlk4yCqCLCvS32E6ZpWxVKop9x3tqCa4yAj1++facrmkOf62JsJHjmjABdKxXofYioCw==} peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) dev: false /react-docgen-typescript@2.2.2(typescript@5.0.4): @@ -8566,29 +8565,28 @@ packages: typescript: 5.0.4 dev: false - /react-dom@18.2.0(react@18.2.0): - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + /react-dom@19.0.0(react@19.0.0): + resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} peerDependencies: - react: ^18.2.0 + react: ^19.0.0 dependencies: - loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 + react: 19.0.0 + scheduler: 0.25.0 /react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} dev: false - /react-helmet@6.1.0(react@18.2.0): + /react-helmet@6.1.0(react@19.0.0): resolution: {integrity: sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==} peerDependencies: react: '>=16.3.0' dependencies: object-assign: 4.1.1 prop-types: 15.8.1 - react: 18.2.0 + react: 19.0.0 react-fast-compare: 3.2.2 - react-side-effect: 2.1.2(react@18.2.0) + react-side-effect: 2.1.2(react@19.0.0) dev: false /react-is@16.13.1: @@ -8602,15 +8600,15 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true - /react-side-effect@2.1.2(react@18.2.0): + /react-side-effect@2.1.2(react@19.0.0): resolution: {integrity: sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==} peerDependencies: react: ^16.3.0 || ^17.0.0 || ^18.0.0 dependencies: - react: 18.2.0 + react: 19.0.0 dev: false - /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): + /react-transition-group@4.4.5(react-dom@19.0.0)(react@19.0.0): resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: react: '>=16.6.0' @@ -8620,21 +8618,21 @@ packages: dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) dev: false - /react-universal-interface@0.6.2(react@18.2.0)(tslib@2.6.0): + /react-universal-interface@0.6.2(react@19.0.0)(tslib@2.6.0): resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} peerDependencies: react: '*' tslib: '*' dependencies: - react: 18.2.0 + react: 19.0.0 tslib: 2.6.0 dev: false - /react-use@17.4.0(react-dom@18.2.0)(react@18.2.0): + /react-use@17.4.0(patch_hash=f42hight6xh6nh4xod5b2cx4ku)(react-dom@19.0.0)(react@19.0.0): resolution: {integrity: sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -8646,10 +8644,10 @@ packages: fast-deep-equal: 3.1.3 fast-shallow-equal: 1.0.0 js-cookie: 2.2.1 - nano-css: 5.3.5(react-dom@18.2.0)(react@18.2.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-universal-interface: 0.6.2(react@18.2.0)(tslib@2.6.0) + nano-css: 5.3.5(react-dom@19.0.0)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + react-universal-interface: 0.6.2(react@19.0.0)(tslib@2.6.0) resize-observer-polyfill: 1.5.1 screenfull: 5.2.0 set-harmonic-interval: 1.0.1 @@ -8657,12 +8655,11 @@ packages: ts-easing: 0.2.0 tslib: 2.6.0 dev: false + patched: true - /react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + /react@19.0.0: + resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} engines: {node: '>=0.10.0'} - dependencies: - loose-envify: 1.4.0 /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} @@ -9063,10 +9060,8 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} - dependencies: - loose-envify: 1.4.0 + /scheduler@0.25.0: + resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} /schema-utils@3.1.1: resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} @@ -10201,13 +10196,13 @@ packages: requires-port: 1.0.0 dev: true - /use-debounce@10.0.0(react@18.2.0): + /use-debounce@10.0.0(react@19.0.0): resolution: {integrity: sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A==} engines: {node: '>= 16.0.0'} peerDependencies: react: '>=16.8.0' dependencies: - react: 18.2.0 + react: 19.0.0 dev: false /util-deprecate@1.0.2: diff --git a/src/Playroom/CodeEditor/CodeMirror2.tsx b/src/Playroom/CodeEditor/CodeMirror2.tsx index e84fbbd1..99cbe57e 100644 --- a/src/Playroom/CodeEditor/CodeMirror2.tsx +++ b/src/Playroom/CodeEditor/CodeMirror2.tsx @@ -743,6 +743,13 @@ export class UnControlled extends React.Component< ? `react-codemirror2 ${this.props.className}` : 'react-codemirror2'; - return
(this.ref = self!)} />; + return ( +
{ + this.ref = self!; + }} + /> + ); } } diff --git a/src/Playroom/SettingsPanel/SettingsPanel.tsx b/src/Playroom/SettingsPanel/SettingsPanel.tsx index 99c6912b..7d895a97 100644 --- a/src/Playroom/SettingsPanel/SettingsPanel.tsx +++ b/src/Playroom/SettingsPanel/SettingsPanel.tsx @@ -1,4 +1,4 @@ -import React, { useContext, type ReactChild } from 'react'; +import React, { useContext, type ReactElement } from 'react'; import { Heading } from '../Heading/Heading'; import { ToolbarPanel } from '../ToolbarPanel/ToolbarPanel'; import { @@ -43,13 +43,13 @@ const getKeyBindings = () => { }; }; -const positionIcon: Record = { +const positionIcon: Record = { undocked: , right: , bottom: , }; -const colorModeIcon: Record = { +const colorModeIcon: Record = { light: , dark: , system: , diff --git a/src/Playroom/StatusMessage/StatusMessage.tsx b/src/Playroom/StatusMessage/StatusMessage.tsx index 688a841e..a06f18b9 100644 --- a/src/Playroom/StatusMessage/StatusMessage.tsx +++ b/src/Playroom/StatusMessage/StatusMessage.tsx @@ -14,8 +14,12 @@ interface Props { } export const StatusMessage = ({ dismissable = false }: Props) => { const [{ statusMessage }, dispatch] = useContext(StoreContext); - const cleanupTimerRef = useRef>(); - const showStatusTimerRef = useRef>(); + const cleanupTimerRef = useRef | undefined>( + undefined + ); + const showStatusTimerRef = useRef | undefined>( + undefined + ); const [show, setShow] = useState(false); const [internalMessage, setInternalMessage] = useState(statusMessage); diff --git a/src/Playroom/ToolbarItem/ToolbarItem.tsx b/src/Playroom/ToolbarItem/ToolbarItem.tsx index 37a23681..eba7576f 100644 --- a/src/Playroom/ToolbarItem/ToolbarItem.tsx +++ b/src/Playroom/ToolbarItem/ToolbarItem.tsx @@ -1,11 +1,11 @@ -import type { ReactChild } from 'react'; +import type { ReactElement } from 'react'; import classnames from 'classnames'; import TickIcon from '../icons/TickIcon'; import * as styles from './ToolbarItem.css'; interface Props { - children: ReactChild; + children: ReactElement | string | number; title: string; active?: boolean; success?: boolean; diff --git a/src/render.js b/src/render.js index fe1e0355..0b072ab4 100644 --- a/src/render.js +++ b/src/render.js @@ -5,7 +5,7 @@ import ReactDOM, { version as reactDomVersion } from 'react-dom'; // versions of React is removed. const canUseNewReactRootApi = reactDomVersion && - (reactDomVersion.startsWith('18') || reactDomVersion.startsWith('0.0.0')); + (reactDomVersion.startsWith('18') || reactDomVersion.startsWith('19') || reactDomVersion.startsWith('0.0.0')); export const renderElement = (node, outlet) => { if (canUseNewReactRootApi) {