Compare commits

...

54 Commits

Author SHA1 Message Date
semantic-release-bot
3f126fe471 chore(release): 1.7.1 [CI SKIP] 2022-08-17 18:52:21 +00:00
AAGaming
e644de35d7 fix(utils): better method to wrap react classes 2022-08-17 14:51:24 -04:00
semantic-release-bot
9b79f70ac7 chore(release): 1.7.0 [CI SKIP] 2022-08-17 18:46:25 +00:00
AAGaming
d237bd48e4 feat(utils): add wrapReactClass 2022-08-17 14:45:34 -04:00
semantic-release-bot
f7d73b4dc3 chore(release): 1.6.2 [CI SKIP] 2022-08-15 17:13:15 +00:00
AAGaming
9edb1e6b97 chore(classes): add scrollClasses 2022-08-15 13:12:15 -04:00
AAGaming
605e4f5eae chore(semantic-release): tweak commit-analyzer 2022-08-15 13:11:38 -04:00
semantic-release-bot
e2f675835e chore(release): 1.6.1 [CI SKIP] 2022-08-13 01:36:15 +00:00
AAGaming
b7dc1d6275 fix(wrapReactType): try another method 2022-08-12 21:35:27 -04:00
semantic-release-bot
a1fdae9cd2 chore(release): 1.6.0 [CI SKIP] 2022-08-13 01:25:46 +00:00
AAGaming
7cf45cf371 feat(Utilities): add wrapReactType utility 2022-08-12 21:24:56 -04:00
semantic-release-bot
df1c8dbb8b chore(release): 1.5.1 [CI SKIP] 2022-08-10 22:46:24 +00:00
TrainDoctor
1de979f713 fix(security): update for minimist pollution exploit 2022-08-10 15:44:37 -07:00
TrainDoctor
f23070a82a Merge pull request #10 from SteamDeckHomebrew/dependabot/npm_and_yarn/semantic-release-19.0.3
chore(deps-dev): bump semantic-release from 19.0.2 to 19.0.3
2022-08-10 15:39:43 -07:00
dependabot[bot]
b87e7c2f40 chore(deps-dev): bump semantic-release from 19.0.2 to 19.0.3
Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 19.0.2 to 19.0.3.
- [Release notes](https://github.com/semantic-release/semantic-release/releases)
- [Commits](https://github.com/semantic-release/semantic-release/compare/v19.0.2...v19.0.3)

---
updated-dependencies:
- dependency-name: semantic-release
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-10 22:39:05 +00:00
semantic-release-bot
6db29a9a6e chore(release): 1.5.0 [CI SKIP] 2022-08-10 01:37:31 +00:00
AAGaming
e2126afd06 feat(ServerAPI): add Toaster to serverAPI 2022-08-09 21:36:32 -04:00
semantic-release-bot
cea587958e chore(release): 1.4.0 [CI SKIP] 2022-08-08 23:31:05 +00:00
AAGaming
b21dfcdb66 feat(utils): add findInTree and findInReactTree 2022-08-08 19:30:08 -04:00
semantic-release-bot
d46251bb91 chore(release): 1.3.0 [CI SKIP] 2022-08-02 22:55:55 +00:00
AAGaming
5b29447cfa feat(plugin): api for patching existing routes 2022-08-02 18:50:39 -04:00
TrainDoctor
e993d06963 Update README.md 2022-07-28 15:28:50 -07:00
semantic-release-bot
a3c136a07e chore(release): 1.2.4 [CI SKIP] 2022-07-25 19:44:53 +00:00
AAGaming
994b9e2cc6 fix(Modal): add closeModal 2022-07-25 15:44:06 -04:00
semantic-release-bot
801d70f300 chore(release): 1.2.3 [CI SKIP] 2022-07-25 19:34:45 +00:00
AAGaming
2fdfcdd478 fix(Modal): add another prop 2022-07-25 15:33:35 -04:00
semantic-release-bot
9a728611f4 chore(release): 1.2.2 [CI SKIP] 2022-07-25 19:30:30 +00:00
AAGaming
97997adfaf fix(Modal): add more props to typings 2022-07-25 15:29:38 -04:00
semantic-release-bot
279069ee34 chore(release): 1.2.1 [CI SKIP] 2022-07-13 01:07:46 +00:00
AAGaming
944a9024ff fix(ProgressBar): extend correct prop type 2022-07-12 21:06:46 -04:00
AAGaming
0a2220b4b4 chore(ProgressBar): formatting 2022-07-12 20:45:56 -04:00
semantic-release-bot
aa567e9dd0 chore(release): 1.2.0 [CI SKIP] 2022-07-13 00:34:28 +00:00
AAGaming
d9e4ff3ebd feat(ProgressBar): add new progress bars 2022-07-12 20:33:38 -04:00
semantic-release-bot
79d73dea2e chore(release): 1.1.0 [CI SKIP] 2022-07-09 14:34:48 +00:00
hulkrelax
602f93ae6a feat(Router.tsx): adds more methods to router (#9)
Adds the ability to get the main running app and to navigate to the running app
2022-07-09 10:34:09 -04:00
semantic-release-bot
d86c86cd80 chore(release): 1.0.2 [CI SKIP] 2022-07-07 04:03:42 +00:00
AAGaming
51c418d560 fix(Plugin): support non-ui plugins 2022-07-07 00:00:40 -04:00
semantic-release-bot
95de7346df chore(release): 1.0.1 [CI SKIP] 2022-06-29 15:53:25 +00:00
AAGaming
58933f827c fix(package): enable tree shaking 2022-06-29 11:50:20 -04:00
hulkrelax
0ff3476987 bugfix: Fix issue with incorrect typing on fetchNoCors (#7)
* make fetchNoCors have similar typing to fetch

* request param should be optional
2022-06-28 21:12:44 -04:00
semantic-release-bot
2c7d266c81 chore(release): 1.0.0 [CI SKIP] 2022-06-23 02:58:38 +00:00
AAGaming
9bd96227a0 refactor(components): rename Field components
BREAKING CHANGE: Toggle -> ToggleField Slider -> SliderField & add Toggle component
2022-06-22 22:57:51 -04:00
semantic-release-bot
ddafa5666d chore(release): 0.12.3 [CI SKIP] 2022-06-23 02:45:11 +00:00
AAGaming
46977496fd fix(Field): description is a string you idiot 2022-06-22 22:44:13 -04:00
semantic-release-bot
71a6c79384 chore(release): 0.12.2 [CI SKIP] 2022-06-23 01:53:07 +00:00
AAGaming
da4c79b5ae fix(Field): title -> label 2022-06-22 21:52:17 -04:00
semantic-release-bot
7b04bf5827 chore(release): 0.12.1 [CI SKIP] 2022-06-23 01:47:38 +00:00
AAGaming
a87e1bb46f fix(components): export FIeld 2022-06-22 21:46:50 -04:00
semantic-release-bot
b6e2e7e4dc chore(release): 0.12.0 [CI SKIP] 2022-06-23 01:45:47 +00:00
AAGaming
7d82a82e9c feat(components): add Field 2022-06-22 21:44:46 -04:00
semantic-release-bot
0cee60d122 chore(release): 0.11.1 [CI SKIP] 2022-06-23 00:42:16 +00:00
AAGaming
7efc0347f7 fix(Router): make specifying quick access tab not required 2022-06-22 20:41:22 -04:00
semantic-release-bot
d227858e62 chore(release): 0.11.0 [CI SKIP] 2022-06-20 21:37:03 +00:00
AAGaming
db64f34725 feat(utils): add sleep util 2022-06-20 17:35:56 -04:00
16 changed files with 646 additions and 755 deletions

View File

@@ -1,7 +1,15 @@
{
"branches": ["main", "dev"],
"plugins": [
"@semantic-release/commit-analyzer",
[
"@semantic-release/commit-analyzer",
{
"preset": "angular",
"releaseRules": [
{"type": "chore", "scope": "classes", "release": "patch"}
]
}
],
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",

View File

@@ -1,3 +1,171 @@
## [1.7.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.7.0...v1.7.1) (2022-08-17)
### Bug Fixes
* **utils:** better method to wrap react classes ([e644de3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/e644de35d70680d17d70e89cc9b929a5aae08b48))
# [1.7.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.6.2...v1.7.0) (2022-08-17)
### Features
* **utils:** add wrapReactClass ([d237bd4](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/d237bd48e4b9e6436d7daefdf70327875e9e940d))
## [1.6.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.6.1...v1.6.2) (2022-08-15)
## [1.6.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.6.0...v1.6.1) (2022-08-13)
### Bug Fixes
* **wrapReactType:** try another method ([b7dc1d6](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/b7dc1d6275ed28b1e37b6cb512b2c5d1600a8f63))
# [1.6.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.5.1...v1.6.0) (2022-08-13)
### Features
* **Utilities:** add wrapReactType utility ([7cf45cf](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/7cf45cf3718d6e5295115f28a5f4dd24c6ff14e3))
## [1.5.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.5.0...v1.5.1) (2022-08-10)
### Bug Fixes
* **security:** update for minimist pollution exploit ([1de979f](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/1de979f7135c8d5eea1faca3d480d662c5e41d3d))
# [1.5.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.4.0...v1.5.0) (2022-08-10)
### Features
* **ServerAPI:** add Toaster to serverAPI ([e2126af](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/e2126afd06f339a22dbbaea89b834157a5975b96))
# [1.4.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.3.0...v1.4.0) (2022-08-08)
### Features
* **utils:** add findInTree and findInReactTree ([b21dfcd](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/b21dfcdb661fd7ad43213756dadb6cfdf0ac1e94))
# [1.3.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.2.4...v1.3.0) (2022-08-02)
### Features
* **plugin:** api for patching existing routes ([5b29447](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/5b29447cfa597773a81aa233da9362346683505d))
## [1.2.4](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.2.3...v1.2.4) (2022-07-25)
### Bug Fixes
* **Modal:** add closeModal ([994b9e2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/994b9e2cc6f41da3d813e6f339bd2fd30e4fa3ad))
## [1.2.3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.2.2...v1.2.3) (2022-07-25)
### Bug Fixes
* **Modal:** add another prop ([2fdfcdd](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/2fdfcdd4788ea0d6483e92729c3102212f3ec0fb))
## [1.2.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.2.1...v1.2.2) (2022-07-25)
### Bug Fixes
* **Modal:** add more props to typings ([97997ad](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/97997adfaf1a68ef436279e6e48f34f5eaa9531c))
## [1.2.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.2.0...v1.2.1) (2022-07-13)
### Bug Fixes
* **ProgressBar:** extend correct prop type ([944a902](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/944a9024ff20f0b596869564d014d7dd73e74254))
# [1.2.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.1.0...v1.2.0) (2022-07-13)
### Features
* **ProgressBar:** add new progress bars ([d9e4ff3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/d9e4ff3ebd22a31306f564e7f8ad82879c8fb699))
# [1.1.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.0.2...v1.1.0) (2022-07-09)
### Features
* **Router.tsx:** adds more methods to router ([#9](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/9)) ([602f93a](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/602f93ae6a5ceca5383b888cd4803638799558c5))
## [1.0.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.0.1...v1.0.2) (2022-07-07)
### Bug Fixes
* **Plugin:** support non-ui plugins ([51c418d](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/51c418d560247c917125cd5534a978256724e5f3))
## [1.0.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v1.0.0...v1.0.1) (2022-06-29)
### Bug Fixes
* **package:** enable tree shaking ([58933f8](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/58933f827ce2e2ae9b162da4e0061a7591c5759d))
# [1.0.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.12.3...v1.0.0) (2022-06-23)
### Code Refactoring
* **components:** rename Field components ([9bd9622](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/9bd96227a0bb295dcc29abca71e37983307f0505))
### BREAKING CHANGES
* **components:** Toggle -> ToggleField Slider -> SliderField & add Toggle component
## [0.12.3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.12.2...v0.12.3) (2022-06-23)
### Bug Fixes
* **Field:** description is a string you idiot ([4697749](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/46977496fd4cbe266c370fcffe59a9d9b7543a92))
## [0.12.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.12.1...v0.12.2) (2022-06-23)
### Bug Fixes
* **Field:** title -> label ([da4c79b](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/da4c79b5aeb3c589527e17ad29610a8e3f929b79))
## [0.12.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.12.0...v0.12.1) (2022-06-23)
### Bug Fixes
* **components:** export FIeld ([a87e1bb](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/a87e1bb46f749e10ea2b94a011df48f162834c25))
# [0.12.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.11.1...v0.12.0) (2022-06-23)
### Features
* **components:** add Field ([7d82a82](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/7d82a82e9c4db59832593cb6f0f78775b252dc69))
## [0.11.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.11.0...v0.11.1) (2022-06-23)
### Bug Fixes
* **Router:** make specifying quick access tab not required ([7efc034](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/7efc0347f7aa22773feccb0763280c4fd1c4a231))
# [0.11.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.10.5...v0.11.0) (2022-06-20)
### Features
* **utils:** add sleep util ([db64f34](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/db64f3472542b080b1d470c6b8d7aa441db0bfe6))
## [0.10.5](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.10.4...v0.10.5) (2022-06-20)

View File

@@ -1 +1,27 @@
# Decky Frontend Library
Library used to develop plugins used for use with [decky-loader](https://github.com/SteamDeckHomebrew/decky-loader).
## Decky Loader Discord [![Chat](https://img.shields.io/badge/chat-on%20discord-7289da.svg)](https://discord.gg/ZU74G2NJzk)
Please contact the developers here for questions and support that cannot be addressed via a Github issue.
## Developers and Contributors
This library is focused on usage by developers to provide custom React components based on those found in the Steam Deck's React UI.
This method allows developers to add UI elements and code without clobbering the existing UI of the deck in order to do so.
This library can also theoretically be used to extend existing UI elements of the Steam Deck UI but this has not been tested extensively.
### Getting Started (Contributors)
1. Clone the repository to your preferred location
2. If you wish to add features such as new UI components, please create a feature branch to PR to the original repo.
3. Bug/hotfixes are acceptable on the main branch,
### Getting Started (Developers)
If you would like a feature added to decky-frontend-lib, please request it via a Github issue.
If you want to start making a plugin with decky-frontend-lib, please direct your attention to the [decky-plugin-template](https://github.com/SteamDeckHomebrew/decky-plugin-template) repository.
This library can be found on [npm](https://www.npmjs.com/package/decky-frontend-lib) and as such you can pull it without a local copy for your project as needed.

946
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,11 @@
{
"name": "decky-frontend-lib",
"version": "0.10.5",
"version": "1.7.1",
"description": "A library for building decky plugins",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"module": "dist/index.js",
"sideEffects": false,
"scripts": {
"build": "shx rm -rf dist && tsc -b",
"dev": "tsc -b -w",
@@ -53,7 +54,7 @@
"import-sort-style-module": "^6.0.0",
"jest": "^27.5.1",
"prettier-plugin-import-sort": "^0.0.7",
"semantic-release": "^19.0.2",
"semantic-release": "^19.0.3",
"shx": "^0.3.4",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3"
@@ -71,5 +72,8 @@
"style": "module",
"parser": "typescript"
}
},
"dependencies": {
"minimist": "^1.2.6"
}
}

View File

@@ -0,0 +1,22 @@
import { FC, HTMLAttributes, ReactNode, RefAttributes } from 'react';
import { findModuleChild } from '../webpack';
export interface FieldProps extends HTMLAttributes<HTMLDivElement> {
label?: string | ReactNode;
description?: string | ReactNode;
disabled?: boolean;
icon?: ReactNode;
childrenLayout?: string;
childrenContainerWidth?: string;
padding?: string;
highlightOnFocus?: boolean;
indentLevel?: number;
verticalAlignment?: string;
}
export const Field = findModuleChild((m) => {
if (typeof m !== "object") return undefined;
for (let prop in m) {
if (m[prop]?.render?.toString().includes('"shift-children-below"')) return m[prop]
}
}) as FC<FieldProps & RefAttributes<HTMLDivElement>>;

View File

@@ -16,7 +16,15 @@ export interface ModalRootProps {
onMiddleButton?(): void;
onCancel?(): void;
onOK?(): void;
onEscKeypress?(): void;
closeModal?(): void;
className?: string;
modalClassName?: string;
bAllowFullSize?: boolean;
bDestructiveWarning?: boolean;
bDisableBackgroundDismiss?: boolean;
bHideCloseIcon?: boolean;
bOKDisabled?: boolean;
}
export const ModalRoot = findModuleChild((m) => {

View File

@@ -1,18 +1,44 @@
import { VFC } from 'react';
import { VFC, ReactNode } from 'react';
import { findModuleChild } from '../webpack';
import { ItemProps } from './Item';
export interface ProgressBarItem extends ItemProps {
export interface ProgressBarItemProps extends ItemProps {
indeterminate?: boolean;
nTransitionSec?: number;
nProgress?: number;
focusable?: boolean;
}
export interface ProgressBarProps {
indeterminate?: boolean;
nTransitionSec?: number;
nProgress?: number;
focusable?: boolean;
}
export interface ProgressBarWithInfoProps extends ProgressBarItemProps {
sTimeRemaining?: ReactNode;
sOperationText?: ReactNode;
}
export const ProgressBar = findModuleChild((m) => {
if (typeof m !== 'object') return undefined;
for (let prop in m) {
if (m[prop]?.toString()?.includes('.ProgressBar,"standard"==')) return m[prop];
}
}) as VFC<ProgressBarProps>;
export const ProgressBarWithInfo = findModuleChild((m) => {
if (typeof m !== 'object') return undefined;
for (let prop in m) {
if (m[prop]?.toString()?.includes('.ProgressBarFieldStatus},')) return m[prop];
}
}) as VFC<ProgressBarWithInfoProps>;
export const ProgressBarItem = findModuleChild((m) => {
if (typeof m !== 'object') return undefined;
for (let prop in m) {
if (m[prop]?.toString()?.includes('"indeterminate","nTransitionSec"')) return m[prop];
}
}) as VFC<ProgressBarItem>;
}) as VFC<ProgressBarItemProps>;

View File

@@ -17,19 +17,67 @@ export enum QuickAccessTab {
Decky,
}
export enum DisplayStatus {
Invalid = 0,
Launching = 1,
Uninstalling = 2,
Installing = 3,
Running = 4,
Validating = 5,
Updating = 6,
Downloading = 7,
Synchronizing = 8,
ReadyToInstall = 9,
ReadyToPreload = 10,
ReadyToLaunch = 11,
RegionRestricted = 12,
PresaleOnly = 13,
InvalidPlatform = 14,
PreloadComplete = 16,
BorrowerLocked = 17,
UpdatePaused = 18,
UpdateQueued = 19,
UpdateRequired = 20,
UpdateDisabled = 21,
DownloadPaused = 22,
DownloadQueued = 23,
DownloadRequired = 24,
DownloadDisabled = 25,
LicensePending = 26,
LicenseExpired = 27,
AvailForFree = 28,
AvailToBorrow = 29,
AvailGuestPass = 30,
Purchase = 31,
Unavailable = 32,
NotLaunchable = 33,
CloudError = 34,
CloudOutOfDate = 35,
Terminating = 36,
}
export type AppOverview = {
appid: string
display_name: string
display_status: DisplayStatus
sort_as: string
}
export interface Router {
CloseSideMenus(): void;
OpenQuickAccessMenu(quickAccessTab: QuickAccessTab): void;
OpenQuickAccessMenu(quickAccessTab?: QuickAccessTab): void;
GetQuickAccessTab(): QuickAccessTab;
Navigate(path: string): void;
NavigateBackOrOpenMenu(): void;
NavigateToExternalWeb(url: string): void;
NavigateToRunningApp(replace?: boolean): void;
NavigateToStore(): void;
ToggleSideMenu(sideMenu: SideMenu): void;
CloseSideMenus(): void;
OpenSideMenu(sideMenu: SideMenu): void;
OpenPowerMenu(unknown?: any): void;
get RunningApps(): any;
get MainRunningApp(): AppOverview | undefined;
}
export const Router = findModuleChild((m: Module) => {

View File

@@ -9,7 +9,7 @@ export interface NotchLabel {
value?: number;
}
export interface SliderProps extends ItemProps {
export interface SliderFieldProps extends ItemProps {
value: number;
min?: number;
max?: number;
@@ -27,6 +27,6 @@ export interface SliderProps extends ItemProps {
onChange?(value: number): void;
}
export const Slider = Object.values(CommonUIModule).find((mod: any) =>
export const SliderField = Object.values(CommonUIModule).find((mod: any) =>
mod?.toString()?.includes('SliderField,fallback'),
) as FC<SliderProps>;
) as FC<SliderFieldProps>;

View File

@@ -1,14 +1,14 @@
import { FC } from 'react';
import { CommonUIModule } from '../webpack';
import { ItemProps } from './Item';
export interface ToggleProps extends ItemProps {
checked: boolean;
export interface ToggleProps {
value: boolean;
disabled?: boolean;
onChange?(checked: boolean): void;
navRef?: any; // TODO figure out what this is
}
export const Toggle = Object.values(CommonUIModule).find((mod: any) =>
mod?.render?.toString()?.includes('ToggleField,fallback'),
mod?.render?.toString()?.includes('.ToggleOff)'),
) as FC<ToggleProps>;

View File

@@ -0,0 +1,14 @@
import { FC } from 'react';
import { CommonUIModule } from '../webpack';
import { ItemProps } from './Item';
export interface ToggleFieldProps extends ItemProps {
checked: boolean;
disabled?: boolean;
onChange?(checked: boolean): void;
}
export const ToggleField = Object.values(CommonUIModule).find((mod: any) =>
mod?.render?.toString()?.includes('ToggleField,fallback'),
) as FC<ToggleFieldProps>;

View File

@@ -1,6 +1,7 @@
export * from './Button';
export * from './ButtonItem';
export * from './Dropdown';
export * from './Field';
export * from './Focusable';
export * from './Menu';
export * from './Modal';
@@ -8,9 +9,10 @@ export * from './Panel';
export * from './ProgressBar';
export * from './Router';
export * from './SidebarNavigation';
export * from './Slider';
export * from './SliderField';
export * from './Spinner';
export * from './static-classes';
export * from './SteamSpinner';
export * from './TextField';
export * from './Toggle';
export * from './ToggleField';

View File

@@ -63,6 +63,14 @@ type StaticClasses = Record<
string
>;
type ScrollClasses = Record<
| 'ScrollBoth'
| 'ScrollPanel'
| 'ScrollX'
| 'ScrollY',
string
>;
type GamepadDialogClasses = Record<
| 'duration-app-launch'
| 'GamepadDialogContent'
@@ -167,6 +175,16 @@ export const staticClasses: StaticClasses = findModule((mod) => {
return false;
});
export const scrollClasses: ScrollClasses = findModule((mod) => {
if (typeof mod !== 'object') return false;
if (mod.ScrollPanel && mod.ScrollY) {
return true;
}
return false;
});
export const gamepadDialogClasses: GamepadDialogClasses = findModule((mod) => {
if (typeof mod !== 'object') return false;

View File

@@ -1,10 +1,10 @@
import type { ComponentType } from 'react';
import type { ComponentType, ReactNode } from 'react';
import { RouteProps } from 'react-router';
export interface Plugin {
title: JSX.Element;
icon: JSX.Element;
content: JSX.Element;
content?: JSX.Element;
onDismount?(): void;
}
@@ -20,16 +20,37 @@ interface ServerResponseError {
type ServerResponse<TRes> = ServerResponseSuccess<TRes> | ServerResponseError;
interface RouterHook {
type RoutePatch = (route: RouteProps) => RouteProps;
export interface RouterHook {
addRoute(path: string, component: ComponentType, props?: Omit<RouteProps, 'path' | 'children'>): void;
addPatch(path: string, patch: RoutePatch): RoutePatch;
removePatch(path: string, patch: RoutePatch): void;
removeRoute(path: string): void;
}
export interface ToastData {
title: ReactNode;
body: ReactNode;
onClick?: () => void;
logo?: ReactNode;
icon?: ReactNode;
className?: string;
contentClassName?: string;
duration?: number
critical?: boolean
}
export interface Toaster {
toast(toast: ToastData): void;
}
export interface ServerAPI {
routerHook: RouterHook;
toaster: Toaster;
callPluginMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
callServerMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
fetchNoCors<TRes = {}>(url: string, request: RequestInfo): Promise<ServerResponse<TRes>>;
fetchNoCors<TRes = {}>(url: RequestInfo, request?: RequestInit): Promise<ServerResponse<TRes>>;
executeInTab(tab: string, runAsync: boolean, code: string): Promise<unknown>;
injectCssIntoTab<TRes = string>(tab: string, style: string): Promise<ServerResponse<TRes>>;
removeCssFromTab(tab: string, cssId: string): Promise<unknown>;

View File

@@ -82,10 +82,60 @@ export function unpatch(obj: any, name: any): void {
obj[name] = obj[name].__deckyOrig;
}
export function wrapReactType(node: any, prop?: any) {
return node[prop || "type"] = {...node[prop || "type"]};
}
export function wrapReactClass(node: any, prop?: any) {
const cls = node[prop || "type"];
const wrappedCls = class extends cls {};
Object.getOwnPropertyNames(cls.prototype).forEach((prop: any) => {
wrappedCls.prototype[prop] = cls.prototype[prop]
});
Object.getOwnPropertyNames(cls).forEach((prop: any) => {
if (prop != "prototype") wrappedCls[prop] = cls[prop]
});
wrappedCls.prototype.__proto__ = cls.prototype.__proto__;
return node[prop || "type"] = wrappedCls;
}
export function getReactInstance(o: HTMLElement | Element | Node) {
return o[Object.keys(o).find(k => k.startsWith('__reactInternalInstance')) as string]
}
export function joinClassNames(...classes: string[]): string {
return classes.join(" ");
}
}
export function sleep(ms: number) {
return new Promise(res => setTimeout(res, ms));
}
// Based on https://github.com/GooseMod/GooseMod/blob/9ef146515a9e59ed4e25665ed365fd72fc0dcf23/src/util/react.js#L20
export interface findInTreeOpts {
walkable?: string[],
ignore?: string[]
}
export declare type findInTreeFilter = (element: any) => boolean
export const findInTree = (parent: any, filter: findInTreeFilter, opts: findInTreeOpts): any => {
const { walkable = null, ignore = [] } = opts ?? {};
if (!parent || typeof parent !== 'object') { // Parent is invalid to search through
return null;
}
if (filter(parent)) return parent; // Parent matches, just return
if (Array.isArray(parent)) { // Parent is an array, go through values
return parent.map((x) => findInTree(x, filter, opts)).find((x) => x);
}
// Parent is an object, go through values (or option to only use certain keys)
return (walkable || Object.keys(parent)).map((x) => !ignore.includes(x) && findInTree(parent[x], filter, opts)).find((x: any) => x);
};
export const findInReactTree = (node: any, filter: findInTreeFilter) => findInTree(node, filter, { // Specialised findInTree for React nodes
walkable: [ 'props', 'children', 'child', 'sibling' ]
});