@decky/ui 4.9.0 → 4.9.1

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.
@@ -1,5 +1,6 @@
1
1
  import { ReactNode, FC } from 'react';
2
2
  import { ItemProps } from './Item';
3
+ import type { ContextMenuPositionOptions } from './Menu';
3
4
  export interface SingleDropdownOption {
4
5
  data: any;
5
6
  label: ReactNode;
@@ -11,10 +12,6 @@ export interface MultiDropdownOption {
11
12
  data?: never;
12
13
  }
13
14
  export type DropdownOption = SingleDropdownOption | MultiDropdownOption;
14
- export interface DropdownMenuPositionOptions {
15
- [_: string]: unknown;
16
- bMatchWidth?: boolean;
17
- }
18
15
  export interface DropdownProps {
19
16
  rgOptions: DropdownOption[];
20
17
  selectedOption: any;
@@ -22,7 +19,7 @@ export interface DropdownProps {
22
19
  onMenuWillOpen?(showMenu: () => void): void;
23
20
  onMenuOpened?(): void;
24
21
  onChange?(data: SingleDropdownOption): void;
25
- contextMenuPositionOptions?: DropdownMenuPositionOptions;
22
+ contextMenuPositionOptions?: ContextMenuPositionOptions;
26
23
  menuLabel?: string;
27
24
  strDefaultLabel?: string;
28
25
  renderButtonValue?(element: ReactNode): ReactNode;
@@ -1,6 +1,45 @@
1
1
  import { FC, ReactNode } from 'react';
2
2
  import { FooterLegendProps } from './FooterLegend';
3
- export declare const showContextMenu: (children: ReactNode, parent?: EventTarget) => void;
3
+ interface PopupCreationOptions {
4
+ bCreateHidden?: boolean;
5
+ bModal?: boolean;
6
+ title?: string;
7
+ }
8
+ interface MonitorOptions {
9
+ targetMonitor: {
10
+ flMonitorScale: number;
11
+ nScreenLeft: number;
12
+ nScreenTop: number;
13
+ nScreenWidth: number;
14
+ nScreenHeight: number;
15
+ };
16
+ flGamepadScale: number;
17
+ }
18
+ export interface ContextMenuPositionOptions extends PopupCreationOptions, Partial<MonitorOptions> {
19
+ bAlwaysOnTop?: boolean;
20
+ bDisableMouseOverlay?: boolean;
21
+ bDisablePopTop?: boolean;
22
+ bFitToWindow?: boolean;
23
+ bForcePopup?: boolean;
24
+ bGrowToElementWidth?: boolean;
25
+ bMatchHeight?: boolean;
26
+ bMatchWidth?: boolean;
27
+ bNoFocusWhenShown?: boolean;
28
+ bRetainOnHide?: boolean;
29
+ bScreenCoordinates?: boolean;
30
+ bOverlapHorizontal?: boolean;
31
+ bOverlapVertical?: boolean;
32
+ bPreferPopLeft?: boolean;
33
+ bPreferPopTop?: boolean;
34
+ bShiftToFitWindow?: boolean;
35
+ bStandalone?: boolean;
36
+ strClassName?: string;
37
+ }
38
+ interface ContextMenuInstance {
39
+ Hide(): void;
40
+ Show(): void;
41
+ }
42
+ export declare const showContextMenu: (children: ReactNode, parent?: EventTarget, options?: ContextMenuPositionOptions) => ContextMenuInstance;
4
43
  export interface MenuProps extends FooterLegendProps {
5
44
  label: string;
6
45
  onCancel?(): void;
@@ -28,3 +67,4 @@ export interface MenuItemProps extends FooterLegendProps {
28
67
  }
29
68
  export declare const MenuItem: FC<MenuItemProps>;
30
69
  export declare const MenuSeparator: FC;
70
+ export {};
@@ -1,6 +1,7 @@
1
1
  import { findModuleByExport, findModuleExport } from '../webpack';
2
- export const showContextMenu = findModuleExport((e) => typeof e === 'function' && e.toString().includes('GetContextMenuManagerFromWindow(')
3
- && e.toString().includes('.CreateContextMenuInstance('));
2
+ export const showContextMenu = findModuleExport((e) => typeof e === 'function' &&
3
+ e.toString().includes('GetContextMenuManagerFromWindow(') &&
4
+ e.toString().includes('.CreateContextMenuInstance('));
4
5
  export const Menu = findModuleExport((e) => e?.prototype?.HideIfSubmenu && e?.prototype?.HideMenu);
5
6
  const MenuGoupModule = findModuleByExport(e => e?.prototype?.Focus && e?.prototype?.OnOKButton && e?.prototype?.render?.toString().includes?.(`"emphasis"==this.props.tone`));
6
7
  export const MenuGroup = MenuGoupModule && Object.values(MenuGoupModule).find((e) => typeof e == "function" && e?.toString?.()?.includes("bInGamepadUI:"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decky/ui",
3
- "version": "4.9.0",
3
+ "version": "4.9.1",
4
4
  "description": "A library for interacting with the Steam frontend in Decky plugins and elsewhere.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,6 +3,7 @@ import { ReactNode, FC } from 'react';
3
3
  import { CommonUIModule } from '../webpack';
4
4
  import { ItemProps } from './Item';
5
5
  import { createPropListRegex } from '../utils';
6
+ import type { ContextMenuPositionOptions } from './Menu';
6
7
 
7
8
  export interface SingleDropdownOption {
8
9
  data: any;
@@ -20,11 +21,6 @@ export interface MultiDropdownOption {
20
21
 
21
22
  export type DropdownOption = SingleDropdownOption | MultiDropdownOption;
22
23
 
23
- export interface DropdownMenuPositionOptions {
24
- [_: string]: unknown
25
- bMatchWidth?: boolean
26
- }
27
-
28
24
  export interface DropdownProps {
29
25
  rgOptions: DropdownOption[];
30
26
  selectedOption: any;
@@ -32,7 +28,7 @@ export interface DropdownProps {
32
28
  onMenuWillOpen?(showMenu: () => void): void;
33
29
  onMenuOpened?(): void;
34
30
  onChange?(data: SingleDropdownOption): void;
35
- contextMenuPositionOptions?: DropdownMenuPositionOptions;
31
+ contextMenuPositionOptions?: ContextMenuPositionOptions;
36
32
  menuLabel?: string;
37
33
  strDefaultLabel?: string;
38
34
  renderButtonValue?(element: ReactNode): ReactNode;
@@ -3,9 +3,128 @@ import { FC, ReactNode } from 'react';
3
3
  import { Export, findModuleByExport, findModuleExport } from '../webpack';
4
4
  import { FooterLegendProps } from './FooterLegend';
5
5
 
6
- export const showContextMenu: (children: ReactNode, parent?: EventTarget) => void = findModuleExport(
7
- (e: Export) => typeof e === 'function' && e.toString().includes('GetContextMenuManagerFromWindow(')
8
- && e.toString().includes('.CreateContextMenuInstance('),
6
+ interface PopupCreationOptions {
7
+ /**
8
+ * Initially hidden, make it appear with {@link ContextMenuInstance.Show}.
9
+ */
10
+ bCreateHidden?: boolean;
11
+
12
+ bModal?: boolean;
13
+
14
+ /**
15
+ * Document title.
16
+ */
17
+ title?: string;
18
+ }
19
+
20
+ // Separate interface, since one of webpack module exports uses this exact object,
21
+ // so maybe it could be reused elsewhere.
22
+ interface MonitorOptions {
23
+ targetMonitor: {
24
+ flMonitorScale: number;
25
+ nScreenLeft: number;
26
+ nScreenTop: number;
27
+ nScreenWidth: number;
28
+ nScreenHeight: number;
29
+ };
30
+ flGamepadScale: number;
31
+ }
32
+
33
+ export interface ContextMenuPositionOptions extends PopupCreationOptions, Partial<MonitorOptions> {
34
+ /**
35
+ * When {@link bForcePopup} is true, makes the window appear above everything else.
36
+ */
37
+ bAlwaysOnTop?: boolean;
38
+
39
+ /**
40
+ * Disables the mouse overlay, granting the ability to click anywhere while
41
+ * the menu's active.
42
+ */
43
+ bDisableMouseOverlay?: boolean;
44
+
45
+ /**
46
+ * Disables the {@link bPreferPopTop} behavior.
47
+ */
48
+ bDisablePopTop?: boolean;
49
+
50
+ bFitToWindow?: boolean;
51
+
52
+ /**
53
+ * Forces the menu to open in a separate window instead of inside the parent.
54
+ */
55
+ bForcePopup?: boolean;
56
+
57
+ /**
58
+ * Like {@link bMatchWidth}, but don't shrink below the menu's minimum width.
59
+ */
60
+ bGrowToElementWidth?: boolean;
61
+
62
+ /**
63
+ * Match the parent's exact height.
64
+ */
65
+ bMatchHeight?: boolean;
66
+
67
+ /**
68
+ * Match the parent's exact width.
69
+ */
70
+ bMatchWidth?: boolean;
71
+
72
+ bNoFocusWhenShown?: boolean;
73
+
74
+ /**
75
+ * Makes the menu **invisible**, instead of getting removed from the DOM.
76
+ */
77
+ bRetainOnHide?: boolean;
78
+
79
+ bScreenCoordinates?: boolean;
80
+
81
+ /**
82
+ * Set to `true` to not account for the parent's width.
83
+ */
84
+ bOverlapHorizontal?: boolean;
85
+
86
+ /**
87
+ * Set to `true` to not account for the parent's height.
88
+ */
89
+ bOverlapVertical?: boolean;
90
+
91
+ /**
92
+ * Set to `true` to make the entire menu try to appear on the left side from
93
+ * the parent.
94
+ */
95
+ bPreferPopLeft?: boolean;
96
+
97
+ /**
98
+ * Set to `true` to make the entire menu try to appear above the parent.
99
+ */
100
+ bPreferPopTop?: boolean;
101
+
102
+ bShiftToFitWindow?: boolean;
103
+
104
+ // different window creation flags (StandaloneContextMenu vs PopupContextMenu)
105
+ bStandalone?: boolean;
106
+
107
+ /**
108
+ * Class name **replacement** for the container element, i.e. it replaces the
109
+ * default class.
110
+ */
111
+ strClassName?: string;
112
+ }
113
+
114
+ interface ContextMenuInstance {
115
+ Hide(): void;
116
+ Show(): void;
117
+ }
118
+
119
+ export const showContextMenu: (
120
+ children: ReactNode,
121
+ parent?: EventTarget,
122
+ options?: ContextMenuPositionOptions,
123
+ ) => ContextMenuInstance = findModuleExport(
124
+ (e: Export) =>
125
+ typeof e === 'function' &&
126
+ e.toString().includes('GetContextMenuManagerFromWindow(') &&
127
+ e.toString().includes('.CreateContextMenuInstance('),
9
128
  );
10
129
 
11
130
  export interface MenuProps extends FooterLegendProps {