diff options
| author | AAGaming <aagaming@riseup.net> | 2025-10-15 00:31:12 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-15 00:31:12 -0400 |
| commit | 44bb023b804b0ab360214360a3947935fb41c86c (patch) | |
| tree | f1313a32a16297fcaadecc3ba3eb2e21dec4ddb7 | |
| parent | 86b5567d4eac84399245c9a71270d6142ee54ded (diff) | |
| download | decky-loader-44bb023b804b0ab360214360a3947935fb41c86c.tar.gz decky-loader-44bb023b804b0ab360214360a3947935fb41c86c.zip | |
React 19 support (#818)v3.2.0-pre1v3.2.0
| -rw-r--r-- | frontend/package.json | 16 | ||||
| -rw-r--r-- | frontend/pnpm-lock.yaml | 169 | ||||
| -rw-r--r-- | frontend/rollup.config.js | 1 | ||||
| -rw-r--r-- | frontend/src/components/QuickAccessVisibleState.tsx | 4 | ||||
| -rw-r--r-- | frontend/src/components/WithSuspense.tsx | 2 | ||||
| -rw-r--r-- | frontend/src/components/modals/filepicker/FilePickerError.tsx | 2 | ||||
| -rw-r--r-- | frontend/src/index.ts | 18 | ||||
| -rw-r--r-- | frontend/src/plugin-loader.tsx | 22 | ||||
| -rw-r--r-- | frontend/src/plugin.ts | 1 | ||||
| -rw-r--r-- | frontend/src/router-hook.tsx | 10 | ||||
| -rw-r--r-- | frontend/tsconfig.json | 7 |
11 files changed, 127 insertions, 125 deletions
diff --git a/frontend/package.json b/frontend/package.json index 16c19e49..12d9ce85 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,8 +20,8 @@ "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-typescript": "^11.1.6", - "@types/react": "18.3.3", - "@types/react-dom": "18.3.0", + "@types/react": "19.1.1", + "@types/react-dom": "19.1.1", "@types/react-file-icon": "^1.0.4", "@types/react-router": "5.1.20", "husky": "^9.0.11", @@ -30,8 +30,8 @@ "inquirer": "^9.2.23", "prettier": "^3.3.2", "prettier-plugin-import-sort": "^0.0.7", - "react": "18.3.1", - "react-dom": "18.3.1", + "react": "19.1.1", + "react-dom": "19.1.1", "rollup": "^4.22.4", "rollup-plugin-delete": "^2.0.0", "rollup-plugin-external-globals": "^0.10.0", @@ -47,13 +47,13 @@ } }, "dependencies": { - "@decky/ui": "^4.10.5", + "@decky/ui": "^4.11.0", "compare-versions": "^6.1.1", "filesize": "^10.1.2", - "i18next": "^23.11.5", + "i18next": "^25.6.0", "i18next-http-backend": "^2.5.2", - "react-file-icon": "^1.5.0", - "react-i18next": "^14.1.2", + "react-file-icon": "^1.6.0", + "react-i18next": "^16.0.1", "react-icons": "^5.2.1", "react-markdown": "^9.0.1", "remark-gfm": "^4.0.0" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index fd5eabaf..10da2f88 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@decky/ui': - specifier: ^4.10.5 - version: 4.10.5 + specifier: ^4.11.0 + version: 4.11.0 compare-versions: specifier: ^6.1.1 version: 6.1.1 @@ -18,23 +18,23 @@ importers: specifier: ^10.1.2 version: 10.1.2 i18next: - specifier: ^23.11.5 - version: 23.11.5 + specifier: ^25.6.0 + version: 25.6.0(typescript@5.4.5) i18next-http-backend: specifier: ^2.5.2 version: 2.5.2 react-file-icon: - specifier: ^1.5.0 - version: 1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.6.0 + version: 1.6.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-i18next: - specifier: ^14.1.2 - version: 14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^16.0.1 + version: 16.0.1(i18next@25.6.0(typescript@5.4.5))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.4.5) react-icons: specifier: ^5.2.1 - version: 5.2.1(react@18.3.1) + version: 5.2.1(react@19.1.1) react-markdown: specifier: ^9.0.1 - version: 9.0.1(@types/react@18.3.3)(react@18.3.1) + version: 9.0.1(@types/react@19.1.1)(react@19.1.1) remark-gfm: specifier: ^4.0.0 version: 4.0.0 @@ -61,11 +61,11 @@ importers: specifier: ^11.1.6 version: 11.1.6(rollup@4.22.4)(tslib@2.6.3)(typescript@5.4.5) '@types/react': - specifier: 18.3.3 - version: 18.3.3 + specifier: 19.1.1 + version: 19.1.1 '@types/react-dom': - specifier: 18.3.0 - version: 18.3.0 + specifier: 19.1.1 + version: 19.1.1(@types/react@19.1.1) '@types/react-file-icon': specifier: ^1.0.4 version: 1.0.4 @@ -91,11 +91,11 @@ importers: specifier: ^0.0.7 version: 0.0.7(prettier@3.3.2) react: - specifier: 18.3.1 - version: 18.3.1 + specifier: 19.1.1 + version: 19.1.1 react-dom: - specifier: 18.3.1 - version: 18.3.1(react@18.3.1) + specifier: 19.1.1 + version: 19.1.1(react@19.1.1) rollup: specifier: ^4.22.4 version: 4.22.4 @@ -203,6 +203,10 @@ packages: resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + '@babel/template@7.24.7': resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} engines: {node: '>=6.9.0'} @@ -218,8 +222,8 @@ packages: '@decky/api@1.1.1': resolution: {integrity: sha512-R5fkBRHBt5QIQY7Q0AlbVIhlIZ/nTzwBOoi8Rt4Go2fjFnoMKPInCJl6cPjXzimGwl2pyqKJgY6VnH6ar0XrHQ==} - '@decky/ui@4.10.5': - resolution: {integrity: sha512-IsQiNtIbNJ5NQQJB9Dir0ir2pgE4QpcsrRB7eic2ClbPwYDuBKc6GLFs3ZQt43Dd4SwCJkzg/CeC+wgkBOMd1w==} + '@decky/ui@4.11.0': + resolution: {integrity: sha512-l9PstFC+S8FE8M2kIM78L8cYW4vzJ/ZD30II0huarHLcCsKM4Q+rbmEnbWjlJ1/KLmGXVRXBdAbyD4X/FzfxnQ==} '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} @@ -598,11 +602,10 @@ packages: '@types/node@20.14.2': resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==} - '@types/prop-types@15.7.12': - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} - - '@types/react-dom@18.3.0': - resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} + '@types/react-dom@19.1.1': + resolution: {integrity: sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w==} + peerDependencies: + '@types/react': ^19.0.0 '@types/react-file-icon@1.0.4': resolution: {integrity: sha512-c1mIklUDaxm9odxf8RTiy/EAxsblZliJ86EKIOAyuafP9eK3iudyn4ATv53DX6ZvgGymc7IttVNm97LTGnTiYA==} @@ -610,8 +613,8 @@ packages: '@types/react-router@5.1.20': resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} - '@types/react@18.3.3': - resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} + '@types/react@19.1.1': + resolution: {integrity: sha512-ePapxDL7qrgqSF67s0h9m412d9DbXyC1n59O2st+9rjuuamWsZuD2w55rqY12CbzsZ7uVXb5Nw0gEp9Z8MMutQ==} '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -1187,8 +1190,16 @@ packages: engines: {node: '>=18.0.0 || >=20.0.0 || >=22.0.0', npm: '>=6', yarn: '>=1'} hasBin: true - i18next@23.11.5: - resolution: {integrity: sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==} + i18next@23.16.8: + resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} + + i18next@25.6.0: + resolution: {integrity: sha512-tTn8fLrwBYtnclpL5aPXK/tAYBLWVvoHM1zdfXoRNLcI+RvtMsoZRV98ePlaW3khHYKuNh/Q65W/+NVFUeIwVw==} + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -1709,29 +1720,32 @@ packages: quick-temp@0.1.8: resolution: {integrity: sha512-YsmIFfD9j2zaFwJkzI6eMG7y0lQP7YeWzgtFgNl38pGWZBSXJooZbOWwkcRot7Vt0Fg9L23pX0tqWU3VvLDsiA==} - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + react-dom@19.1.1: + resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} peerDependencies: - react: ^18.3.1 + react: ^19.1.1 - react-file-icon@1.5.0: - resolution: {integrity: sha512-6K2/nAI69CS838HOS+4S95MLXwf1neWywek1FgqcTFPTYjnM8XT7aBLz4gkjoqQKY9qPhu3A2tu+lvxhmZYY9w==} + react-file-icon@1.6.0: + resolution: {integrity: sha512-Ba4Qa2ya/kvhcCd4LJja77sV7JD7u1ZXcI1DUz+TII3nGmglG6QY+NZeHizThokgct3qI0glwb9eV8NqRGs5lw==} peerDependencies: - react: ^18.0.0 || ^17.0.0 || ^16.2.0 - react-dom: ^18.0.0 || ^17.0.0 || ^16.2.0 + react: ^19.0.0 || ^18.0.0 || ^17.0.0 || ^16.2.0 + react-dom: ^19.0.0 || ^18.0.0 || ^17.0.0 || ^16.2.0 - react-i18next@14.1.2: - resolution: {integrity: sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==} + react-i18next@16.0.1: + resolution: {integrity: sha512-0S//bpYEkCPjzuVmxDf9Z6+Y+ArNvpAUk7eDL4qNCZXjDh6Z9j6MZ+NThU7kMCOsmYmDCun3GYEwkiOjjZo9Ug==} peerDependencies: - i18next: '>= 23.2.3' + i18next: '>= 25.5.2' react: '>= 16.8.0' react-dom: '*' react-native: '*' + typescript: ^5 peerDependenciesMeta: react-dom: optional: true react-native: optional: true + typescript: + optional: true react-icons@5.2.1: resolution: {integrity: sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==} @@ -1747,8 +1761,8 @@ packages: '@types/react': '>=18' react: '>=18' - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.1.1: + resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} engines: {node: '>=0.10.0'} readable-stream@2.3.8: @@ -1873,8 +1887,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -2266,6 +2280,8 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 + '@babel/runtime@7.28.4': {} + '@babel/template@7.24.7': dependencies: '@babel/code-frame': 7.24.7 @@ -2295,7 +2311,7 @@ snapshots: '@decky/api@1.1.1': {} - '@decky/ui@4.10.5': {} + '@decky/ui@4.11.0': {} '@esbuild/aix-ppc64@0.20.2': optional: true @@ -2567,24 +2583,21 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/prop-types@15.7.12': {} - - '@types/react-dom@18.3.0': + '@types/react-dom@19.1.1(@types/react@19.1.1)': dependencies: - '@types/react': 18.3.3 + '@types/react': 19.1.1 '@types/react-file-icon@1.0.4': dependencies: - '@types/react': 18.3.3 + '@types/react': 19.1.1 '@types/react-router@5.1.20': dependencies: '@types/history': 4.7.11 - '@types/react': 18.3.3 + '@types/react': 19.1.1 - '@types/react@18.3.3': + '@types/react@19.1.1': dependencies: - '@types/prop-types': 15.7.12 csstype: 3.1.3 '@types/resolve@1.20.2': {} @@ -3229,7 +3242,7 @@ snapshots: esbuild: 0.20.2 fs-extra: 11.2.0 gulp-sort: 2.0.0 - i18next: 23.11.5 + i18next: 23.16.8 js-yaml: 4.1.0 lilconfig: 3.1.2 rsvp: 4.8.5 @@ -3240,10 +3253,16 @@ snapshots: transitivePeerDependencies: - supports-color - i18next@23.11.5: + i18next@23.16.8: dependencies: '@babel/runtime': 7.24.7 + i18next@25.6.0(typescript@5.4.5): + dependencies: + '@babel/runtime': 7.28.4 + optionalDependencies: + typescript: 5.4.5 + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -3960,43 +3979,43 @@ snapshots: rimraf: 2.7.1 underscore.string: 3.3.6 - react-dom@18.3.1(react@18.3.1): + react-dom@19.1.1(react@19.1.1): dependencies: - loose-envify: 1.4.0 - react: 18.3.1 - scheduler: 0.23.2 + react: 19.1.1 + scheduler: 0.26.0 - react-file-icon@1.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-file-icon@1.6.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: colord: 2.9.3 prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) - react-i18next@14.1.2(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-i18next@16.0.1(i18next@25.6.0(typescript@5.4.5))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.4.5): dependencies: - '@babel/runtime': 7.24.7 + '@babel/runtime': 7.28.4 html-parse-stringify: 3.0.1 - i18next: 23.11.5 - react: 18.3.1 + i18next: 25.6.0(typescript@5.4.5) + react: 19.1.1 optionalDependencies: - react-dom: 18.3.1(react@18.3.1) + react-dom: 19.1.1(react@19.1.1) + typescript: 5.4.5 - react-icons@5.2.1(react@18.3.1): + react-icons@5.2.1(react@19.1.1): dependencies: - react: 18.3.1 + react: 19.1.1 react-is@16.13.1: {} - react-markdown@9.0.1(@types/react@18.3.3)(react@18.3.1): + react-markdown@9.0.1(@types/react@19.1.1)(react@19.1.1): dependencies: '@types/hast': 3.0.4 - '@types/react': 18.3.3 + '@types/react': 19.1.1 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.0 html-url-attributes: 3.0.0 mdast-util-to-hast: 13.2.0 - react: 18.3.1 + react: 19.1.1 remark-parse: 11.0.0 remark-rehype: 11.1.0 unified: 11.0.4 @@ -4005,9 +4024,7 @@ snapshots: transitivePeerDependencies: - supports-color - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react@19.1.1: {} readable-stream@2.3.8: dependencies: @@ -4164,9 +4181,7 @@ snapshots: safer-buffer@2.1.2: {} - scheduler@0.23.2: - dependencies: - loose-envify: 1.4.0 + scheduler@0.26.0: {} semver@6.3.1: {} diff --git a/frontend/rollup.config.js b/frontend/rollup.config.js index 57804c4f..0d6e1a6b 100644 --- a/frontend/rollup.config.js +++ b/frontend/rollup.config.js @@ -23,6 +23,7 @@ export default defineConfig([ }), externalGlobals({ react: 'SP_REACT', + 'react/jsx-runtime': 'SP_JSX', 'react-dom': 'SP_REACTDOM', // hack to shut up react-markdown process: '{cwd: () => {}}', diff --git a/frontend/src/components/QuickAccessVisibleState.tsx b/frontend/src/components/QuickAccessVisibleState.tsx index f5c05061..f90c24b4 100644 --- a/frontend/src/components/QuickAccessVisibleState.tsx +++ b/frontend/src/components/QuickAccessVisibleState.tsx @@ -1,10 +1,10 @@ -import { FC, ReactNode, createContext, useContext, useState } from 'react'; +import { FC, PropsWithChildren, createContext, useContext, useState } from 'react'; const QuickAccessVisibleState = createContext<boolean>(false); export const useQuickAccessVisible = () => useContext(QuickAccessVisibleState); -export const QuickAccessVisibleStateProvider: FC<{ tab: any; children: ReactNode }> = ({ children, tab }) => { +export const QuickAccessVisibleStateProvider: FC<PropsWithChildren<{ tab: any }>> = ({ children, tab }) => { const initial = tab.initialVisibility; const [visible, setVisible] = useState<boolean>(initial); // HACK but i can't think of a better way to do this diff --git a/frontend/src/components/WithSuspense.tsx b/frontend/src/components/WithSuspense.tsx index 153bec8d..d6281e3e 100644 --- a/frontend/src/components/WithSuspense.tsx +++ b/frontend/src/components/WithSuspense.tsx @@ -10,7 +10,7 @@ interface WithSuspenseProps { const WithSuspense: FunctionComponent<WithSuspenseProps> = (props) => { const propsCopy = { ...props }; delete propsCopy.children; - (props.children as ReactElement)?.props && Object.assign((props.children as ReactElement).props, propsCopy); // There is probably a better way to do this but valve does it this way so ¯\_(ツ)_/¯ + (props.children as ReactElement<any>)?.props && Object.assign((props.children as ReactElement<any>).props, propsCopy); // There is probably a better way to do this but valve does it this way so ¯\_(ツ)_/¯ return ( <Suspense fallback={ diff --git a/frontend/src/components/modals/filepicker/FilePickerError.tsx b/frontend/src/components/modals/filepicker/FilePickerError.tsx index f2330b9a..ac672226 100644 --- a/frontend/src/components/modals/filepicker/FilePickerError.tsx +++ b/frontend/src/components/modals/filepicker/FilePickerError.tsx @@ -1,4 +1,4 @@ -import { FC, useEffect, useState } from 'react'; +import { FC, JSX, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { IconContext } from 'react-icons'; import { FaExclamationTriangle, FaQuestionCircle, FaUserSlash } from 'react-icons/fa'; diff --git a/frontend/src/index.ts b/frontend/src/index.ts index 2ee018e0..4f4ff4f7 100644 --- a/frontend/src/index.ts +++ b/frontend/src/index.ts @@ -1,8 +1,4 @@ // Sets up DFL, then loads start.ts which starts up the loader -interface Window { - // Shut up TS - SP_REACTDOM: any; -} (async () => { console.debug('[Decky:Boot] Frontend init'); @@ -21,7 +17,19 @@ interface Window { // deliberate partial import const DFLWebpack = await import('@decky/ui/dist/webpack'); window.SP_REACT = DFLWebpack.findModule((m) => m.Component && m.PureComponent && m.useLayoutEffect); - window.SP_REACTDOM = DFLWebpack.findModule((m) => m.createPortal && m.createRoot); + window.SP_REACTDOM = + DFLWebpack.findModule((m) => m.createPortal && m.createRoot) || + DFLWebpack.findModule((m) => m.createPortal && m.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE); + + console.debug('[Decky:Boot] Setting up JSX internals...'); + const jsx = DFLWebpack.findModule((m) => m.jsx && Object.keys(m).length == 1)?.jsx; + if (jsx) { + window.SP_JSX = { + jsx, + jsxs: jsx, + Fragment: window.SP_REACT.Fragment, + }; + } } console.debug('[Decky:Boot] Setting up @decky/ui...'); window.DFL = await import('@decky/ui'); diff --git a/frontend/src/plugin-loader.tsx b/frontend/src/plugin-loader.tsx index df0a6956..2bdfcec1 100644 --- a/frontend/src/plugin-loader.tsx +++ b/frontend/src/plugin-loader.tsx @@ -120,28 +120,6 @@ class PluginLoader extends Logger { <DeckyStateContextProvider deckyState={this.deckyState}> <FaPlug /> <TabBadge /> - <style> - {` - /* fixes random overscrolling in QAM */ - .${quickAccessMenuClasses?.TabContentColumn} { - flex-grow: 1 !important; - margin-top: 0 !important; - margin-bottom: 0 !important; - justify-content: center !important; - } - .${quickAccessMenuClasses?.Tab} { - flex-grow: 1 !important; - height: unset !important; - --decky-qam-tab-max-height: 64px; /* make things a little easier for themers */ - max-height: var(--decky-qam-tab-max-height) !important; - } - /* they broke the footer a while ago and forgot to update the styles LOL */ - .${quickAccessMenuClasses?.Tabs}.${quickAccessMenuClasses.TabsWithFooter} { - margin-bottom: 0 !important; - padding-bottom: 0 !important; - } - `} - </style> </DeckyStateContextProvider> ), }); diff --git a/frontend/src/plugin.ts b/frontend/src/plugin.ts index 0035990e..f2b99f71 100644 --- a/frontend/src/plugin.ts +++ b/frontend/src/plugin.ts @@ -1,3 +1,4 @@ +import type { JSX } from 'react'; export enum PluginLoadType { LEGACY_EVAL_IIFE = 0, // legacy, uses legacy serverAPI ESMODULE_V1 = 1, // esmodule loading with modern @decky/backend apis diff --git a/frontend/src/router-hook.tsx b/frontend/src/router-hook.tsx index b3355d76..9b5f65dc 100644 --- a/frontend/src/router-hook.tsx +++ b/frontend/src/router-hook.tsx @@ -9,7 +9,7 @@ import { getReactRoot, sleep, } from '@decky/ui'; -import { FC, ReactElement, ReactNode, cloneElement, createElement } from 'react'; +import { FC, JSX, ReactElement, ReactNode, cloneElement, createElement } from 'react'; import type { Route } from 'react-router'; import { @@ -37,7 +37,7 @@ const isPatched = Symbol('is patched'); class RouterHook extends Logger { private routerState: DeckyRouterState = new DeckyRouterState(); private globalComponentsState: DeckyGlobalComponentsState = new DeckyGlobalComponentsState(); - private renderedComponents: ReactElement[] = []; + private renderedComponents: ReactElement<any>[] = []; private Route: any; private DeckyGamepadRouterWrapper = this.gamepadRouterWrapper.bind(this); private DeckyDesktopRouterWrapper = this.desktopRouterWrapper.bind(this); @@ -233,7 +233,7 @@ class RouterHook extends Logger { return <>{this.renderedComponents}</>; } - private gamepadRouterWrapper({ children }: { children: ReactElement }) { + private gamepadRouterWrapper({ children }: { children: ReactElement<any> }) { // Used to store the new replicated routes we create to allow routes to be unpatched. const { routes, routePatches } = useDeckyRouterState(); @@ -251,7 +251,7 @@ class RouterHook extends Logger { return children; } - private desktopRouterWrapper({ children }: { children: ReactElement }) { + private desktopRouterWrapper({ children }: { children: ReactElement<any> }) { // Used to store the new replicated routes we create to allow routes to be unpatched. this.debug('desktop router wrapper render', children); const { routes, routePatches } = useDeckyRouterState(); @@ -287,7 +287,7 @@ class RouterHook extends Logger { if (routes) { if (!routeList[routerIndex - 1]?.length || routeList[routerIndex - 1]?.length !== routes.size) { if (routeList[routerIndex - 1]?.length && routeList[routerIndex - 1].length !== routes.size) routerIndex--; - const newRouterArray: (ReactElement | JSX.Element)[] = []; + const newRouterArray: (ReactElement<any> | JSX.Element)[] = []; routes.forEach(({ component, props }, path) => { newRouterArray.push( <Route path={path} {...props}> diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index d12d14da..02d3d4ad 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -2,9 +2,7 @@ "compilerOptions": { "module": "ESNext", "target": "ES2021", - "jsx": "react", - "jsxFactory": "window.SP_REACT.createElement", - "jsxFragmentFactory": "window.SP_REACT.Fragment", + "jsx": "react-jsx", "declaration": false, "moduleResolution": "node", "noUnusedLocals": true, @@ -15,7 +13,8 @@ "noImplicitAny": true, "strict": true, "allowSyntheticDefaultImports": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "skipLibCheck": true }, "include": ["src", "index.d.ts"], "exclude": ["node_modules"] |
