@decky/ui 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/LICENSE +504 -0
  2. package/README.md +27 -0
  3. package/dist/class-mapper.d.ts +7 -0
  4. package/dist/class-mapper.js +26 -0
  5. package/dist/components/Button.d.ts +5 -0
  6. package/dist/components/Button.js +2 -0
  7. package/dist/components/ButtonItem.d.ts +7 -0
  8. package/dist/components/ButtonItem.js +3 -0
  9. package/dist/components/Carousel.d.ts +19 -0
  10. package/dist/components/Carousel.js +2 -0
  11. package/dist/components/ControlsList.d.ts +6 -0
  12. package/dist/components/ControlsList.js +2 -0
  13. package/dist/components/Dialog.d.ts +32 -0
  14. package/dist/components/Dialog.js +19 -0
  15. package/dist/components/DialogCheckbox.d.ts +17 -0
  16. package/dist/components/DialogCheckbox.js +14 -0
  17. package/dist/components/Dropdown.d.ts +34 -0
  18. package/dist/components/Dropdown.js +3 -0
  19. package/dist/components/Field.d.ts +22 -0
  20. package/dist/components/Field.js +2 -0
  21. package/dist/components/FocusRing.d.ts +9 -0
  22. package/dist/components/FocusRing.js +2 -0
  23. package/dist/components/Focusable.d.ts +12 -0
  24. package/dist/components/Focusable.js +2 -0
  25. package/dist/components/FooterLegend.d.ts +66 -0
  26. package/dist/components/FooterLegend.js +32 -0
  27. package/dist/components/Item.d.ts +11 -0
  28. package/dist/components/Item.js +1 -0
  29. package/dist/components/Marquee.d.ts +14 -0
  30. package/dist/components/Marquee.js +2 -0
  31. package/dist/components/Menu.d.ts +29 -0
  32. package/dist/components/Menu.js +8 -0
  33. package/dist/components/Modal.d.ts +52 -0
  34. package/dist/components/Modal.js +29 -0
  35. package/dist/components/Panel.d.ts +11 -0
  36. package/dist/components/Panel.js +4 -0
  37. package/dist/components/ProgressBar.d.ts +21 -0
  38. package/dist/components/ProgressBar.js +4 -0
  39. package/dist/components/Scroll.d.ts +7 -0
  40. package/dist/components/Scroll.js +5 -0
  41. package/dist/components/SidebarNavigation.d.ts +21 -0
  42. package/dist/components/SidebarNavigation.js +2 -0
  43. package/dist/components/SliderField.d.ts +26 -0
  44. package/dist/components/SliderField.js +2 -0
  45. package/dist/components/Spinner.d.ts +2 -0
  46. package/dist/components/Spinner.js +2 -0
  47. package/dist/components/SteamSpinner.d.ts +2 -0
  48. package/dist/components/SteamSpinner.js +2 -0
  49. package/dist/components/Tabs.d.ts +16 -0
  50. package/dist/components/Tabs.js +48 -0
  51. package/dist/components/TextField.d.ts +22 -0
  52. package/dist/components/TextField.js +2 -0
  53. package/dist/components/Toggle.d.ts +8 -0
  54. package/dist/components/Toggle.js +2 -0
  55. package/dist/components/ToggleField.d.ts +9 -0
  56. package/dist/components/ToggleField.js +2 -0
  57. package/dist/components/index.d.ts +25 -0
  58. package/dist/components/index.js +25 -0
  59. package/dist/custom-components/ColorPickerModal.d.ts +12 -0
  60. package/dist/custom-components/ColorPickerModal.js +87 -0
  61. package/dist/custom-components/ReorderableList.d.ts +26 -0
  62. package/dist/custom-components/ReorderableList.js +84 -0
  63. package/dist/custom-components/SuspensefulImage.d.ts +7 -0
  64. package/dist/custom-components/SuspensefulImage.js +27 -0
  65. package/dist/custom-components/index.d.ts +3 -0
  66. package/dist/custom-components/index.js +3 -0
  67. package/dist/custom-hooks/index.d.ts +1 -0
  68. package/dist/custom-hooks/index.js +1 -0
  69. package/dist/custom-hooks/useQuickAccessVisible.d.ts +1 -0
  70. package/dist/custom-hooks/useQuickAccessVisible.js +22 -0
  71. package/dist/deck-hooks/index.d.ts +1 -0
  72. package/dist/deck-hooks/index.js +1 -0
  73. package/dist/deck-hooks/useParams.d.ts +1 -0
  74. package/dist/deck-hooks/useParams.js +2 -0
  75. package/dist/globals/SteamClient.d.ts +307 -0
  76. package/dist/globals/SteamClient.js +1 -0
  77. package/dist/globals/index.d.ts +2 -0
  78. package/dist/globals/index.js +2 -0
  79. package/dist/globals/stores.d.ts +50 -0
  80. package/dist/globals/stores.js +1 -0
  81. package/dist/index.d.ts +10 -0
  82. package/dist/index.js +10 -0
  83. package/dist/logger.d.ts +17 -0
  84. package/dist/logger.js +46 -0
  85. package/dist/modules/Router.d.ts +110 -0
  86. package/dist/modules/Router.js +102 -0
  87. package/dist/modules/index.d.ts +1 -0
  88. package/dist/modules/index.js +1 -0
  89. package/dist/plugin.d.ts +68 -0
  90. package/dist/plugin.js +5 -0
  91. package/dist/utils/index.d.ts +12 -0
  92. package/dist/utils/index.js +23 -0
  93. package/dist/utils/patcher.d.ts +18 -0
  94. package/dist/utils/patcher.js +103 -0
  95. package/dist/utils/react.d.ts +18 -0
  96. package/dist/utils/react.js +74 -0
  97. package/dist/utils/static-classes.d.ts +52 -0
  98. package/dist/utils/static-classes.js +28 -0
  99. package/dist/webpack.d.ts +21 -0
  100. package/dist/webpack.js +102 -0
  101. package/package.json +82 -0
  102. package/src/class-mapper.ts +34 -0
  103. package/src/components/Button.tsx +8 -0
  104. package/src/components/ButtonItem.tsx +14 -0
  105. package/src/components/Carousel.ts +25 -0
  106. package/src/components/ControlsList.tsx +13 -0
  107. package/src/components/Dialog.tsx +86 -0
  108. package/src/components/DialogCheckbox.tsx +36 -0
  109. package/src/components/Dropdown.tsx +49 -0
  110. package/src/components/Field.tsx +28 -0
  111. package/src/components/FocusRing.ts +15 -0
  112. package/src/components/Focusable.tsx +18 -0
  113. package/src/components/FooterLegend.ts +67 -0
  114. package/src/components/Item.tsx +12 -0
  115. package/src/components/Marquee.tsx +20 -0
  116. package/src/components/Menu.tsx +57 -0
  117. package/src/components/Modal.tsx +119 -0
  118. package/src/components/Panel.tsx +26 -0
  119. package/src/components/ProgressBar.tsx +35 -0
  120. package/src/components/Scroll.tsx +15 -0
  121. package/src/components/SidebarNavigation.tsx +28 -0
  122. package/src/components/SliderField.tsx +33 -0
  123. package/src/components/Spinner.tsx +8 -0
  124. package/src/components/SteamSpinner.tsx +7 -0
  125. package/src/components/Tabs.tsx +127 -0
  126. package/src/components/TextField.tsx +28 -0
  127. package/src/components/Toggle.tsx +14 -0
  128. package/src/components/ToggleField.tsx +15 -0
  129. package/src/components/index.ts +25 -0
  130. package/src/custom-components/ColorPickerModal.tsx +132 -0
  131. package/src/custom-components/ReorderableList.tsx +183 -0
  132. package/src/custom-components/SuspensefulImage.tsx +44 -0
  133. package/src/custom-components/index.ts +3 -0
  134. package/src/custom-hooks/index.ts +1 -0
  135. package/src/custom-hooks/useQuickAccessVisible.tsx +63 -0
  136. package/src/deck-hooks/index.ts +1 -0
  137. package/src/deck-hooks/useParams.ts +15 -0
  138. package/src/globals/SteamClient.ts +321 -0
  139. package/src/globals/index.ts +2 -0
  140. package/src/globals/stores.ts +50 -0
  141. package/src/index.ts +11 -0
  142. package/src/logger.ts +77 -0
  143. package/src/modules/Router.tsx +174 -0
  144. package/src/modules/index.ts +1 -0
  145. package/src/plugin.tsx +96 -0
  146. package/src/utils/index.ts +43 -0
  147. package/src/utils/patcher.ts +160 -0
  148. package/src/utils/react.ts +119 -0
  149. package/src/utils/static-classes.ts +1104 -0
  150. package/src/webpack.ts +136 -0
