mirror of
https://github.com/SteamDeckHomebrew/decky-frontend-lib.git
synced 2026-05-20 10:00:08 +02:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
377d7adde8 | ||
|
|
f34b9de97f | ||
|
|
b5192cf590 | ||
|
|
2e7b4b664a | ||
|
|
b92e6a5b9d | ||
|
|
32c355f2a7 | ||
|
|
747d70dcca | ||
|
|
7f9dfc5910 | ||
|
|
a3c1a7c7b7 | ||
|
|
fccfdd6f11 | ||
|
|
f124480af8 | ||
|
|
15e672afef | ||
|
|
bf0c2b17bf | ||
|
|
0625dc385a | ||
|
|
b04992d29c | ||
|
|
228fe1f22c | ||
|
|
5d4214176e | ||
|
|
62bf0eaffa | ||
|
|
43b04b267e | ||
|
|
58595d54ea | ||
|
|
aec27a18a7 |
3
.commitlintrc.json
Normal file
3
.commitlintrc.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": ["@commitlint/config-conventional"]
|
||||
}
|
||||
29
.github/workflows/release.yaml
vendored
Normal file
29
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Setup | Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup | Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Setup | Dependencies
|
||||
run: npm ci
|
||||
- name: Test
|
||||
run: npm test
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npm exec semantic-release
|
||||
4
.husky/commit-msg
Executable file
4
.husky/commit-msg
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx --no -- commitlint --edit "${1}"
|
||||
17
.releaserc.json
Normal file
17
.releaserc.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"branches": ["main", "dev"],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog",
|
||||
"@semantic-release/npm",
|
||||
"@semantic-release/github",
|
||||
[
|
||||
"@semantic-release/git",
|
||||
{
|
||||
"assets": ["CHANGELOG.md", "package.json"],
|
||||
"message": "chore(release): ${nextRelease.version} [CI SKIP]"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
53
CHANGELOG.md
Normal file
53
CHANGELOG.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# [0.5.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.4.2...v0.5.0) (2022-06-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **utils:** add joinClassNames util ([f34b9de](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/f34b9de97f61eb5b075d6adedfcacfa5e097943b))
|
||||
|
||||
## [0.4.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.4.1...v0.4.2) (2022-06-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **classes:** add gamepadDialogClasses and quickAccessControlsClasses ([2e7b4b6](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/2e7b4b664a673b46b402b995fb58f0ce8ffbafac))
|
||||
|
||||
## [0.4.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.4.0...v0.4.1) (2022-06-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **textfield:** correct type for onChange callback ([32c355f](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/32c355f2a7e0b6ca6592b956e8174d217766bc5c))
|
||||
|
||||
# [0.4.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.3.0...v0.4.0) (2022-06-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **typings:** export all prop types ([7f9dfc5](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/7f9dfc5910dfc172ba161d9b63763e85eb289a43))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **textfield:** extract TextField component ([a3c1a7c](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/a3c1a7c7b73eae475574a13b6ff9c75ff78cbcb6))
|
||||
|
||||
# [0.3.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.2.0...v0.3.0) (2022-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **typings:** add Navigate to router typings ([f124480](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/f124480af8082d24730ed03fdf88742f76abc026))
|
||||
|
||||
# [0.2.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.1.0...v0.2.0) (2022-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** expose GetQuickAccessTab and rename QuickAccessTabs to QuickAccessTab ([bf0c2b1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/bf0c2b17bfc4e67a8aa90cfee6a91bd1482720d4))
|
||||
|
||||
# [0.1.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v0.0.6...v0.1.0) (2022-06-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** types for steam router ([62bf0ea](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/62bf0eaffa83d85245a038ffe3819315bd02f045))
|
||||
12328
package-lock.json
generated
12328
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "decky-frontend-lib",
|
||||
"version": "0.0.6",
|
||||
"version": "0.5.0",
|
||||
"description": "A library for building decky plugins",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
@@ -9,7 +9,9 @@
|
||||
"build": "shx rm -rf dist && tsc -b",
|
||||
"dev": "tsc -b -w",
|
||||
"prepack": "npm run build",
|
||||
"test": "jest"
|
||||
"test": "echo 'No tests for now!'",
|
||||
"postinstall": "husky install",
|
||||
"commit": "git-cz"
|
||||
},
|
||||
"files": [
|
||||
"/lib",
|
||||
@@ -32,13 +34,26 @@
|
||||
"url": "https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues"
|
||||
},
|
||||
"homepage": "https://github.com/SteamDeckHomebrew/decky-frontend-lib#readme",
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "@commitlint/cz-commitlint"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.0.2",
|
||||
"@commitlint/config-conventional": "^17.0.2",
|
||||
"@commitlint/cz-commitlint": "^17.0.0",
|
||||
"@semantic-release/changelog": "^6.0.1",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/react": "16.14.0",
|
||||
"@types/react-router": "5.1.18",
|
||||
"commitizen": "^4.2.4",
|
||||
"husky": "^8.0.1",
|
||||
"import-sort-style-module": "^6.0.0",
|
||||
"jest": "^27.5.1",
|
||||
"prettier-plugin-import-sort": "^0.0.7",
|
||||
"semantic-release": "^19.0.2",
|
||||
"shx": "^0.3.4",
|
||||
"ts-jest": "^27.1.4",
|
||||
"typescript": "^4.6.3"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
||||
|
||||
import { CommonUIModule } from '../webpack';
|
||||
|
||||
interface ButtonProps {
|
||||
export interface ButtonProps {
|
||||
className?: string;
|
||||
noFocusRing?: boolean;
|
||||
disabled?: boolean;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
||||
|
||||
import { CommonUIModule } from '../webpack';
|
||||
|
||||
interface ButtonItemProps {
|
||||
export interface ButtonItemProps {
|
||||
label?: string;
|
||||
description?: string;
|
||||
layout?: 'below';
|
||||
|
||||
@@ -11,7 +11,7 @@ export const showContextMenu: (children: ReactNode, parent?: EventTarget) => voi
|
||||
}
|
||||
});
|
||||
|
||||
interface MenuProps {
|
||||
export interface MenuProps {
|
||||
label: string;
|
||||
onCancel?(): void;
|
||||
cancelText?: string;
|
||||
@@ -27,7 +27,7 @@ export const Menu: FC<MenuProps> = findModuleChild((m) => {
|
||||
}
|
||||
});
|
||||
|
||||
interface MenuItemProps {
|
||||
export interface MenuItemProps {
|
||||
onSelected?(): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FC, ReactNode } from 'react';
|
||||
|
||||
import { findModuleChild } from '../webpack';
|
||||
|
||||
// TODO: there is another argument, figure out what it does
|
||||
@@ -11,18 +12,18 @@ export const showModal: (children: ReactNode, parent?: EventTarget) => void = fi
|
||||
}
|
||||
});
|
||||
|
||||
interface ModalRootProps {
|
||||
onMiddleButton?(): void,
|
||||
export interface ModalRootProps {
|
||||
onMiddleButton?(): void;
|
||||
onCancel?(): void;
|
||||
onOK?(): void;
|
||||
bAllowFullSize?: boolean;
|
||||
}
|
||||
|
||||
export const ModalRoot = findModuleChild(m => {
|
||||
if (typeof m !== "object") return undefined;
|
||||
export const ModalRoot = findModuleChild((m) => {
|
||||
if (typeof m !== 'object') return undefined;
|
||||
for (let prop in m) {
|
||||
if (!m[prop]?.prototype?.OK && m[prop]?.prototype?.Cancel && m[prop]?.prototype?.render) {
|
||||
return m[prop];
|
||||
}
|
||||
}
|
||||
}) as FC<ModalRootProps>;
|
||||
}) as FC<ModalRootProps>;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
||||
|
||||
import { findModuleChild } from '../webpack';
|
||||
|
||||
interface PanelSectionProps {
|
||||
export interface PanelSectionProps {
|
||||
title?: string;
|
||||
spinner?: boolean;
|
||||
}
|
||||
|
||||
38
src/deck-components/Router.tsx
Normal file
38
src/deck-components/Router.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Module, findModuleChild } from '../webpack';
|
||||
|
||||
export enum SideMenu {
|
||||
None,
|
||||
Main,
|
||||
QuickAccess,
|
||||
}
|
||||
|
||||
export enum QuickAccessTab {
|
||||
Notifications,
|
||||
RemotePlayTogetherControls,
|
||||
VoiceChat,
|
||||
Friends,
|
||||
Settings,
|
||||
Perf,
|
||||
Help,
|
||||
Decky,
|
||||
}
|
||||
|
||||
export interface Router {
|
||||
CloseSideMenus(): void;
|
||||
OpenQuickAccessMenu(quickAccessTab: QuickAccessTab): void;
|
||||
GetQuickAccessTab(): QuickAccessTab;
|
||||
Navigate(path: string): void;
|
||||
NavigateToExternalWeb(url: string): void;
|
||||
ToggleSideMenu(sideMenu: SideMenu): void;
|
||||
CloseSideMenus(): void;
|
||||
OpenSideMenu(sideMenu: SideMenu): void;
|
||||
OpenPowerMenu(unknown?: any): void;
|
||||
get RunningApps(): any;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}) as Router;
|
||||
@@ -2,13 +2,13 @@ import { FC } from 'react';
|
||||
|
||||
import { CommonUIModule } from '../webpack';
|
||||
|
||||
interface NotchLabel {
|
||||
export interface NotchLabel {
|
||||
notchIndex: number;
|
||||
label: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
interface SliderProps {
|
||||
export interface SliderProps {
|
||||
label?: string;
|
||||
value: number;
|
||||
layout?: 'below';
|
||||
|
||||
29
src/deck-components/TextField.tsx
Normal file
29
src/deck-components/TextField.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { ChangeEventHandler, ReactNode, VFC } from 'react';
|
||||
|
||||
import { CommonUIModule, Module } from '../webpack';
|
||||
|
||||
export interface TextFieldProps {
|
||||
label?: ReactNode;
|
||||
requiredLabel?: ReactNode;
|
||||
description?: ReactNode;
|
||||
bShowCopyAction?: boolean;
|
||||
bShowClearAction?: boolean;
|
||||
bAlwaysShowClearAction?: boolean;
|
||||
bIsPassword?: boolean;
|
||||
rangeMin?: number;
|
||||
rangeMax?: number;
|
||||
mustBeNumeric?: boolean;
|
||||
mustBeURL?: boolean;
|
||||
mustBeEmail?: boolean;
|
||||
focusOnMount?: boolean;
|
||||
tooltip?: string;
|
||||
inlineControls?: ReactNode;
|
||||
onChange?: ChangeEventHandler<HTMLInputElement>;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export const TextField = Object.values(CommonUIModule).find(
|
||||
(mod: Module) => mod?.validateUrl && mod?.validateEmail,
|
||||
) as VFC<TextFieldProps>;
|
||||
|
||||
console.log(TextField);
|
||||
@@ -2,7 +2,7 @@ import { FC } from 'react';
|
||||
|
||||
import { CommonUIModule } from '../webpack';
|
||||
|
||||
interface ToggleProps {
|
||||
export interface ToggleProps {
|
||||
label?: string;
|
||||
description?: string;
|
||||
checked: boolean;
|
||||
|
||||
@@ -3,8 +3,10 @@ export * from './ButtonItem';
|
||||
export * from './Menu';
|
||||
export * from './Modal';
|
||||
export * from './Panel';
|
||||
export * from './Router';
|
||||
export * from './Slider';
|
||||
export * from './SteamSpinner';
|
||||
export * from './Spinner';
|
||||
export * from './static-classes';
|
||||
export * from './SteamSpinner';
|
||||
export * from './TextField';
|
||||
export * from './Toggle';
|
||||
|
||||
@@ -63,6 +63,100 @@ type StaticClasses = Record<
|
||||
string
|
||||
>;
|
||||
|
||||
type GamepadDialogClasses = Record<
|
||||
| 'duration-app-launch'
|
||||
| 'GamepadDialogContent'
|
||||
| 'GamepadDialogContent_InnerWidth'
|
||||
| 'Field'
|
||||
| 'Button'
|
||||
| 'NoMinWidth'
|
||||
| 'ActiveAndUnfocused'
|
||||
| 'StandaloneFieldSeparator'
|
||||
| 'StandardPadding'
|
||||
| 'CompactPadding'
|
||||
| 'WithDescription'
|
||||
| 'WithBottomSeparatorStandard'
|
||||
| 'WithBottomSeparatorThick'
|
||||
| 'HighlightOnFocus'
|
||||
| 'ItemFocusAnim-darkerGrey'
|
||||
| 'ItemFocusAnim-darkGrey'
|
||||
| 'WithBottomSeparator'
|
||||
| 'Disabled'
|
||||
| 'Clickable'
|
||||
| 'FieldClickTarget'
|
||||
| 'FieldChildren'
|
||||
| 'FieldLeadIcon'
|
||||
| 'FieldLabelRow'
|
||||
| 'VerticalAlignCenter'
|
||||
| 'InlineWrapShiftsChildrenBelow'
|
||||
| 'ExtraPaddingOnChildrenBelow'
|
||||
| 'ChildrenWidthFixed'
|
||||
| 'ChildrenWidthGrow'
|
||||
| 'WithFirstRow'
|
||||
| 'WithChildrenBelow'
|
||||
| 'FieldLabel'
|
||||
| 'FieldLabelValue'
|
||||
| 'FieldDescription'
|
||||
| 'ModalPosition'
|
||||
| 'WithStandardPadding'
|
||||
| 'slideInAnimation'
|
||||
| 'BasicTextInput'
|
||||
| 'Toggle'
|
||||
| 'ToggleRail'
|
||||
| 'On'
|
||||
| 'ToggleSwitch'
|
||||
| 'LabelFieldValue'
|
||||
| 'DropDownControlButtonContents'
|
||||
| 'Spacer'
|
||||
| 'ControlsListOuterPanel'
|
||||
| 'StandardSpacing'
|
||||
| 'ExtraSpacing'
|
||||
| 'AlignRight'
|
||||
| 'AlignLeft'
|
||||
| 'AlignCenter'
|
||||
| 'ControlsListChild'
|
||||
| 'QuickAccess-Menu'
|
||||
| 'BigButtons'
|
||||
| 'BottomButtons'
|
||||
| 'ItemFocusAnim-darkerGrey-nocolor'
|
||||
| 'ItemFocusAnim-grey'
|
||||
| 'ItemFocusAnimBorder-darkGrey'
|
||||
| 'ItemFocusAnim-green'
|
||||
| 'focusAnimation'
|
||||
| 'hoverAnimation',
|
||||
string
|
||||
>;
|
||||
|
||||
type QuickAccessControlsClasses = Record<
|
||||
| 'duration-app-launch'
|
||||
| 'PanelSection'
|
||||
| 'PanelSectionTitle'
|
||||
| 'Text'
|
||||
| 'PanelSectionRow'
|
||||
| 'Label'
|
||||
| 'ComingSoon'
|
||||
| 'LowBattery'
|
||||
| 'ReallyLow'
|
||||
| 'LowBatteryGauge'
|
||||
| 'Remaining'
|
||||
| 'EmptyNotifications'
|
||||
| 'BatterySectionContainer'
|
||||
| 'BatteryIcon'
|
||||
| 'BatteryPercentageLabel'
|
||||
| 'BatteryDetailsLabels'
|
||||
| 'BatteryProjectedValue'
|
||||
| 'BatteryProjectedLabel'
|
||||
| 'ItemFocusAnim-darkerGrey-nocolor'
|
||||
| 'ItemFocusAnim-darkerGrey'
|
||||
| 'ItemFocusAnim-darkGrey'
|
||||
| 'ItemFocusAnim-grey'
|
||||
| 'ItemFocusAnimBorder-darkGrey'
|
||||
| 'ItemFocusAnim-green'
|
||||
| 'focusAnimation'
|
||||
| 'hoverAnimation',
|
||||
string
|
||||
>;
|
||||
|
||||
export const staticClasses: StaticClasses = findModuleChild((mod) => {
|
||||
if (typeof mod !== 'object') return false;
|
||||
|
||||
@@ -70,3 +164,19 @@ export const staticClasses: StaticClasses = findModuleChild((mod) => {
|
||||
return mod;
|
||||
}
|
||||
});
|
||||
|
||||
export const gamepadDialogClasses: GamepadDialogClasses = findModuleChild((mod) => {
|
||||
if (typeof mod !== 'object') return false;
|
||||
|
||||
if (mod.WithFirstRow) {
|
||||
return mod;
|
||||
}
|
||||
});
|
||||
|
||||
export const quickAccessControlsClasses: QuickAccessControlsClasses = findModuleChild((mod) => {
|
||||
if (typeof mod !== 'object') return false;
|
||||
|
||||
if (mod.PanelSectionRow) {
|
||||
return mod;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -85,3 +85,7 @@ export function unpatch(obj: any, name: any): void {
|
||||
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(" ");
|
||||
}
|
||||
@@ -5,7 +5,7 @@ declare global {
|
||||
}
|
||||
|
||||
// TODO
|
||||
type Module = any;
|
||||
export type Module = any;
|
||||
type FilterFn = (module: any) => boolean;
|
||||
type FindFn = (module: any) => any;
|
||||
|
||||
@@ -59,23 +59,17 @@ export const CommonUIModule = allModules.find((m: Module) => {
|
||||
});
|
||||
|
||||
export const IconsModule = findModule((m: Module) => {
|
||||
if (typeof m !== "object") return false;
|
||||
if (typeof m !== 'object') return false;
|
||||
for (let prop in m) {
|
||||
if (m[prop]?.toString && /Spinner\)}\),.\.createElement\(\"path\",{d:\"M18 /.test(m[prop].toString())) 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]
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
export const ReactRouter = allModules.find((m: Module) => {
|
||||
if (typeof m !== "object") return undefined;
|
||||
if (typeof m !== 'object') return undefined;
|
||||
for (let prop in m) {
|
||||
if (m[prop]?.computeRootMatch) return true
|
||||
if (m[prop]?.computeRootMatch) return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user