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