From 1e38d5564a7534cdd9af82d550a1bc35ccbbd4de Mon Sep 17 00:00:00 2001 From: Jordan Thomson Date: Fri, 7 Feb 2025 19:42:09 +1100 Subject: [PATCH 1/5] feat: React 19 support --- lib/makeWebpackConfig.js | 2 +- package.json | 17 ++- patches/react-use@17.4.0.patch | 21 ++++ pnpm-lock.yaml | 125 +++++++++---------- src/Playroom/CodeEditor/CodeMirror2.tsx | 9 +- src/Playroom/SettingsPanel/SettingsPanel.tsx | 6 +- src/Playroom/StatusMessage/StatusMessage.tsx | 8 +- src/Playroom/ToolbarItem/ToolbarItem.tsx | 4 +- src/render.js | 2 +- 9 files changed, 113 insertions(+), 81 deletions(-) create mode 100644 patches/react-use@17.4.0.patch 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) { From 3345be4973576e46253abf6f483391ef3c5bc620 Mon Sep 17 00:00:00 2001 From: Jordan Thomson Date: Fri, 7 Feb 2025 20:00:57 +1100 Subject: [PATCH 2/5] changeset --- .changeset/new-hairs-appear.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/new-hairs-appear.md diff --git a/.changeset/new-hairs-appear.md b/.changeset/new-hairs-appear.md new file mode 100644 index 00000000..fb17760b --- /dev/null +++ b/.changeset/new-hairs-appear.md @@ -0,0 +1,5 @@ +--- +'playroom': minor +--- + +React 19 support From 38df855bddca897b5b1dd13eeb9d4087c76a30a5 Mon Sep 17 00:00:00 2001 From: Jordan Thomson Date: Fri, 7 Feb 2025 20:03:19 +1100 Subject: [PATCH 3/5] format --- lib/makeWebpackConfig.js | 6 +++++- src/render.js | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/makeWebpackConfig.js b/lib/makeWebpackConfig.js index 2cd7d317..dcbcdb24 100644 --- a/lib/makeWebpackConfig.js +++ b/lib/makeWebpackConfig.js @@ -30,7 +30,11 @@ module.exports = async (playroomConfig, options) => { } ); const { version } = JSON.parse(pkgContents); - isLegacyReact = !(version.startsWith('18') || version.startsWith('19') || 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/src/render.js b/src/render.js index 0b072ab4..ff4dcc85 100644 --- a/src/render.js +++ b/src/render.js @@ -5,7 +5,9 @@ import ReactDOM, { version as reactDomVersion } from 'react-dom'; // versions of React is removed. const canUseNewReactRootApi = reactDomVersion && - (reactDomVersion.startsWith('18') || reactDomVersion.startsWith('19') || reactDomVersion.startsWith('0.0.0')); + (reactDomVersion.startsWith('18') || + reactDomVersion.startsWith('19') || + reactDomVersion.startsWith('0.0.0')); export const renderElement = (node, outlet) => { if (canUseNewReactRootApi) { From 3669acfd3fd922008d94bf0314284566c13135f6 Mon Sep 17 00:00:00 2001 From: Jordan Thomson Date: Fri, 7 Feb 2025 20:34:24 +1100 Subject: [PATCH 4/5] removed `react-use` dep --- package.json | 6 -- patches/react-use@17.4.0.patch | 21 ---- pnpm-lock.yaml | 178 ------------------------------- src/Playroom/Frames/Iframe.tsx | 32 +++++- src/Playroom/Toolbar/Toolbar.tsx | 52 ++++++++- 5 files changed, 81 insertions(+), 208 deletions(-) delete mode 100644 patches/react-use@17.4.0.patch diff --git a/package.json b/package.json index e5c14d29..0cc7d02a 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,6 @@ "react-docgen-typescript": "^2.2.2", "react-helmet": "^6.1.0", "react-transition-group": "^4.4.5", - "react-use": "^17.4.0", "read-pkg-up": "^7.0.1", "scope-eval": "^1.0.0", "sucrase": "^3.34.0", @@ -148,10 +147,5 @@ "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 deleted file mode 100644 index 6e214d80..00000000 --- a/patches/react-use@17.4.0.patch +++ /dev/null @@ -1,21 +0,0 @@ -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 317118cb..7940fa87 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,11 +4,6 @@ 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 @@ -136,9 +131,6 @@ dependencies: react-transition-group: specifier: ^4.4.5 version: 4.4.5(react-dom@19.0.0)(react@19.0.0) - react-use: - specifier: ^17.4.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 @@ -2812,10 +2804,6 @@ packages: pretty-format: 29.3.1 dev: true - /@types/js-cookie@2.2.7: - resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} - dev: false - /@types/json-schema@7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} @@ -3306,10 +3294,6 @@ packages: '@xtuc/long': 4.2.2 dev: false - /@xobotyi/scrollbar-width@1.9.5: - resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} - dev: false - /@xtuc/ieee754@1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} dev: false @@ -4432,12 +4416,6 @@ packages: shebang-command: 2.0.0 which: 2.0.2 - /css-in-js-utils@3.1.0: - resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} - dependencies: - hyphenate-style-name: 1.0.4 - dev: false - /css-loader@6.7.2(webpack@5.75.0): resolution: {integrity: sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==} engines: {node: '>= 12.13.0'} @@ -4465,14 +4443,6 @@ packages: nth-check: 2.1.1 dev: false - /css-tree@1.1.3: - resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} - engines: {node: '>=8.0.0'} - dependencies: - mdn-data: 2.0.14 - source-map: 0.6.1 - dev: false - /css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} @@ -5581,24 +5551,12 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true - /fast-loops@1.1.3: - resolution: {integrity: sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==} - dev: false - - /fast-shallow-equal@1.0.0: - resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} - dev: false - /fast-url-parser@1.1.3: resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} dependencies: punycode: 1.4.1 dev: true - /fastest-stable-stringify@2.0.2: - resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} - dev: false - /fastq@1.14.0: resolution: {integrity: sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==} dependencies: @@ -6287,10 +6245,6 @@ packages: hasBin: true dev: true - /hyphenate-style-name@1.0.4: - resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} - dev: false - /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -6368,13 +6322,6 @@ packages: engines: {node: '>=10'} dev: true - /inline-style-prefixer@6.0.4: - resolution: {integrity: sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==} - dependencies: - css-in-js-utils: 3.1.0 - fast-loops: 1.1.3 - dev: false - /inquirer@6.5.2: resolution: {integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==} engines: {node: '>=6.0.0'} @@ -7215,10 +7162,6 @@ packages: '@sideway/pinpoint': 2.0.0 dev: true - /js-cookie@2.2.1: - resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} - dev: false - /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -7593,10 +7536,6 @@ packages: resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} dev: true - /mdn-data@2.0.14: - resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} - dev: false - /media-query-parser@2.0.2: resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} dependencies: @@ -7814,24 +7753,6 @@ packages: thenify-all: 1.6.0 dev: false - /nano-css@5.3.5(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==} - peerDependencies: - react: '*' - react-dom: '*' - dependencies: - css-tree: 1.1.3 - csstype: 3.1.1 - fastest-stable-stringify: 2.0.2 - inline-style-prefixer: 6.0.4 - 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 - stylis: 4.1.3 - dev: false - /nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -8622,41 +8543,6 @@ packages: react-dom: 19.0.0(react@19.0.0) dev: false - /react-universal-interface@0.6.2(react@19.0.0)(tslib@2.6.0): - resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} - peerDependencies: - react: '*' - tslib: '*' - dependencies: - react: 19.0.0 - tslib: 2.6.0 - dev: false - - /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 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@types/js-cookie': 2.2.7 - '@xobotyi/scrollbar-width': 1.9.5 - copy-to-clipboard: 3.3.3 - fast-deep-equal: 3.1.3 - fast-shallow-equal: 1.0.0 - js-cookie: 2.2.1 - 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 - throttle-debounce: 3.0.1 - ts-easing: 0.2.0 - tslib: 2.6.0 - dev: false - patched: true - /react@19.0.0: resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} engines: {node: '>=0.10.0'} @@ -8880,10 +8766,6 @@ packages: /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - /resize-observer-polyfill@1.5.1: - resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - dev: false - /resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -9009,12 +8891,6 @@ packages: fsevents: 2.3.3 dev: false - /rtl-css-js@1.16.0: - resolution: {integrity: sha512-Oc7PnzwIEU4M0K1J4h/7qUUaljXhQ0kCObRsZjxs2HjkpKsnoTMvSmvJ4sqgJZd0zBoEfAyTdnK/jMIYvrjySQ==} - dependencies: - '@babel/runtime': 7.20.6 - dev: false - /run-applescript@7.0.0: resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} engines: {node: '>=18'} @@ -9086,11 +8962,6 @@ packages: resolution: {integrity: sha512-oWKaZEXqucTGRzhJCXE+D+hHDkiDe1iHhBlWwxkFTzO3phrdPo4Kju2tSJiWC3x+egyqxdpbs7s+YOPlZlqB1A==} dev: false - /screenfull@5.2.0: - resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} - engines: {node: '>=0.10.0'} - dev: false - /select-hose@2.0.0: resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} dev: false @@ -9230,11 +9101,6 @@ packages: has-property-descriptors: 1.0.2 dev: true - /set-harmonic-interval@1.0.1: - resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} - engines: {node: '>=6.9'} - dev: false - /setprototypeof@1.1.0: resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} dev: false @@ -9377,20 +9243,10 @@ packages: source-map: 0.6.1 dev: false - /source-map@0.5.6: - resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} - engines: {node: '>=0.10.0'} - dev: false - /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - dev: false - /spawn-command@0.0.2-1: resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} dev: true @@ -9478,12 +9334,6 @@ packages: tweetnacl: 0.14.5 dev: true - /stack-generator@2.0.10: - resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} - dependencies: - stackframe: 1.3.4 - dev: false - /stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -9495,21 +9345,6 @@ packages: resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} dev: false - /stacktrace-gps@3.1.2: - resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==} - dependencies: - source-map: 0.5.6 - stackframe: 1.3.4 - dev: false - - /stacktrace-js@2.0.2: - resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} - dependencies: - error-stack-parser: 2.1.4 - stack-generator: 2.0.10 - stacktrace-gps: 3.1.2 - dev: false - /start-server-and-test@1.15.2: resolution: {integrity: sha512-t5xJX04Hg7hqxiKHMJBz/n4zIMsE6G7hpAcerFAH+4Vh9le/LeyFcJERJM7WLiPygWF9TOg33oroJF1XOzJtYQ==} engines: {node: '>=6'} @@ -9705,10 +9540,6 @@ packages: engines: {node: '>=8'} dev: true - /stylis@4.1.3: - resolution: {integrity: sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==} - dev: false - /sucrase@3.34.0: resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} engines: {node: '>=8'} @@ -9874,11 +9705,6 @@ packages: any-promise: 1.3.0 dev: false - /throttle-debounce@3.0.1: - resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} - engines: {node: '>=10'} - dev: false - /throttleit@1.0.0: resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} dev: true @@ -9967,10 +9793,6 @@ packages: engines: {node: '>=8'} dev: true - /ts-easing@0.2.0: - resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} - dev: false - /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: false diff --git a/src/Playroom/Frames/Iframe.tsx b/src/Playroom/Frames/Iframe.tsx index 888ee9f0..e62570b2 100644 --- a/src/Playroom/Frames/Iframe.tsx +++ b/src/Playroom/Frames/Iframe.tsx @@ -4,8 +4,8 @@ import { useRef, type AllHTMLAttributes, type MutableRefObject, + type RefObject, } from 'react'; -import { useIntersection } from 'react-use'; import playroomConfig from '../../config'; @@ -70,3 +70,33 @@ export default function Iframe({ /> ); } + +// copied directly from `react-use` +function useIntersection( + ref: RefObject, + options: IntersectionObserverInit +): IntersectionObserverEntry | null { + const [intersectionObserverEntry, setIntersectionObserverEntry] = + useState(null); + + useEffect(() => { + if (ref.current && typeof IntersectionObserver === 'function') { + const handler = (entries: IntersectionObserverEntry[]) => { + setIntersectionObserverEntry(entries[0]); + }; + + const observer = new IntersectionObserver(handler, options); + observer.observe(ref.current); + + return () => { + setIntersectionObserverEntry(null); + observer.disconnect(); + }; + } + return () => {}; + // disabled in the original implementation + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ref.current, options.threshold, options.root, options.rootMargin]); + + return intersectionObserverEntry; +} diff --git a/src/Playroom/Toolbar/Toolbar.tsx b/src/Playroom/Toolbar/Toolbar.tsx index 801d3acd..0d9ae41a 100644 --- a/src/Playroom/Toolbar/Toolbar.tsx +++ b/src/Playroom/Toolbar/Toolbar.tsx @@ -1,5 +1,4 @@ -import { useContext, useState, useCallback, useEffect } from 'react'; -import { useTimeoutFn } from 'react-use'; +import { useContext, useState, useCallback, useEffect, useRef } from 'react'; import classnames from 'classnames'; import type { PlayroomProps } from '../Playroom'; import { StoreContext } from '../../StoreContext/StoreContext'; @@ -205,3 +204,52 @@ export default ({ themes: allThemes, widths: allWidths, snippets }: Props) => {
); }; + +// copied directly from `react-use` +type UseTimeoutFnReturn = [() => boolean | null, () => void, () => void]; + +function useTimeoutFn void>( + fn: T, + ms: number = 0 +): UseTimeoutFnReturn { + const ready = useRef(false); + const timeout = useRef | undefined>(undefined); + const callback = useRef(fn); + + const isReady = useCallback(() => ready.current, []); + + const set = useCallback(() => { + ready.current = false; + if (timeout.current) { + clearTimeout(timeout.current); + } + + timeout.current = setTimeout(() => { + ready.current = true; + callback.current(); + }, ms); + }, [ms]); + + const clear = useCallback(() => { + ready.current = null; + if (timeout.current) { + clearTimeout(timeout.current); + } + }, []); + + // update ref when function changes + useEffect(() => { + callback.current = fn; + }, [fn]); + + // set on mount, clear on unmount + useEffect(() => { + set(); + + return clear; + // disabled in the original implementation + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ms]); + + return [isReady, clear, set]; +} From da900382cc524aaaef655ac31e001ea9184e906d Mon Sep 17 00:00:00 2001 From: Jordan Thomson Date: Fri, 7 Feb 2025 20:34:49 +1100 Subject: [PATCH 5/5] bump `re-resizable` --- package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 0cc7d02a..48c16543 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "portfinder": "^1.0.32", "prettier": "^2.8.1", "prop-types": "^15.8.1", - "re-resizable": "^6.10.0", + "re-resizable": "^6.10.3", "react-docgen-typescript": "^2.2.2", "react-helmet": "^6.1.0", "react-transition-group": "^4.4.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7940fa87..1f26395f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,8 +120,8 @@ dependencies: specifier: ^15.8.1 version: 15.8.1 re-resizable: - specifier: ^6.10.0 - version: 6.10.0(react-dom@19.0.0)(react@19.0.0) + specifier: ^6.10.3 + version: 6.10.3(react-dom@19.0.0)(react@19.0.0) react-docgen-typescript: specifier: ^2.2.2 version: 2.2.2(typescript@5.0.4) @@ -8468,11 +8468,11 @@ packages: strip-json-comments: 2.0.1 dev: true - /re-resizable@6.10.0(react-dom@19.0.0)(react@19.0.0): - resolution: {integrity: sha512-hysSK0xmA5nz24HBVztlk4yCqCLCvS32E6ZpWxVKop9x3tqCa4yAj1++facrmkOf62JsJHjmjABdKxXofYioCw==} + /re-resizable@6.10.3(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-zvWb7X3RJMA4cuSrqoxgs3KR+D+pEXnGrD2FAD6BMYAULnZsSF4b7AOVyG6pC3VVNVOtlagGDCDmZSwWLjjBBw==} peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 dependencies: react: 19.0.0 react-dom: 19.0.0(react@19.0.0)