@brand-map/primitives 0.0.0-broken.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 (121) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.oxfmtrc.json +35 -0
  4. package/.oxlintrc.json +166 -0
  5. package/README.md +78 -0
  6. package/bun.lock +904 -0
  7. package/mise.toml +3 -0
  8. package/package.json +61 -0
  9. package/src/accordion/accordion.tsx +189 -0
  10. package/src/accordion/accordion.web.tsx +282 -0
  11. package/src/accordion/index.ts +2 -0
  12. package/src/accordion/types.ts +44 -0
  13. package/src/alert-dialog/alert-dialog.tsx +238 -0
  14. package/src/alert-dialog/alert-dialog.web.tsx +260 -0
  15. package/src/alert-dialog/index.ts +2 -0
  16. package/src/alert-dialog/types.ts +81 -0
  17. package/src/aspect-ratio/aspect-ratio.tsx +27 -0
  18. package/src/aspect-ratio/index.ts +1 -0
  19. package/src/avatar/avatar.tsx +122 -0
  20. package/src/avatar/index.ts +2 -0
  21. package/src/avatar/types.ts +20 -0
  22. package/src/checkbox/checkbox.tsx +95 -0
  23. package/src/checkbox/checkbox.web.tsx +111 -0
  24. package/src/checkbox/index.ts +2 -0
  25. package/src/checkbox/types.ts +14 -0
  26. package/src/collapsible/collapsible.tsx +98 -0
  27. package/src/collapsible/collapsible.web.tsx +149 -0
  28. package/src/collapsible/index.ts +2 -0
  29. package/src/collapsible/types.ts +23 -0
  30. package/src/context-menu/context-menu.tsx +616 -0
  31. package/src/context-menu/context-menu.web.tsx +560 -0
  32. package/src/context-menu/index.ts +2 -0
  33. package/src/context-menu/types.ts +136 -0
  34. package/src/dialog/dialog.tsx +286 -0
  35. package/src/dialog/dialog.web.tsx +215 -0
  36. package/src/dialog/index.ts +2 -0
  37. package/src/dialog/types.ts +92 -0
  38. package/src/dropdown-menu/dropdown-menu.tsx +575 -0
  39. package/src/dropdown-menu/dropdown-menu.web.tsx +565 -0
  40. package/src/dropdown-menu/index.ts +2 -0
  41. package/src/dropdown-menu/types.ts +121 -0
  42. package/src/hooks/index.ts +4 -0
  43. package/src/hooks/use-Isomorphic-layout-effect.tsx +12 -0
  44. package/src/hooks/use-augmented-ref.tsx +25 -0
  45. package/src/hooks/use-controllable-state.tsx +70 -0
  46. package/src/hooks/use-relative-position.tsx +175 -0
  47. package/src/hover-card/hover-card.tsx +255 -0
  48. package/src/hover-card/hover-card.web.tsx +161 -0
  49. package/src/hover-card/index.ts +2 -0
  50. package/src/hover-card/types.ts +56 -0
  51. package/src/label/index.ts +2 -0
  52. package/src/label/label.tsx +36 -0
  53. package/src/label/label.web.tsx +38 -0
  54. package/src/label/types.ts +24 -0
  55. package/src/menubar/index.ts +2 -0
  56. package/src/menubar/menubar.tsx +602 -0
  57. package/src/menubar/menubar.web.tsx +575 -0
  58. package/src/menubar/types.ts +126 -0
  59. package/src/navigation-menu/index.ts +2 -0
  60. package/src/navigation-menu/navigation-menu.tsx +302 -0
  61. package/src/navigation-menu/navigation-menu.web.tsx +259 -0
  62. package/src/navigation-menu/types.ts +85 -0
  63. package/src/popover/index.ts +2 -0
  64. package/src/popover/popover.tsx +279 -0
  65. package/src/popover/popover.web.tsx +217 -0
  66. package/src/popover/types.ts +44 -0
  67. package/src/portal/index.ts +1 -0
  68. package/src/portal/portal.tsx +56 -0
  69. package/src/progress/index.ts +2 -0
  70. package/src/progress/progress.tsx +59 -0
  71. package/src/progress/progress.web.tsx +46 -0
  72. package/src/progress/types.ts +14 -0
  73. package/src/radio-group/index.ts +2 -0
  74. package/src/radio-group/radio-group.tsx +106 -0
  75. package/src/radio-group/radio-group.web.tsx +85 -0
  76. package/src/radio-group/types.ts +24 -0
  77. package/src/select/index.ts +2 -0
  78. package/src/select/select.tsx +447 -0
  79. package/src/select/select.web.tsx +368 -0
  80. package/src/select/types.ts +145 -0
  81. package/src/separator/index.ts +2 -0
  82. package/src/separator/separator.tsx +21 -0
  83. package/src/separator/types.ts +10 -0
  84. package/src/slider/index.ts +2 -0
  85. package/src/slider/slider.tsx +77 -0
  86. package/src/slider/slider.web.tsx +75 -0
  87. package/src/slider/types.ts +39 -0
  88. package/src/slot/index.ts +1 -0
  89. package/src/slot/slot.tsx +224 -0
  90. package/src/switch/index.ts +2 -0
  91. package/src/switch/switch.tsx +49 -0
  92. package/src/switch/switch.web.tsx +60 -0
  93. package/src/switch/types.ts +19 -0
  94. package/src/table/index.ts +1 -0
  95. package/src/table/table.tsx +121 -0
  96. package/src/tabs/index.ts +2 -0
  97. package/src/tabs/tabs.tsx +120 -0
  98. package/src/tabs/tabs.web.tsx +106 -0
  99. package/src/tabs/types.ts +37 -0
  100. package/src/toast/index.ts +2 -0
  101. package/src/toast/toast.tsx +124 -0
  102. package/src/toast/types.ts +20 -0
  103. package/src/toggle/index.ts +2 -0
  104. package/src/toggle/toggle.tsx +35 -0
  105. package/src/toggle/toggle.web.tsx +36 -0
  106. package/src/toggle/types.ts +11 -0
  107. package/src/toggle-group/index.ts +2 -0
  108. package/src/toggle-group/toggle-group.tsx +100 -0
  109. package/src/toggle-group/toggle-group.web.tsx +103 -0
  110. package/src/toggle-group/types.ts +46 -0
  111. package/src/toolbar/index.ts +2 -0
  112. package/src/toolbar/toolbar.tsx +141 -0
  113. package/src/toolbar/toolbar.web.tsx +158 -0
  114. package/src/toolbar/types.ts +64 -0
  115. package/src/tooltip/index.ts +2 -0
  116. package/src/tooltip/tooltip.tsx +261 -0
  117. package/src/tooltip/tooltip.web.tsx +175 -0
  118. package/src/tooltip/types.ts +61 -0
  119. package/src/types/index.ts +141 -0
  120. package/src/utils/index.ts +69 -0
  121. package/tsconfig.json +23 -0
