@react-native-reusables/cli 0.0.8 → 0.0.10

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 (136) hide show
  1. package/dist/generated/components/primitives/accordion/accordion.tsx +216 -0
  2. package/dist/generated/components/primitives/accordion/accordion.web.tsx +295 -0
  3. package/dist/generated/components/primitives/accordion/index.ts +1 -0
  4. package/dist/generated/components/primitives/accordion/types.ts +45 -0
  5. package/dist/generated/components/primitives/alert-dialog/alert-dialog.tsx +237 -0
  6. package/dist/generated/components/primitives/alert-dialog/alert-dialog.web.tsx +256 -0
  7. package/dist/generated/components/primitives/alert-dialog/index.ts +1 -0
  8. package/dist/generated/components/primitives/alert-dialog/types.ts +48 -0
  9. package/dist/generated/components/primitives/aspect-ratio.tsx +23 -0
  10. package/dist/generated/components/primitives/avatar/ types.ts +10 -0
  11. package/dist/generated/components/primitives/avatar/index.tsx +95 -0
  12. package/dist/generated/components/primitives/checkbox/checkbox.tsx +101 -0
  13. package/dist/generated/components/primitives/checkbox/checkbox.web.tsx +114 -0
  14. package/dist/generated/components/primitives/checkbox/index.ts +1 -0
  15. package/dist/generated/components/primitives/checkbox/types.ts +11 -0
  16. package/dist/generated/components/primitives/collapsible/collapsible.tsx +119 -0
  17. package/dist/generated/components/primitives/collapsible/collapsible.web.tsx +157 -0
  18. package/dist/generated/components/primitives/collapsible/index.ts +1 -0
  19. package/dist/generated/components/primitives/collapsible/types.ts +18 -0
  20. package/dist/generated/components/primitives/context-menu/context-menu.tsx +626 -0
  21. package/dist/generated/components/primitives/context-menu/context-menu.web.tsx +504 -0
  22. package/dist/generated/components/primitives/context-menu/index.ts +1 -0
  23. package/dist/generated/components/primitives/context-menu/types.ts +82 -0
  24. package/dist/generated/components/primitives/dialog/dialog.tsx +211 -0
  25. package/dist/generated/components/primitives/dialog/dialog.web.tsx +197 -0
  26. package/dist/generated/components/primitives/dialog/index.ts +1 -0
  27. package/dist/generated/components/primitives/dialog/types.ts +60 -0
  28. package/dist/generated/components/primitives/dropdown-menu/dropdown-menu.tsx +584 -0
  29. package/dist/generated/components/primitives/dropdown-menu/dropdown-menu.web.tsx +521 -0
  30. package/dist/generated/components/primitives/dropdown-menu/index.ts +1 -0
  31. package/dist/generated/components/primitives/dropdown-menu/types.ts +71 -0
  32. package/dist/generated/components/primitives/hooks/index.ts +3 -0
  33. package/dist/generated/components/primitives/hooks/useAugmentedRef.tsx +29 -0
  34. package/dist/generated/components/primitives/hooks/useControllableState.tsx +75 -0
  35. package/dist/generated/components/primitives/hooks/useRelativePosition.tsx +227 -0
  36. package/dist/generated/components/primitives/hover-card/hover-card.tsx +271 -0
  37. package/dist/generated/components/primitives/hover-card/hover-card.web.tsx +145 -0
  38. package/dist/generated/components/primitives/hover-card/index.ts +1 -0
  39. package/dist/generated/components/primitives/hover-card/types.ts +42 -0
  40. package/dist/generated/components/primitives/label/index.ts +1 -0
  41. package/dist/generated/components/primitives/label/label.tsx +31 -0
  42. package/dist/generated/components/primitives/label/label.web.tsx +36 -0
  43. package/dist/generated/components/primitives/label/types.ts +15 -0
  44. package/dist/generated/components/primitives/menubar/index.ts +1 -0
  45. package/dist/generated/components/primitives/menubar/menubar.tsx +624 -0
  46. package/dist/generated/components/primitives/menubar/menubar.web.tsx +543 -0
  47. package/dist/generated/components/primitives/menubar/types.ts +76 -0
  48. package/dist/generated/components/primitives/navigation-menu/index.ts +1 -0
  49. package/dist/generated/components/primitives/navigation-menu/navigation-menu.tsx +315 -0
  50. package/dist/generated/components/primitives/navigation-menu/navigation-menu.web.tsx +264 -0
  51. package/dist/generated/components/primitives/navigation-menu/types.ts +49 -0
  52. package/dist/generated/components/primitives/popover/index.ts +1 -0
  53. package/dist/generated/components/primitives/popover/popover.tsx +286 -0
  54. package/dist/generated/components/primitives/popover/popover.web.tsx +179 -0
  55. package/dist/generated/components/primitives/popover/types.ts +30 -0
  56. package/dist/generated/components/primitives/portal.tsx +67 -0
  57. package/dist/generated/components/primitives/progress/index.ts +1 -0
  58. package/dist/generated/components/primitives/progress/progress.tsx +59 -0
  59. package/dist/generated/components/primitives/progress/progress.web.tsx +36 -0
  60. package/dist/generated/components/primitives/progress/types.ts +7 -0
  61. package/dist/generated/components/primitives/radio-group/index.ts +1 -0
  62. package/dist/generated/components/primitives/radio-group/radio-group.tsx +116 -0
  63. package/dist/generated/components/primitives/radio-group/radio-group.web.tsx +78 -0
  64. package/dist/generated/components/primitives/radio-group/types.ts +15 -0
  65. package/dist/generated/components/primitives/select/index.ts +1 -0
  66. package/dist/generated/components/primitives/select/select.tsx +455 -0
  67. package/dist/generated/components/primitives/select/select.web.tsx +319 -0
  68. package/dist/generated/components/primitives/select/types.ts +87 -0
  69. package/dist/generated/components/primitives/separator/ types.ts +6 -0
  70. package/dist/generated/components/primitives/separator/index.tsx +23 -0
  71. package/dist/generated/components/primitives/slider/index.ts +1 -0
  72. package/dist/generated/components/primitives/slider/slider.tsx +89 -0
  73. package/dist/generated/components/primitives/slider/slider.web.tsx +67 -0
  74. package/dist/generated/components/primitives/slider/types.ts +24 -0
  75. package/dist/generated/components/primitives/slot.tsx +187 -0
  76. package/dist/generated/components/primitives/switch/index.ts +1 -0
  77. package/dist/generated/components/primitives/switch/switch.tsx +65 -0
  78. package/dist/generated/components/primitives/switch/switch.web.tsx +67 -0
  79. package/dist/generated/components/primitives/switch/types.ts +11 -0
  80. package/dist/generated/components/primitives/table.tsx +55 -0
  81. package/dist/generated/components/primitives/tabs/index.ts +1 -0
  82. package/dist/generated/components/primitives/tabs/tabs.tsx +133 -0
  83. package/dist/generated/components/primitives/tabs/tabs.web.tsx +97 -0
  84. package/dist/generated/components/primitives/tabs/types.ts +24 -0
  85. package/dist/generated/components/primitives/toast/ types.ts +7 -0
  86. package/dist/generated/components/primitives/toast/index.tsx +128 -0
  87. package/dist/generated/components/primitives/toggle/index.ts +1 -0
  88. package/dist/generated/components/primitives/toggle/toggle.tsx +37 -0
  89. package/dist/generated/components/primitives/toggle/toggle.web.tsx +26 -0
  90. package/dist/generated/components/primitives/toggle/types.ts +7 -0
  91. package/dist/generated/components/primitives/toggle-group/index.ts +1 -0
  92. package/dist/generated/components/primitives/toggle-group/toggle-group.tsx +125 -0
  93. package/dist/generated/components/primitives/toggle-group/toggle-group.web.tsx +124 -0
  94. package/dist/generated/components/primitives/toggle-group/types.ts +37 -0
  95. package/dist/generated/components/primitives/toolbar/index.ts +1 -0
  96. package/dist/generated/components/primitives/toolbar/toolbar.tsx +125 -0
  97. package/dist/generated/components/primitives/toolbar/toolbar.web.tsx +129 -0
  98. package/dist/generated/components/primitives/toolbar/types.ts +39 -0
  99. package/dist/generated/components/primitives/tooltip/index.ts +1 -0
  100. package/dist/generated/components/primitives/tooltip/tooltip.tsx +271 -0
  101. package/dist/generated/components/primitives/tooltip/tooltip.web.tsx +167 -0
  102. package/dist/generated/components/primitives/tooltip/types.ts +44 -0
  103. package/dist/generated/components/primitives/types.ts +105 -0
  104. package/dist/generated/components/primitives/utils.ts +61 -0
  105. package/dist/generated/components/ui/accordion.tsx +127 -0
  106. package/dist/generated/components/ui/alert-dialog.tsx +167 -0
  107. package/dist/generated/components/ui/aspect-ratio.tsx +5 -0
  108. package/dist/generated/components/ui/avatar.tsx +44 -0
  109. package/dist/generated/components/ui/badge.tsx +51 -0
  110. package/dist/generated/components/ui/button.tsx +88 -0
  111. package/dist/generated/components/ui/card.tsx +67 -0
  112. package/dist/generated/components/ui/checkbox.tsx +34 -0
  113. package/dist/generated/components/ui/collapsible.tsx +9 -0
  114. package/dist/generated/components/ui/context-menu.tsx +244 -0
  115. package/dist/generated/components/ui/dialog.tsx +150 -0
  116. package/dist/generated/components/ui/dropdown-menu.tsx +244 -0
  117. package/dist/generated/components/ui/hover-card.tsx +45 -0
  118. package/dist/generated/components/ui/input.tsx +26 -0
  119. package/dist/generated/components/ui/label.tsx +28 -0
  120. package/dist/generated/components/ui/menubar.tsx +260 -0
  121. package/dist/generated/components/ui/navigation-menu.tsx +177 -0
  122. package/dist/generated/components/ui/popover.tsx +39 -0
  123. package/dist/generated/components/ui/radio-group.tsx +38 -0
  124. package/dist/generated/components/ui/select.tsx +181 -0
  125. package/dist/generated/components/ui/separator.tsx +23 -0
  126. package/dist/generated/components/ui/skeleton.tsx +39 -0
  127. package/dist/generated/components/ui/switch.tsx +97 -0
  128. package/dist/generated/components/ui/table.tsx +99 -0
  129. package/dist/generated/components/ui/tabs.tsx +65 -0
  130. package/dist/generated/components/ui/text.tsx +24 -0
  131. package/dist/generated/components/ui/textarea.tsx +28 -0
  132. package/dist/generated/components/ui/toggle-group.tsx +86 -0
  133. package/dist/generated/components/ui/toggle.tsx +85 -0
  134. package/dist/generated/components/ui/tooltip.tsx +36 -0
  135. package/dist/generated/components/ui/typography.tsx +204 -0
  136. package/package.json +8 -8
