@xsolla/xui-context-menu 0.157.0 → 0.158.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/README.md +150 -309
- package/native/index.d.mts +91 -218
- package/native/index.d.ts +91 -218
- package/native/index.js +29590 -2320
- package/native/index.js.map +1 -1
- package/native/index.mjs +29616 -2317
- package/native/index.mjs.map +1 -1
- package/package.json +9 -8
- package/web/index.d.mts +91 -218
- package/web/index.d.ts +91 -218
- package/web/index.js +29589 -2346
- package/web/index.js.map +1 -1
- package/web/index.mjs +29612 -2333
- package/web/index.mjs.map +1 -1
package/native/index.d.ts
CHANGED
|
@@ -2,206 +2,98 @@ import * as React$1 from 'react';
|
|
|
2
2
|
import React__default, { ReactNode, RefObject } from 'react';
|
|
3
3
|
import { ThemeOverrideProps } from '@xsolla/xui-core';
|
|
4
4
|
|
|
5
|
-
/** Size variants for the context menu */
|
|
6
5
|
type ContextMenuSize = "sm" | "md" | "lg" | "xl";
|
|
7
|
-
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
type
|
|
11
|
-
/** Position configuration for context menu */
|
|
12
|
-
interface ContextMenuPosition {
|
|
13
|
-
x: number;
|
|
14
|
-
y: number;
|
|
15
|
-
}
|
|
16
|
-
/** Individual menu item data structure for data-driven API */
|
|
17
|
-
interface ContextMenuItemData {
|
|
18
|
-
id: string;
|
|
19
|
-
label: string;
|
|
20
|
-
description?: string;
|
|
21
|
-
icon?: ReactNode;
|
|
22
|
-
trailing?: {
|
|
23
|
-
type: ContextMenuTrailingType;
|
|
24
|
-
content?: ReactNode | string;
|
|
25
|
-
};
|
|
26
|
-
variant?: ContextMenuItemVariant;
|
|
27
|
-
checked?: boolean;
|
|
28
|
-
/** Whether this item is selected (shows trailing checkmark) - for Select/Dropdown usage */
|
|
29
|
-
selected?: boolean;
|
|
30
|
-
disabled?: boolean;
|
|
31
|
-
onPress?: () => void;
|
|
32
|
-
children?: ContextMenuItemData[];
|
|
33
|
-
groupId?: string;
|
|
34
|
-
}
|
|
35
|
-
/** Menu group with optional header */
|
|
36
|
-
interface ContextMenuGroupData {
|
|
37
|
-
id: string;
|
|
38
|
-
label?: string;
|
|
39
|
-
description?: string;
|
|
40
|
-
items: ContextMenuItemData[];
|
|
41
|
-
}
|
|
42
|
-
/** Main ContextMenu Container Props */
|
|
43
|
-
interface ContextMenuProps {
|
|
44
|
-
/** Menu items - data-driven API (alternative to children) */
|
|
45
|
-
list?: ContextMenuItemData[];
|
|
46
|
-
/** Grouped menu items with optional headers */
|
|
47
|
-
groups?: ContextMenuGroupData[];
|
|
48
|
-
/** Render function for custom children (alternative to list/groups) */
|
|
49
|
-
children?: ReactNode;
|
|
50
|
-
/** Size of the context menu */
|
|
6
|
+
type ContextMenuItemType = "option" | "search" | "heading" | "divider";
|
|
7
|
+
type ContextMenuItemLeadingControl = "checkbox" | "radio";
|
|
8
|
+
interface ContextMenuOptionItemProps {
|
|
9
|
+
type: "option";
|
|
51
10
|
size?: ContextMenuSize;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
/** Callback when an item is selected */
|
|
65
|
-
onSelect?: (item: ContextMenuItemData) => void;
|
|
66
|
-
/** Callback when checkbox/radio values change */
|
|
67
|
-
onCheckedChange?: (itemId: string, checked: boolean) => void;
|
|
68
|
-
/** Close menu on item select (default: true for non-checkbox items) */
|
|
69
|
-
closeOnSelect?: boolean;
|
|
70
|
-
/** Loading state - shows spinner */
|
|
71
|
-
isLoading?: boolean;
|
|
72
|
-
/** ARIA label for the menu */
|
|
73
|
-
"aria-label"?: string;
|
|
74
|
-
/** Test ID */
|
|
75
|
-
"data-testid"?: string;
|
|
76
|
-
}
|
|
77
|
-
/** ContextMenuItem Component Props - for default menu items */
|
|
78
|
-
interface ContextMenuItemProps {
|
|
79
|
-
/** Item label text */
|
|
80
|
-
children: ReactNode;
|
|
81
|
-
/** Description text below label */
|
|
82
|
-
description?: string;
|
|
83
|
-
/** Leading icon */
|
|
84
|
-
icon?: ReactNode;
|
|
85
|
-
/** Trailing element */
|
|
86
|
-
trailing?: ReactNode;
|
|
87
|
-
/** Keyboard shortcut display text */
|
|
88
|
-
shortcut?: string;
|
|
89
|
-
/** Whether this item is selected (cyan background) - for Select/Dropdown usage */
|
|
90
|
-
selected?: boolean;
|
|
91
|
-
/** Whether item is disabled */
|
|
92
|
-
disabled?: boolean;
|
|
93
|
-
/** Whether item is currently active/focused (for keyboard navigation) */
|
|
94
|
-
active?: boolean;
|
|
95
|
-
/** Size inherited from parent */
|
|
96
|
-
size?: ContextMenuSize;
|
|
97
|
-
/** Whether this item has a submenu */
|
|
11
|
+
leadingControl?: ContextMenuItemLeadingControl;
|
|
12
|
+
leadingIcon?: ReactNode;
|
|
13
|
+
status?: ReactNode;
|
|
14
|
+
iconWrapper?: ReactNode;
|
|
15
|
+
slot?: ReactNode;
|
|
16
|
+
slotContent?: ReactNode;
|
|
17
|
+
label: ReactNode;
|
|
18
|
+
description?: ReactNode;
|
|
19
|
+
value?: ReactNode;
|
|
20
|
+
hint?: ReactNode;
|
|
21
|
+
trailingIcon?: ReactNode;
|
|
22
|
+
keyboardShortcut?: string;
|
|
98
23
|
hasSubmenu?: boolean;
|
|
99
|
-
|
|
100
|
-
onPress?: () => void;
|
|
101
|
-
/** Test ID */
|
|
102
|
-
"data-testid"?: string;
|
|
103
|
-
}
|
|
104
|
-
/** ContextMenuCheckboxItem Component Props */
|
|
105
|
-
interface ContextMenuCheckboxItemProps {
|
|
106
|
-
/** Item label text */
|
|
107
|
-
children: ReactNode;
|
|
108
|
-
/** Description text below label */
|
|
109
|
-
description?: string;
|
|
110
|
-
/** Content placed after checkbox but before label (e.g., Status indicator) */
|
|
111
|
-
leadingContent?: ReactNode;
|
|
112
|
-
/** Trailing element */
|
|
113
|
-
trailing?: ReactNode;
|
|
114
|
-
/** Checked state */
|
|
24
|
+
submenu?: ReactNode;
|
|
115
25
|
checked?: boolean;
|
|
116
|
-
/** Indeterminate state - shows minus icon instead of check (for "select all" partially selected) */
|
|
117
|
-
indeterminate?: boolean;
|
|
118
|
-
/** Whether item is disabled */
|
|
119
26
|
disabled?: boolean;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
/** Checked change handler */
|
|
27
|
+
destructive?: boolean;
|
|
28
|
+
onSelect?: () => void;
|
|
123
29
|
onCheckedChange?: (checked: boolean) => void;
|
|
124
|
-
/** Press handler */
|
|
125
|
-
onPress?: () => void;
|
|
126
|
-
/** Test ID */
|
|
127
30
|
"data-testid"?: string;
|
|
128
31
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
children: ReactNode;
|
|
133
|
-
/** Current selected value */
|
|
32
|
+
interface ContextMenuSearchItemProps {
|
|
33
|
+
type: "search";
|
|
34
|
+
size?: ContextMenuSize;
|
|
134
35
|
value: string;
|
|
135
|
-
/** Value change handler */
|
|
136
36
|
onValueChange: (value: string) => void;
|
|
137
|
-
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
autoFocus?: boolean;
|
|
39
|
+
"aria-label"?: string;
|
|
138
40
|
"data-testid"?: string;
|
|
139
41
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
/** Item label text */
|
|
143
|
-
children: ReactNode;
|
|
144
|
-
/** Description text below label */
|
|
145
|
-
description?: string;
|
|
146
|
-
/** Value for this radio item */
|
|
147
|
-
value: string;
|
|
148
|
-
/** Whether item is disabled */
|
|
149
|
-
disabled?: boolean;
|
|
150
|
-
/** Size inherited from parent */
|
|
42
|
+
interface ContextMenuHeadingItemProps {
|
|
43
|
+
type: "heading";
|
|
151
44
|
size?: ContextMenuSize;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
/** Test ID */
|
|
45
|
+
label: ReactNode;
|
|
46
|
+
description?: ReactNode;
|
|
155
47
|
"data-testid"?: string;
|
|
156
48
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
/** Group heading text */
|
|
160
|
-
label?: string;
|
|
161
|
-
/** Group description */
|
|
162
|
-
description?: string;
|
|
163
|
-
/** Group items */
|
|
164
|
-
children: ReactNode;
|
|
165
|
-
/** Size inherited from parent */
|
|
49
|
+
interface ContextMenuDividerItemProps {
|
|
50
|
+
type: "divider";
|
|
166
51
|
size?: ContextMenuSize;
|
|
167
|
-
/** Test ID */
|
|
168
52
|
"data-testid"?: string;
|
|
169
53
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
54
|
+
type ContextMenuItemProps = ContextMenuOptionItemProps | ContextMenuSearchItemProps | ContextMenuHeadingItemProps | ContextMenuDividerItemProps;
|
|
55
|
+
type ContextMenuPanelType = "list" | "phone" | "checkbox" | "status" | "brandLogo" | "radio" | "avatar";
|
|
56
|
+
type ContextMenuPlacement = "bottom-start" | "top-start" | "bottom-end" | "top-end";
|
|
57
|
+
interface ContextMenuPosition {
|
|
58
|
+
x: number;
|
|
59
|
+
y: number;
|
|
176
60
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
/** Change handler (event-based) */
|
|
182
|
-
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
183
|
-
/** Change handler (value-based) */
|
|
184
|
-
onValueChange?: (value: string) => void;
|
|
185
|
-
/** Placeholder text */
|
|
186
|
-
placeholder?: string;
|
|
187
|
-
/** Whether to auto-focus the input when mounted */
|
|
188
|
-
autoFocus?: boolean;
|
|
189
|
-
/** Size inherited from parent */
|
|
61
|
+
interface ContextMenuProps {
|
|
62
|
+
type?: ContextMenuPanelType;
|
|
63
|
+
items?: ReadonlyArray<ContextMenuOptionItemProps | ContextMenuHeadingItemProps | ContextMenuDividerItemProps>;
|
|
64
|
+
children?: ReactNode;
|
|
190
65
|
size?: ContextMenuSize;
|
|
191
|
-
|
|
66
|
+
searchable?: boolean;
|
|
67
|
+
loading?: boolean;
|
|
68
|
+
emptyMessage?: string;
|
|
69
|
+
empty?: ReactNode;
|
|
70
|
+
trigger?: ReactNode;
|
|
71
|
+
position?: ContextMenuPosition;
|
|
72
|
+
placement?: ContextMenuPlacement;
|
|
73
|
+
isOpen?: boolean;
|
|
74
|
+
onOpenChange?: (open: boolean) => void;
|
|
75
|
+
closeOnSelect?: boolean;
|
|
76
|
+
width?: number;
|
|
77
|
+
maxHeight?: number;
|
|
78
|
+
onSelect?: (item: ContextMenuOptionItemProps) => void;
|
|
79
|
+
"aria-label"?: string;
|
|
192
80
|
"data-testid"?: string;
|
|
193
81
|
}
|
|
194
|
-
|
|
82
|
+
interface ContextMenuCellMeta {
|
|
83
|
+
type: ContextMenuItemType;
|
|
84
|
+
onSelect?: () => void;
|
|
85
|
+
disabled?: boolean;
|
|
86
|
+
}
|
|
195
87
|
interface ContextMenuContextValue {
|
|
196
88
|
size: ContextMenuSize;
|
|
197
89
|
closeMenu: () => void;
|
|
198
|
-
|
|
90
|
+
registerCell: (id: string, meta: ContextMenuCellMeta) => number;
|
|
91
|
+
unregisterCell: (id: string) => void;
|
|
199
92
|
activeIndex: number;
|
|
200
|
-
setActiveIndex: (
|
|
201
|
-
|
|
202
|
-
|
|
93
|
+
setActiveIndex: (i: number) => void;
|
|
94
|
+
query: string;
|
|
95
|
+
setQuery: (q: string) => void;
|
|
203
96
|
}
|
|
204
|
-
/** Sizing configuration returned by theme.sizing.contextMenu */
|
|
205
97
|
interface ContextMenuSizing {
|
|
206
98
|
paddingVertical: number;
|
|
207
99
|
itemPaddingHorizontal: number;
|
|
@@ -213,68 +105,49 @@ interface ContextMenuSizing {
|
|
|
213
105
|
minWidth: number;
|
|
214
106
|
}
|
|
215
107
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
CheckboxItem: React__default.ForwardRefExoticComponent<ContextMenuCheckboxItemProps & ThemeOverrideProps & React__default.RefAttributes<any>>;
|
|
219
|
-
RadioGroup: React__default.ForwardRefExoticComponent<ContextMenuRadioGroupProps & React__default.RefAttributes<any>>;
|
|
220
|
-
RadioItem: React__default.ForwardRefExoticComponent<ContextMenuRadioItemProps & ThemeOverrideProps & React__default.RefAttributes<any>>;
|
|
221
|
-
Group: React__default.ForwardRefExoticComponent<ContextMenuGroupProps & ThemeOverrideProps & React__default.RefAttributes<any>>;
|
|
222
|
-
Separator: React__default.FC<ContextMenuSeparatorProps & ThemeOverrideProps>;
|
|
223
|
-
Search: React__default.ForwardRefExoticComponent<ContextMenuSearchProps & ThemeOverrideProps & React__default.RefAttributes<HTMLInputElement>>;
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
declare const ContextMenuItem: React__default.ForwardRefExoticComponent<ContextMenuItemProps & ThemeOverrideProps & React__default.RefAttributes<any>>;
|
|
108
|
+
type Props$1 = ContextMenuProps & ThemeOverrideProps;
|
|
109
|
+
declare const ContextMenu: React__default.FC<Props$1>;
|
|
227
110
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
interface RadioGroupContextValue {
|
|
231
|
-
value: string;
|
|
232
|
-
onValueChange: (value: string) => void;
|
|
233
|
-
}
|
|
234
|
-
declare const useRadioGroup: () => RadioGroupContextValue | null;
|
|
235
|
-
declare const ContextMenuRadioGroup: React$1.ForwardRefExoticComponent<ContextMenuRadioGroupProps & React$1.RefAttributes<any>>;
|
|
236
|
-
|
|
237
|
-
declare const ContextMenuRadioItem: React__default.ForwardRefExoticComponent<ContextMenuRadioItemProps & ThemeOverrideProps & React__default.RefAttributes<any>>;
|
|
238
|
-
|
|
239
|
-
declare const ContextMenuGroup: React$1.ForwardRefExoticComponent<ContextMenuGroupProps & ThemeOverrideProps & React$1.RefAttributes<any>>;
|
|
240
|
-
|
|
241
|
-
declare const ContextMenuSeparator: React__default.FC<ContextMenuSeparatorProps & ThemeOverrideProps>;
|
|
242
|
-
|
|
243
|
-
declare const ContextMenuSearch: React__default.ForwardRefExoticComponent<ContextMenuSearchProps & ThemeOverrideProps & React__default.RefAttributes<HTMLInputElement>>;
|
|
111
|
+
type Props = ContextMenuItemProps & ThemeOverrideProps;
|
|
112
|
+
declare const ContextMenuItem: React__default.FC<Props>;
|
|
244
113
|
|
|
114
|
+
declare const ContextMenuContext: React$1.Context<ContextMenuContextValue | undefined>;
|
|
245
115
|
declare const useContextMenu: () => ContextMenuContextValue | undefined;
|
|
246
116
|
declare const useContextMenuRequired: () => ContextMenuContextValue;
|
|
247
117
|
|
|
248
118
|
interface UseContextMenuPositionOptions {
|
|
249
|
-
|
|
250
|
-
|
|
119
|
+
triggerRef: RefObject<HTMLElement | null>;
|
|
120
|
+
panelRef: RefObject<HTMLElement | null>;
|
|
251
121
|
isOpen: boolean;
|
|
122
|
+
placement?: ContextMenuPlacement;
|
|
252
123
|
offset?: number;
|
|
253
124
|
}
|
|
254
|
-
interface
|
|
255
|
-
|
|
125
|
+
interface ResolvedPosition {
|
|
126
|
+
top: number;
|
|
127
|
+
left: number;
|
|
128
|
+
placement: ContextMenuPlacement;
|
|
256
129
|
}
|
|
257
|
-
|
|
258
|
-
* Hook to calculate smart positioning for context menus
|
|
259
|
-
* Adjusts position to avoid viewport overflow
|
|
260
|
-
*/
|
|
261
|
-
declare const useContextMenuPosition: ({ position, menuRef, isOpen, offset, }: UseContextMenuPositionOptions) => AdjustedPosition | undefined;
|
|
130
|
+
declare const useContextMenuPosition: ({ triggerRef, panelRef, isOpen, placement, offset, }: UseContextMenuPositionOptions) => ResolvedPosition | undefined;
|
|
262
131
|
|
|
132
|
+
type CellType = "option" | "search" | "heading" | "divider";
|
|
133
|
+
interface CellMeta {
|
|
134
|
+
type: CellType;
|
|
135
|
+
onSelect?: () => void;
|
|
136
|
+
disabled?: boolean;
|
|
137
|
+
}
|
|
263
138
|
interface UseKeyboardNavigationOptions {
|
|
264
139
|
isOpen: boolean;
|
|
265
|
-
|
|
140
|
+
cells: Array<{
|
|
141
|
+
id: string;
|
|
142
|
+
meta: CellMeta;
|
|
143
|
+
}>;
|
|
266
144
|
activeIndex: number;
|
|
267
145
|
setActiveIndex: (index: number) => void;
|
|
268
|
-
onSelect: (index: number) => void;
|
|
269
146
|
onClose: () => void;
|
|
270
|
-
|
|
147
|
+
triggerRef?: RefObject<HTMLElement | null>;
|
|
271
148
|
}
|
|
272
|
-
|
|
273
|
-
* Hook to handle keyboard navigation in context menus
|
|
274
|
-
* Supports arrow keys, home/end, enter/space, and escape
|
|
275
|
-
*/
|
|
276
|
-
declare const useKeyboardNavigation: ({ isOpen, itemCount, activeIndex, setActiveIndex, onSelect, onClose, loop, }: UseKeyboardNavigationOptions) => {
|
|
149
|
+
declare const useKeyboardNavigation: ({ isOpen, cells, activeIndex, setActiveIndex, onClose, triggerRef, }: UseKeyboardNavigationOptions) => {
|
|
277
150
|
handleKeyDown: (event: React.KeyboardEvent) => void;
|
|
278
151
|
};
|
|
279
152
|
|
|
280
|
-
export { ContextMenu,
|
|
153
|
+
export { ContextMenu, ContextMenuContext, type ContextMenuContextValue, type ContextMenuDividerItemProps, type ContextMenuHeadingItemProps, ContextMenuItem, type ContextMenuItemLeadingControl, type ContextMenuItemProps, type ContextMenuItemType, type ContextMenuOptionItemProps, type ContextMenuPanelType, type ContextMenuPlacement, type ContextMenuPosition, type ContextMenuProps, type ContextMenuSearchItemProps, type ContextMenuSize, type ContextMenuSizing, useContextMenu, useContextMenuPosition, useContextMenuRequired, useKeyboardNavigation };
|