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