Compare commits

..

22 Commits

Author SHA1 Message Date
semantic-release-bot
245dd0f3cf chore(release): 3.5.2 [CI SKIP] 2022-10-08 02:22:06 +00:00
AAGaming
7161e757e9 fix(Tabs): make onShowTab required 2022-10-07 22:21:30 -04:00
semantic-release-bot
c60d1e9787 chore(release): 3.5.1 [CI SKIP] 2022-10-08 02:11:59 +00:00
AAGaming
0e0e0d204a fix(Tabs): actually export it lmao 2022-10-07 22:11:23 -04:00
semantic-release-bot
e5120928d3 chore(release): 3.5.0 [CI SKIP] 2022-10-08 02:04:42 +00:00
AAGaming
abbd3cddae feat(Tabs): initial tabs component, props, docs 2022-10-07 22:04:02 -04:00
semantic-release-bot
621e47c6a0 chore(release): 3.4.0 [CI SKIP] 2022-10-06 01:43:25 +00:00
OMGDuke
e2920dd91e feat(hooks): Added useParams hook (#36) 2022-10-05 21:42:54 -04:00
semantic-release-bot
67a76e2691 chore(release): 3.3.5 [CI SKIP] 2022-10-02 16:38:31 +00:00
AAGaming
0f205e8916 fix(docs): set categorizeByGroup to true 2022-10-02 12:37:45 -04:00
semantic-release-bot
472307e4a4 chore(release): 3.3.4 [CI SKIP] 2022-10-02 16:34:00 +00:00
AAGaming
fbd936dc1f fix(docs): build each component as a seperate page 2022-10-02 12:33:20 -04:00
AAGaming
33dd4e5548 chore(docs): initial typedoc setup (#35) 2022-10-02 12:22:58 -04:00
semantic-release-bot
4b76ccd91a chore(release): 3.3.3 [CI SKIP] 2022-10-02 12:36:26 +00:00
Lukas Senionis
99ad7543a9 fix(modal): make children optional (#34) 2022-10-02 08:36:00 -04:00
semantic-release-bot
b5dc08a977 chore(release): 3.3.2 [CI SKIP] 2022-10-02 02:31:09 +00:00
AAGaming
40871af853 fix(modal): allow children 2022-10-01 22:30:33 -04:00
Lukas Senionis
c910dbde79 Add dialog components (#22) 2022-10-01 21:41:47 -04:00
Lukas Senionis
4cbb30c21c Add custom-hook: useQuickAccessVisible (#28) 2022-10-01 21:38:46 -04:00
semantic-release-bot
54a1ef6201 chore(release): 3.3.1 [CI SKIP] 2022-10-02 01:33:33 +00:00
Barend Du Toit
ed0be5e87e fix(SidebarNavigation): add more props (#29) 2022-10-01 21:33:02 -04:00
Travis Lane
a064163b49 updated static-classes (#26) 2022-10-01 21:32:23 -04:00
18 changed files with 569 additions and 39 deletions

53
.github/workflows/docs.yaml vendored Normal file
View File

@@ -0,0 +1,53 @@
name: Generate docs
on:
push:
branches:
- main
jobs:
release:
name: Generate Docs
runs-on: ubuntu-22.04
steps:
- name: Setup | Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
path: lib
- name: Setup | Checkout wiki
uses: actions/checkout@v3
with:
repository: SteamDeckHomebrew/wiki
path: wiki
ssh-key: ${{ secrets.SSH_DEPLOY_KEY }}
persist-credentials: true
- name: Setup | Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Setup | Dependencies
run: |
cd lib
npm ci
- name: Build Docs
run: |
cd lib
npm run docs -- --out ../wiki/api-docs/decky-frontend-lib
- name: Commit files
run: |
cd wiki
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add -A ./api-docs/decky-frontend-lib
git commit -m "Update decky-frontend-lib API docs"
- name: Push changes
uses: ad-m/github-push-action@master
with:
ssh: true
directory: ./wiki
repository: SteamDeckHomebrew/wiki
branch: main

2
.gitignore vendored
View File

@@ -38,3 +38,5 @@ research/
# PNPM lockfile
pnpm-lock.yaml
docs/

View File

@@ -1,3 +1,66 @@
## [3.5.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.5.1...v3.5.2) (2022-10-08)
### Bug Fixes
* **Tabs:** make onShowTab required ([7161e75](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/7161e757e9c98d677510e03eb2606ce58152f3b1))
## [3.5.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.5.0...v3.5.1) (2022-10-08)
### Bug Fixes
* **Tabs:** actually export it lmao ([0e0e0d2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/0e0e0d204adc8d888f05e98edb6c1a1a171d00bb))
# [3.5.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.4.0...v3.5.0) (2022-10-08)
### Features
* **Tabs:** initial tabs component, props, docs ([abbd3cd](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/abbd3cddae24039cbc9b7d955924431e8fbacf94))
# [3.4.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.3.5...v3.4.0) (2022-10-06)
### Features
* **hooks:** Added useParams hook ([#36](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/36)) ([e2920dd](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/e2920dd91e81d915a2319280d8473df71a4e4232))
## [3.3.5](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.3.4...v3.3.5) (2022-10-02)
### Bug Fixes
* **docs:** set categorizeByGroup to true ([0f205e8](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/0f205e891694e2cee211b0c2db74a6dda2432507))
## [3.3.4](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.3.3...v3.3.4) (2022-10-02)
### Bug Fixes
* **docs:** build each component as a seperate page ([fbd936d](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/fbd936dc1fe4c23c72f4ee27af95abc004382acd))
## [3.3.3](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.3.2...v3.3.3) (2022-10-02)
### Bug Fixes
* **modal:** make children optional ([#34](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/34)) ([99ad754](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/99ad7543a9966b8ff3f4ec01e6f05c94e5242c93))
## [3.3.2](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.3.1...v3.3.2) (2022-10-02)
### Bug Fixes
* **modal:** allow children ([40871af](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/40871af8539858f435c83123a56d4b31b63d627d))
## [3.3.1](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.3.0...v3.3.1) (2022-10-02)
### Bug Fixes
* **SidebarNavigation:** add more props ([#29](https://github.com/SteamDeckHomebrew/decky-frontend-lib/issues/29)) ([ed0be5e](https://github.com/SteamDeckHomebrew/decky-frontend-lib/commit/ed0be5e87e964ed57cc99b40ff55fe35a2f518b2))
# [3.3.0](https://github.com/SteamDeckHomebrew/decky-frontend-lib/compare/v3.2.2...v3.3.0) (2022-10-02)

219
package-lock.json generated
View File

@@ -1,13 +1,13 @@
{
"name": "decky-frontend-lib",
"version": "3.3.0",
"version": "3.5.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "decky-frontend-lib",
"version": "3.3.0",
"license": "GPL-2.0-or-later",
"version": "3.5.2",
"license": "LGPL-2.1",
"dependencies": {
"minimist": "^1.2.6"
},
@@ -28,6 +28,10 @@
"semantic-release": "^19.0.3",
"shx": "^0.3.4",
"ts-jest": "^27.1.4",
"typedoc": "^0.23.15",
"typedoc-plugin-markdown": "^3.13.6",
"typedoc-plugin-mdn-links": "^2.0.0",
"typedoc-plugin-missing-exports": "^1.0.0",
"typescript": "^4.6.3"
}
},
@@ -7335,6 +7339,12 @@
"node": ">=6"
}
},
"node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
"dev": true
},
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -7624,6 +7634,12 @@
"node": ">=10"
}
},
"node_modules/lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
"dev": true
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -7667,9 +7683,9 @@
}
},
"node_modules/marked": {
"version": "4.0.16",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz",
"integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz",
"integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==",
"dev": true,
"bin": {
"marked": "bin/marked.js"
@@ -11706,6 +11722,17 @@
"node": ">=4"
}
},
"node_modules/shiki": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz",
"integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==",
"dev": true,
"dependencies": {
"jsonc-parser": "^3.0.0",
"vscode-oniguruma": "^1.6.1",
"vscode-textmate": "^6.0.0"
}
},
"node_modules/shx": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz",
@@ -12401,6 +12428,78 @@
"is-typedarray": "^1.0.0"
}
},
"node_modules/typedoc": {
"version": "0.23.15",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.15.tgz",
"integrity": "sha512-x9Zu+tTnwxb9YdVr+zvX7LYzyBl1nieOr6lrSHbHsA22/RJK2m4Y525WIg5Mj4jWCmfL47v6f4hUzY7EIuwS5w==",
"dev": true,
"dependencies": {
"lunr": "^2.3.9",
"marked": "^4.0.19",
"minimatch": "^5.1.0",
"shiki": "^0.11.1"
},
"bin": {
"typedoc": "bin/typedoc"
},
"engines": {
"node": ">= 14.14"
},
"peerDependencies": {
"typescript": "4.6.x || 4.7.x || 4.8.x"
}
},
"node_modules/typedoc-plugin-markdown": {
"version": "3.13.6",
"resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.13.6.tgz",
"integrity": "sha512-ISSc9v3BK7HkokxSBuJPttXox4tJ6hP0N9wfSIk0fmLN67+eqtAxbk97gs2nDiuha+RTO5eW9gdeAb+RPP0mgg==",
"dev": true,
"dependencies": {
"handlebars": "^4.7.7"
},
"peerDependencies": {
"typedoc": ">=0.23.0"
}
},
"node_modules/typedoc-plugin-mdn-links": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/typedoc-plugin-mdn-links/-/typedoc-plugin-mdn-links-2.0.0.tgz",
"integrity": "sha512-IGLuelXPOenGdmklr5DHgPPf/MfZj7aEYCxCMtPN8C1D0lA7w0YLahd0jhDDcOMU7zL1EPcM5pPnhZHltDhqGQ==",
"dev": true,
"peerDependencies": {
"typedoc": "0.22.x || 0.23.x"
}
},
"node_modules/typedoc-plugin-missing-exports": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-1.0.0.tgz",
"integrity": "sha512-7s6znXnuAj1eD9KYPyzVzR1lBF5nwAY8IKccP5sdoO9crG4lpd16RoFpLsh2PccJM+I2NASpr0+/NMka6ThwVA==",
"dev": true,
"peerDependencies": {
"typedoc": "0.22.x || 0.23.x"
}
},
"node_modules/typedoc/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/typedoc/node_modules/minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/typescript": {
"version": "4.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz",
@@ -12514,6 +12613,18 @@
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/vscode-oniguruma": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==",
"dev": true
},
"node_modules/vscode-textmate": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz",
"integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==",
"dev": true
},
"node_modules/w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
@@ -18354,6 +18465,12 @@
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"dev": true
},
"jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
"dev": true
},
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@@ -18581,6 +18698,12 @@
"yallist": "^4.0.0"
}
},
"lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
"dev": true
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -18612,9 +18735,9 @@
"dev": true
},
"marked": {
"version": "4.0.16",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz",
"integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz",
"integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==",
"dev": true
},
"marked-terminal": {
@@ -21487,6 +21610,17 @@
"rechoir": "^0.6.2"
}
},
"shiki": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz",
"integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==",
"dev": true,
"requires": {
"jsonc-parser": "^3.0.0",
"vscode-oniguruma": "^1.6.1",
"vscode-textmate": "^6.0.0"
}
},
"shx": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz",
@@ -22008,6 +22142,61 @@
"is-typedarray": "^1.0.0"
}
},
"typedoc": {
"version": "0.23.15",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.15.tgz",
"integrity": "sha512-x9Zu+tTnwxb9YdVr+zvX7LYzyBl1nieOr6lrSHbHsA22/RJK2m4Y525WIg5Mj4jWCmfL47v6f4hUzY7EIuwS5w==",
"dev": true,
"requires": {
"lunr": "^2.3.9",
"marked": "^4.0.19",
"minimatch": "^5.1.0",
"shiki": "^0.11.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"minimatch": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
"integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
}
}
},
"typedoc-plugin-markdown": {
"version": "3.13.6",
"resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.13.6.tgz",
"integrity": "sha512-ISSc9v3BK7HkokxSBuJPttXox4tJ6hP0N9wfSIk0fmLN67+eqtAxbk97gs2nDiuha+RTO5eW9gdeAb+RPP0mgg==",
"dev": true,
"requires": {
"handlebars": "^4.7.7"
}
},
"typedoc-plugin-mdn-links": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/typedoc-plugin-mdn-links/-/typedoc-plugin-mdn-links-2.0.0.tgz",
"integrity": "sha512-IGLuelXPOenGdmklr5DHgPPf/MfZj7aEYCxCMtPN8C1D0lA7w0YLahd0jhDDcOMU7zL1EPcM5pPnhZHltDhqGQ==",
"dev": true,
"requires": {}
},
"typedoc-plugin-missing-exports": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-1.0.0.tgz",
"integrity": "sha512-7s6znXnuAj1eD9KYPyzVzR1lBF5nwAY8IKccP5sdoO9crG4lpd16RoFpLsh2PccJM+I2NASpr0+/NMka6ThwVA==",
"dev": true,
"requires": {}
},
"typescript": {
"version": "4.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz",
@@ -22098,6 +22287,18 @@
"spdx-expression-parse": "^3.0.0"
}
},
"vscode-oniguruma": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz",
"integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==",
"dev": true
},
"vscode-textmate": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz",
"integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==",
"dev": true
},
"w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "decky-frontend-lib",
"version": "3.3.0",
"version": "3.5.2",
"description": "A library for building decky plugins",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -9,6 +9,7 @@
"scripts": {
"build": "shx rm -rf dist && tsc -b",
"dev": "tsc -b -w",
"docs": "typedoc --tsconfig ./tsconfig.json src/**/*",
"prepack": "npm run build",
"test": "echo 'No tests for now!'",
"prepare": "husky install",
@@ -57,6 +58,10 @@
"semantic-release": "^19.0.3",
"shx": "^0.3.4",
"ts-jest": "^27.1.4",
"typedoc": "^0.23.15",
"typedoc-plugin-markdown": "^3.13.6",
"typedoc-plugin-mdn-links": "^2.0.0",
"typedoc-plugin-missing-exports": "^1.0.0",
"typescript": "^4.6.3"
},
"pnpm": {

View File

@@ -0,0 +1 @@
export * from './usequickaccessvisible';

View File

@@ -0,0 +1,67 @@
import { useState, useEffect } from 'react';
declare global {
var FocusNavController: any;
}
/**
* Returns state indicating the visibility of quick access menu.
*
* @remarks
* During development it is possible to open the quick access menu without giving it
* focus in some cases. In such cases, the quick access menu state is invisible.
*
* This seems to be impossible to replicate when running the deck normally. Even in
* the edge cases it always seems to have a focus.
*
* @returns `true` if quick access menu is visible (focused) and `false` otherwise.
*
* @example
* import { VFC, useEffect } from "react";
* import { useQuickAccessVisible } from "decky-frontend-lib";
*
* export const PluginPanelView: VFC<{}> = ({ }) => {
* const isVisible = useQuickAccessVisible();
*
* useEffect(() => {
* if (!isVisible) {
* return;
* }
*
* const interval = setInterval(() => console.log("Hello world!"), 1000);
* return () => {
* clearInterval(interval);
* }
* }, [isVisible])
*
* return (
* <div>
* {isVisible ? "VISIBLE" : "INVISIBLE"}
* </div>
* );
* };
*/
export function useQuickAccessVisible(): boolean {
// Assuming that the component is rendered in QAM already, so true by default...
const [isVisible, setIsVisible] = useState(true);
useEffect(() => {
const quickAccessWindow: Window | null = FocusNavController?.GetGamepadNavTreeByID("QuickAccess-NA")?.m_Root?.m_element?.ownerDocument.defaultView ?? null;
if (quickAccessWindow === null) {
console.error("Could not get window of QuickAccess menu!");
return;
}
const onBlur = () => setIsVisible(false);
const onFocus = () => setIsVisible(true);
quickAccessWindow.addEventListener("blur", onBlur);
quickAccessWindow.addEventListener("focus", onFocus);
return () => {
quickAccessWindow.removeEventListener("blur", onBlur);
quickAccessWindow.removeEventListener("focus", onFocus);
};
}, []);
return isVisible;
}

View File

@@ -1,22 +1,8 @@
import { CSSProperties, FC, RefAttributes } from 'react';
import { FC } from 'react';
import { DialogButton, DialogButtonProps } from "./Dialog";
import { CommonUIModule } from '../webpack';
import { FooterLegendProps } from './FooterLegend';
export interface DialogButtonProps extends RefAttributes<HTMLDivElement>, FooterLegendProps {
label?: string;
style?: CSSProperties;
className?: string;
noFocusRing?: boolean;
description?: string;
layout?: 'below';
onClick?(e: MouseEvent): void;
disabled?: boolean;
bottomSeparator?: boolean;
export interface ButtonProps extends DialogButtonProps {
}
export const DialogButton = Object.values(CommonUIModule).find(
(mod: any) =>
mod?.render?.toString()?.includes('Object.assign({type:"button"') &&
mod?.render?.toString()?.includes('DialogButton'),
) as FC<DialogButtonProps>;
// Button isn't exported, so call DialogButton to grab it
export const Button = (DialogButton as any)?.render({}).type as FC<ButtonProps>;

View File

@@ -0,0 +1,63 @@
import { CommonUIModule } from "../webpack";
import { CSSProperties, FC, RefAttributes } from "react";
import { FooterLegendProps } from './FooterLegend';
export interface DialogCommonProps extends RefAttributes<HTMLDivElement> {
style?: CSSProperties;
className?: string;
}
export interface DialogButtonProps extends DialogCommonProps, FooterLegendProps {
noFocusRing?: boolean;
disabled?: boolean;
onClick?(e: MouseEvent): void;
onPointerDown?(e: PointerEvent): void;
onPointerUp?(e: PointerEvent): void;
onPointerCancel?(e: PointerEvent): void;
onMouseDown?(e: MouseEvent): void;
onMouseUp?(e: MouseEvent): void;
onTouchStart?(e: TouchEvent): void;
onTouchEnd?(e: TouchEvent): void;
onTouchCancel?(e: TouchEvent): void;
onSubmit?(e: SubmitEvent): void;
}
const CommonDialogDivs = Object.values(CommonUIModule).filter((m: any) => typeof m === "object" && m?.render?.toString().includes('"div",Object.assign({},'));
const MappedDialogDivs = new Map(Object.values(CommonDialogDivs).map((m: any) => {
const renderedDiv = m.render({});
// Take only the first class name segment as it identifies the element we want
return [renderedDiv.props.className.split(" ")[0], m]
}));
export const DialogHeader = MappedDialogDivs.get("DialogHeader") as FC<DialogCommonProps>;
export const DialogSubHeader = MappedDialogDivs.get("DialogSubHeader") as FC<DialogCommonProps>;
export const DialogFooter = MappedDialogDivs.get("DialogFooter") as FC<DialogCommonProps>;
export const DialogLabel = MappedDialogDivs.get("DialogLabel") as FC<DialogCommonProps>;
export const DialogBodyText = MappedDialogDivs.get("DialogBodyText") as FC<DialogCommonProps>;
export const DialogBody = MappedDialogDivs.get("DialogBody") as FC<DialogCommonProps>;
export const DialogControlsSection = MappedDialogDivs.get("DialogControlsSection") as FC<DialogCommonProps>;
export const DialogControlsSectionHeader = MappedDialogDivs.get("DialogControlsSectionHeader") as FC<DialogCommonProps>;
export const DialogButtonPrimary = Object.values(CommonUIModule).find(
(mod: any) =>
mod?.render?.toString()?.includes('DialogButton') &&
mod?.render?.toString()?.includes('Primary')
) as FC<DialogButtonProps>;
export const DialogButtonSecondary = Object.values(CommonUIModule).find(
(mod: any) =>
mod?.render?.toString()?.includes('Object.assign({type:"button"') &&
mod?.render?.toString()?.includes('DialogButton') &&
mod?.render?.toString()?.includes('Secondary')
) as FC<DialogButtonProps>;
export const DialogButtonSmall = Object.values(CommonUIModule).find(
(mod: any) =>
mod?.render?.toString()?.includes('Object.assign({type:"button"') &&
mod?.render?.toString()?.includes('DialogButton') &&
mod?.render?.toString()?.includes('Small')
) as FC<DialogButtonProps>;
// This is the "main" button. The Primary can act as a submit button,
// therefore secondary is chosen (also for backwards comp. reasons)
export const DialogButton = DialogButtonSecondary;

View File

@@ -37,6 +37,7 @@ export const showModal: (modal: ReactNode, parent?: EventTarget, props?: ShowMod
});
export interface ModalRootProps {
children?: ReactNode;
onCancel?(): void;
closeModal?(): void;
onOK?(): void;

View File

@@ -4,8 +4,14 @@ import { Module, findModuleChild } from '../webpack';
export interface SidebarNavigationPages {
title: string;
route: string;
content: ReactNode;
icon?: ReactNode;
visible?: boolean;
hideTitle?: boolean;
identifier?: string;
route?: string;
link?: string;
padding?: "none" | "compact";
}
export interface SidebarNavigationProps {
@@ -13,6 +19,8 @@ export interface SidebarNavigationProps {
pages: SidebarNavigationPages[];
showTitle?: boolean;
disableRouteReporting?: boolean;
page?: string;
onPageRequested?: (page: string) => void;
}
export const SidebarNavigation = findModuleChild((mod: Module) => {

View File

@@ -0,0 +1,47 @@
import { FC, ReactNode } from 'react';
import { findModule } from '../webpack';
import { FooterLegendProps } from './FooterLegend';
/**
* Individual tab objects for the Tabs component
*
* @property id ID of this tab, can be used with activeTab to auto-focus a given tab
* @property title Title shown in the header bar
* @property renderTabAddon Return a {@link ReactNode} to render it next to the tab title, i.e. the counts for each tab on the Media page
* @property content Content of the tab
* @property footer Sets up button handlers and labels
*/
export interface Tab {
id: string;
title: string;
renderTabAddon?: () => ReactNode;
content: ReactNode;
footer?: FooterLegendProps;
}
/**
* Props for the {@link Tabs}
*
* @property tabs array of {@link Tab}
* @property activeTab tab to automatically focus, {@link Tab.id}
* @property onShowTab Currently unknown, but required.
* @property autoFocusContents Whether to automatically focus the tab contents or not.
* @property footer Sets up button handlers and labels
*/
export interface TabsProps {
tabs: Tab[];
activeTab?: string;
onShowTab: (...args: unknown[]) => void;
autoFocusContents?: boolean;
}
/**
* Tabs component as used in the library and media tabs. See {@link TabsProps}
*/
export const Tabs = Object.values(findModule((m) => {
if (typeof m !== 'object') return false;
for (let prop in m) {
if (m[prop]?.Unbleed) return true;
}
return false;
})).find((x: any) => x?.type?.toString()?.includes("((function(){")) as FC<TabsProps>;

View File

@@ -1,6 +1,7 @@
export * from './Button';
export * from './ButtonItem';
export * from './Carousel';
export * from './Dialog';
export * from './Dropdown';
export * from './Field';
export * from './Focusable';
@@ -16,6 +17,7 @@ export * from './SliderField';
export * from './Spinner';
export * from './static-classes';
export * from './SteamSpinner';
export * from './Tabs';
export * from './TextField';
export * from './Toggle';
export * from './ToggleField';

View File

@@ -1,6 +1,6 @@
import { findModule } from '../webpack';
type StaticClasses = Record<
type QuickAccessMenuClasses = Record<
| 'ActiveTab'
| 'AllTabContents'
| 'BatteryDetailsLabels'
@@ -63,7 +63,7 @@ type StaticClasses = Record<
string
>;
type ScrollClasses = Record<
type ScrollPanelClasses = Record<
| 'ScrollBoth'
| 'ScrollPanel'
| 'ScrollX'
@@ -355,10 +355,18 @@ type GamepadSliderClasses = Record<
string
>;
export const staticClasses: StaticClasses = findModule((mod) => typeof mod === 'object' && mod.TransitionMenuDelay);
export const scrollClasses: ScrollClasses = findModule((mod) => typeof mod === 'object' && mod.ScrollPanel && mod.ScrollY);
export const gamepadDialogClasses: GamepadDialogClasses = findModule((mod) => typeof mod === 'object' && mod.WithFirstRow);
export const quickAccessControlsClasses: QuickAccessControlsClasses = findModule((mod) => typeof mod === 'object' && mod.PanelSectionRow);
export const updaterFieldClasses: UpdaterFieldClasses = findModule((mod) => typeof mod === 'object' && mod.PatchNotes && mod.PostedTime);
export const playSectionClasses: PlaySectionClasses = findModule((mod) => typeof mod === 'object' && mod.MenuButton && mod.MenuActive);
export const gamepadSliderClasses: GamepadSliderClasses = findModule((mod) => typeof mod === 'object' && mod.SliderTrack && mod.SliderHasNotches);
export const quickAccessMenuClasses: QuickAccessMenuClasses = findModule((mod) => typeof mod === 'object' && mod?.Title?.includes('quickaccessmenu'));
/**
* @depreciated please use quickAccessMenuClasses instead
*/
export const staticClasses = quickAccessMenuClasses;
export const scrollPanelClasses: ScrollPanelClasses = findModule((mod) => typeof mod === 'object' && mod?.ScrollPanel?.includes('scrollpanel'));
/**
* @depreciated please use scrollPanelClasses instead
*/
export const scrollClasses = scrollPanelClasses;
export const gamepadDialogClasses: GamepadDialogClasses = findModule((mod) => typeof mod === 'object' && mod?.GamepadDialogContent?.includes('gamepaddialog'));
export const quickAccessControlsClasses: QuickAccessControlsClasses = findModule((mod) => typeof mod === 'object' && mod?.PanelSection?.includes('quickaccesscontrols'));
export const updaterFieldClasses: UpdaterFieldClasses = findModule((mod) => typeof mod === 'object' && mod?.OOBEUpdateStatusContainer?.includes('updaterfield'));
export const playSectionClasses: PlaySectionClasses = findModule((mod) => typeof mod === 'object' && mod?.Container?.includes('appdetailsplaysection'));
export const gamepadSliderClasses: GamepadSliderClasses = findModule((mod) => typeof mod === 'object' && mod?.SliderControlPanelGroup?.includes('gamepadslider'));

1
src/deck-hooks/index.ts Normal file
View File

@@ -0,0 +1 @@
export * from './useParams'

View File

@@ -0,0 +1,15 @@
import { ReactRouter } from "../webpack";
/**
* Get the current params from ReactRouter
*
* @returns an object with the current ReactRouter params
*
* @example
* import { useParams } from "decky-frontend-lib";
*
* const { appid } = useParams<{ appid: string }>()
*/
export const useParams = Object.values(ReactRouter).find((val) =>
/return (\w)\?\1\.params:{}/.test(`${val}`)
) as <T>() => T

View File

@@ -1,6 +1,8 @@
// export * from './deck-libs';
export * from './custom-components';
export * from './custom-hooks';
export * from './deck-components';
export * from './deck-hooks'
export * from './plugin';
export * from './webpack';
export * from './utils';

5
typedoc.json Normal file
View File

@@ -0,0 +1,5 @@
{
"githubPages": false,
"categorizeByGroup": false,
"excludeExternals": true
}