@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/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
- /** Item variant types for data-driven API */
8
- type ContextMenuItemVariant = "default" | "checkbox" | "radio";
9
- /** Trailing element types */
10
- type ContextMenuTrailingType = "none" | "shortcut" | "badge" | "switch" | "arrow";
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
- /** Controlled open state */
53
- isOpen?: boolean;
54
- /** Callback when open state changes */
55
- onOpenChange?: (open: boolean) => void;
56
- /** Position for right-click context menu mode */
57
- position?: ContextMenuPosition;
58
- /** Trigger element (button, etc.) for dropdown mode */
59
- trigger?: ReactNode;
60
- /** Width of the menu */
61
- width?: number | string;
62
- /** Maximum height before scrolling */
63
- maxHeight?: number;
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
- /** Press handler */
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
- /** Size inherited from parent */
121
- size?: ContextMenuSize;
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
- /** ContextMenuRadioGroup Component Props */
130
- interface ContextMenuRadioGroupProps {
131
- /** Radio items */
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
- /** Test ID */
37
+ placeholder?: string;
38
+ autoFocus?: boolean;
39
+ "aria-label"?: string;
138
40
  "data-testid"?: string;
139
41
  }
140
- /** ContextMenuRadioItem Component Props */
141
- interface ContextMenuRadioItemProps {
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
- /** Press handler */
153
- onPress?: () => void;
154
- /** Test ID */
45
+ label: ReactNode;
46
+ description?: ReactNode;
155
47
  "data-testid"?: string;
156
48
  }
157
- /** ContextMenuGroup Component Props */
158
- interface ContextMenuGroupProps {
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
- /** ContextMenuSeparator Component Props */
171
- interface ContextMenuSeparatorProps {
172
- /** Size for consistent spacing */
173
- size?: ContextMenuSize;
174
- /** Test ID */
175
- "data-testid"?: string;
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
- /** ContextMenuSearch Component Props */
178
- interface ContextMenuSearchProps {
179
- /** Current search value */
180
- value?: string;
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
- /** Test ID */
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
- /** Context for passing state to children */
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
- onItemSelect: (item: ContextMenuItemData) => void;
90
+ registerCell: (id: string, meta: ContextMenuCellMeta) => number;
91
+ unregisterCell: (id: string) => void;
199
92
  activeIndex: number;
200
- setActiveIndex: (index: number) => void;
201
- registerItem: (id: string) => number;
202
- unregisterItem: (id: string) => void;
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
- declare const ContextMenu: React__default.ForwardRefExoticComponent<ContextMenuProps & ThemeOverrideProps & React__default.RefAttributes<any>> & {
217
- Item: React__default.ForwardRefExoticComponent<ContextMenuItemProps & ThemeOverrideProps & React__default.RefAttributes<any>>;
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
- declare const ContextMenuCheckboxItem: React__default.ForwardRefExoticComponent<ContextMenuCheckboxItemProps & ThemeOverrideProps & React__default.RefAttributes<any>>;
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
- position?: ContextMenuPosition;
250
- menuRef: RefObject<HTMLElement>;
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 AdjustedPosition extends ContextMenuPosition {
255
- transformOrigin: string;
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
- itemCount: number;
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
- loop?: boolean;
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, ContextMenuCheckboxItem, type ContextMenuCheckboxItemProps, type ContextMenuContextValue, ContextMenuGroup, type ContextMenuGroupData, type ContextMenuGroupProps, ContextMenuItem, type ContextMenuItemData, type ContextMenuItemProps, type ContextMenuItemVariant, type ContextMenuPosition, type ContextMenuProps, ContextMenuRadioGroup, type ContextMenuRadioGroupProps, ContextMenuRadioItem, type ContextMenuRadioItemProps, ContextMenuSearch, type ContextMenuSearchProps, ContextMenuSeparator, type ContextMenuSeparatorProps, type ContextMenuSize, type ContextMenuSizing, type ContextMenuTrailingType, useContextMenu, useContextMenuPosition, useContextMenuRequired, useKeyboardNavigation, useRadioGroup };
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 };