@decky/ui 3.26.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.
- package/LICENSE +504 -0
- package/README.md +30 -0
- package/dist/class-mapper.d.ts +7 -0
- package/dist/class-mapper.js +26 -0
- package/dist/components/Button.d.ts +5 -0
- package/dist/components/Button.js +2 -0
- package/dist/components/ButtonItem.d.ts +7 -0
- package/dist/components/ButtonItem.js +5 -0
- package/dist/components/Carousel.d.ts +19 -0
- package/dist/components/Carousel.js +2 -0
- package/dist/components/ControlsList.d.ts +7 -0
- package/dist/components/ControlsList.js +2 -0
- package/dist/components/Dialog.d.ts +33 -0
- package/dist/components/Dialog.js +24 -0
- package/dist/components/DialogCheckbox.d.ts +17 -0
- package/dist/components/DialogCheckbox.js +14 -0
- package/dist/components/Dropdown.d.ts +34 -0
- package/dist/components/Dropdown.js +5 -0
- package/dist/components/Field.d.ts +23 -0
- package/dist/components/Field.js +2 -0
- package/dist/components/FocusRing.d.ts +9 -0
- package/dist/components/FocusRing.js +2 -0
- package/dist/components/Focusable.d.ts +12 -0
- package/dist/components/Focusable.js +4 -0
- package/dist/components/FooterLegend.d.ts +66 -0
- package/dist/components/FooterLegend.js +32 -0
- package/dist/components/Item.d.ts +12 -0
- package/dist/components/Item.js +1 -0
- package/dist/components/Marquee.d.ts +14 -0
- package/dist/components/Marquee.js +2 -0
- package/dist/components/Menu.d.ts +29 -0
- package/dist/components/Menu.js +9 -0
- package/dist/components/Modal.d.ts +52 -0
- package/dist/components/Modal.js +29 -0
- package/dist/components/Panel.d.ts +11 -0
- package/dist/components/Panel.js +4 -0
- package/dist/components/ProgressBar.d.ts +21 -0
- package/dist/components/ProgressBar.js +6 -0
- package/dist/components/Scroll.d.ts +7 -0
- package/dist/components/Scroll.js +5 -0
- package/dist/components/SidebarNavigation.d.ts +21 -0
- package/dist/components/SidebarNavigation.js +4 -0
- package/dist/components/SliderField.d.ts +26 -0
- package/dist/components/SliderField.js +2 -0
- package/dist/components/Spinner.d.ts +2 -0
- package/dist/components/Spinner.js +2 -0
- package/dist/components/SteamSpinner.d.ts +2 -0
- package/dist/components/SteamSpinner.js +2 -0
- package/dist/components/Tabs.d.ts +16 -0
- package/dist/components/Tabs.js +48 -0
- package/dist/components/TextField.d.ts +22 -0
- package/dist/components/TextField.js +2 -0
- package/dist/components/Toggle.d.ts +8 -0
- package/dist/components/Toggle.js +2 -0
- package/dist/components/ToggleField.d.ts +9 -0
- package/dist/components/ToggleField.js +2 -0
- package/dist/components/index.d.ts +25 -0
- package/dist/components/index.js +25 -0
- package/dist/custom-components/ColorPickerModal.d.ts +12 -0
- package/dist/custom-components/ColorPickerModal.js +87 -0
- package/dist/custom-components/ReorderableList.d.ts +26 -0
- package/dist/custom-components/ReorderableList.js +84 -0
- package/dist/custom-components/SuspensefulImage.d.ts +7 -0
- package/dist/custom-components/SuspensefulImage.js +27 -0
- package/dist/custom-components/index.d.ts +3 -0
- package/dist/custom-components/index.js +3 -0
- package/dist/custom-hooks/index.d.ts +1 -0
- package/dist/custom-hooks/index.js +1 -0
- package/dist/custom-hooks/useQuickAccessVisible.d.ts +1 -0
- package/dist/custom-hooks/useQuickAccessVisible.js +22 -0
- package/dist/deck-hooks/index.d.ts +1 -0
- package/dist/deck-hooks/index.js +1 -0
- package/dist/deck-hooks/useParams.d.ts +1 -0
- package/dist/deck-hooks/useParams.js +2 -0
- package/dist/globals/SteamClient.d.ts +307 -0
- package/dist/globals/SteamClient.js +1 -0
- package/dist/globals/index.d.ts +2 -0
- package/dist/globals/index.js +2 -0
- package/dist/globals/stores.d.ts +50 -0
- package/dist/globals/stores.js +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +14 -0
- package/dist/logger.d.ts +17 -0
- package/dist/logger.js +46 -0
- package/dist/modules/Router.d.ts +110 -0
- package/dist/modules/Router.js +102 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +1 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.js +23 -0
- package/dist/utils/patcher.d.ts +18 -0
- package/dist/utils/patcher.js +103 -0
- package/dist/utils/react.d.ts +19 -0
- package/dist/utils/react.js +89 -0
- package/dist/utils/static-classes.d.ts +52 -0
- package/dist/utils/static-classes.js +28 -0
- package/dist/webpack.d.ts +21 -0
- package/dist/webpack.js +102 -0
- package/package.json +89 -0
- package/src/class-mapper.ts +34 -0
- package/src/components/Button.ts +8 -0
- package/src/components/ButtonItem.ts +16 -0
- package/src/components/Carousel.ts +25 -0
- package/src/components/ControlsList.ts +14 -0
- package/src/components/Dialog.ts +90 -0
- package/src/components/DialogCheckbox.ts +36 -0
- package/src/components/Dropdown.ts +51 -0
- package/src/components/Field.ts +29 -0
- package/src/components/FocusRing.ts +15 -0
- package/src/components/Focusable.ts +21 -0
- package/src/components/FooterLegend.ts +67 -0
- package/src/components/Item.ts +13 -0
- package/src/components/Marquee.ts +20 -0
- package/src/components/Menu.ts +58 -0
- package/src/components/Modal.ts +119 -0
- package/src/components/Panel.ts +26 -0
- package/src/components/ProgressBar.ts +37 -0
- package/src/components/Scroll.ts +15 -0
- package/src/components/SidebarNavigation.ts +30 -0
- package/src/components/SliderField.ts +33 -0
- package/src/components/Spinner.ts +8 -0
- package/src/components/SteamSpinner.ts +7 -0
- package/src/components/Tabs.tsx +127 -0
- package/src/components/TextField.ts +28 -0
- package/src/components/Toggle.ts +14 -0
- package/src/components/ToggleField.ts +15 -0
- package/src/components/index.ts +25 -0
- package/src/custom-components/ColorPickerModal.tsx +132 -0
- package/src/custom-components/ReorderableList.tsx +183 -0
- package/src/custom-components/SuspensefulImage.tsx +44 -0
- package/src/custom-components/index.ts +3 -0
- package/src/custom-hooks/index.ts +1 -0
- package/src/custom-hooks/useQuickAccessVisible.ts +63 -0
- package/src/deck-hooks/index.ts +1 -0
- package/src/deck-hooks/useParams.ts +15 -0
- package/src/globals/SteamClient.ts +321 -0
- package/src/globals/index.ts +2 -0
- package/src/globals/stores.ts +50 -0
- package/src/index.ts +20 -0
- package/src/logger.ts +77 -0
- package/src/modules/Router.ts +174 -0
- package/src/modules/index.ts +1 -0
- package/src/utils/index.ts +43 -0
- package/src/utils/patcher.ts +160 -0
- package/src/utils/react.ts +141 -0
- package/src/utils/static-classes.ts +1104 -0
- package/src/webpack.ts +136 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CommonUIModule } from '../webpack';
|
|
2
|
+
const CommonDialogDivs = Object.values(CommonUIModule).filter((m) => typeof m === 'object' && m?.render?.toString().includes('createElement("div",{...') ||
|
|
3
|
+
m?.render?.toString().includes('createElement("div",Object.assign({},'));
|
|
4
|
+
const MappedDialogDivs = new Map(Object.values(CommonDialogDivs).map((m) => {
|
|
5
|
+
try {
|
|
6
|
+
const renderedDiv = m.render({});
|
|
7
|
+
return [renderedDiv.props.className.split(' ')[0], m];
|
|
8
|
+
}
|
|
9
|
+
catch (e) {
|
|
10
|
+
console.error("[DFL:Dialog]: failed to render common dialog component", e);
|
|
11
|
+
return [null, null];
|
|
12
|
+
}
|
|
13
|
+
}));
|
|
14
|
+
export const DialogHeader = MappedDialogDivs.get('DialogHeader');
|
|
15
|
+
export const DialogSubHeader = MappedDialogDivs.get('DialogSubHeader');
|
|
16
|
+
export const DialogFooter = MappedDialogDivs.get('DialogFooter');
|
|
17
|
+
export const DialogLabel = MappedDialogDivs.get('DialogLabel');
|
|
18
|
+
export const DialogBodyText = MappedDialogDivs.get('DialogBodyText');
|
|
19
|
+
export const DialogBody = MappedDialogDivs.get('DialogBody');
|
|
20
|
+
export const DialogControlsSection = MappedDialogDivs.get('DialogControlsSection');
|
|
21
|
+
export const DialogControlsSectionHeader = MappedDialogDivs.get('DialogControlsSectionHeader');
|
|
22
|
+
export const DialogButtonPrimary = Object.values(CommonUIModule).find((mod) => mod?.render?.toString()?.includes('"DialogButton","_DialogLayout","Primary"'));
|
|
23
|
+
export const DialogButtonSecondary = Object.values(CommonUIModule).find((mod) => mod?.render?.toString()?.includes('"DialogButton","_DialogLayout","Secondary"'));
|
|
24
|
+
export const DialogButton = DialogButtonSecondary;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
import { DialogCommonProps } from './Dialog';
|
|
3
|
+
import { FooterLegendProps } from './FooterLegend';
|
|
4
|
+
export interface DialogCheckboxProps extends DialogCommonProps, FooterLegendProps {
|
|
5
|
+
onChange?(checked: boolean): void;
|
|
6
|
+
label?: ReactNode;
|
|
7
|
+
description?: ReactNode;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
tooltip?: string;
|
|
10
|
+
color?: string;
|
|
11
|
+
highlightColor?: string;
|
|
12
|
+
bottomSeparator?: 'standard' | 'thick' | 'none';
|
|
13
|
+
controlled?: boolean;
|
|
14
|
+
checked?: boolean;
|
|
15
|
+
onClick?(evt: Event): void;
|
|
16
|
+
}
|
|
17
|
+
export declare const DialogCheckbox: FC<DialogCheckboxProps>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { findModule } from '../webpack';
|
|
2
|
+
export const DialogCheckbox = Object.values(findModule((m) => {
|
|
3
|
+
if (typeof m !== 'object')
|
|
4
|
+
return false;
|
|
5
|
+
for (const prop in m) {
|
|
6
|
+
if (m[prop]?.prototype?.GetPanelElementProps)
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
return false;
|
|
10
|
+
})).find((m) => m.contextType &&
|
|
11
|
+
m.prototype?.render.toString().includes('fallback:') &&
|
|
12
|
+
m?.prototype?.SetChecked &&
|
|
13
|
+
m?.prototype?.Toggle &&
|
|
14
|
+
m?.prototype?.GetPanelElementProps);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ReactNode, FC } from 'react';
|
|
2
|
+
import { ItemProps } from './Item';
|
|
3
|
+
export interface SingleDropdownOption {
|
|
4
|
+
data: any;
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
options?: never;
|
|
7
|
+
}
|
|
8
|
+
export interface MultiDropdownOption {
|
|
9
|
+
label: ReactNode;
|
|
10
|
+
options: DropdownOption[];
|
|
11
|
+
data?: never;
|
|
12
|
+
}
|
|
13
|
+
export type DropdownOption = SingleDropdownOption | MultiDropdownOption;
|
|
14
|
+
export interface DropdownMenuPositionOptions {
|
|
15
|
+
[_: string]: unknown;
|
|
16
|
+
bMatchWidth?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface DropdownProps {
|
|
19
|
+
rgOptions: DropdownOption[];
|
|
20
|
+
selectedOption: any;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
onMenuWillOpen?(showMenu: () => void): void;
|
|
23
|
+
onMenuOpened?(): void;
|
|
24
|
+
onChange?(data: SingleDropdownOption): void;
|
|
25
|
+
contextMenuPositionOptions?: DropdownMenuPositionOptions;
|
|
26
|
+
menuLabel?: string;
|
|
27
|
+
strDefaultLabel?: string;
|
|
28
|
+
renderButtonValue?(element: ReactNode): ReactNode;
|
|
29
|
+
focusable?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare const Dropdown: FC<DropdownProps>;
|
|
32
|
+
export interface DropdownItemProps extends DropdownProps, ItemProps {
|
|
33
|
+
}
|
|
34
|
+
export declare const DropdownItem: FC<DropdownItemProps>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CommonUIModule } from '../webpack';
|
|
2
|
+
import { createPropListRegex } from '../utils';
|
|
3
|
+
export const Dropdown = Object.values(CommonUIModule).find((mod) => mod?.prototype?.SetSelectedOption && mod?.prototype?.BuildMenu);
|
|
4
|
+
const dropdownItemRegex = createPropListRegex(["dropDownControlRef", "description"], false);
|
|
5
|
+
export const DropdownItem = Object.values(CommonUIModule).find((mod) => mod?.toString && dropdownItemRegex.test(mod.toString()));
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FC, ReactNode, RefAttributes } from 'react';
|
|
2
|
+
import { FooterLegendProps } from './FooterLegend';
|
|
3
|
+
export interface FieldProps extends FooterLegendProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
label?: ReactNode;
|
|
6
|
+
bottomSeparator?: 'standard' | 'thick' | 'none';
|
|
7
|
+
description?: ReactNode;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
icon?: ReactNode;
|
|
10
|
+
inlineWrap?: 'keep-inline' | 'shift-children-below';
|
|
11
|
+
childrenLayout?: 'below' | 'inline';
|
|
12
|
+
childrenContainerWidth?: 'min' | 'max' | 'fixed';
|
|
13
|
+
spacingBetweenLabelAndChild?: 'none';
|
|
14
|
+
padding?: 'none' | 'standard' | 'compact';
|
|
15
|
+
className?: string;
|
|
16
|
+
highlightOnFocus?: boolean;
|
|
17
|
+
indentLevel?: number;
|
|
18
|
+
verticalAlignment?: 'center' | 'none';
|
|
19
|
+
focusable?: boolean;
|
|
20
|
+
onActivate?: (e: CustomEvent | MouseEvent) => void;
|
|
21
|
+
onClick?: (e: CustomEvent | MouseEvent) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare const Field: FC<FieldProps & RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ElementType, FC, ReactNode } from 'react';
|
|
2
|
+
export interface FocusRingProps {
|
|
3
|
+
className?: string;
|
|
4
|
+
rootClassName?: string;
|
|
5
|
+
render?: ElementType;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
NavigationManager?: any;
|
|
8
|
+
}
|
|
9
|
+
export declare const FocusRing: FC<FocusRingProps>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode, RefAttributes, FC } from 'react';
|
|
2
|
+
import { FooterLegendProps } from './FooterLegend';
|
|
3
|
+
export interface FocusableProps extends HTMLAttributes<HTMLDivElement>, FooterLegendProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
'flow-children'?: string;
|
|
6
|
+
focusClassName?: string;
|
|
7
|
+
focusWithinClassName?: string;
|
|
8
|
+
noFocusRing?: boolean;
|
|
9
|
+
onActivate?: (e: CustomEvent) => void;
|
|
10
|
+
onCancel?: (e: CustomEvent) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const Focusable: FC<FocusableProps & RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { findModuleExport } from '../webpack';
|
|
2
|
+
import { createPropListRegex } from '../utils';
|
|
3
|
+
const focusableRegex = createPropListRegex(["flow-children", "onActivate", "onCancel", "focusClassName", "focusWithinClassName"]);
|
|
4
|
+
export const Focusable = findModuleExport((e) => e?.render?.toString && focusableRegex.test(e.render.toString()));
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export declare enum GamepadButton {
|
|
3
|
+
INVALID = 0,
|
|
4
|
+
OK = 1,
|
|
5
|
+
CANCEL = 2,
|
|
6
|
+
SECONDARY = 3,
|
|
7
|
+
OPTIONS = 4,
|
|
8
|
+
BUMPER_LEFT = 5,
|
|
9
|
+
BUMPER_RIGHT = 6,
|
|
10
|
+
TRIGGER_LEFT = 7,
|
|
11
|
+
TRIGGER_RIGHT = 8,
|
|
12
|
+
DIR_UP = 9,
|
|
13
|
+
DIR_DOWN = 10,
|
|
14
|
+
DIR_LEFT = 11,
|
|
15
|
+
DIR_RIGHT = 12,
|
|
16
|
+
SELECT = 13,
|
|
17
|
+
START = 14,
|
|
18
|
+
LSTICK_CLICK = 15,
|
|
19
|
+
RSTICK_CLICK = 16,
|
|
20
|
+
LSTICK_TOUCH = 17,
|
|
21
|
+
RSTICK_TOUCH = 18,
|
|
22
|
+
LPAD_TOUCH = 19,
|
|
23
|
+
LPAD_CLICK = 20,
|
|
24
|
+
RPAD_TOUCH = 21,
|
|
25
|
+
RPAD_CLICK = 22,
|
|
26
|
+
REAR_LEFT_UPPER = 23,
|
|
27
|
+
REAR_LEFT_LOWER = 24,
|
|
28
|
+
REAR_RIGHT_UPPER = 25,
|
|
29
|
+
REAR_RIGHT_LOWER = 26,
|
|
30
|
+
STEAM_GUIDE = 27,
|
|
31
|
+
STEAM_QUICK_MENU = 28
|
|
32
|
+
}
|
|
33
|
+
export declare enum NavEntryPositionPreferences {
|
|
34
|
+
FIRST,
|
|
35
|
+
LAST,
|
|
36
|
+
MAINTAIN_X,
|
|
37
|
+
MAINTAIN_Y,
|
|
38
|
+
PREFERRED_CHILD
|
|
39
|
+
}
|
|
40
|
+
export interface GamepadEventDetail {
|
|
41
|
+
button: number;
|
|
42
|
+
is_repeat?: boolean;
|
|
43
|
+
source: number;
|
|
44
|
+
}
|
|
45
|
+
export declare type ActionDescriptionMap = {
|
|
46
|
+
[key in GamepadButton]?: ReactNode;
|
|
47
|
+
};
|
|
48
|
+
export declare type GamepadEvent = CustomEvent<GamepadEventDetail>;
|
|
49
|
+
export interface FooterLegendProps {
|
|
50
|
+
actionDescriptionMap?: ActionDescriptionMap;
|
|
51
|
+
onOKActionDescription?: ReactNode;
|
|
52
|
+
onCancelActionDescription?: ReactNode;
|
|
53
|
+
onSecondaryActionDescription?: ReactNode;
|
|
54
|
+
onOptionsActionDescription?: ReactNode;
|
|
55
|
+
onMenuActionDescription?: ReactNode;
|
|
56
|
+
onButtonDown?: (evt: GamepadEvent) => void;
|
|
57
|
+
onButtonUp?: (evt: GamepadEvent) => void;
|
|
58
|
+
onOKButton?: (evt: GamepadEvent) => void;
|
|
59
|
+
onCancelButton?: (evt: GamepadEvent) => void;
|
|
60
|
+
onSecondaryButton?: (evt: GamepadEvent) => void;
|
|
61
|
+
onOptionsButton?: (evt: GamepadEvent) => void;
|
|
62
|
+
onGamepadDirection?: (evt: GamepadEvent) => void;
|
|
63
|
+
onGamepadFocus?: (evt: GamepadEvent) => void;
|
|
64
|
+
onGamepadBlur?: (evt: GamepadEvent) => void;
|
|
65
|
+
onMenuButton?: (evt: GamepadEvent) => void;
|
|
66
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export var GamepadButton;
|
|
2
|
+
(function (GamepadButton) {
|
|
3
|
+
GamepadButton[GamepadButton["INVALID"] = 0] = "INVALID";
|
|
4
|
+
GamepadButton[GamepadButton["OK"] = 1] = "OK";
|
|
5
|
+
GamepadButton[GamepadButton["CANCEL"] = 2] = "CANCEL";
|
|
6
|
+
GamepadButton[GamepadButton["SECONDARY"] = 3] = "SECONDARY";
|
|
7
|
+
GamepadButton[GamepadButton["OPTIONS"] = 4] = "OPTIONS";
|
|
8
|
+
GamepadButton[GamepadButton["BUMPER_LEFT"] = 5] = "BUMPER_LEFT";
|
|
9
|
+
GamepadButton[GamepadButton["BUMPER_RIGHT"] = 6] = "BUMPER_RIGHT";
|
|
10
|
+
GamepadButton[GamepadButton["TRIGGER_LEFT"] = 7] = "TRIGGER_LEFT";
|
|
11
|
+
GamepadButton[GamepadButton["TRIGGER_RIGHT"] = 8] = "TRIGGER_RIGHT";
|
|
12
|
+
GamepadButton[GamepadButton["DIR_UP"] = 9] = "DIR_UP";
|
|
13
|
+
GamepadButton[GamepadButton["DIR_DOWN"] = 10] = "DIR_DOWN";
|
|
14
|
+
GamepadButton[GamepadButton["DIR_LEFT"] = 11] = "DIR_LEFT";
|
|
15
|
+
GamepadButton[GamepadButton["DIR_RIGHT"] = 12] = "DIR_RIGHT";
|
|
16
|
+
GamepadButton[GamepadButton["SELECT"] = 13] = "SELECT";
|
|
17
|
+
GamepadButton[GamepadButton["START"] = 14] = "START";
|
|
18
|
+
GamepadButton[GamepadButton["LSTICK_CLICK"] = 15] = "LSTICK_CLICK";
|
|
19
|
+
GamepadButton[GamepadButton["RSTICK_CLICK"] = 16] = "RSTICK_CLICK";
|
|
20
|
+
GamepadButton[GamepadButton["LSTICK_TOUCH"] = 17] = "LSTICK_TOUCH";
|
|
21
|
+
GamepadButton[GamepadButton["RSTICK_TOUCH"] = 18] = "RSTICK_TOUCH";
|
|
22
|
+
GamepadButton[GamepadButton["LPAD_TOUCH"] = 19] = "LPAD_TOUCH";
|
|
23
|
+
GamepadButton[GamepadButton["LPAD_CLICK"] = 20] = "LPAD_CLICK";
|
|
24
|
+
GamepadButton[GamepadButton["RPAD_TOUCH"] = 21] = "RPAD_TOUCH";
|
|
25
|
+
GamepadButton[GamepadButton["RPAD_CLICK"] = 22] = "RPAD_CLICK";
|
|
26
|
+
GamepadButton[GamepadButton["REAR_LEFT_UPPER"] = 23] = "REAR_LEFT_UPPER";
|
|
27
|
+
GamepadButton[GamepadButton["REAR_LEFT_LOWER"] = 24] = "REAR_LEFT_LOWER";
|
|
28
|
+
GamepadButton[GamepadButton["REAR_RIGHT_UPPER"] = 25] = "REAR_RIGHT_UPPER";
|
|
29
|
+
GamepadButton[GamepadButton["REAR_RIGHT_LOWER"] = 26] = "REAR_RIGHT_LOWER";
|
|
30
|
+
GamepadButton[GamepadButton["STEAM_GUIDE"] = 27] = "STEAM_GUIDE";
|
|
31
|
+
GamepadButton[GamepadButton["STEAM_QUICK_MENU"] = 28] = "STEAM_QUICK_MENU";
|
|
32
|
+
})(GamepadButton || (GamepadButton = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface ItemProps {
|
|
3
|
+
label?: ReactNode;
|
|
4
|
+
description?: ReactNode;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
layout?: 'below' | 'inline';
|
|
7
|
+
icon?: ReactNode;
|
|
8
|
+
bottomSeparator?: 'standard' | 'thick' | 'none';
|
|
9
|
+
indentLevel?: number;
|
|
10
|
+
tooltip?: string;
|
|
11
|
+
highlightOnFocus?: boolean;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CSSProperties, FC } from 'react';
|
|
2
|
+
export interface MarqueeProps {
|
|
3
|
+
play?: boolean;
|
|
4
|
+
direction?: 'left' | 'right';
|
|
5
|
+
speed?: number;
|
|
6
|
+
delay?: number;
|
|
7
|
+
fadeLength?: number;
|
|
8
|
+
center?: boolean;
|
|
9
|
+
resetOnPause?: boolean;
|
|
10
|
+
style?: CSSProperties;
|
|
11
|
+
className?: string;
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export declare const Marquee: FC<MarqueeProps>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
import { FooterLegendProps } from './FooterLegend';
|
|
3
|
+
export declare const showContextMenu: (children: ReactNode, parent?: EventTarget) => void;
|
|
4
|
+
export interface MenuProps extends FooterLegendProps {
|
|
5
|
+
label: string;
|
|
6
|
+
onCancel?(): void;
|
|
7
|
+
cancelText?: string;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare const Menu: FC<MenuProps>;
|
|
11
|
+
export interface MenuGroupProps {
|
|
12
|
+
label: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare const MenuGroup: FC<MenuGroupProps>;
|
|
17
|
+
export interface MenuItemProps extends FooterLegendProps {
|
|
18
|
+
bInteractableItem?: boolean;
|
|
19
|
+
onClick?(evt: Event): void;
|
|
20
|
+
onSelected?(evt: Event): void;
|
|
21
|
+
onMouseEnter?(evt: MouseEvent): void;
|
|
22
|
+
onMoveRight?(): void;
|
|
23
|
+
selected?: boolean;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
bPlayAudio?: boolean;
|
|
26
|
+
tone?: 'positive' | 'emphasis' | 'destructive';
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
export declare const MenuItem: FC<MenuItemProps>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { fakeRenderComponent } from '../utils';
|
|
2
|
+
import { findModuleExport } from '../webpack';
|
|
3
|
+
export const showContextMenu = findModuleExport((e) => typeof e === 'function' && e.toString().includes('GetContextMenuManagerFromWindow(')
|
|
4
|
+
&& e.toString().includes('.CreateContextMenuInstance('));
|
|
5
|
+
export const Menu = findModuleExport((e) => e?.prototype?.HideIfSubmenu && e?.prototype?.HideMenu);
|
|
6
|
+
export const MenuGroup = findModuleExport((e) => (e?.toString()?.includes?.('bInGamepadUI:') &&
|
|
7
|
+
fakeRenderComponent(() => e({ overview: { appid: 7 } }), { useContext: () => ({ IN_GAMEPADUI: true }) })?.type?.prototype?.RenderSubMenu) ||
|
|
8
|
+
(e?.prototype?.RenderSubMenu && e?.prototype?.ShowSubMenu));
|
|
9
|
+
export const MenuItem = findModuleExport((e) => e?.render?.toString()?.includes('bPlayAudio:') || (e?.prototype?.OnOKButton && e?.prototype?.OnMouseEnter));
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
export interface ShowModalProps {
|
|
3
|
+
browserContext?: unknown;
|
|
4
|
+
bForcePopOut?: boolean;
|
|
5
|
+
bHideActionIcons?: boolean;
|
|
6
|
+
bHideMainWindowForPopouts?: boolean;
|
|
7
|
+
bNeverPopOut?: boolean;
|
|
8
|
+
fnOnClose?: () => void;
|
|
9
|
+
popupHeight?: number;
|
|
10
|
+
popupWidth?: number;
|
|
11
|
+
promiseRenderComplete?: Promise<void>;
|
|
12
|
+
strTitle?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ShowModalResult {
|
|
15
|
+
Close: () => void;
|
|
16
|
+
Update: (modal: ReactNode) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const showModal: (modal: ReactNode, parent?: EventTarget, props?: ShowModalProps) => ShowModalResult;
|
|
19
|
+
export interface ModalRootProps {
|
|
20
|
+
children?: ReactNode;
|
|
21
|
+
onCancel?(): void;
|
|
22
|
+
closeModal?(): void;
|
|
23
|
+
onOK?(): void;
|
|
24
|
+
onEscKeypress?(): void;
|
|
25
|
+
className?: string;
|
|
26
|
+
modalClassName?: string;
|
|
27
|
+
bAllowFullSize?: boolean;
|
|
28
|
+
bDestructiveWarning?: boolean;
|
|
29
|
+
bDisableBackgroundDismiss?: boolean;
|
|
30
|
+
bHideCloseIcon?: boolean;
|
|
31
|
+
bOKDisabled?: boolean;
|
|
32
|
+
bCancelDisabled?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface ConfirmModalProps extends ModalRootProps {
|
|
35
|
+
onMiddleButton?(): void;
|
|
36
|
+
strTitle?: ReactNode;
|
|
37
|
+
strDescription?: ReactNode;
|
|
38
|
+
strOKButtonText?: ReactNode;
|
|
39
|
+
strCancelButtonText?: ReactNode;
|
|
40
|
+
strMiddleButtonText?: ReactNode;
|
|
41
|
+
bAlertDialog?: boolean;
|
|
42
|
+
bMiddleDisabled?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare const ConfirmModal: FC<ConfirmModalProps>;
|
|
45
|
+
export declare const ModalRoot: FC<ModalRootProps>;
|
|
46
|
+
interface SimpleModalProps {
|
|
47
|
+
active?: boolean;
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
}
|
|
50
|
+
export declare const SimpleModal: FC<SimpleModalProps>;
|
|
51
|
+
export declare const ModalPosition: FC<SimpleModalProps>;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { findSP } from '../utils';
|
|
2
|
+
import { findModule, findModuleByExport, findModuleExport } from '../webpack';
|
|
3
|
+
const showModalRaw = findModuleExport((e) => typeof e === 'function' && e.toString().includes('props.bDisableBackgroundDismiss') && !e?.prototype?.Cancel);
|
|
4
|
+
export const showModal = (modal, parent, props = {
|
|
5
|
+
strTitle: 'Decky Dialog',
|
|
6
|
+
bHideMainWindowForPopouts: false,
|
|
7
|
+
}) => {
|
|
8
|
+
return showModalRaw(modal, parent || findSP(), props.strTitle, props, undefined, {
|
|
9
|
+
bHideActions: props.bHideActionIcons,
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
export const ConfirmModal = findModuleExport((e) => !e?.prototype?.OK && e?.prototype?.Cancel && e?.prototype?.render);
|
|
13
|
+
export const ModalRoot = Object.values(findModule((m) => {
|
|
14
|
+
if (typeof m !== 'object')
|
|
15
|
+
return false;
|
|
16
|
+
for (let prop in m) {
|
|
17
|
+
if (m[prop]?.m_mapModalManager && Object.values(m)?.find((x) => x?.type)) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
}) || {})?.find((x) => x?.type?.toString()?.includes('((function(){'));
|
|
23
|
+
const ModalModule = findModuleByExport((e) => e?.toString().includes('.ModalPosition,fallback:'), 5);
|
|
24
|
+
const ModalModuleProps = ModalModule ? Object.values(ModalModule) : [];
|
|
25
|
+
export const SimpleModal = ModalModuleProps.find((prop) => {
|
|
26
|
+
const string = prop?.toString();
|
|
27
|
+
return string?.includes('.ShowPortalModal()') && string?.includes('.OnElementReadyCallbacks.Register(');
|
|
28
|
+
});
|
|
29
|
+
export const ModalPosition = ModalModuleProps.find((prop) => prop?.toString().includes('.ModalPosition,fallback:'));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
export interface PanelSectionProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
spinner?: boolean;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare const PanelSection: FC<PanelSectionProps>;
|
|
8
|
+
export interface PanelSectionRowProps {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export declare const PanelSectionRow: FC<PanelSectionRowProps>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { findModuleDetailsByExport } from '../webpack';
|
|
2
|
+
const [mod, panelSection] = findModuleDetailsByExport((e) => e.toString()?.includes('.PanelSection'));
|
|
3
|
+
export const PanelSection = panelSection;
|
|
4
|
+
export const PanelSectionRow = Object.values(mod).filter((exp) => !exp?.toString()?.includes('.PanelSection'))[0];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactNode, FC } from 'react';
|
|
2
|
+
import { ItemProps } from './Item';
|
|
3
|
+
export interface ProgressBarItemProps extends ItemProps {
|
|
4
|
+
indeterminate?: boolean;
|
|
5
|
+
nTransitionSec?: number;
|
|
6
|
+
nProgress?: number;
|
|
7
|
+
focusable?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ProgressBarProps {
|
|
10
|
+
indeterminate?: boolean;
|
|
11
|
+
nTransitionSec?: number;
|
|
12
|
+
nProgress?: number;
|
|
13
|
+
focusable?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface ProgressBarWithInfoProps extends ProgressBarItemProps {
|
|
16
|
+
sTimeRemaining?: ReactNode;
|
|
17
|
+
sOperationText?: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare const ProgressBar: FC<ProgressBarProps>;
|
|
20
|
+
export declare const ProgressBarWithInfo: FC<ProgressBarWithInfoProps>;
|
|
21
|
+
export declare const ProgressBarItem: FC<ProgressBarItemProps>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { findModuleExport } from '../webpack';
|
|
2
|
+
import { createPropListRegex } from '../utils';
|
|
3
|
+
export const ProgressBar = findModuleExport((e) => e?.toString()?.includes('.ProgressBar,"standard"=='));
|
|
4
|
+
export const ProgressBarWithInfo = findModuleExport((e) => e?.toString()?.includes('.ProgressBarFieldStatus},'));
|
|
5
|
+
const progressBarItemRegex = createPropListRegex(["indeterminate", "nTransitionSec", "nProgress"]);
|
|
6
|
+
export const ProgressBarItem = findModuleExport((e) => e?.toString && progressBarItemRegex.test(e.toString()));
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { findModuleByExport, findModuleExport } from '../webpack';
|
|
2
|
+
const ScrollingModule = findModuleByExport((e) => e?.render?.toString?.().includes('{case"x":'));
|
|
3
|
+
const ScrollingModuleProps = ScrollingModule ? Object.values(ScrollingModule) : [];
|
|
4
|
+
export const ScrollPanel = ScrollingModuleProps.find((prop) => prop?.render?.toString?.().includes('{case"x":'));
|
|
5
|
+
export const ScrollPanelGroup = findModuleExport((e) => e?.render?.toString().includes('.FocusVisibleChild()),[])'));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactNode, FC } from 'react';
|
|
2
|
+
export interface SidebarNavigationPage {
|
|
3
|
+
title: ReactNode;
|
|
4
|
+
content: ReactNode;
|
|
5
|
+
icon?: ReactNode;
|
|
6
|
+
visible?: boolean;
|
|
7
|
+
hideTitle?: boolean;
|
|
8
|
+
identifier?: string;
|
|
9
|
+
route?: string;
|
|
10
|
+
link?: string;
|
|
11
|
+
padding?: 'none' | 'compact';
|
|
12
|
+
}
|
|
13
|
+
export interface SidebarNavigationProps {
|
|
14
|
+
title?: string;
|
|
15
|
+
pages: (SidebarNavigationPage | 'separator')[];
|
|
16
|
+
showTitle?: boolean;
|
|
17
|
+
disableRouteReporting?: boolean;
|
|
18
|
+
page?: string;
|
|
19
|
+
onPageRequested?: (page: string) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare const SidebarNavigation: FC<SidebarNavigationProps>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { findModuleExport } from '../webpack';
|
|
2
|
+
import { createPropListRegex } from '../utils';
|
|
3
|
+
const sidebarNavigationRegex = createPropListRegex(["pages", "fnSetNavigateToPage", "disableRouteReporting"]);
|
|
4
|
+
export const SidebarNavigation = findModuleExport((e) => e?.toString && sidebarNavigationRegex.test(e.toString()));
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { ItemProps } from './Item';
|
|
3
|
+
export interface NotchLabel {
|
|
4
|
+
notchIndex: number;
|
|
5
|
+
label: string;
|
|
6
|
+
value?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface SliderFieldProps extends ItemProps {
|
|
9
|
+
value: number;
|
|
10
|
+
min?: number;
|
|
11
|
+
max?: number;
|
|
12
|
+
step?: number;
|
|
13
|
+
notchCount?: number;
|
|
14
|
+
notchLabels?: NotchLabel[];
|
|
15
|
+
notchTicksVisible?: boolean;
|
|
16
|
+
showValue?: boolean;
|
|
17
|
+
resetValue?: number;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
editableValue?: boolean;
|
|
20
|
+
validValues?: 'steps' | 'range' | ((value: number) => boolean);
|
|
21
|
+
valueSuffix?: string;
|
|
22
|
+
minimumDpadGranularity?: number;
|
|
23
|
+
onChange?(value: number): void;
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const SliderField: FC<SliderFieldProps>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
import { FooterLegendProps } from './FooterLegend';
|
|
3
|
+
export interface Tab {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
renderTabAddon?: () => ReactNode;
|
|
7
|
+
content: ReactNode;
|
|
8
|
+
footer?: FooterLegendProps;
|
|
9
|
+
}
|
|
10
|
+
export interface TabsProps {
|
|
11
|
+
tabs: Tab[];
|
|
12
|
+
activeTab: string;
|
|
13
|
+
onShowTab: (tab: string) => void;
|
|
14
|
+
autoFocusContents?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const Tabs: FC<TabsProps>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createElement, useEffect, useState } from 'react';
|
|
2
|
+
import { fakeRenderComponent, findInReactTree, sleep } from '../utils';
|
|
3
|
+
import { findModuleByExport } from '../webpack';
|
|
4
|
+
import { SteamSpinner } from './SteamSpinner';
|
|
5
|
+
let tabsComponent;
|
|
6
|
+
const getTabs = async () => {
|
|
7
|
+
if (tabsComponent)
|
|
8
|
+
return tabsComponent;
|
|
9
|
+
while (!window?.DeckyPluginLoader?.routerHook?.routes) {
|
|
10
|
+
console.debug('[DFL:Tabs]: Waiting for Decky router...');
|
|
11
|
+
await sleep(500);
|
|
12
|
+
}
|
|
13
|
+
return (tabsComponent = fakeRenderComponent(() => {
|
|
14
|
+
return findInReactTree(findInReactTree(window.DeckyPluginLoader.routerHook.routes
|
|
15
|
+
.find((x) => x.props.path == '/library/app/:appid/achievements')
|
|
16
|
+
.props.children.type(), (x) => x?.props?.scrollTabsTop).type({ appid: 1 }), (x) => x?.props?.tabs).type;
|
|
17
|
+
}, {
|
|
18
|
+
useRef: () => ({ current: { reaction: { track: () => { } } } }),
|
|
19
|
+
useContext: () => ({ match: { params: { appid: 1 } } }),
|
|
20
|
+
useMemo: () => ({ data: {} }),
|
|
21
|
+
}));
|
|
22
|
+
};
|
|
23
|
+
let oldTabs;
|
|
24
|
+
try {
|
|
25
|
+
const oldTabsModule = findModuleByExport((e) => e.Unbleed);
|
|
26
|
+
if (oldTabsModule)
|
|
27
|
+
oldTabs = Object.values(oldTabsModule).find((x) => x?.type?.toString()?.includes('((function(){'));
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
console.error('Error finding oldTabs:', e);
|
|
31
|
+
}
|
|
32
|
+
export const Tabs = (oldTabs ||
|
|
33
|
+
((props) => {
|
|
34
|
+
const found = tabsComponent;
|
|
35
|
+
const [tc, setTC] = useState(found);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (found)
|
|
38
|
+
return;
|
|
39
|
+
(async () => {
|
|
40
|
+
console.debug('[DFL:Tabs]: Finding component...');
|
|
41
|
+
const t = await getTabs();
|
|
42
|
+
console.debug('[DFL:Tabs]: Found!');
|
|
43
|
+
setTC(t);
|
|
44
|
+
})();
|
|
45
|
+
}, []);
|
|
46
|
+
console.log('tc', tc);
|
|
47
|
+
return tc ? createElement(tc, props) : window.SP_REACT.createElement(SteamSpinner, null);
|
|
48
|
+
}));
|