@@ -0,0 +1,68 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ import { RouteProps } from 'react-router';
3
+ export interface Plugin {
4
+ title: JSX.Element;
5
+ icon: JSX.Element;
6
+ content?: JSX.Element;
7
+ onDismount?(): void;
8
+ alwaysRender?: boolean;
9
+ }
10
+ interface ServerResponseSuccess<TRes> {
11
+ success: true;
12
+ result: TRes;
13
+ }
14
+ interface ServerResponseError {
15
+ success: false;
16
+ result: string;
17
+ }
18
+ export type ServerResponse<TRes> = ServerResponseSuccess<TRes> | ServerResponseError;
19
+ export type RoutePatch = (route: RouteProps) => RouteProps;
20
+ export interface RouterHook {
21
+ addRoute(path: string, component: ComponentType, props?: Omit<RouteProps, 'path' | 'children'>): void;
22
+ addPatch(path: string, patch: RoutePatch): RoutePatch;
23
+ addGlobalComponent(name: string, component: ComponentType): void;
24
+ removeRoute(path: string): void;
25
+ removePatch(path: string, patch: RoutePatch): void;
26
+ removeGlobalComponent(name: string): void;
27
+ }
28
+ export interface ToastData {
29
+ title: ReactNode;
30
+ body: ReactNode;
31
+ onClick?: () => void;
32
+ logo?: ReactNode;
33
+ icon?: ReactNode;
34
+ className?: string;
35
+ contentClassName?: string;
36
+ duration?: number;
37
+ critical?: boolean;
38
+ eType?: number;
39
+ sound?: number;
40
+ playSound?: boolean;
41
+ showToast?: boolean;
42
+ }
43
+ export interface Toaster {
44
+ toast(toast: ToastData): void;
45
+ }
46
+ export interface FilePickerRes {
47
+ path: string;
48
+ realpath: string;
49
+ }
50
+ export declare const enum FileSelectionType {
51
+ FILE = 0,
52
+ FOLDER = 1
53
+ }
54
+ export interface ServerAPI {
55
+ routerHook: RouterHook;
56
+ toaster: Toaster;
57
+ openFilePicker(startPath: string, includeFiles?: boolean, regex?: RegExp): Promise<FilePickerRes>;
58
+ openFilePickerV2(select: FileSelectionType, startPath: string, includeFiles?: boolean, includeFolders?: boolean, filter?: RegExp | ((file: File) => boolean), extensions?: string[], showHiddenFiles?: boolean, allowAllFiles?: boolean, max?: number): Promise<FilePickerRes>;
59
+ callPluginMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
60
+ callServerMethod<TArgs = {}, TRes = {}>(methodName: string, args: TArgs): Promise<ServerResponse<TRes>>;
61
+ fetchNoCors<TRes = {}>(url: RequestInfo, request?: RequestInit): Promise<ServerResponse<TRes>>;
62
+ executeInTab(tab: string, runAsync: boolean, code: string): Promise<unknown>;
63
+ injectCssIntoTab<TRes = string>(tab: string, style: string): Promise<ServerResponse<TRes>>;
64
+ removeCssFromTab(tab: string, cssId: string): Promise<unknown>;
65
+ }
66
+ type DefinePluginFn = (serverAPI: ServerAPI) => Plugin;
67
+ export declare const definePlugin: (fn: DefinePluginFn) => DefinePluginFn;
68
+ export {};
package/dist/plugin.js ADDED
@@ -0,0 +1,5 @@
1
+ export const definePlugin = (fn) => {
2
+ return (...args) => {
3
+ return fn(...args);
4
+ };
5
+ };
@@ -0,0 +1,12 @@
1
+ export * from './patcher';
2
+ export * from './react';
3
+ export * from './static-classes';
4
+ declare global {
5
+ var FocusNavController: any;
6
+ var GamepadNavTree: any;
7
+ }
8
+ export declare function joinClassNames(...classes: string[]): string;
9
+ export declare function sleep(ms: number): Promise<unknown>;
10
+ export declare function findSP(): Window;
11
+ export declare function getFocusNavController(): any;
12
+ export declare function getGamepadNavigationTrees(): any;
@@ -0,0 +1,23 @@
1
+ export * from './patcher';
2
+ export * from './react';
3
+ export * from './static-classes';
4
+ export function joinClassNames(...classes) {
5
+ return classes.join(' ');
6
+ }
7
+ export function sleep(ms) {
8
+ return new Promise((res) => setTimeout(res, ms));
9
+ }
10
+ export function findSP() {
11
+ if (document.title == 'SP')
12
+ return window;
13
+ const navTrees = getGamepadNavigationTrees();
14
+ return navTrees?.find((x) => x.m_ID == 'root_1_').Root.Element.ownerDocument.defaultView;
15
+ }
16
+ export function getFocusNavController() {
17
+ return window.GamepadNavTree?.m_context?.m_controller || window.FocusNavController;
18
+ }
19
+ export function getGamepadNavigationTrees() {
20
+ const focusNav = getFocusNavController();
21
+ const context = focusNav.m_ActiveContext || focusNav.m_LastActiveContext;
22
+ return context?.m_rgGamepadNavigationTrees;
23
+ }
@@ -0,0 +1,18 @@
1
+ export declare let callOriginal: symbol;
2
+ export interface PatchOptions {
3
+ singleShot?: boolean;
4
+ }
5
+ type GenericPatchHandler = (args: any[], ret?: any) => any;
6
+ export interface Patch {
7
+ original: Function;
8
+ property: string;
9
+ object: any;
10
+ patchedFunction: any;
11
+ hasUnpatched: boolean;
12
+ handler: GenericPatchHandler;
13
+ unpatch: () => void;
14
+ }
15
+ export declare function beforePatch(object: any, property: string, handler: (args: any[]) => any, options?: PatchOptions): Patch;
16
+ export declare function afterPatch(object: any, property: string, handler: (args: any[], ret: any) => any, options?: PatchOptions): Patch;
17
+ export declare function replacePatch(object: any, property: string, handler: (args: any[]) => any, options?: PatchOptions): Patch;
18
+ export {};
@@ -0,0 +1,103 @@
1
+ export let callOriginal = Symbol('DECKY_CALL_ORIGINAL');
2
+ export function beforePatch(object, property, handler, options = {}) {
3
+ const orig = object[property];
4
+ object[property] = function (...args) {
5
+ handler.call(this, args);
6
+ const ret = patch.original.call(this, ...args);
7
+ if (options.singleShot) {
8
+ patch.unpatch();
9
+ }
10
+ return ret;
11
+ };
12
+ const patch = processPatch(object, property, handler, object[property], orig);
13
+ return patch;
14
+ }
15
+ export function afterPatch(object, property, handler, options = {}) {
16
+ const orig = object[property];
17
+ object[property] = function (...args) {
18
+ let ret = patch.original.call(this, ...args);
19
+ ret = handler.call(this, args, ret);
20
+ if (options.singleShot) {
21
+ patch.unpatch();
22
+ }
23
+ return ret;
24
+ };
25
+ const patch = processPatch(object, property, handler, object[property], orig);
26
+ return patch;
27
+ }
28
+ export function replacePatch(object, property, handler, options = {}) {
29
+ const orig = object[property];
30
+ object[property] = function (...args) {
31
+ const ret = handler.call(this, args);
32
+ if (ret == callOriginal)
33
+ return patch.original.call(this, ...args);
34
+ if (options.singleShot) {
35
+ patch.unpatch();
36
+ }
37
+ return ret;
38
+ };
39
+ const patch = processPatch(object, property, handler, object[property], orig);
40
+ return patch;
41
+ }
42
+ function processPatch(object, property, handler, patchedFunction, original) {
43
+ Object.assign(object[property], original);
44
+ object[property].toString = () => original.toString();
45
+ Object.defineProperty(object[property], '__deckyOrig', {
46
+ get: () => patch.original,
47
+ set: (val) => (patch.original = val),
48
+ });
49
+ const patch = {
50
+ object,
51
+ property,
52
+ handler,
53
+ patchedFunction,
54
+ original,
55
+ hasUnpatched: false,
56
+ unpatch: () => unpatch(patch),
57
+ };
58
+ object[property].__deckyPatch = patch;
59
+ return patch;
60
+ }
61
+ function unpatch(patch) {
62
+ const { object, property, handler, patchedFunction, original } = patch;
63
+ if (patch.hasUnpatched)
64
+ throw new Error('Function is already unpatched.');
65
+ let realProp = property;
66
+ let realObject = object;
67
+ console.debug('[Patcher] unpatching', {
68
+ realObject,
69
+ realProp,
70
+ object,
71
+ property,
72
+ handler,
73
+ patchedFunction,
74
+ original,
75
+ isEqual: realObject[realProp] === patchedFunction,
76
+ });
77
+ while (realObject[realProp] && realObject[realProp] !== patchedFunction) {
78
+ realObject = realObject[realProp].__deckyPatch;
79
+ realProp = 'original';
80
+ console.debug('[Patcher] moved to next', {
81
+ realObject,
82
+ realProp,
83
+ object,
84
+ property,
85
+ handler,
86
+ patchedFunction,
87
+ original,
88
+ isEqual: realObject[realProp] === patchedFunction,
89
+ });
90
+ }
91
+ realObject[realProp] = realObject[realProp].__deckyPatch.original;
92
+ patch.hasUnpatched = true;
93
+ console.debug('[Patcher] unpatched', {
94
+ realObject,
95
+ realProp,
96
+ object,
97
+ property,
98
+ handler,
99
+ patchedFunction,
100
+ original,
101
+ isEqual: realObject[realProp] === patchedFunction,
102
+ });
103
+ }
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ declare global {
3
+ interface Window {
4
+ SP_REACT: typeof React;
5
+ }
6
+ }
7
+ export declare function fakeRenderComponent(fun: Function, customHooks?: any): any;
8
+ export declare function wrapReactType(node: any, prop?: any): any;
9
+ export declare function wrapReactClass(node: any, prop?: any): any;
10
+ export declare function getReactRoot(o: HTMLElement | Element | Node): any;
11
+ export declare function getReactInstance(o: HTMLElement | Element | Node): any;
12
+ export interface findInTreeOpts {
13
+ walkable?: string[];
14
+ ignore?: string[];
15
+ }
16
+ export declare type findInTreeFilter = (element: any) => boolean;
17
+ export declare const findInTree: (parent: any, filter: findInTreeFilter, opts: findInTreeOpts) => any;
18
+ export declare const findInReactTree: (node: any, filter: findInTreeFilter) => any;
@@ -0,0 +1,74 @@
1
+ export function fakeRenderComponent(fun, customHooks = {}) {
2
+ const hooks = window.SP_REACT.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher
3
+ .current;
4
+ let oldHooks = {
5
+ useContext: hooks.useContext,
6
+ useCallback: hooks.useCallback,
7
+ useLayoutEffect: hooks.useLayoutEffect,
8
+ useEffect: hooks.useEffect,
9
+ useMemo: hooks.useMemo,
10
+ useRef: hooks.useRef,
11
+ useState: hooks.useState,
12
+ };
13
+ hooks.useCallback = (cb) => cb;
14
+ hooks.useContext = (cb) => cb._currentValue;
15
+ hooks.useLayoutEffect = (_) => { };
16
+ hooks.useMemo = (cb, _) => cb;
17
+ hooks.useEffect = (_) => { };
18
+ hooks.useRef = (val) => ({ current: val || {} });
19
+ hooks.useState = (v) => {
20
+ let val = v;
21
+ return [val, (n) => (val = n)];
22
+ };
23
+ Object.assign(hooks, customHooks);
24
+ const res = fun(hooks);
25
+ Object.assign(hooks, oldHooks);
26
+ return res;
27
+ }
28
+ export function wrapReactType(node, prop = 'type') {
29
+ if (node[prop]?.__DECKY_WRAPPED) {
30
+ return node[prop];
31
+ }
32
+ else {
33
+ return (node[prop] = { ...node[prop], __DECKY_WRAPPED: true });
34
+ }
35
+ }
36
+ export function wrapReactClass(node, prop = 'type') {
37
+ var _a;
38
+ if (node[prop]?.__DECKY_WRAPPED) {
39
+ return node[prop];
40
+ }
41
+ else {
42
+ const cls = node[prop];
43
+ const wrappedCls = (_a = class extends cls {
44
+ },
45
+ _a.__DECKY_WRAPPED = true,
46
+ _a);
47
+ return (node[prop] = wrappedCls);
48
+ }
49
+ }
50
+ export function getReactRoot(o) {
51
+ return (o[Object.keys(o).find((k) => k.startsWith('__reactContainer$'))] ||
52
+ o['_reactRootContainer']?._internalRoot?.current);
53
+ }
54
+ export function getReactInstance(o) {
55
+ return (o[Object.keys(o).find((k) => k.startsWith('__reactFiber'))] ||
56
+ o[Object.keys(o).find((k) => k.startsWith('__reactInternalInstance'))]);
57
+ }
58
+ export const findInTree = (parent, filter, opts) => {
59
+ const { walkable = null, ignore = [] } = opts ?? {};
60
+ if (!parent || typeof parent !== 'object') {
61
+ return null;
62
+ }
63
+ if (filter(parent))
64
+ return parent;
65
+ if (Array.isArray(parent)) {
66
+ return parent.map((x) => findInTree(x, filter, opts)).find((x) => x);
67
+ }
68
+ return (walkable || Object.keys(parent))
69
+ .map((x) => !ignore.includes(x) && findInTree(parent[x], filter, opts))
70
+ .find((x) => x);
71
+ };
72
+ export const findInReactTree = (node, filter) => findInTree(node, filter, {
73
+ walkable: ['props', 'children', 'child', 'sibling'],
74
+ });
@@ -0,0 +1,52 @@
1
+ type QuickAccessMenuClasses = Record<'ActiveTab' | 'AllTabContents' | 'BackgroundAnimation' | 'BatteryDetailsLabels' | 'BatteryIcon' | 'BatteryPercentageLabel' | 'BatteryProjectedLabel' | 'BatteryProjectedValue' | 'BatterySectionContainer' | 'Blocked' | 'ComingSoon' | 'Container' | 'ContentTransition' | 'Down' | 'EmptyNotifications' | 'Enter' | 'EnterActive' | 'Exit' | 'ExitActive' | 'FooterBoxShadow' | 'FriendsListTabPanel' | 'FriendsTitle' | 'FullHeight' | 'HeaderAndFooterVisible' | 'HeaderContainer' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'KeyboardButton' | 'Label' | 'LowBattery' | 'LowBatteryGauge' | 'Menu' | 'Open' | 'PanelExitAnchor' | 'PanelOuterNav' | 'PanelSection' | 'PanelSectionRow' | 'PanelSectionTitle' | 'PopupBody' | 'QuickAccessMenu' | 'QuickAccessNotifications' | 'ReallyLow' | 'Remaining' | 'Selected' | 'Tab' | 'TabContentColumn' | 'TabGroupPanel' | 'TabPanelHidden' | 'Tabs' | 'TabsWithFooter' | 'Text' | 'Title' | 'TransitionMenuDelay' | 'Up' | 'VR' | 'ViewPlaceholder' | 'VoiceTab' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation' | 'vrgamepadui-floating-bar-popup-panel-height' | 'vrgamepadui-floating-bar-popup-panel-width' | 'vrgamepadui-floating-keyboard-height' | 'vrgamepadui-floating-keyboard-width' | 'vrgamepadui-floating-side-panel-height' | 'vrgamepadui-floating-side-panel-width', string>;
2
+ type ScrollPanelClasses = Record<'ScrollBoth' | 'ScrollPanel' | 'ScrollX' | 'ScrollY', string>;
3
+ type GamepadDialogClasses = Record<'ActiveAndUnfocused' | 'AlignCenter' | 'AlignLeft' | 'AlignRight' | 'BackgroundAnimation' | 'BasicTextInput' | 'BeforeChildren' | 'BottomButtons' | 'Button' | 'ChildrenWidthFixed' | 'ChildrenWidthGrow' | 'Clickable' | 'CompactPadding' | 'ControlsListChild' | 'ControlsListOuterPanel' | 'Disabled' | 'DropDownControlButtonContents' | 'DropDownRow' | 'ExtraPaddingOnChildrenBelow' | 'ExtraSpacing' | 'Field' | 'FieldChildrenInner' | 'FieldChildrenWithIcon' | 'FieldClickTarget' | 'FieldDescription' | 'FieldIcon' | 'FieldLabel' | 'FieldLabelRow' | 'FieldLabelValue' | 'Front' | 'FullWidth' | 'GamepadDialogContent' | 'GamepadDialogContent_InnerWidth' | 'HighlightOnFocus' | 'IconContainer' | 'InlineWrapShiftsChildrenBelow' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'ItemMaxSizeDesktop' | 'Label' | 'LabelFieldValue' | 'ModalClickToDismiss' | 'ModalPosition' | 'NoHeaderPadding' | 'NoMinWidth' | 'On' | 'QuickAccess-Menu' | 'ScrollWithin' | 'Spacer' | 'StandaloneFieldSeparator' | 'StandardPadding' | 'StandardSpacing' | 'Toggle' | 'ToggleRail' | 'ToggleSwitch' | 'VR' | 'VerticalAlignCenter' | 'WithBottomSeparator' | 'WithBottomSeparatorStandard' | 'WithBottomSeparatorThick' | 'WithChildrenBelow' | 'WithDescription' | 'WithFirstRow' | 'WithStandardPadding' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation' | 'slideInAnimation', string>;
4
+ type QuickAccessControlsClasses = Record<'BackgroundAnimation' | 'BatteryDetailsLabels' | 'BatteryIcon' | 'BatteryPercentageLabel' | 'BatteryProjectedLabel' | 'BatteryProjectedValue' | 'BatterySectionContainer' | 'ComingSoon' | 'EmptyNotifications' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'Label' | 'LowBattery' | 'LowBatteryGauge' | 'PanelSection' | 'PanelSectionRow' | 'PanelSectionTitle' | 'QuickAccessNotifications' | 'ReallyLow' | 'Remaining' | 'Text' | 'VR' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation', string>;
5
+ type UpdaterFieldClasses = Record<'ApplyingText' | 'BackgroundAnimation' | 'BatteryLowWarning' | 'Body' | 'CurrentStatus' | 'Denominator' | 'EventDetailTitle' | 'EventDetailsBody' | 'EventDetailsSubTitle' | 'InsufficientBatteryText' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'Label' | 'Numerator' | 'OOBEUpdateStatusContainer' | 'PatchNotes' | 'PostedTime' | 'ProgressInfoContainer' | 'ProgressStatus' | 'Separator' | 'Text' | 'TextContainer' | 'TimeRemaining' | 'Title' | 'TotalUpdateSize' | 'UnsupportedHardwareWarning' | 'UpdateBytesRemaining' | 'UpdatePanel' | 'UpdateScreen' | 'UpdateStatusContainer' | 'UpdaterFieldStatusApplying' | 'UpdaterFieldStatusSuccess' | 'duration-app-launch' | 'fadeInAnimation' | 'focusAnimation' | 'hoverAnimation', string>;
6
+ type PlaySectionClasses = Record<'AchievementCountLabel' | 'AchievementProgressRow' | 'AchievementSVG' | 'ActionSection' | 'AppButtonsContainer' | 'Arrow' | 'AvatarAndPersona' | 'BackgroundAnimation' | 'BreakNarrow' | 'BreakShort' | 'BreakTall' | 'BreakUltraWide' | 'BreakWide' | 'ButtonChild' | 'ButtonText' | 'ChooseButton' | 'ClaimButton' | 'ClaimButtonContainer' | 'ClickablePlayBarItem' | 'CloudIconSVG' | 'CloudStatusIcon' | 'CloudStatusLabel' | 'CloudStatusRow' | 'CloudStatusSyncFail' | 'CloudSyncProblem' | 'CloudSynching' | 'ComingSoon' | 'Container' | 'ControllerConfigButton' | 'ControllerSupportInfo' | 'ControllerSupportRow' | 'DetailsProgressBar' | 'DetailsProgressContainer' | 'DetailsSection' | 'DetailsSectionExtra' | 'DetailsSectionStatus' | 'Disabled' | 'DotDotDot' | 'DownloadPaused' | 'DownloadProgressBar' | 'Downloading' | 'FavoriteButton' | 'Favorited' | 'FeatureHidden' | 'GameInfoButton' | 'GameStat' | 'GameStatIcon' | 'GameStatIconForced' | 'GameStatRight' | 'GameStatsSection' | 'GamepadUIBreakNarrow' | 'GamepadUIBreakShort' | 'GamepadUIBreakWide' | 'Glassy' | 'HideWhenNarrow' | 'Icon' | 'Icons' | 'InPage' | 'InnerContainer' | 'InvalidPlatform' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'LastPlayed' | 'LastPlayedInfo' | 'LaunchOptionCallout' | 'LaunchOptionCalloutMessage' | 'LaunchOptionCalloutMessageContainer' | 'LongButton' | 'MenuActive' | 'MenuButton' | 'MenuButtonContainer' | 'MiniAchievements' | 'OfflineMode' | 'OnlyDownloadBar' | 'PermanentlyUnavailable' | 'PlayBar' | 'PlayBarCloudStatusContainer' | 'PlayBarDetailLabel' | 'PlayBarGameIcon' | 'PlayBarGameName' | 'PlayBarIconAndGame' | 'PlayBarLabel' | 'Playtime' | 'PlaytimeIcon' | 'PlaytimeIconForced' | 'PortraitBar' | 'PrivateAppActiveIndicator' | 'RecentlyUpdated' | 'RecentlyUpdatedIcon' | 'RecentlyUpdatedLink' | 'RecentlyUpdatedText' | 'RightBreakNarrow' | 'RightBreakUltraNarrow' | 'RightBreakUltraWide' | 'RightBreakWide' | 'RightControls' | 'Row' | 'SharedLibrary' | 'ShowStreaming' | 'StatusAndStats' | 'StatusNameContainer' | 'StickyHeader' | 'StickyHeaderShadow' | 'SuperimposedGridItems' | 'SyncAnim' | 'Visible' | 'duration-app-launch' | 'favorited' | 'focusAnimation' | 'hoverAnimation', string>;
7
+ type GamepadSliderClasses = Record<'AlignToEnds' | 'AlignToLeft' | 'AlignToRight' | 'BackgroundAnimation' | 'CompoundSlider' | 'CompoundSliderSubSlider' | 'CompoundSliderSubSliderLabel' | 'CompoundSliderSubSliderLabelContainer' | 'CompoundSliderSubSliderLabelInternal' | 'CompoundSliderSubSliderLabelPositioner' | 'DefaultValueColorLeft' | 'DefaultValueColorRight' | 'DefaultValueIsColorRange' | 'DefaultValueTick' | 'DefaultValueTickContainer' | 'DescriptionValue' | 'Disabled' | 'EditableValue' | 'ErrorShake' | 'FakeEditableValue' | 'Icon' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'LabelText' | 'Left' | 'ParenSliderHandle' | 'ParenSliderHandleContainer' | 'RedBorder' | 'Right' | 'SliderControl' | 'SliderControlAndNotches' | 'SliderControlPanelGroup' | 'SliderHandle' | 'SliderHandleContainer' | 'SliderHandleFocusPop' | 'SliderHasNotches' | 'SliderNotch' | 'SliderNotchContainer' | 'SliderNotchLabel' | 'SliderNotchTick' | 'SliderTrack' | 'SliderTrackDark' | 'TickActive' | 'VerticalLineSliderHandle' | 'VerticalLineSliderHandleContainer' | 'WithDefaultValue' | 'duration-app-launch' | 'error-shake' | 'error-shake-duration', string>;
8
+ type AppDetailsHeaderClasses = Record<'AddBoxSizer' | 'Background' | 'Bottom' | 'BottomCenter' | 'BottomLeft' | 'BottomRight' | 'BoxSizer' | 'BoxSizerButtonContainer' | 'BoxSizerContainer' | 'BoxSizerDelete' | 'BoxSizerDragBox' | 'BoxSizerEdge' | 'BoxSizerGridBox' | 'BoxSizerInfo' | 'BoxSizerSettings' | 'BoxSizerValidRegion' | 'CenterCenter' | 'DialogButton' | 'EdgeDown' | 'FallbackArt' | 'Features' | 'FullscreenEnterActive' | 'FullscreenEnterDone' | 'FullscreenEnterStart' | 'FullscreenExitActive' | 'FullscreenExitDone' | 'FullscreenExitStart' | 'HeaderBackgroundImage' | 'ImgBlur' | 'ImgBlurBackdrop' | 'ImgContainer' | 'ImgSrc' | 'Left' | 'Loaded' | 'Middle' | 'NoArt' | 'PinBox' | 'Right' | 'SVGTitle' | 'SaveBoxSizer' | 'TextNameSpace' | 'TitleImageContainer' | 'TitleLogo' | 'TitleSection' | 'Top' | 'TopCapsule' | 'TopGradient' | 'TopLeft' | 'TopRight' | 'UpperCenter' | 'UpperLeft' | 'duration-app-launch', string>;
9
+ type AppDetailsClasses = Record<'AppDetailsOverviewPanel' | 'BackgroundAnimation' | 'BreakNarrow' | 'BreakShort' | 'BreakTall' | 'BreakUltraWide' | 'BreakWide' | 'Container' | 'GamepadUIBreakNarrow' | 'GamepadUIBreakShort' | 'GamepadUIBreakWide' | 'Glassy' | 'Header' | 'HeaderLoaded' | 'InnerContainer' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'PlayBar' | 'PreventScrolling' | 'RightBreakNarrow' | 'RightBreakUltraNarrow' | 'RightBreakUltraWide' | 'RightBreakWide' | 'ScrollContainer' | 'ShowPlayBar' | 'Throbber' | 'duration-app-launch' | 'fadein' | 'focusAnimation' | 'hoverAnimation', string>;
10
+ type GamepadUIClasses = Record<'BackgroundAnimation' | 'BasicHome' | 'BasicUiRoot' | 'Content' | 'ContinuousRenderPixel' | 'ContinuousRenderPixelBlink' | 'GamepadDialogOverlay' | 'GamepadUIPopupWindowBody' | 'HeaderHeightVisible' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'MainNavMenuAnchor' | 'MainNavMenuMainSplit' | 'OpaqueBackground' | 'PopupBody' | 'QuickAccessMenuAnchor' | 'StandaloneKeyboard' | 'SteamUIPopupHTML' | 'SteamUIPopupWindow' | 'SteamUIPopupWindowBody' | 'TransparentBackground' | 'TrueBlackBackground' | 'VR' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation' | 'vrgamepadui-floating-bar-popup-panel-height' | 'vrgamepadui-floating-bar-popup-panel-width' | 'vrgamepadui-floating-keyboard-height' | 'vrgamepadui-floating-keyboard-width' | 'vrgamepadui-floating-side-panel-height' | 'vrgamepadui-floating-side-panel-width', string>;
11
+ type GamepadTabbedPageClasses = Record<'Active' | 'AnimateDownwardExpansion' | 'Arrows' | 'BackgroundAnimation' | 'BleedGlyphs' | 'CanBeHeaderBackground' | 'ContentTransition' | 'Enter' | 'EnterActive' | 'Exit' | 'ExitActive' | 'ExpandFadeDownwards' | 'FixCenterAlignScroll' | 'Floating' | 'GamepadTabbedPage' | 'Glyphs' | 'HasAddon' | 'IsUnderHeader' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'Left' | 'LeftAddon' | 'OverlayPinnedView' | 'Right' | 'RightAddon' | 'ScrolledDown' | 'Selected' | 'Show' | 'SortAndFilterButton' | 'SortAndFilterContainer' | 'Tab' | 'TabBadge' | 'TabContents' | 'TabContentsScroll' | 'TabCount' | 'TabCountBadge' | 'TabHeaderRowWrapper' | 'TabIcon' | 'TabRow' | 'TabRowSpacer' | 'TabRowTabs' | 'TabTitle' | 'TabsRowScroll' | 'contentPadding' | 'duration-app-launch' | 'headerHeight', string>;
12
+ type GamepadContextMenuClasses = Record<'Arrow' | 'BackgroundAnimation' | 'BasicContextMenuContainer' | 'BasicContextMenuHeader' | 'BasicContextMenuHeaderShrinkableSpacing' | 'BasicContextMenuModal' | 'Capitalized' | 'ContextMenuSeparator' | 'Destructive' | 'Emphasis' | 'Focused' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'Label' | 'MenuSectionHeader' | 'Positive' | 'Selected' | 'SubMenu' | 'UpperCase' | 'active' | 'contextMenu' | 'contextMenuContents' | 'contextMenuFade' | 'contextMenuItem' | 'duration-app-launch' | 'focusAnimation' | 'hasSubMenu' | 'hoverAnimation' | 'slideInAnimation', string>;
13
+ type AchievementListClasses = Record<'AchievementContent' | 'AchievementDescription' | 'AchievementGlobalPercentage' | 'AchievementList' | 'AchievementListItemBase' | 'AchievementTitle' | 'AlignEnd' | 'Avatar' | 'AvatarContainer' | 'ComparisonAchieverColumn' | 'ComparisonAchieverInfo' | 'Container' | 'Content' | 'Description' | 'Footer' | 'FriendAchievementFooter' | 'GlobalAchievementListItem' | 'GlobalAchievementsListHeader' | 'GlobalPercentage' | 'HeaderText' | 'Hidden' | 'HiddenAchievementContent' | 'ImageContainer' | 'InBody' | 'Info' | 'ListTitle' | 'Percent' | 'ProgressBar' | 'ProgressContainer' | 'ProgressCount' | 'ProgressFill' | 'ProgressLabel' | 'Right' | 'SearchField' | 'Secondary' | 'SpoilerWarning' | 'Title' | 'Unachieved' | 'UnlockContainer' | 'UnlockDate' | 'UserUnlockDateTime' | 'VerticalContent' | 'duration-app-launch' | 'nAchievementGap' | 'nAchievementHeight' | 'nAchievementsListTitleHeight' | 'nGlobalAchievementHeight', string>;
14
+ type AchievementPageClasses = Record<'AchievementContent' | 'AchievementDescription' | 'AchievementGlobalPercentage' | 'AchievementList' | 'AchievementListItemBase' | 'AchievementTabs' | 'AchievementTitle' | 'AlignEnd' | 'Avatar' | 'AvatarContainer' | 'Background' | 'Blur' | 'CompareButtonContainer' | 'ComparisonAchieverColumn' | 'ComparisonAchieverInfo' | 'Container' | 'Content' | 'Description' | 'DragHandle' | 'ErrorButtons' | 'ErrorContainer' | 'ErrorTitle' | 'Footer' | 'FriendAchievementFooter' | 'FriendAchievementsListHeader' | 'GlobalAchievementListItem' | 'GlobalAchievementsListHeader' | 'GlobalButton' | 'GlobalPercentage' | 'HeaderContainer' | 'HeaderImage' | 'HeaderText' | 'Hidden' | 'HiddenAchievementContent' | 'ImageContainer' | 'InBody' | 'Info' | 'Label' | 'List' | 'ListTitle' | 'LoadingContainer' | 'MyAchievementsHeader' | 'Nav' | 'NotOwnedMessage' | 'Page' | 'Percent' | 'PerfectGame' | 'PinnedView' | 'PinnedViewTabs' | 'ProgressBar' | 'ProgressContainer' | 'ProgressCount' | 'ProgressFill' | 'ProgressLabel' | 'Right' | 'SearchField' | 'Secondary' | 'SortableAchievementsList' | 'SortableUserAchievement' | 'SortableUserAchievementInner' | 'SpoilerWarning' | 'Text' | 'Throbber' | 'Title' | 'ToggleContainer' | 'Unachieved' | 'UnlockContainer' | 'UnlockDate' | 'UserContext' | 'UserUnlockDateTime' | 'VerticalContent' | 'duration-app-launch' | 'headerPadding' | 'nAchievementGap' | 'nAchievementHeight' | 'nAchievementsListTitleHeight' | 'nGlobalAchievementHeight', string>;
15
+ type MainMenuAppRunningClasses = Record<'Active' | 'ActiveContent' | 'ActiveDot' | 'AppColumn' | 'AppColumnContent' | 'AppRunningControls' | 'BackgroundAnimation' | 'Collapsible' | 'Container' | 'ControllerColumnFocused' | 'CurrentGameBackground' | 'CurrentGameLogo' | 'Disabled' | 'FocusedColumn' | 'HideMask' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'KeyBoardVisible' | 'NavColumnFocused' | 'NavigationBox' | 'NavigationColumn' | 'NavigationMenuItem' | 'NavigationMenuItemSeparator' | 'OverlayAchievements' | 'OverlayGuides' | 'OverlayInplaceBrowser' | 'OverlayNotes' | 'ScrollMask' | 'SelectableAppWindow' | 'SwitchAppsTitle' | 'Visible' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation', string>;
16
+ type BasicAppDetailsSectionStylerClasses = Record<'ActionButtonAndStatusPanel' | 'ActionRow' | 'AppActionButton' | 'AppButtons' | 'AppDetailSectionList' | 'AppDetailsContainer' | 'AppDetailsContent' | 'AppDetailsRoot' | 'CollectionsHeader' | 'DeckVerifiedFeedbackButton' | 'DeckVerifiedFeedbackConfirmation' | 'DeckVerifiedFeedbackConfirmationContainer' | 'DeckVerifiedFeedbackContainer' | 'DeckVerifiedFeedbackQuestion' | 'GameInfoCollections' | 'GameInfoContainer' | 'GameInfoQuickLinks' | 'Header' | 'InvertFocusedIcon' | 'PlaySection' | 'duration-app-launch' | 'headerPadding', string>;
17
+ type SteamSpinnerClasses = Record<'BackgroundAnimation' | 'Black' | 'Container' | 'ContainerBackground' | 'ExtraSpace' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'LoadingStatus' | 'Medium' | 'Small' | 'Spacer' | 'SpinnerLoaderContainer' | 'focusAnimation' | 'hoverAnimation', string>;
18
+ type FooterClasses = Record<'BackgroundAnimation' | 'BasicFooter' | 'FooterLegend' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'Opaque' | 'PillShapedIcon' | 'QuickAccessFooter' | 'Relative' | 'Spacer' | 'WithKeyboard' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation', string>;
19
+ type AppActionButtonClasses = Record<'BackgroundAnimation' | 'BreakNarrow' | 'BreakShort' | 'BreakTall' | 'BreakUltraWide' | 'BreakWide' | 'ButtonChild' | 'ButtonText' | 'ButtonThrobberPadding' | 'Disabled' | 'ForceShutdownButton' | 'GamepadUIBreakNarrow' | 'GamepadUIBreakShort' | 'GamepadUIBreakWide' | 'Green' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'LongButton' | 'NoAction' | 'PlayButton' | 'PlayButtonContainer' | 'RightBreakNarrow' | 'RightBreakUltraNarrow' | 'RightBreakUltraWide' | 'RightBreakWide' | 'ShowStreaming' | 'ShowingStreaming' | 'ShutdownAppButton' | 'StreamingCallout' | 'StreamingCalloutMessage' | 'StreamingCalloutMessageContainer' | 'StreamingContextMenuItem' | 'StreamingSelector' | 'Throbber' | 'ThrobberContainer' | 'WaitingForForceShutdown' | 'WaitingForShutdownSpinner' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation' | 'rotate', string>;
20
+ type LibraryAssetImageClasses = Record<'Container' | 'GreyBackground' | 'Hidden' | 'Image' | 'LandscapeImage' | 'LongTitles' | 'NoTransitions' | 'PortraitImage' | 'Short' | 'Title' | 'Visibility' | 'Visible' | 'duration-app-launch', string>;
21
+ type GamepadLibraryClasses = Record<'AppGridFilterHeader' | 'AppGridFilterHeaderAsButton' | 'AppGridFilterText' | 'BackgroundAnimation' | 'BreakNarrow' | 'BreakShort' | 'BreakTall' | 'BreakUltraWide' | 'BreakWide' | 'CollectionContents' | 'CollectionHeader' | 'ComingSoon' | 'GamepadLibrary' | 'GamepadUIBreakNarrow' | 'GamepadUIBreakShort' | 'GamepadUIBreakWide' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'RightBreakNarrow' | 'RightBreakUltraNarrow' | 'RightBreakUltraWide' | 'RightBreakWide' | 'duration-app-launch' | 'focusAnimation' | 'hoverAnimation', string>;
22
+ type FocusRingClasses = Record<'DebugFocusRing' | 'FocusRing' | 'FocusRingOnHiddenItem' | 'FocusRingRoot' | 'blinker' | 'fadeOutline' | 'flash' | 'growOutline', string>;
23
+ type SearchBarClasses = Record<'BackgroundAnimation' | 'ForceExpanded' | 'IconMovesOnHover' | 'ItemFocusAnim-darkGrey' | 'ItemFocusAnim-darkerGrey' | 'ItemFocusAnim-darkerGrey-nocolor' | 'ItemFocusAnim-green' | 'ItemFocusAnim-grey' | 'ItemFocusAnim-translucent-white-10' | 'ItemFocusAnim-translucent-white-20' | 'ItemFocusAnimBorder-darkGrey' | 'SearchAndTitleContainer' | 'SearchBox' | 'SearchFieldBackground' | 'SearchIconLeft' | 'SearchIconRight' | 'ShowingSearch' | 'ShowingTitle' | 'VR' | 'Visible' | 'WhiteBackground' | 'duration-app-launch', string>;
24
+ type MainBrowserClasses = Record<'Browser' | 'BrowserContainer' | 'BrowserNavRoot' | 'Disabled' | 'ExternalBrowserContainer' | 'InputSupportLevel' | 'MainBrowser' | 'MainBrowserContainer' | 'MicroTxnContainer' | 'NavigationButton' | 'RequireTouchscreenLabel' | 'StatusIcon' | 'Toggled' | 'URL' | 'URLBar' | 'URLInput' | 'Visible' | 'duration-app-launch' | 'showSupportLevel', string>;
25
+ export declare const quickAccessMenuClasses: QuickAccessMenuClasses;
26
+ export declare const scrollPanelClasses: ScrollPanelClasses;
27
+ export declare const gamepadDialogClasses: GamepadDialogClasses;
28
+ export declare const quickAccessControlsClasses: QuickAccessControlsClasses;
29
+ export declare const updaterFieldClasses: UpdaterFieldClasses;
30
+ export declare const playSectionClasses: PlaySectionClasses;
31
+ export declare const gamepadSliderClasses: GamepadSliderClasses;
32
+ export declare const appDetailsHeaderClasses: AppDetailsHeaderClasses;
33
+ export declare const appDetailsClasses: AppDetailsClasses;
34
+ export declare const gamepadUIClasses: GamepadUIClasses;
35
+ export declare const gamepadTabbedPageClasses: GamepadTabbedPageClasses;
36
+ export declare const gamepadContextMenuClasses: GamepadContextMenuClasses;
37
+ export declare const achievementListClasses: AchievementListClasses;
38
+ export declare const achievementPageClasses: AchievementPageClasses;
39
+ export declare const mainMenuAppRunningClasses: MainMenuAppRunningClasses;
40
+ export declare const basicAppDetailsSectionStylerClasses: BasicAppDetailsSectionStylerClasses;
41
+ export declare const steamSpinnerClasses: SteamSpinnerClasses;
42
+ export declare const footerClasses: FooterClasses;
43
+ export declare const appActionButtonClasses: AppActionButtonClasses;
44
+ export declare const libraryAssetImageClasses: LibraryAssetImageClasses;
45
+ export declare const gamepadLibraryClasses: GamepadLibraryClasses;
46
+ export declare const focusRingClasses: FocusRingClasses;
47
+ export declare const searchBarClasses: SearchBarClasses;
48
+ export declare const mainBrowserClasses: MainBrowserClasses;
49
+ export declare const staticClasses: QuickAccessMenuClasses;
50
+ export declare const scrollClasses: ScrollPanelClasses;
51
+ export declare const achievementClasses: AchievementListClasses;
52
+ export {};
@@ -0,0 +1,28 @@
1
+ import { findClassModule } from '../class-mapper';
2
+ export const quickAccessMenuClasses = findClassModule((m) => m.Title && m.QuickAccessMenu && m.BatteryDetailsLabels);
3
+ export const scrollPanelClasses = findClassModule((m) => m.ScrollPanel);
4
+ export const gamepadDialogClasses = findClassModule((m) => m.GamepadDialogContent && !m.BindingButtons);
5
+ export const quickAccessControlsClasses = findClassModule((m) => m.BatteryPercentageLabel && m.PanelSection && !m['vr-dashboard-bar-height'] && !m.QuickAccessMenu && !m.QuickAccess && !m.PerfProfileInfo);
6
+ export const updaterFieldClasses = findClassModule((m) => m.OOBEUpdateStatusContainer);
7
+ export const playSectionClasses = findClassModule((m) => m.PlayBarDetailLabel);
8
+ export const gamepadSliderClasses = findClassModule((m) => m.SliderControlPanelGroup);
9
+ export const appDetailsHeaderClasses = findClassModule((m) => m.TopCapsule);
10
+ export const appDetailsClasses = findClassModule((m) => m.HeaderLoaded);
11
+ export const gamepadUIClasses = findClassModule((m) => m.BasicUiRoot);
12
+ export const gamepadTabbedPageClasses = findClassModule((m) => m.GamepadTabbedPage);
13
+ export const gamepadContextMenuClasses = findClassModule((m) => m.BasicContextMenuModal);
14
+ export const achievementListClasses = findClassModule((m) => m.AchievementListItemBase && !m.Page);
15
+ export const achievementPageClasses = findClassModule((m) => m.AchievementListItemBase && m.Page);
16
+ export const mainMenuAppRunningClasses = findClassModule((m) => m.AppRunningControls && m.OverlayAchievements);
17
+ export const basicAppDetailsSectionStylerClasses = findClassModule((m) => m.AppDetailsRoot);
18
+ export const steamSpinnerClasses = findClassModule(m => m.SpinnerLoaderContainer);
19
+ export const footerClasses = findClassModule(m => m.QuickAccessFooter);
20
+ export const appActionButtonClasses = findClassModule(m => m.PlayButtonContainer);
21
+ export const libraryAssetImageClasses = findClassModule(m => m.LongTitles && m.GreyBackground);
22
+ export const gamepadLibraryClasses = findClassModule(m => m.GamepadLibrary);
23
+ export const focusRingClasses = findClassModule(m => m.FocusRingRoot);
24
+ export const searchBarClasses = findClassModule(m => m.SearchAndTitleContainer);
25
+ export const mainBrowserClasses = findClassModule(m => m.MainBrowserContainer);
26
+ export const staticClasses = quickAccessMenuClasses;
27
+ export const scrollClasses = scrollPanelClasses;
28
+ export const achievementClasses = achievementListClasses;
@@ -0,0 +1,21 @@
1
+ declare global {
2
+ interface Window {
3
+ webpackChunksteamui: any;
4
+ }
5
+ }
6
+ export type Module = any;
7
+ export type Export = any;
8
+ type FilterFn = (module: any) => boolean;
9
+ type ExportFilterFn = (moduleExport: any, exportName?: any) => boolean;
10
+ type FindFn = (module: any) => any;
11
+ export declare let modules: any;
12
+ export declare const findModule: (filter: FilterFn) => any;
13
+ export declare const findModuleDetailsByExport: (filter: ExportFilterFn, minExports?: number) => [module: Module | undefined, moduleExport: any, exportName: any];
14
+ export declare const findModuleByExport: (filter: ExportFilterFn, minExports?: number) => any;
15
+ export declare const findModuleExport: (filter: ExportFilterFn, minExports?: number) => any;
16
+ export declare const findModuleChild: (filter: FindFn) => any;
17
+ export declare const findAllModules: (filter: FilterFn) => any[];
18
+ export declare const CommonUIModule: any;
19
+ export declare const IconsModule: any;
20
+ export declare const ReactRouter: any;
21
+ export {};
@@ -0,0 +1,102 @@
1
+ import Logger from './logger';
2
+ const logger = new Logger('Webpack');
3
+ export let modules = [];
4
+ function initModuleCache() {
5
+ const startTime = performance.now();
6
+ logger.group('Webpack Module Init');
7
+ const id = Math.random();
8
+ let webpackRequire;
9
+ window.webpackChunksteamui.push([
10
+ [id],
11
+ {},
12
+ (r) => {
13
+ webpackRequire = r;
14
+ },
15
+ ]);
16
+ logger.log('Initializing all modules. Errors here likely do not matter, as they are usually just failing module side effects.');
17
+ for (let i of Object.keys(webpackRequire.m)) {
18
+ try {
19
+ const module = webpackRequire(i);
20
+ if (module) {
21
+ modules.push(module);
22
+ }
23
+ }
24
+ catch (e) {
25
+ logger.debug('Ignoring require error for module', i, e);
26
+ }
27
+ }
28
+ logger.groupEnd(`Modules initialized in ${performance.now() - startTime}ms...`);
29
+ }
30
+ initModuleCache();
31
+ export const findModule = (filter) => {
32
+ for (const m of modules) {
33
+ if (m.default && filter(m.default))
34
+ return m.default;
35
+ if (filter(m))
36
+ return m;
37
+ }
38
+ };
39
+ export const findModuleDetailsByExport = (filter, minExports) => {
40
+ for (const m of modules) {
41
+ if (!m)
42
+ continue;
43
+ for (const mod of [m.default, m]) {
44
+ if (typeof mod !== 'object')
45
+ continue;
46
+ if (minExports && Object.keys(mod).length < minExports)
47
+ continue;
48
+ for (let exportName in mod) {
49
+ if (mod?.[exportName]) {
50
+ const filterRes = filter(mod[exportName], exportName);
51
+ if (filterRes) {
52
+ return [mod, mod[exportName], exportName];
53
+ }
54
+ else {
55
+ continue;
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ return [undefined, undefined, undefined];
62
+ };
63
+ export const findModuleByExport = (filter, minExports) => {
64
+ return findModuleDetailsByExport(filter, minExports)?.[0];
65
+ };
66
+ export const findModuleExport = (filter, minExports) => {
67
+ return findModuleDetailsByExport(filter, minExports)?.[1];
68
+ };
69
+ export const findModuleChild = (filter) => {
70
+ for (const m of modules) {
71
+ for (const mod of [m.default, m]) {
72
+ const filterRes = filter(mod);
73
+ if (filterRes) {
74
+ return filterRes;
75
+ }
76
+ else {
77
+ continue;
78
+ }
79
+ }
80
+ }
81
+ };
82
+ export const findAllModules = (filter) => {
83
+ const out = [];
84
+ for (const m of modules) {
85
+ if (m.default && filter(m.default))
86
+ out.push(m.default);
87
+ if (filter(m))
88
+ out.push(m);
89
+ }
90
+ return out;
91
+ };
92
+ export const CommonUIModule = modules.find((m) => {
93
+ if (typeof m !== 'object')
94
+ return false;
95
+ for (let prop in m) {
96
+ if (m[prop]?.contextType?._currentValue && Object.keys(m).length > 60)
97
+ return true;
98
+ }
99
+ return false;
100
+ });
101
+ export const IconsModule = findModuleByExport((e) => e?.toString && /Spinner\)}\),.\.createElement\(\"path\",{d:\"M18 /.test(e.toString()));
102
+ export const ReactRouter = findModuleByExport((e) => e.computeRootMatch);