Compare commits

..

6 Commits

Author SHA1 Message Date
Jonas Dellinger
f882636be7 0.0.3 2022-05-26 13:29:00 +02:00
Jonas Dellinger
815129d03f Export DialogButton and add icon prop 2022-05-26 13:28:35 +02:00
Jonas Dellinger
ef41d17e43 Add back panels 2022-05-26 10:15:32 +02:00
AAGaming
6d4ca5dc92 Merge branch 'main' of github.com:steamdeckhomebrew/decky-frontend-lib 2022-05-25 20:26:43 -04:00
AAGaming
0303724794 export more stuff, replace button component with actual button and move the old one to ButtonItem 2022-05-25 20:26:30 -04:00
Jonas Dellinger
98c226b8e6 Remove pnpm lock 2022-05-25 21:03:03 +02:00
11 changed files with 102 additions and 2977 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "decky-frontend-lib",
"version": "0.0.1",
"version": "0.0.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "decky-frontend-lib",
"version": "0.0.1",
"version": "0.0.3",
"license": "GPL-2.0-or-later",
"devDependencies": {
"@types/jest": "^27.4.1",

View File

@@ -1,6 +1,6 @@
{
"name": "decky-frontend-lib",
"version": "0.0.2",
"version": "0.0.3",
"description": "A library for building decky plugins",
"main": "dist/index.js",
"types": "dist/index.d.ts",

2899
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,14 +3,27 @@ import { FC } from 'react';
import { CommonUIModule } from '../webpack';
interface ButtonProps {
label?: string;
description?: string;
layout?: 'below';
onClick?(e: MouseEvent): void;
className?: string;
noFocusRing?: boolean;
disabled?: boolean;
bottomSeparator?: boolean;
onClick?(e: MouseEvent): void;
onPointerDown?(e: PointerEvent): void;
onPointerUp?(e: PointerEvent): void;
onPointerCancel?(e: PointerEvent): void;
onMouseDown?(e: PointerEvent): void;
onMouseUp?(e: MouseEvent): void;
onTouchStart?(e: TouchEvent): void;
onTouchEnd?(e: TouchEvent): void;
onTouchCancel?(e: TouchEvent): void;
onSubmit?(e: SubmitEvent): void;
}
export const Button = Object.values(CommonUIModule).find((mod: any) =>
mod?.render?.toString()?.includes('childrenContainerWidth:"min"'),
) as FC<ButtonProps>;
export const DialogButton = Object.values(CommonUIModule).find(
(mod: any) =>
mod?.render?.toString()?.includes('Object.assign({type:"button"') &&
mod?.render?.toString()?.includes('DialogButton'),
) as any;
// Button isn't exported, so call DialogButton to grab it
export const Button = DialogButton!.render({}).type as FC<ButtonProps>; // its actually a forwarded ref but that doesn't really matter in usage

View File

@@ -0,0 +1,17 @@
import { FC } from 'react';
import { CommonUIModule } from '../webpack';
interface ButtonItemProps {
label?: string;
description?: string;
layout?: 'below';
icon?: JSX.Element;
onClick?(e: MouseEvent): void;
disabled?: boolean;
bottomSeparator?: boolean;
}
export const ButtonItem = Object.values(CommonUIModule).find((mod: any) =>
mod?.render?.toString()?.includes('childrenContainerWidth:"min"'),
) as FC<ButtonItemProps>;

View File

@@ -0,0 +1,23 @@
import { FC } from 'react';
import { findModuleChild } from '../webpack';
interface PanelSectionProps {
title?: string;
spinner?: boolean;
}
const [panelSection, mod] = findModuleChild((mod: any) => {
for (let prop in mod) {
if (mod[prop]?.toString()?.includes('.PanelSection')) {
return [mod[prop], mod];
}
}
return null;
});
export const PanelSection = panelSection as FC<PanelSectionProps>;
export const PanelSectionRow = Object.values(mod).filter(
(exp: any) => !exp?.toString()?.includes('.PanelSection'),
)[0] as FC;

View File

@@ -0,0 +1,16 @@
import { FC } from 'react';
import { IconsModule } from '../webpack';
// interface ButtonProps {
// label?: string;
// description?: string;
// layout?: 'below';
// onClick?(e: MouseEvent): void;
// disabled?: boolean;
// bottomSeparator?: boolean;
// }
export const Spinner = Object.values(IconsModule).find((mod: any) =>
mod?.toString()?.includes("Spinner)}),a.createElement(\"path\",{d:\"M18 "),
) as FC<{}>;

View File

@@ -1,6 +1,9 @@
export * from './Button';
export * from './ButtonItem';
export * from './Menu';
export * from './Modal';
export * from './Panel';
export * from './Slider';
export * from './Spinner';
export * from './static-classes';
export * from './Toggle';

View File

@@ -2,4 +2,3 @@
export * from './deck-components';
export * from './plugin';
export * from './webpack';
export * from './utils';

View File

@@ -1,65 +0,0 @@
export function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
declare global {
interface Window {
SP_REACT: any;
}
}
export function fakeRenderComponent(fun: Function): any {
const hooks = window.SP_REACT.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher.current;
// TODO: add more hooks
let oldHooks = {
useContext: hooks.useContext,
useCallback: hooks.useCallback,
useEffect: hooks.useEffect,
useState: hooks.useState,
}
hooks.useCallback = (cb: Function) => cb;
hooks.useContext = (cb: Function) => cb;
hooks.useEffect = (cb: Function) => cb();
hooks.useState = (v: any) => {
let val = v;
return [val, (n: any) => val = n];
};
const res = fun();
Object.assign(hooks, oldHooks);
return res;
}
export function beforePatch(obj: any, name: string, fnc: Function): void {
const orig = obj[name];
obj[name] = function (...args: any[]) {
fnc.call(this, args);
return orig.call(this, ...args);
}
Object.assign(obj[name], orig);
obj[name].toString = () => orig.toString();
obj[name].__deckyOrig = orig;
}
export function afterPatch(obj: any, name: string, fnc: Function): void {
const orig = obj[name];
obj[name] = function (...args: any[]) {
let ret = orig.apply(...args);
ret = fnc(ret);
return ret;
}
Object.assign(obj[name], orig);
obj[name].toString = () => orig.toString();
obj[name].__deckyOrig = orig;
}
// TODO allow one method to be patched and unpatched multiple times independently using IDs in a Map or something
export function unpatch(obj: any, name: any): void {
obj[name] = obj[name].__deckyOrig;
}

View File

@@ -58,7 +58,25 @@ export const CommonUIModule = allModules.find((m: Module) => {
return false;
});
export const IconsModule = allModules.find((m: Module) => {
if (typeof m !== "object") return undefined;
for (let prop in m) {
if (m[prop]?.toString()?.includes("Spinner)}),a.createElement(\"path\",{d:\"M18 ")) return true;
}
return false;
})
export const Router = findModuleChild((m: Module) => {
if (typeof m !== "object") return undefined;
for (let prop in m) { if (m[prop]?.Navigate && m[prop]?.NavigationManager) return m[prop]}
for (let prop in m) {
if (m[prop]?.Navigate && m[prop]?.NavigationManager) return m[prop]
}
})
export const ReactRouter = allModules.find((m: Module) => {
if (typeof m !== "object") return undefined;
for (let prop in m) {
if (m[prop]?.computeRootMatch) return true
}
return false;
})