mirror of
https://github.com/SteamDeckHomebrew/decky-frontend-lib.git
synced 2026-05-18 01:00:08 +02:00
feat(*): react 19 support update
This commit is contained in:
5
global.d.ts
vendored
5
global.d.ts
vendored
@@ -1,5 +1,10 @@
|
||||
import type * as React from 'react';
|
||||
import type * as ReactDOM from 'react-dom';
|
||||
import type * as JSXRuntime from 'react/jsx-runtime';
|
||||
declare global {
|
||||
interface Window {
|
||||
SP_REACT: typeof React;
|
||||
SP_REACTDOM: typeof ReactDOM;
|
||||
SP_JSX: typeof JSXRuntime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/react": "18.3.3",
|
||||
"@types/react-dom": "18.3.0",
|
||||
"@types/react": "19.1.1",
|
||||
"@types/react-dom": "19.1.1",
|
||||
"@types/react-router": "5.1.20",
|
||||
"commitizen": "^4.3.1",
|
||||
"husky": "^9.1.7",
|
||||
|
||||
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
@@ -27,11 +27,11 @@ importers:
|
||||
specifier: ^29.5.14
|
||||
version: 29.5.14
|
||||
'@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-router':
|
||||
specifier: 5.1.20
|
||||
version: 5.1.20
|
||||
@@ -606,17 +606,16 @@ packages:
|
||||
'@types/normalize-package-data@2.4.4':
|
||||
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
||||
|
||||
'@types/prop-types@15.7.15':
|
||||
resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
|
||||
|
||||
'@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-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/stack-utils@2.0.3':
|
||||
resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
|
||||
@@ -3622,20 +3621,17 @@ snapshots:
|
||||
|
||||
'@types/normalize-package-data@2.4.4': {}
|
||||
|
||||
'@types/prop-types@15.7.15': {}
|
||||
|
||||
'@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-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.15
|
||||
csstype: 3.1.3
|
||||
|
||||
'@types/stack-utils@2.0.3': {}
|
||||
|
||||
@@ -17,5 +17,5 @@ export interface FocusableProps extends HTMLAttributes<HTMLDivElement>, FooterLe
|
||||
const focusableRegex = createPropListRegex(["flow-children", "onActivate", "onCancel", "focusClassName", "focusWithinClassName"]);
|
||||
|
||||
export const Focusable = findModuleExport((e: Export) =>
|
||||
e?.render?.toString && focusableRegex.test(e.render.toString())
|
||||
(typeof e == 'function' && e?.toString && focusableRegex.test(e.toString())) || (e?.render?.toString && focusableRegex.test(e.render.toString()))
|
||||
) as FC<FocusableProps & RefAttributes<HTMLDivElement>>;
|
||||
|
||||
@@ -108,7 +108,7 @@ export type ReorderableListEntryProps<T> = {
|
||||
reorderEntryFunc: CallableFunction;
|
||||
reorderEnabled: boolean;
|
||||
animate: boolean;
|
||||
children: ReactElement | null;
|
||||
children: ReactElement<any> | null;
|
||||
};
|
||||
|
||||
function ReorderableItem<T>(props: ReorderableListEntryProps<T>) {
|
||||
|
||||
@@ -69,71 +69,145 @@ export function injectFCTrampoline(component: FC, customHooks?: any): FCTrampoli
|
||||
|
||||
let renderHookStep = 0;
|
||||
|
||||
// Accessed two times, once directly before class instantiation, and again in some extra logic we don't need to worry about that we hanlde below just in case.
|
||||
Object.defineProperty(component, "contextType", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get contexttype", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("contextType trace");
|
||||
if (renderHookStep == 0) renderHookStep = 1;
|
||||
else if (renderHookStep == 3) renderHookStep = 4;
|
||||
return this._contextType;
|
||||
},
|
||||
set: function (value) {
|
||||
this._contextType = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Always accessed directly after contextType for the path we want to catch.
|
||||
Object.defineProperty(component, "contextTypes", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get contexttypes", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("contextTypes trace");
|
||||
if (renderHookStep == 1) {
|
||||
renderHookStep = 2;
|
||||
applyStubsIfNeeded();
|
||||
};
|
||||
return this._contextTypes;
|
||||
},
|
||||
set: function (value) {
|
||||
this._contextTypes = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Set directly after class is instantiated
|
||||
Object.defineProperty(component.prototype, "updater", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
return this._updater;
|
||||
},
|
||||
set: function (value) {
|
||||
loggingEnabled && logger.debug("set updater", this, value, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("updater trace");
|
||||
if (renderHookStep == 2) {
|
||||
renderHookStep = 0;
|
||||
removeStubsIfNeeded();
|
||||
if (window.SP_REACTDOM.version.startsWith("19.")) {
|
||||
// Accessed two times directly before class instantiation on path A and once on path B
|
||||
Object.defineProperty(component, "contextType", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get contexttype", this, this._contextType, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("contextType trace");
|
||||
if (renderHookStep == 0) {
|
||||
renderHookStep = 1;
|
||||
}
|
||||
if (this._contextType == null) {
|
||||
this._contextType = {};
|
||||
}
|
||||
if (!this._contextType.appliedCurrentValueHook) {
|
||||
logger.debug("applied currentvalue hook");
|
||||
this._contextType.appliedCurrentValueHook = true;
|
||||
Object.defineProperty(this._contextType, "_currentValue", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get currentValue", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("currentValue trace");
|
||||
if (renderHookStep == 1) {
|
||||
renderHookStep = 2;
|
||||
applyStubsIfNeeded();
|
||||
}
|
||||
return this.__currentValue;
|
||||
},
|
||||
set: function (value) {
|
||||
return this.__currentValue = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
return this._contextType;
|
||||
},
|
||||
set: function (value) {
|
||||
this._contextType = value;
|
||||
}
|
||||
return this._updater = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Prevents the second contextType+contextTypes access from leaving its hooks around
|
||||
Object.defineProperty(component, "getDerivedStateFromProps", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get getDerivedStateFromProps", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("getDerivedStateFromProps trace");
|
||||
if (renderHookStep == 2) {
|
||||
renderHookStep = 0;
|
||||
removeStubsIfNeeded();
|
||||
// Set directly after class is instantiated
|
||||
Object.defineProperty(component.prototype, "updater", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
return this._updater;
|
||||
},
|
||||
set: function (value) {
|
||||
loggingEnabled && logger.debug("set updater", this, value, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("updater trace");
|
||||
if (renderHookStep == 1 || renderHookStep == 2) {
|
||||
renderHookStep = 0;
|
||||
removeStubsIfNeeded();
|
||||
}
|
||||
return this._updater = value;
|
||||
}
|
||||
return this._getDerivedStateFromProps;
|
||||
},
|
||||
set: function (value) {
|
||||
this._getDerivedStateFromProps = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Prevents the second contextType access from leaving its hooks around
|
||||
Object.defineProperty(component, "getDerivedStateFromProps", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get getDerivedStateFromProps", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("getDerivedStateFromProps trace");
|
||||
if (renderHookStep == 1|| renderHookStep == 2) {
|
||||
renderHookStep = 0;
|
||||
removeStubsIfNeeded();
|
||||
}
|
||||
return this._getDerivedStateFromProps;
|
||||
},
|
||||
set: function (value) {
|
||||
this._getDerivedStateFromProps = value;
|
||||
}
|
||||
});
|
||||
} else if (window.SP_REACTDOM.version.startsWith("18.")) {
|
||||
// Accessed two times, once directly before class instantiation, and again in some extra logic we don't need to worry about that we hanlde below just in case.
|
||||
Object.defineProperty(component, "contextType", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get contexttype", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("contextType trace");
|
||||
if (renderHookStep == 0) renderHookStep = 1;
|
||||
else if (renderHookStep == 3) renderHookStep = 4;
|
||||
return this._contextType;
|
||||
},
|
||||
set: function (value) {
|
||||
this._contextType = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Always accessed directly after contextType for the path we want to catch.
|
||||
Object.defineProperty(component, "contextTypes", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get contexttypes", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("contextTypes trace");
|
||||
if (renderHookStep == 1) {
|
||||
renderHookStep = 2;
|
||||
applyStubsIfNeeded();
|
||||
};
|
||||
return this._contextTypes;
|
||||
},
|
||||
set: function (value) {
|
||||
this._contextTypes = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Set directly after class is instantiated
|
||||
Object.defineProperty(component.prototype, "updater", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
return this._updater;
|
||||
},
|
||||
set: function (value) {
|
||||
loggingEnabled && logger.debug("set updater", this, value, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("updater trace");
|
||||
if (renderHookStep == 2) {
|
||||
renderHookStep = 0;
|
||||
removeStubsIfNeeded();
|
||||
}
|
||||
return this._updater = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Prevents the second contextType+contextTypes access from leaving its hooks around
|
||||
Object.defineProperty(component, "getDerivedStateFromProps", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
loggingEnabled && logger.debug("get getDerivedStateFromProps", this, stubsApplied, renderHookStep);
|
||||
loggingEnabled && console.trace("getDerivedStateFromProps trace");
|
||||
if (renderHookStep == 2) {
|
||||
renderHookStep = 0;
|
||||
removeStubsIfNeeded();
|
||||
}
|
||||
return this._getDerivedStateFromProps;
|
||||
},
|
||||
set: function (value) {
|
||||
this._getDerivedStateFromProps = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return userComponent;
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import type * as React from 'react';
|
||||
import type * as ReactDOM from 'react-dom';
|
||||
import type * as JSXRuntime from 'react/jsx-runtime';
|
||||
import { Ref, useState } from 'react';
|
||||
|
||||
// this shouldn't need to be redeclared but it does for some reason
|
||||
@@ -6,6 +8,8 @@ import { Ref, useState } from 'react';
|
||||
declare global {
|
||||
interface Window {
|
||||
SP_REACT: typeof React;
|
||||
SP_REACTDOM: typeof ReactDOM;
|
||||
SP_JSX: typeof JSXRuntime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +37,11 @@ export function createPropListRegex(propList: string[], fromStart: boolean = tru
|
||||
|
||||
let oldHooks = {};
|
||||
|
||||
export let INTERNAL_HOOKS = (window.SP_REACT as any)?.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?.ReactCurrentDispatcher
|
||||
.current || Object.values((window.SP_REACT as any)?.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE).find((p: any) => p?.useEffect);
|
||||
|
||||
export function applyHookStubs(customHooks: any = {}): any {
|
||||
const hooks = (window.SP_REACT as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher
|
||||
.current;
|
||||
const hooks = INTERNAL_HOOKS;
|
||||
|
||||
// TODO: add more hooks
|
||||
|
||||
@@ -50,7 +56,7 @@ export function applyHookStubs(customHooks: any = {}): any {
|
||||
};
|
||||
|
||||
hooks.useCallback = (cb: Function) => cb;
|
||||
hooks.useContext = (cb: any) => cb._currentValue;
|
||||
hooks.useContext = (cb: any) => cb?._currentValue;
|
||||
hooks.useLayoutEffect = (_: Function) => {}; //cb();
|
||||
hooks.useMemo = (cb: Function, _: any[]) => cb;
|
||||
hooks.useEffect = (_: Function) => {}; //cb();
|
||||
@@ -67,8 +73,7 @@ export function applyHookStubs(customHooks: any = {}): any {
|
||||
}
|
||||
|
||||
export function removeHookStubs() {
|
||||
const hooks = (window.SP_REACT as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher
|
||||
.current;
|
||||
const hooks = INTERNAL_HOOKS;
|
||||
Object.assign(hooks, oldHooks);
|
||||
oldHooks = {};
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
"outDir": "dist",
|
||||
"module": "ESNext",
|
||||
"target": "ES2020",
|
||||
"jsx": "react",
|
||||
"jsxFactory": "window.SP_REACT.createElement",
|
||||
"jsx": "react-jsx",
|
||||
"declaration": true,
|
||||
"moduleResolution": "node",
|
||||
"noUnusedLocals": true,
|
||||
|
||||
Reference in New Issue
Block a user