@@ -0,0 +1,116 @@
1
+ import * as React from 'react';
2
+ import { Pressable, View, type GestureResponderEvent } from 'react-native';
3
+ import * as Slot from '@rnr/slot';
4
+ import type {
5
+ ForceMountable,
6
+ PressableRef,
7
+ SlottablePressableProps,
8
+ SlottableViewProps,
9
+ ViewRef,
10
+ } from '@rnr/types';
11
+ import type { RadioGroupItemProps, RadioGroupRootProps } from './types';
12
+
13
+ const RadioGroupContext = React.createContext<RadioGroupRootProps | null>(null);
14
+
15
+ const Root = React.forwardRef<ViewRef, SlottableViewProps & RadioGroupRootProps>(
16
+ ({ asChild, value, onValueChange, disabled = false, ...viewProps }, ref) => {
17
+ const Component = asChild ? Slot.View : View;
18
+ return (
19
+ <RadioGroupContext.Provider
20
+ value={{
21
+ value,
22
+ disabled,
23
+ onValueChange,
24
+ }}
25
+ >
26
+ <Component ref={ref} role='radiogroup' {...viewProps} />
27
+ </RadioGroupContext.Provider>
28
+ );
29
+ }
30
+ );
31
+
32
+ Root.displayName = 'RootRadioGroup';
33
+
34
+ function useRadioGroupContext() {
35
+ const context = React.useContext(RadioGroupContext);
36
+ if (!context) {
37
+ throw new Error(
38
+ 'RadioGroup compound components cannot be rendered outside the RadioGroup component'
39
+ );
40
+ }
41
+ return context;
42
+ }
43
+
44
+ interface RadioItemContext {
45
+ itemValue: string | undefined;
46
+ }
47
+
48
+ const RadioItemContext = React.createContext<RadioItemContext | null>(null);
49
+
50
+ const Item = React.forwardRef<PressableRef, SlottablePressableProps & RadioGroupItemProps>(
51
+ (
52
+ { asChild, value: itemValue, disabled: disabledProp = false, onPress: onPressProp, ...props },
53
+ ref
54
+ ) => {
55
+ const { disabled, value, onValueChange } = useRadioGroupContext();
56
+
57
+ function onPress(ev: GestureResponderEvent) {
58
+ if (disabled || disabledProp) return;
59
+ onValueChange(itemValue);
60
+ onPressProp?.(ev);
61
+ }
62
+
63
+ const Component = asChild ? Slot.Pressable : Pressable;
64
+ return (
65
+ <RadioItemContext.Provider
66
+ value={{
67
+ itemValue: itemValue,
68
+ }}
69
+ >
70
+ <Component
71
+ ref={ref}
72
+ role='radio'
73
+ onPress={onPress}
74
+ aria-checked={value === itemValue}
75
+ disabled={(disabled || disabledProp) ?? false}
76
+ accessibilityState={{
77
+ disabled: (disabled || disabledProp) ?? false,
78
+ checked: value === itemValue,
79
+ }}
80
+ {...props}
81
+ />
82
+ </RadioItemContext.Provider>
83
+ );
84
+ }
85
+ );
86
+
87
+ Item.displayName = 'ItemRadioGroup';
88
+
89
+ function useRadioItemContext() {
90
+ const context = React.useContext(RadioItemContext);
91
+ if (!context) {
92
+ throw new Error(
93
+ 'RadioItem compound components cannot be rendered outside the RadioItem component'
94
+ );
95
+ }
96
+ return context;
97
+ }
98
+
99
+ const Indicator = React.forwardRef<ViewRef, SlottableViewProps & ForceMountable>(
100
+ ({ asChild, forceMount, ...props }, ref) => {
101
+ const { value } = useRadioGroupContext();
102
+ const { itemValue } = useRadioItemContext();
103
+
104
+ if (!forceMount) {
105
+ if (value !== itemValue) {
106
+ return null;
107
+ }
108
+ }
109
+ const Component = asChild ? Slot.View : View;
110
+ return <Component ref={ref} role='presentation' {...props} />;
111
+ }
112
+ );
113
+
114
+ Indicator.displayName = 'IndicatorRadioGroup';
115
+
116
+ export { Indicator, Item, Root };
@@ -0,0 +1,78 @@
1
+ import * as RadioGroup from '@radix-ui/react-radio-group';
2
+ import * as React from 'react';
3
+ import { GestureResponderEvent, Pressable, View } from 'react-native';
4
+ import * as Slot from '@rnr/slot';
5
+ import type {
6
+ ForceMountable,
7
+ PressableRef,
8
+ SlottablePressableProps,
9
+ SlottableViewProps,
10
+ ViewRef,
11
+ } from '@rnr/types';
12
+ import type { RadioGroupItemProps, RadioGroupRootProps } from './types';
13
+ const RadioGroupContext = React.createContext<RadioGroupRootProps | null>(null);
14
+ const Root = React.forwardRef<ViewRef, SlottableViewProps & RadioGroupRootProps>(
15
+ ({ asChild, value, onValueChange, disabled = false, ...viewProps }, ref) => {
16
+ const Component = asChild ? Slot.View : View;
17
+ return (
18
+ <RadioGroupContext.Provider
19
+ value={{
20
+ value,
21
+ disabled,
22
+ onValueChange,
23
+ }}
24
+ >
25
+ <RadioGroup.Root value={value} onValueChange={onValueChange} disabled={disabled} asChild>
26
+ <Component ref={ref} {...viewProps} />
27
+ </RadioGroup.Root>
28
+ </RadioGroupContext.Provider>
29
+ );
30
+ }
31
+ );
32
+
33
+ Root.displayName = 'RootRadioGroup';
34
+ function useRadioGroupContext() {
35
+ const context = React.useContext(RadioGroupContext);
36
+ if (!context) {
37
+ throw new Error(
38
+ 'RadioGroup compound components cannot be rendered outside the RadioGroup component'
39
+ );
40
+ }
41
+ return context;
42
+ }
43
+ const Item = React.forwardRef<PressableRef, SlottablePressableProps & RadioGroupItemProps>(
44
+ ({ asChild, value, onPress: onPressProps, ...props }, ref) => {
45
+ const { onValueChange } = useRadioGroupContext();
46
+
47
+ function onPress(ev: GestureResponderEvent) {
48
+ if (onPressProps) {
49
+ onPressProps(ev);
50
+ }
51
+ onValueChange(value);
52
+ }
53
+
54
+ const Component = asChild ? Slot.Pressable : Pressable;
55
+ return (
56
+ <RadioGroup.Item value={value} asChild>
57
+ <Component ref={ref} onPress={onPress} {...props} />
58
+ </RadioGroup.Item>
59
+ );
60
+ }
61
+ );
62
+
63
+ Item.displayName = 'ItemRadioGroup';
64
+
65
+ const Indicator = React.forwardRef<ViewRef, SlottableViewProps & ForceMountable>(
66
+ ({ asChild, forceMount, ...props }, ref) => {
67
+ const Component = asChild ? Slot.View : View;
68
+ return (
69
+ <RadioGroup.Indicator asChild>
70
+ <Component ref={ref} {...props} />
71
+ </RadioGroup.Indicator>
72
+ );
73
+ }
74
+ );
75
+
76
+ Indicator.displayName = 'IndicatorRadioGroup';
77
+
78
+ export { Indicator, Item, Root };
@@ -0,0 +1,15 @@
1
+ interface RadioGroupRootProps {
2
+ value: string | undefined;
3
+ onValueChange: (val: string) => void;
4
+ disabled?: boolean;
5
+ }
6
+
7
+ interface RadioGroupItemProps {
8
+ value: string;
9
+ /**
10
+ * nativeID of the label element that describes this radio group item
11
+ */
12
+ 'aria-labelledby': string;
13
+ }
14
+
15
+ export type { RadioGroupRootProps, RadioGroupItemProps };
@@ -0,0 +1 @@
1
+ export * from './select';
@@ -0,0 +1,455 @@
1
+ import { useControllableState, useRelativePosition, type LayoutPosition } from '@rnr/hooks';
2
+ import { Portal as RNPPortal } from '@rnr/portal';
3
+ import * as Slot from '@rnr/slot';
4
+ import type {
5
+ ForceMountable,
6
+ PositionedContentProps,
7
+ PressableRef,
8
+ SlottablePressableProps,
9
+ SlottableTextProps,
10
+ SlottableViewProps,
11
+ TextRef,
12
+ ViewRef,
13
+ } from '@rnr/types';
14
+ import * as React from 'react';
15
+ import {
16
+ BackHandler,
17
+ Pressable,
18
+ Text,
19
+ View,
20
+ type GestureResponderEvent,
21
+ type LayoutChangeEvent,
22
+ type LayoutRectangle,
23
+ } from 'react-native';
24
+ import type {
25
+ RootContext,
26
+ SelectContentProps,
27
+ SelectItemProps,
28
+ SelectOverlayProps,
29
+ SelectPortalProps,
30
+ SelectRootProps,
31
+ SelectSeparatorProps,
32
+ SelectValueProps,
33
+ } from './types';
34
+
35
+ interface IRootContext extends RootContext {
36
+ triggerPosition: LayoutPosition | null;
37
+ setTriggerPosition: (triggerPosition: LayoutPosition | null) => void;
38
+ contentLayout: LayoutRectangle | null;
39
+ setContentLayout: (contentLayout: LayoutRectangle | null) => void;
40
+ nativeID: string;
41
+ }
42
+
43
+ const RootContext = React.createContext<IRootContext | null>(null);
44
+
45
+ const Root = React.forwardRef<ViewRef, SlottableViewProps & SelectRootProps>(
46
+ (
47
+ {
48
+ asChild,
49
+ value: valueProp,
50
+ defaultValue,
51
+ onValueChange: onValueChangeProp,
52
+ open: openProp,
53
+ defaultOpen,
54
+ onOpenChange: onOpenChangeProp,
55
+ disabled,
56
+ ...viewProps
57
+ },
58
+ ref
59
+ ) => {
60
+ const nativeID = React.useId();
61
+ const [open = false, onOpenChange] = useControllableState({
62
+ prop: openProp,
63
+ defaultProp: defaultOpen,
64
+ onChange: onOpenChangeProp,
65
+ });
66
+ const [value, onValueChange] = useControllableState({
67
+ prop: valueProp,
68
+ defaultProp: defaultValue,
69
+ onChange: onValueChangeProp,
70
+ });
71
+ const [triggerPosition, setTriggerPosition] = React.useState<LayoutPosition | null>(null);
72
+ const [contentLayout, setContentLayout] = React.useState<LayoutRectangle | null>(null);
73
+
74
+ const Component = asChild ? Slot.View : View;
75
+ return (
76
+ <RootContext.Provider
77
+ value={{
78
+ value,
79
+ onValueChange,
80
+ open,
81
+ onOpenChange,
82
+ disabled,
83
+ contentLayout,
84
+ nativeID,
85
+ setContentLayout,
86
+ setTriggerPosition,
87
+ triggerPosition,
88
+ }}
89
+ >
90
+ <Component ref={ref} {...viewProps} />
91
+ </RootContext.Provider>
92
+ );
93
+ }
94
+ );
95
+
96
+ Root.displayName = 'RootNativeSelect';
97
+
98
+ function useRootContext() {
99
+ const context = React.useContext(RootContext);
100
+ if (!context) {
101
+ throw new Error('Select compound components cannot be rendered outside the Select component');
102
+ }
103
+ return context;
104
+ }
105
+
106
+ const Trigger = React.forwardRef<PressableRef, SlottablePressableProps>(
107
+ ({ asChild, onPress: onPressProp, disabled = false, ...props }, ref) => {
108
+ const triggerRef = React.useRef<View>(null);
109
+ const { open, onOpenChange, disabled: disabledRoot, setTriggerPosition } = useRootContext();
110
+
111
+ React.useImperativeHandle(
112
+ ref,
113
+ () => {
114
+ if (!triggerRef.current) {
115
+ return new View({});
116
+ }
117
+ return triggerRef.current;
118
+ },
119
+ [triggerRef.current]
120
+ );
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: pageY, height });
126
+ });
127
+ onOpenChange(!open);
128
+ onPressProp?.(ev);
129
+ }
130
+
131
+ const Component = asChild ? Slot.Pressable : Pressable;
132
+ return (
133
+ <Component
134
+ ref={triggerRef}
135
+ aria-disabled={disabled ?? undefined}
136
+ role='combobox'
137
+ onPress={onPress}
138
+ disabled={disabled ?? disabledRoot}
139
+ aria-expanded={open}
140
+ {...props}
141
+ />
142
+ );
143
+ }
144
+ );
145
+
146
+ Trigger.displayName = 'TriggerNativeSelect';
147
+
148
+ const Value = React.forwardRef<TextRef, SlottableTextProps & SelectValueProps>(
149
+ ({ asChild, placeholder, ...props }, ref) => {
150
+ const { value } = useRootContext();
151
+ const Component = asChild ? Slot.Text : Text;
152
+ return (
153
+ <Component ref={ref} {...props}>
154
+ {value?.label ?? placeholder}
155
+ </Component>
156
+ );
157
+ }
158
+ );
159
+
160
+ Value.displayName = 'ValueNativeSelect';
161
+
162
+ /**
163
+ * @warning when using a custom `<PortalHost />`, you might have to adjust the Content's sideOffset.
164
+ */
165
+ function Portal({ forceMount, hostName, children }: SelectPortalProps) {
166
+ const value = useRootContext();
167
+
168
+ if (!value.triggerPosition) {
169
+ return null;
170
+ }
171
+
172
+ if (!forceMount) {
173
+ if (!value.open) {
174
+ return null;
175
+ }
176
+ }
177
+
178
+ return (
179
+ <RNPPortal hostName={hostName} name={`${value.nativeID}_portal`}>
180
+ <RootContext.Provider value={value}>{children}</RootContext.Provider>
181
+ </RNPPortal>
182
+ );
183
+ }
184
+
185
+ const Overlay = React.forwardRef<PressableRef, SlottablePressableProps & SelectOverlayProps>(
186
+ ({ asChild, forceMount, onPress: OnPressProp, closeOnPress = true, ...props }, ref) => {
187
+ const { open, onOpenChange, setTriggerPosition, setContentLayout } = useRootContext();
188
+
189
+ function onPress(ev: GestureResponderEvent) {
190
+ if (closeOnPress) {
191
+ setTriggerPosition(null);
192
+ setContentLayout(null);
193
+ onOpenChange(false);
194
+ }
195
+ OnPressProp?.(ev);
196
+ }
197
+
198
+ if (!forceMount) {
199
+ if (!open) {
200
+ return null;
201
+ }
202
+ }
203
+
204
+ const Component = asChild ? Slot.Pressable : Pressable;
205
+ return <Component ref={ref} onPress={onPress} {...props} />;
206
+ }
207
+ );
208
+
209
+ Overlay.displayName = 'OverlayNativeSelect';
210
+
211
+ /**
212
+ * @info `position`, `top`, `left`, and `maxWidth` style properties are controlled internally. Opt out of this behavior by setting `disablePositioningStyle` to `true`.
213
+ */
214
+ const Content = React.forwardRef<
215
+ ViewRef,
216
+ SlottableViewProps & PositionedContentProps & SelectContentProps
217
+ >(
218
+ (
219
+ {
220
+ asChild = false,
221
+ forceMount,
222
+ align = 'start',
223
+ side = 'bottom',
224
+ sideOffset = 0,
225
+ alignOffset = 0,
226
+ avoidCollisions = true,
227
+ onLayout: onLayoutProp,
228
+ insets,
229
+ style,
230
+ disablePositioningStyle,
231
+ position: _position,
232
+ ...props
233
+ },
234
+ ref
235
+ ) => {
236
+ const {
237
+ open,
238
+ onOpenChange,
239
+ contentLayout,
240
+ nativeID,
241
+ triggerPosition,
242
+ setContentLayout,
243
+ setTriggerPosition,
244
+ } = useRootContext();
245
+
246
+ React.useEffect(() => {
247
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
248
+ setTriggerPosition(null);
249
+ setContentLayout(null);
250
+ onOpenChange(false);
251
+ return true;
252
+ });
253
+
254
+ return () => {
255
+ setContentLayout(null);
256
+ backHandler.remove();
257
+ };
258
+ }, []);
259
+
260
+ const positionStyle = useRelativePosition({
261
+ align,
262
+ avoidCollisions,
263
+ triggerPosition,
264
+ contentLayout,
265
+ alignOffset,
266
+ insets,
267
+ sideOffset,
268
+ side,
269
+ disablePositioningStyle,
270
+ });
271
+
272
+ function onLayout(event: LayoutChangeEvent) {
273
+ setContentLayout(event.nativeEvent.layout);
274
+ onLayoutProp?.(event);
275
+ }
276
+
277
+ if (!forceMount) {
278
+ if (!open) {
279
+ return null;
280
+ }
281
+ }
282
+
283
+ const Component = asChild ? Slot.View : View;
284
+ return (
285
+ <Component
286
+ ref={ref}
287
+ role='list'
288
+ nativeID={nativeID}
289
+ aria-modal={true}
290
+ style={[positionStyle, style]}
291
+ onLayout={onLayout}
292
+ onStartShouldSetResponder={onStartShouldSetResponder}
293
+ {...props}
294
+ />
295
+ );
296
+ }
297
+ );
298
+
299
+ Content.displayName = 'ContentNativeSelect';
300
+
301
+ const ItemContext = React.createContext<{
302
+ itemValue: string;
303
+ label: string;
304
+ } | null>(null);
305
+
306
+ const Item = React.forwardRef<PressableRef, SlottablePressableProps & SelectItemProps>(
307
+ (
308
+ {
309
+ asChild,
310
+ value: itemValue,
311
+ label,
312
+ onPress: onPressProp,
313
+ disabled = false,
314
+ closeOnPress = true,
315
+ ...props
316
+ },
317
+ ref
318
+ ) => {
319
+ const { onOpenChange, value, onValueChange, setTriggerPosition, setContentLayout } =
320
+ useRootContext();
321
+ function onPress(ev: GestureResponderEvent) {
322
+ if (closeOnPress) {
323
+ setTriggerPosition(null);
324
+ setContentLayout(null);
325
+ onOpenChange(false);
326
+ }
327
+
328
+ onValueChange({ value: itemValue, label });
329
+ onPressProp?.(ev);
330
+ }
331
+
332
+ const Component = asChild ? Slot.Pressable : Pressable;
333
+ return (
334
+ <ItemContext.Provider value={{ itemValue, label }}>
335
+ <Component
336
+ ref={ref}
337
+ role='option'
338
+ onPress={onPress}
339
+ disabled={disabled}
340
+ aria-checked={value?.value === itemValue}
341
+ aria-valuetext={label}
342
+ aria-disabled={!!disabled}
343
+ accessibilityState={{
344
+ disabled: !!disabled,
345
+ checked: value?.value === itemValue,
346
+ }}
347
+ {...props}
348
+ />
349
+ </ItemContext.Provider>
350
+ );
351
+ }
352
+ );
353
+
354
+ Item.displayName = 'ItemNativeSelect';
355
+
356
+ function useItemContext() {
357
+ const context = React.useContext(ItemContext);
358
+ if (!context) {
359
+ throw new Error('Item compound components cannot be rendered outside of an Item component');
360
+ }
361
+ return context;
362
+ }
363
+
364
+ const ItemText = React.forwardRef<TextRef, Omit<SlottableTextProps, 'children'>>(
365
+ ({ asChild, ...props }, ref) => {
366
+ const { label } = useItemContext();
367
+
368
+ const Component = asChild ? Slot.Text : Text;
369
+ return (
370
+ <Component ref={ref} {...props}>
371
+ {label}
372
+ </Component>
373
+ );
374
+ }
375
+ );
376
+
377
+ ItemText.displayName = 'ItemTextNativeSelect';
378
+
379
+ const ItemIndicator = React.forwardRef<ViewRef, SlottableViewProps & ForceMountable>(
380
+ ({ asChild, forceMount, ...props }, ref) => {
381
+ const { itemValue } = useItemContext();
382
+ const { value } = useRootContext();
383
+
384
+ if (!forceMount) {
385
+ if (value?.value !== itemValue) {
386
+ return null;
387
+ }
388
+ }
389
+ const Component = asChild ? Slot.View : View;
390
+ return <Component ref={ref} role='presentation' {...props} />;
391
+ }
392
+ );
393
+
394
+ ItemIndicator.displayName = 'ItemIndicatorNativeSelect';
395
+
396
+ const Group = React.forwardRef<ViewRef, SlottableViewProps>(({ asChild, ...props }, ref) => {
397
+ const Component = asChild ? Slot.View : View;
398
+ return <Component ref={ref} role='group' {...props} />;
399
+ });
400
+
401
+ Group.displayName = 'GroupNativeSelect';
402
+
403
+ const Label = React.forwardRef<TextRef, SlottableTextProps>(({ asChild, ...props }, ref) => {
404
+ const Component = asChild ? Slot.Text : Text;
405
+ return <Component ref={ref} {...props} />;
406
+ });
407
+
408
+ Label.displayName = 'LabelNativeSelect';
409
+
410
+ const Separator = React.forwardRef<ViewRef, SlottableViewProps & SelectSeparatorProps>(
411
+ ({ asChild, decorative, ...props }, ref) => {
412
+ const Component = asChild ? Slot.View : View;
413
+ return <Component role={decorative ? 'presentation' : 'separator'} ref={ref} {...props} />;
414
+ }
415
+ );
416
+
417
+ Separator.displayName = 'SeparatorNativeSelect';
418
+
419
+ const ScrollUpButton = ({ children }: { children?: React.ReactNode; className?: string }) => {
420
+ return children;
421
+ };
422
+
423
+ const ScrollDownButton = ({ children }: { children?: React.ReactNode; className?: string }) => {
424
+ return children;
425
+ };
426
+
427
+ const Viewport = ({ children }: { children?: React.ReactNode; className?: string }) => {
428
+ return children;
429
+ };
430
+
431
+ export {
432
+ Content,
433
+ Group,
434
+ Item,
435
+ ItemIndicator,
436
+ ItemText,
437
+ Label,
438
+ Overlay,
439
+ Portal,
440
+ Root,
441
+ ScrollDownButton,
442
+ ScrollUpButton,
443
+ Separator,
444
+ Trigger,
445
+ Value,
446
+ Viewport,
447
+ useItemContext,
448
+ useRootContext,
449
+ };
450
+
451
+ export type { Option } from './types';
452
+
453
+ function onStartShouldSetResponder() {
454
+ return true;
455
+ }