@@ -0,0 +1,616 @@
1
+ import * as React from "react";
2
+ import {
3
+ BackHandler,
4
+ Pressable,
5
+ Text,
6
+ View,
7
+ type AccessibilityActionEvent,
8
+ type GestureResponderEvent,
9
+ type LayoutChangeEvent,
10
+ type LayoutRectangle,
11
+ } from "react-native";
12
+
13
+ import { useAugmentedRef, useControllableState, useRelativePosition, type LayoutPosition } from "../hooks";
14
+ import { Portal as RNPPortal } from "../portal";
15
+ import * as Slot from "../slot";
16
+
17
+ import type {
18
+ CheckboxItemProps,
19
+ CheckboxItemRef,
20
+ ContentProps,
21
+ ContentRef,
22
+ GroupProps,
23
+ GroupRef,
24
+ ItemIndicatorProps,
25
+ ItemIndicatorRef,
26
+ ItemProps,
27
+ ItemRef,
28
+ LabelProps,
29
+ LabelRef,
30
+ BackdropProps,
31
+ BackdropRef,
32
+ PortalProps,
33
+ RadioGroupProps,
34
+ RadioGroupRef,
35
+ RadioItemProps,
36
+ RadioItemRef,
37
+ RootProps,
38
+ RootRef,
39
+ SeparatorProps,
40
+ SeparatorRef,
41
+ SubContentProps,
42
+ SubContentRef,
43
+ SubProps,
44
+ SubRef,
45
+ SubTriggerProps,
46
+ SubTriggerRef,
47
+ TriggerProps,
48
+ TriggerRef,
49
+ } from "./types";
50
+
51
+ interface RootContextInterface extends RootProps {
52
+ open: boolean;
53
+ onOpenChange: (open: boolean) => void;
54
+ pressPosition: LayoutPosition | null;
55
+ setPressPosition: (pressPosition: LayoutPosition | null) => void;
56
+ contentLayout: LayoutRectangle | null;
57
+ setContentLayout: (contentLayout: LayoutRectangle | null) => void;
58
+ nativeID: string;
59
+ }
60
+
61
+ const RootContext = React.createContext<RootContextInterface | null>(null);
62
+
63
+ const Root = React.forwardRef<RootRef, RootProps>(({ relativeTo = "longPress", onOpenChange: onOpenChangeProp, ...viewProps }, ref) => {
64
+ const nativeID = React.useId();
65
+ const [pressPosition, setPressPosition] = React.useState<LayoutPosition | null>(null);
66
+ const [contentLayout, setContentLayout] = React.useState<LayoutRectangle | null>(null);
67
+ const [open, setOpen] = React.useState(false);
68
+
69
+ function onOpenChange(value: boolean) {
70
+ setOpen(value);
71
+ onOpenChangeProp?.(value);
72
+ }
73
+
74
+ return (
75
+ <RootContext.Provider
76
+ value={{
77
+ open,
78
+ onOpenChange,
79
+ relativeTo,
80
+ contentLayout,
81
+ nativeID,
82
+ pressPosition,
83
+ setContentLayout,
84
+ setPressPosition,
85
+ }}
86
+ >
87
+ <Component
88
+ ref={ref}
89
+ {...viewProps}
90
+ />
91
+ </RootContext.Provider>
92
+ );
93
+ });
94
+
95
+ Root.displayName = "RootNativeContextMenu";
96
+
97
+ function useRootContext() {
98
+ const context = React.useContext(RootContext);
99
+ if (!context) {
100
+ throw new Error("ContextMenu compound components cannot be rendered outside the ContextMenu component");
101
+ }
102
+ return context;
103
+ }
104
+
105
+ const accessibilityActions = [{ name: "longpress" }];
106
+
107
+ const Trigger = React.forwardRef<TriggerRef, TriggerProps>(
108
+ ({ render, onLongPress: onLongPressProp, disabled = false, onAccessibilityAction: onAccessibilityActionProp, ...props }, ref) => {
109
+ const { open, onOpenChange, relativeTo, setPressPosition } = useRootContext();
110
+ const augmentedRef = useAugmentedRef({
111
+ ref,
112
+ methods: {
113
+ open: () => {
114
+ onOpenChange(true);
115
+ augmentedRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
116
+ setPressPosition({ width, pageX, pageY: pageY, height });
117
+ });
118
+ },
119
+ close: () => {
120
+ setPressPosition(null);
121
+ onOpenChange(false);
122
+ },
123
+ },
124
+ });
125
+
126
+ function onLongPress(ev: GestureResponderEvent) {
127
+ if (disabled) return;
128
+ if (relativeTo === "longPress") {
129
+ setPressPosition({
130
+ width: 0,
131
+ pageX: ev.nativeEvent.pageX,
132
+ pageY: ev.nativeEvent.pageY,
133
+ height: 0,
134
+ });
135
+ }
136
+ if (relativeTo === "trigger") {
137
+ augmentedRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
138
+ setPressPosition({ width, pageX, pageY: pageY, height });
139
+ });
140
+ }
141
+ onOpenChange(!open);
142
+ onLongPressProp?.(ev);
143
+ }
144
+
145
+ function onAccessibilityAction(event: AccessibilityActionEvent) {
146
+ if (disabled) return;
147
+ if (event.nativeEvent.actionName === "longpress") {
148
+ setPressPosition({
149
+ width: 0,
150
+ pageX: 0,
151
+ pageY: 0,
152
+ height: 0,
153
+ });
154
+ const newValue = !open;
155
+ onOpenChange(newValue);
156
+ }
157
+ onAccessibilityActionProp?.(event);
158
+ }
159
+
160
+ return (
161
+ <Component
162
+ ref={augmentedRef}
163
+ aria-disabled={disabled ?? undefined}
164
+ role="button"
165
+ onLongPress={onLongPress}
166
+ disabled={disabled ?? undefined}
167
+ aria-expanded={open}
168
+ accessibilityActions={accessibilityActions}
169
+ onAccessibilityAction={onAccessibilityAction}
170
+ {...props}
171
+ />
172
+ );
173
+ },
174
+ );
175
+
176
+ Trigger.displayName = "TriggerNativeContextMenu";
177
+
178
+ /**
179
+ * @warning when using a custom `<PortalHost />`, you will have to adjust the Content's sideOffset to account for nav elements like headers.
180
+ */
181
+ function Portal({ keepMounted, hostName, children }: PortalProps) {
182
+ const value = useRootContext();
183
+
184
+ if (!value.pressPosition) {
185
+ return null;
186
+ }
187
+
188
+ if (!keepMounted) {
189
+ if (!value.open) {
190
+ return null;
191
+ }
192
+ }
193
+
194
+ return (
195
+ <RNPPortal
196
+ hostName={hostName}
197
+ name={`${value.nativeID}_portal`}
198
+ >
199
+ <RootContext.Provider value={value}>{children}</RootContext.Provider>
200
+ </RNPPortal>
201
+ );
202
+ }
203
+
204
+ const Backdrop = React.forwardRef<BackdropRef, BackdropProps>(({ keepMounted, onPress: OnPressProp, closeOnPress = true, ...props }, ref) => {
205
+ const { open, onOpenChange, setContentLayout, setPressPosition } = useRootContext();
206
+
207
+ function onPress(ev: GestureResponderEvent) {
208
+ if (closeOnPress) {
209
+ setPressPosition(null);
210
+ setContentLayout(null);
211
+ onOpenChange(false);
212
+ }
213
+ OnPressProp?.(ev);
214
+ }
215
+
216
+ if (!keepMounted) {
217
+ if (!open) {
218
+ return null;
219
+ }
220
+ }
221
+
222
+ return (
223
+ <Component
224
+ ref={ref}
225
+ onPress={onPress}
226
+ {...props}
227
+ />
228
+ );
229
+ });
230
+
231
+ Backdrop.displayName = "BackdropNativeContextMenu";
232
+
233
+ const Content = React.forwardRef<ContentRef, ContentProps>(
234
+ (
235
+ {
236
+ render = false,
237
+ keepMounted,
238
+ align = "start",
239
+ side = "bottom",
240
+ sideOffset = 0,
241
+ alignOffset = 0,
242
+ avoidCollisions = true,
243
+ onLayout: onLayoutProp,
244
+ insets,
245
+ style,
246
+ disablePositioningStyle,
247
+ ...props
248
+ },
249
+ ref,
250
+ ) => {
251
+ const { open, onOpenChange, contentLayout, nativeID, pressPosition, setContentLayout, setPressPosition } = useRootContext();
252
+
253
+ React.useEffect(() => {
254
+ const backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
255
+ setPressPosition(null);
256
+ setContentLayout(null);
257
+ onOpenChange(false);
258
+ return true;
259
+ });
260
+
261
+ return () => {
262
+ setContentLayout(null);
263
+ backHandler.remove();
264
+ };
265
+ }, []);
266
+
267
+ const positionStyle = useRelativePosition({
268
+ align,
269
+ avoidCollisions,
270
+ triggerPosition: pressPosition,
271
+ contentLayout,
272
+ alignOffset,
273
+ insets,
274
+ sideOffset,
275
+ side,
276
+ disablePositioningStyle,
277
+ });
278
+
279
+ function onLayout(event: LayoutChangeEvent) {
280
+ setContentLayout(event.nativeEvent.layout);
281
+ onLayoutProp?.(event);
282
+ }
283
+
284
+ if (!keepMounted) {
285
+ if (!open) {
286
+ return null;
287
+ }
288
+ }
289
+
290
+ return (
291
+ <Component
292
+ ref={ref}
293
+ role="menu"
294
+ nativeID={nativeID}
295
+ aria-modal={true}
296
+ style={[positionStyle, style]}
297
+ onLayout={onLayout}
298
+ onStartShouldSetResponder={onStartShouldSetResponder}
299
+ {...props}
300
+ />
301
+ );
302
+ },
303
+ );
304
+
305
+ Content.displayName = "ContentNativeContextMenu";
306
+
307
+ const Item = React.forwardRef<ItemRef, ItemProps>(({ textValue, onPress: onPressProp, disabled = false, closeOnPress = true, ...props }, ref) => {
308
+ const { onOpenChange, setContentLayout, setPressPosition } = useRootContext();
309
+
310
+ function onPress(ev: GestureResponderEvent) {
311
+ if (closeOnPress) {
312
+ setPressPosition(null);
313
+ setContentLayout(null);
314
+ onOpenChange(false);
315
+ }
316
+ onPressProp?.(ev);
317
+ }
318
+
319
+ return (
320
+ <Component
321
+ ref={ref}
322
+ role="menuitem"
323
+ onPress={onPress}
324
+ disabled={disabled}
325
+ aria-valuetext={textValue}
326
+ aria-disabled={!!disabled}
327
+ accessibilityState={{ disabled: !!disabled }}
328
+ {...props}
329
+ />
330
+ );
331
+ });
332
+
333
+ Item.displayName = "ItemNativeContextMenu";
334
+
335
+ const Group = React.forwardRef<GroupRef, GroupProps>(({ ...props }, ref) => {
336
+ return (
337
+ <Component
338
+ ref={ref}
339
+ role="group"
340
+ {...props}
341
+ />
342
+ );
343
+ });
344
+
345
+ Group.displayName = "GroupNativeContextMenu";
346
+
347
+ const Label = React.forwardRef<LabelRef, LabelProps>(({ ...props }, ref) => {
348
+ return (
349
+ <Component
350
+ ref={ref}
351
+ {...props}
352
+ />
353
+ );
354
+ });
355
+
356
+ Label.displayName = "LabelNativeContextMenu";
357
+
358
+ type FormItemContext =
359
+ | { checked: boolean }
360
+ | {
361
+ value: string | undefined;
362
+ onValueChange: (value: string) => void;
363
+ };
364
+
365
+ const FormItemContext = React.createContext<FormItemContext | null>(null);
366
+
367
+ const CheckboxItem = React.forwardRef<CheckboxItemRef, CheckboxItemProps>(
368
+ ({ render, checked, onCheckedChange, textValue, onPress: onPressProp, closeOnPress = true, disabled = false, ...props }, ref) => {
369
+ const { onOpenChange, setContentLayout, setPressPosition } = useRootContext();
370
+
371
+ function onPress(ev: GestureResponderEvent) {
372
+ onCheckedChange(!checked);
373
+ if (closeOnPress) {
374
+ setPressPosition(null);
375
+ setContentLayout(null);
376
+ onOpenChange(false);
377
+ }
378
+ onPressProp?.(ev);
379
+ }
380
+
381
+ return (
382
+ <FormItemContext.Provider value={{ checked }}>
383
+ <Component
384
+ ref={ref}
385
+ role="checkbox"
386
+ aria-checked={checked}
387
+ onPress={onPress}
388
+ disabled={disabled}
389
+ aria-disabled={!!disabled}
390
+ aria-valuetext={textValue}
391
+ accessibilityState={{ disabled: !!disabled }}
392
+ {...props}
393
+ />
394
+ </FormItemContext.Provider>
395
+ );
396
+ },
397
+ );
398
+
399
+ CheckboxItem.displayName = "CheckboxItemNativeContextMenu";
400
+
401
+ function useFormItemContext() {
402
+ const context = React.useContext(FormItemContext);
403
+ if (!context) {
404
+ throw new Error("CheckboxItem or RadioItem compound components cannot be rendered outside of a CheckboxItem or RadioItem component");
405
+ }
406
+ return context;
407
+ }
408
+
409
+ const RadioGroup = React.forwardRef<RadioGroupRef, RadioGroupProps>(({ value, onValueChange, ...props }, ref) => {
410
+ return (
411
+ <FormItemContext.Provider value={{ value, onValueChange }}>
412
+ <Component
413
+ ref={ref}
414
+ role="radiogroup"
415
+ {...props}
416
+ />
417
+ </FormItemContext.Provider>
418
+ );
419
+ });
420
+
421
+ RadioGroup.displayName = "RadioGroupNativeContextMenu";
422
+
423
+ type BothFormItemContext = Exclude<FormItemContext, { checked: boolean }> & {
424
+ checked: boolean;
425
+ };
426
+
427
+ const RadioItemContext = React.createContext({} as { itemValue: string });
428
+
429
+ const RadioItem = React.forwardRef<RadioItemRef, RadioItemProps>(
430
+ ({ render, value: itemValue, textValue, onPress: onPressProp, disabled = false, closeOnPress = true, ...props }, ref) => {
431
+ const { onOpenChange, setContentLayout, setPressPosition } = useRootContext();
432
+
433
+ const { value, onValueChange } = useFormItemContext() as BothFormItemContext;
434
+ function onPress(ev: GestureResponderEvent) {
435
+ onValueChange(itemValue);
436
+ if (closeOnPress) {
437
+ setPressPosition(null);
438
+ setContentLayout(null);
439
+ onOpenChange(false);
440
+ }
441
+ onPressProp?.(ev);
442
+ }
443
+
444
+ return (
445
+ <RadioItemContext.Provider value={{ itemValue }}>
446
+ <Component
447
+ ref={ref}
448
+ onPress={onPress}
449
+ role="radio"
450
+ aria-checked={value === itemValue}
451
+ disabled={disabled ?? false}
452
+ accessibilityState={{
453
+ disabled: disabled ?? false,
454
+ checked: value === itemValue,
455
+ }}
456
+ aria-valuetext={textValue}
457
+ {...props}
458
+ />
459
+ </RadioItemContext.Provider>
460
+ );
461
+ },
462
+ );
463
+
464
+ RadioItem.displayName = "RadioItemNativeContextMenu";
465
+
466
+ function useItemIndicatorContext() {
467
+ return React.useContext(RadioItemContext);
468
+ }
469
+
470
+ const ItemIndicator = React.forwardRef<ItemIndicatorRef, ItemIndicatorProps>(({ keepMounted, ...props }, ref) => {
471
+ const { itemValue } = useItemIndicatorContext();
472
+ const { checked, value } = useFormItemContext() as BothFormItemContext;
473
+
474
+ if (!keepMounted) {
475
+ if (itemValue == null && !checked) {
476
+ return null;
477
+ }
478
+ if (value !== itemValue) {
479
+ return null;
480
+ }
481
+ }
482
+
483
+ return (
484
+ <Component
485
+ ref={ref}
486
+ role="presentation"
487
+ {...props}
488
+ />
489
+ );
490
+ });
491
+
492
+ ItemIndicator.displayName = "ItemIndicatorNativeContextMenu";
493
+
494
+ const Separator = React.forwardRef<SeparatorRef, SeparatorProps>(({ decorative, ...props }, ref) => {
495
+ return (
496
+ <Component
497
+ role={decorative ? "presentation" : "separator"}
498
+ ref={ref}
499
+ {...props}
500
+ />
501
+ );
502
+ });
503
+
504
+ Separator.displayName = "SeparatorNativeContextMenu";
505
+
506
+ const SubContext = React.createContext<{
507
+ nativeID: string;
508
+ open: boolean;
509
+ onOpenChange: (value: boolean) => void;
510
+ } | null>(null);
511
+
512
+ const Sub = React.forwardRef<SubRef, SubProps>(({ defaultOpen, open: openProp, onOpenChange: onOpenChangeProp, ...props }, ref) => {
513
+ const nativeID = React.useId();
514
+ const [open = false, onOpenChange] = useControllableState({
515
+ prop: openProp,
516
+ defaultProp: defaultOpen,
517
+ onChange: onOpenChangeProp,
518
+ });
519
+
520
+ return (
521
+ <SubContext.Provider
522
+ value={{
523
+ nativeID,
524
+ open,
525
+ onOpenChange,
526
+ }}
527
+ >
528
+ <Component
529
+ ref={ref}
530
+ {...props}
531
+ />
532
+ </SubContext.Provider>
533
+ );
534
+ });
535
+
536
+ Sub.displayName = "SubNativeContextMenu";
537
+
538
+ function useSubContext() {
539
+ const context = React.useContext(SubContext);
540
+ if (!context) {
541
+ throw new Error("Sub compound components cannot be rendered outside of a Sub component");
542
+ }
543
+ return context;
544
+ }
545
+
546
+ const SubTrigger = React.forwardRef<SubTriggerRef, SubTriggerProps>(({ textValue, onPress: onPressProp, disabled = false, ...props }, ref) => {
547
+ const { nativeID, open, onOpenChange } = useSubContext();
548
+
549
+ function onPress(ev: GestureResponderEvent) {
550
+ onOpenChange(!open);
551
+ onPressProp?.(ev);
552
+ }
553
+
554
+ return (
555
+ <Component
556
+ ref={ref}
557
+ aria-valuetext={textValue}
558
+ role="menuitem"
559
+ aria-expanded={open}
560
+ accessibilityState={{ expanded: open, disabled: !!disabled }}
561
+ nativeID={nativeID}
562
+ onPress={onPress}
563
+ disabled={disabled}
564
+ aria-disabled={!!disabled}
565
+ {...props}
566
+ />
567
+ );
568
+ });
569
+
570
+ SubTrigger.displayName = "SubTriggerNativeContextMenu";
571
+
572
+ const SubContent = React.forwardRef<SubContentRef, SubContentProps>(({ render = false, keepMounted, ...props }, ref) => {
573
+ const { open, nativeID } = useSubContext();
574
+
575
+ if (!keepMounted) {
576
+ if (!open) {
577
+ return null;
578
+ }
579
+ }
580
+
581
+ return (
582
+ <Component
583
+ ref={ref}
584
+ role="group"
585
+ aria-labelledby={nativeID}
586
+ {...props}
587
+ />
588
+ );
589
+ });
590
+
591
+ Content.displayName = "ContentNativeContextMenu";
592
+
593
+ export {
594
+ CheckboxItem,
595
+ Content,
596
+ Group,
597
+ Item,
598
+ ItemIndicator,
599
+ Label,
600
+ Backdrop,
601
+ Portal,
602
+ RadioGroup,
603
+ RadioItem,
604
+ Root,
605
+ Separator,
606
+ Sub,
607
+ SubContent,
608
+ SubTrigger,
609
+ Trigger,
610
+ useRootContext,
611
+ useSubContext,
612
+ };
613
+
614
+ function onStartShouldSetResponder() {
615
+ return true;
616
+ }