@react-native-reusables/cli 0.0.9 → 0.0.11

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 (137) hide show
  1. package/README.md +95 -5
  2. package/dist/generated/components/primitives/accordion/accordion.tsx +216 -0
  3. package/dist/generated/components/primitives/accordion/accordion.web.tsx +295 -0
  4. package/dist/generated/components/primitives/accordion/index.ts +1 -0
  5. package/dist/generated/components/primitives/accordion/types.ts +45 -0
  6. package/dist/generated/components/primitives/alert-dialog/alert-dialog.tsx +237 -0
  7. package/dist/generated/components/primitives/alert-dialog/alert-dialog.web.tsx +256 -0
  8. package/dist/generated/components/primitives/alert-dialog/index.ts +1 -0
  9. package/dist/generated/components/primitives/alert-dialog/types.ts +48 -0
  10. package/dist/generated/components/primitives/aspect-ratio.tsx +23 -0
  11. package/dist/generated/components/primitives/avatar/ types.ts +10 -0
  12. package/dist/generated/components/primitives/avatar/index.tsx +95 -0
  13. package/dist/generated/components/primitives/checkbox/checkbox.tsx +101 -0
  14. package/dist/generated/components/primitives/checkbox/checkbox.web.tsx +114 -0
  15. package/dist/generated/components/primitives/checkbox/index.ts +1 -0
  16. package/dist/generated/components/primitives/checkbox/types.ts +11 -0
  17. package/dist/generated/components/primitives/collapsible/collapsible.tsx +119 -0
  18. package/dist/generated/components/primitives/collapsible/collapsible.web.tsx +157 -0
  19. package/dist/generated/components/primitives/collapsible/index.ts +1 -0
  20. package/dist/generated/components/primitives/collapsible/types.ts +18 -0
  21. package/dist/generated/components/primitives/context-menu/context-menu.tsx +626 -0
  22. package/dist/generated/components/primitives/context-menu/context-menu.web.tsx +504 -0
  23. package/dist/generated/components/primitives/context-menu/index.ts +1 -0
  24. package/dist/generated/components/primitives/context-menu/types.ts +82 -0
  25. package/dist/generated/components/primitives/dialog/dialog.tsx +211 -0
  26. package/dist/generated/components/primitives/dialog/dialog.web.tsx +197 -0
  27. package/dist/generated/components/primitives/dialog/index.ts +1 -0
  28. package/dist/generated/components/primitives/dialog/types.ts +60 -0
  29. package/dist/generated/components/primitives/dropdown-menu/dropdown-menu.tsx +584 -0
  30. package/dist/generated/components/primitives/dropdown-menu/dropdown-menu.web.tsx +521 -0
  31. package/dist/generated/components/primitives/dropdown-menu/index.ts +1 -0
  32. package/dist/generated/components/primitives/dropdown-menu/types.ts +71 -0
  33. package/dist/generated/components/primitives/hooks/index.ts +3 -0
  34. package/dist/generated/components/primitives/hooks/useAugmentedRef.tsx +29 -0
  35. package/dist/generated/components/primitives/hooks/useControllableState.tsx +75 -0
  36. package/dist/generated/components/primitives/hooks/useRelativePosition.tsx +227 -0
  37. package/dist/generated/components/primitives/hover-card/hover-card.tsx +271 -0
  38. package/dist/generated/components/primitives/hover-card/hover-card.web.tsx +145 -0
  39. package/dist/generated/components/primitives/hover-card/index.ts +1 -0
  40. package/dist/generated/components/primitives/hover-card/types.ts +42 -0
  41. package/dist/generated/components/primitives/label/index.ts +1 -0
  42. package/dist/generated/components/primitives/label/label.tsx +31 -0
  43. package/dist/generated/components/primitives/label/label.web.tsx +36 -0
  44. package/dist/generated/components/primitives/label/types.ts +15 -0
  45. package/dist/generated/components/primitives/menubar/index.ts +1 -0
  46. package/dist/generated/components/primitives/menubar/menubar.tsx +624 -0
  47. package/dist/generated/components/primitives/menubar/menubar.web.tsx +543 -0
  48. package/dist/generated/components/primitives/menubar/types.ts +76 -0
  49. package/dist/generated/components/primitives/navigation-menu/index.ts +1 -0
  50. package/dist/generated/components/primitives/navigation-menu/navigation-menu.tsx +315 -0
  51. package/dist/generated/components/primitives/navigation-menu/navigation-menu.web.tsx +264 -0
  52. package/dist/generated/components/primitives/navigation-menu/types.ts +49 -0
  53. package/dist/generated/components/primitives/popover/index.ts +1 -0
  54. package/dist/generated/components/primitives/popover/popover.tsx +286 -0
  55. package/dist/generated/components/primitives/popover/popover.web.tsx +179 -0
  56. package/dist/generated/components/primitives/popover/types.ts +30 -0
  57. package/dist/generated/components/primitives/portal.tsx +67 -0
  58. package/dist/generated/components/primitives/progress/index.ts +1 -0
  59. package/dist/generated/components/primitives/progress/progress.tsx +59 -0
  60. package/dist/generated/components/primitives/progress/progress.web.tsx +36 -0
  61. package/dist/generated/components/primitives/progress/types.ts +7 -0
  62. package/dist/generated/components/primitives/radio-group/index.ts +1 -0
  63. package/dist/generated/components/primitives/radio-group/radio-group.tsx +116 -0
  64. package/dist/generated/components/primitives/radio-group/radio-group.web.tsx +78 -0
  65. package/dist/generated/components/primitives/radio-group/types.ts +15 -0
  66. package/dist/generated/components/primitives/select/index.ts +1 -0
  67. package/dist/generated/components/primitives/select/select.tsx +455 -0
  68. package/dist/generated/components/primitives/select/select.web.tsx +319 -0
  69. package/dist/generated/components/primitives/select/types.ts +87 -0
  70. package/dist/generated/components/primitives/separator/ types.ts +6 -0
  71. package/dist/generated/components/primitives/separator/index.tsx +23 -0
  72. package/dist/generated/components/primitives/slider/index.ts +1 -0
  73. package/dist/generated/components/primitives/slider/slider.tsx +89 -0
  74. package/dist/generated/components/primitives/slider/slider.web.tsx +67 -0
  75. package/dist/generated/components/primitives/slider/types.ts +24 -0
  76. package/dist/generated/components/primitives/slot.tsx +187 -0
  77. package/dist/generated/components/primitives/switch/index.ts +1 -0
  78. package/dist/generated/components/primitives/switch/switch.tsx +65 -0
  79. package/dist/generated/components/primitives/switch/switch.web.tsx +67 -0
  80. package/dist/generated/components/primitives/switch/types.ts +11 -0
  81. package/dist/generated/components/primitives/table.tsx +55 -0
  82. package/dist/generated/components/primitives/tabs/index.ts +1 -0
  83. package/dist/generated/components/primitives/tabs/tabs.tsx +133 -0
  84. package/dist/generated/components/primitives/tabs/tabs.web.tsx +97 -0
  85. package/dist/generated/components/primitives/tabs/types.ts +24 -0
  86. package/dist/generated/components/primitives/toast/ types.ts +7 -0
  87. package/dist/generated/components/primitives/toast/index.tsx +128 -0
  88. package/dist/generated/components/primitives/toggle/index.ts +1 -0
  89. package/dist/generated/components/primitives/toggle/toggle.tsx +37 -0
  90. package/dist/generated/components/primitives/toggle/toggle.web.tsx +26 -0
  91. package/dist/generated/components/primitives/toggle/types.ts +7 -0
  92. package/dist/generated/components/primitives/toggle-group/index.ts +1 -0
  93. package/dist/generated/components/primitives/toggle-group/toggle-group.tsx +125 -0
  94. package/dist/generated/components/primitives/toggle-group/toggle-group.web.tsx +124 -0
  95. package/dist/generated/components/primitives/toggle-group/types.ts +37 -0
  96. package/dist/generated/components/primitives/toolbar/index.ts +1 -0
  97. package/dist/generated/components/primitives/toolbar/toolbar.tsx +125 -0
  98. package/dist/generated/components/primitives/toolbar/toolbar.web.tsx +129 -0
  99. package/dist/generated/components/primitives/toolbar/types.ts +39 -0
  100. package/dist/generated/components/primitives/tooltip/index.ts +1 -0
  101. package/dist/generated/components/primitives/tooltip/tooltip.tsx +271 -0
  102. package/dist/generated/components/primitives/tooltip/tooltip.web.tsx +167 -0
  103. package/dist/generated/components/primitives/tooltip/types.ts +44 -0
  104. package/dist/generated/components/primitives/types.ts +105 -0
  105. package/dist/generated/components/primitives/utils.ts +61 -0
  106. package/dist/generated/components/ui/accordion.tsx +127 -0
  107. package/dist/generated/components/ui/alert-dialog.tsx +167 -0
  108. package/dist/generated/components/ui/aspect-ratio.tsx +5 -0
  109. package/dist/generated/components/ui/avatar.tsx +44 -0
  110. package/dist/generated/components/ui/badge.tsx +51 -0
  111. package/dist/generated/components/ui/button.tsx +88 -0
  112. package/dist/generated/components/ui/card.tsx +67 -0
  113. package/dist/generated/components/ui/checkbox.tsx +34 -0
  114. package/dist/generated/components/ui/collapsible.tsx +9 -0
  115. package/dist/generated/components/ui/context-menu.tsx +244 -0
  116. package/dist/generated/components/ui/dialog.tsx +150 -0
  117. package/dist/generated/components/ui/dropdown-menu.tsx +244 -0
  118. package/dist/generated/components/ui/hover-card.tsx +45 -0
  119. package/dist/generated/components/ui/input.tsx +26 -0
  120. package/dist/generated/components/ui/label.tsx +28 -0
  121. package/dist/generated/components/ui/menubar.tsx +260 -0
  122. package/dist/generated/components/ui/navigation-menu.tsx +177 -0
  123. package/dist/generated/components/ui/popover.tsx +39 -0
  124. package/dist/generated/components/ui/radio-group.tsx +38 -0
  125. package/dist/generated/components/ui/select.tsx +181 -0
  126. package/dist/generated/components/ui/separator.tsx +23 -0
  127. package/dist/generated/components/ui/skeleton.tsx +39 -0
  128. package/dist/generated/components/ui/switch.tsx +97 -0
  129. package/dist/generated/components/ui/table.tsx +99 -0
  130. package/dist/generated/components/ui/tabs.tsx +65 -0
  131. package/dist/generated/components/ui/text.tsx +24 -0
  132. package/dist/generated/components/ui/textarea.tsx +28 -0
  133. package/dist/generated/components/ui/toggle-group.tsx +86 -0
  134. package/dist/generated/components/ui/toggle.tsx +85 -0
  135. package/dist/generated/components/ui/tooltip.tsx +36 -0
  136. package/dist/generated/components/ui/typography.tsx +204 -0
  137. package/package.json +8 -8
@@ -0,0 +1,237 @@
1
+ import { useControllableState } from '@rnr/hooks';
2
+ import { Portal as RNPPortal } from '@rnr/portal';
3
+ import * as Slot from '@rnr/slot';
4
+ import type {
5
+ PressableRef,
6
+ SlottablePressableProps,
7
+ SlottableTextProps,
8
+ SlottableViewProps,
9
+ TextRef,
10
+ ViewRef,
11
+ } from '@rnr/types';
12
+ import * as React from 'react';
13
+ import { BackHandler, Pressable, Text, View, type GestureResponderEvent } from 'react-native';
14
+ import type {
15
+ AlertDialogContentProps,
16
+ AlertDialogOverlayProps,
17
+ AlertDialogPortalProps,
18
+ AlertDialogRootProps,
19
+ RootContext,
20
+ } from './types';
21
+
22
+ const AlertDialogContext = React.createContext<(RootContext & { nativeID: string }) | null>(null);
23
+
24
+ const Root = React.forwardRef<ViewRef, SlottableViewProps & AlertDialogRootProps>(
25
+ ({ asChild, open: openProp, defaultOpen, onOpenChange: onOpenChangeProp, ...viewProps }, ref) => {
26
+ const nativeID = React.useId();
27
+ const [open = false, onOpenChange] = useControllableState({
28
+ prop: openProp,
29
+ defaultProp: defaultOpen,
30
+ onChange: onOpenChangeProp,
31
+ });
32
+ const Component = asChild ? Slot.View : View;
33
+ return (
34
+ <AlertDialogContext.Provider
35
+ value={{
36
+ open,
37
+ onOpenChange,
38
+ nativeID,
39
+ }}
40
+ >
41
+ <Component ref={ref} {...viewProps} />
42
+ </AlertDialogContext.Provider>
43
+ );
44
+ }
45
+ );
46
+
47
+ Root.displayName = 'RootNativeAlertDialog';
48
+
49
+ function useRootContext() {
50
+ const context = React.useContext(AlertDialogContext);
51
+ if (!context) {
52
+ throw new Error(
53
+ 'AlertDialog compound components cannot be rendered outside the AlertDialog component'
54
+ );
55
+ }
56
+ return context;
57
+ }
58
+
59
+ const Trigger = React.forwardRef<PressableRef, SlottablePressableProps>(
60
+ ({ asChild, onPress: onPressProp, disabled = false, ...props }, ref) => {
61
+ const { open: value, onOpenChange } = useRootContext();
62
+
63
+ function onPress(ev: GestureResponderEvent) {
64
+ onOpenChange(!value);
65
+ onPressProp?.(ev);
66
+ }
67
+
68
+ const Component = asChild ? Slot.Pressable : Pressable;
69
+ return (
70
+ <Component
71
+ ref={ref}
72
+ aria-disabled={disabled ?? undefined}
73
+ role='button'
74
+ onPress={onPress}
75
+ disabled={disabled ?? undefined}
76
+ {...props}
77
+ />
78
+ );
79
+ }
80
+ );
81
+
82
+ Trigger.displayName = 'TriggerNativeAlertDialog';
83
+
84
+ /**
85
+ * @warning when using a custom `<PortalHost />`, you might have to adjust the Content's sideOffset to account for nav elements like headers.
86
+ */
87
+ function Portal({ forceMount, hostName, children }: AlertDialogPortalProps) {
88
+ const value = useRootContext();
89
+
90
+ if (!forceMount) {
91
+ if (!value.open) {
92
+ return null;
93
+ }
94
+ }
95
+
96
+ return (
97
+ <RNPPortal hostName={hostName} name={`${value.nativeID}_portal`}>
98
+ <AlertDialogContext.Provider value={value}>{children}</AlertDialogContext.Provider>
99
+ </RNPPortal>
100
+ );
101
+ }
102
+
103
+ const Overlay = React.forwardRef<ViewRef, SlottableViewProps & AlertDialogOverlayProps>(
104
+ ({ asChild, forceMount, ...props }, ref) => {
105
+ const { open: value } = useRootContext();
106
+
107
+ if (!forceMount) {
108
+ if (!value) {
109
+ return null;
110
+ }
111
+ }
112
+
113
+ const Component = asChild ? Slot.View : View;
114
+ return <Component ref={ref} {...props} />;
115
+ }
116
+ );
117
+
118
+ Overlay.displayName = 'OverlayNativeAlertDialog';
119
+
120
+ const Content = React.forwardRef<ViewRef, SlottableViewProps & AlertDialogContentProps>(
121
+ ({ asChild, forceMount, ...props }, ref) => {
122
+ const { open: value, nativeID, onOpenChange } = useRootContext();
123
+
124
+ React.useEffect(() => {
125
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
126
+ onOpenChange(false);
127
+ return true;
128
+ });
129
+
130
+ return () => {
131
+ backHandler.remove();
132
+ };
133
+ }, []);
134
+
135
+ if (!forceMount) {
136
+ if (!value) {
137
+ return null;
138
+ }
139
+ }
140
+
141
+ const Component = asChild ? Slot.View : View;
142
+ return (
143
+ <Component
144
+ ref={ref}
145
+ role='alertdialog'
146
+ nativeID={nativeID}
147
+ aria-labelledby={`${nativeID}_label`}
148
+ aria-describedby={`${nativeID}_desc`}
149
+ aria-modal={true}
150
+ {...props}
151
+ />
152
+ );
153
+ }
154
+ );
155
+
156
+ Content.displayName = 'ContentNativeAlertDialog';
157
+
158
+ const Cancel = React.forwardRef<PressableRef, SlottablePressableProps>(
159
+ ({ asChild, onPress: onPressProp, disabled = false, ...props }, ref) => {
160
+ const { onOpenChange } = useRootContext();
161
+
162
+ function onPress(ev: GestureResponderEvent) {
163
+ if (disabled) return;
164
+ onOpenChange(false);
165
+ onPressProp?.(ev);
166
+ }
167
+
168
+ const Component = asChild ? Slot.Pressable : Pressable;
169
+ return (
170
+ <Component
171
+ ref={ref}
172
+ aria-disabled={disabled ?? undefined}
173
+ role='button'
174
+ onPress={onPress}
175
+ disabled={disabled ?? undefined}
176
+ {...props}
177
+ />
178
+ );
179
+ }
180
+ );
181
+
182
+ Cancel.displayName = 'CloseNativeAlertDialog';
183
+
184
+ const Action = React.forwardRef<PressableRef, SlottablePressableProps>(
185
+ ({ asChild, onPress: onPressProp, disabled = false, ...props }, ref) => {
186
+ const { onOpenChange } = useRootContext();
187
+
188
+ function onPress(ev: GestureResponderEvent) {
189
+ if (disabled) return;
190
+ onOpenChange(false);
191
+ onPressProp?.(ev);
192
+ }
193
+
194
+ const Component = asChild ? Slot.Pressable : Pressable;
195
+ return (
196
+ <Component
197
+ ref={ref}
198
+ aria-disabled={disabled ?? undefined}
199
+ role='button'
200
+ onPress={onPress}
201
+ disabled={disabled ?? undefined}
202
+ {...props}
203
+ />
204
+ );
205
+ }
206
+ );
207
+
208
+ Action.displayName = 'ActionNativeAlertDialog';
209
+
210
+ const Title = React.forwardRef<TextRef, SlottableTextProps>(({ asChild, ...props }, ref) => {
211
+ const { nativeID } = useRootContext();
212
+ const Component = asChild ? Slot.Text : Text;
213
+ return <Component ref={ref} role='heading' nativeID={`${nativeID}_label`} {...props} />;
214
+ });
215
+
216
+ Title.displayName = 'TitleNativeAlertDialog';
217
+
218
+ const Description = React.forwardRef<TextRef, SlottableTextProps>(({ asChild, ...props }, ref) => {
219
+ const { nativeID } = useRootContext();
220
+ const Component = asChild ? Slot.Text : Text;
221
+ return <Component ref={ref} nativeID={`${nativeID}_desc`} {...props} />;
222
+ });
223
+
224
+ Description.displayName = 'DescriptionNativeAlertDialog';
225
+
226
+ export {
227
+ Action,
228
+ Cancel,
229
+ Content,
230
+ Description,
231
+ Overlay,
232
+ Portal,
233
+ Root,
234
+ Title,
235
+ Trigger,
236
+ useRootContext,
237
+ };
@@ -0,0 +1,256 @@
1
+ import * as AlertDialog from '@radix-ui/react-alert-dialog';
2
+ import * as React from 'react';
3
+ import { Pressable, Text, View, type GestureResponderEvent } from 'react-native';
4
+ import { useAugmentedRef, useControllableState } from '@rnr/hooks';
5
+ import * as Slot from '@rnr/slot';
6
+ import type {
7
+ PressableRef,
8
+ SlottablePressableProps,
9
+ SlottableTextProps,
10
+ SlottableViewProps,
11
+ TextRef,
12
+ ViewRef,
13
+ } from '@rnr/types';
14
+ import type {
15
+ AlertDialogContentProps,
16
+ AlertDialogOverlayProps,
17
+ AlertDialogPortalProps,
18
+ AlertDialogRootProps,
19
+ RootContext,
20
+ } from './types';
21
+
22
+ const AlertDialogContext = React.createContext<RootContext | null>(null);
23
+
24
+ const Root = React.forwardRef<ViewRef, SlottableViewProps & AlertDialogRootProps>(
25
+ ({ asChild, open: openProp, defaultOpen, onOpenChange: onOpenChangeProp, ...viewProps }, ref) => {
26
+ const [open = false, onOpenChange] = useControllableState({
27
+ prop: openProp,
28
+ defaultProp: defaultOpen,
29
+ onChange: onOpenChangeProp,
30
+ });
31
+ const Component = asChild ? Slot.View : View;
32
+ return (
33
+ <AlertDialogContext.Provider value={{ open, onOpenChange }}>
34
+ <AlertDialog.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>
35
+ <Component ref={ref} {...viewProps} />
36
+ </AlertDialog.Root>
37
+ </AlertDialogContext.Provider>
38
+ );
39
+ }
40
+ );
41
+
42
+ Root.displayName = 'RootAlertWebDialog';
43
+
44
+ function useRootContext() {
45
+ const context = React.useContext(AlertDialogContext);
46
+ if (!context) {
47
+ throw new Error(
48
+ 'AlertDialog compound components cannot be rendered outside the AlertDialog component'
49
+ );
50
+ }
51
+ return context;
52
+ }
53
+
54
+ const Trigger = React.forwardRef<PressableRef, SlottablePressableProps>(
55
+ ({ asChild, onPress: onPressProp, role: _role, disabled, ...props }, ref) => {
56
+ const augmentedRef = useAugmentedRef({ ref });
57
+ const { onOpenChange, open } = useRootContext();
58
+ function onPress(ev: GestureResponderEvent) {
59
+ if (onPressProp) {
60
+ onPressProp(ev);
61
+ }
62
+ onOpenChange(!open);
63
+ }
64
+
65
+ React.useLayoutEffect(() => {
66
+ if (augmentedRef.current) {
67
+ const augRef = augmentedRef.current as unknown as HTMLButtonElement;
68
+ augRef.dataset.state = open ? 'open' : 'closed';
69
+ augRef.type = 'button';
70
+ }
71
+ }, [open]);
72
+
73
+ const Component = asChild ? Slot.Pressable : Pressable;
74
+ return (
75
+ <AlertDialog.Trigger disabled={disabled ?? undefined} asChild>
76
+ <Component
77
+ ref={augmentedRef}
78
+ onPress={onPress}
79
+ role='button'
80
+ disabled={disabled}
81
+ {...props}
82
+ />
83
+ </AlertDialog.Trigger>
84
+ );
85
+ }
86
+ );
87
+
88
+ Trigger.displayName = 'TriggerAlertWebDialog';
89
+
90
+ function Portal({ forceMount, container, children }: AlertDialogPortalProps) {
91
+ return <AlertDialog.Portal forceMount={forceMount} children={children} container={container} />;
92
+ }
93
+
94
+ const Overlay = React.forwardRef<ViewRef, SlottableViewProps & AlertDialogOverlayProps>(
95
+ ({ asChild, forceMount, ...props }, ref) => {
96
+ const Component = asChild ? Slot.View : View;
97
+ return (
98
+ <AlertDialog.Overlay forceMount={forceMount}>
99
+ <Component ref={ref} {...props} />
100
+ </AlertDialog.Overlay>
101
+ );
102
+ }
103
+ );
104
+
105
+ Overlay.displayName = 'OverlayAlertWebDialog';
106
+
107
+ const Content = React.forwardRef<ViewRef, SlottableViewProps & AlertDialogContentProps>(
108
+ (
109
+ {
110
+ asChild,
111
+ forceMount,
112
+
113
+ onOpenAutoFocus,
114
+ onCloseAutoFocus,
115
+ onEscapeKeyDown,
116
+ ...props
117
+ },
118
+ ref
119
+ ) => {
120
+ const augmentedRef = useAugmentedRef({ ref });
121
+ const { open } = useRootContext();
122
+
123
+ React.useLayoutEffect(() => {
124
+ if (augmentedRef.current) {
125
+ const augRef = augmentedRef.current as unknown as HTMLDivElement;
126
+ augRef.dataset.state = open ? 'open' : 'closed';
127
+ }
128
+ }, [open]);
129
+
130
+ const Component = asChild ? Slot.View : View;
131
+ return (
132
+ <AlertDialog.Content
133
+ onOpenAutoFocus={onOpenAutoFocus}
134
+ onCloseAutoFocus={onCloseAutoFocus}
135
+ onEscapeKeyDown={onEscapeKeyDown}
136
+ forceMount={forceMount}
137
+ asChild
138
+ >
139
+ <Component ref={augmentedRef} {...props} />
140
+ </AlertDialog.Content>
141
+ );
142
+ }
143
+ );
144
+
145
+ Content.displayName = 'ContentAlertWebDialog';
146
+
147
+ const Cancel = React.forwardRef<PressableRef, SlottablePressableProps>(
148
+ ({ asChild, onPress: onPressProp, disabled, ...props }, ref) => {
149
+ const augmentedRef = useAugmentedRef({ ref });
150
+ const { onOpenChange, open } = useRootContext();
151
+
152
+ function onPress(ev: GestureResponderEvent) {
153
+ if (onPressProp) {
154
+ onPressProp(ev);
155
+ }
156
+ onOpenChange(!open);
157
+ }
158
+
159
+ React.useLayoutEffect(() => {
160
+ if (augmentedRef.current) {
161
+ const augRef = augmentedRef.current as unknown as HTMLButtonElement;
162
+ augRef.type = 'button';
163
+ }
164
+ }, []);
165
+
166
+ const Component = asChild ? Slot.Pressable : Pressable;
167
+ return (
168
+ <>
169
+ <AlertDialog.Cancel disabled={disabled ?? undefined} asChild>
170
+ <Component
171
+ ref={augmentedRef}
172
+ onPress={onPress}
173
+ role='button'
174
+ disabled={disabled}
175
+ {...props}
176
+ />
177
+ </AlertDialog.Cancel>
178
+ </>
179
+ );
180
+ }
181
+ );
182
+
183
+ Cancel.displayName = 'CancelAlertWebDialog';
184
+
185
+ const Action = React.forwardRef<PressableRef, SlottablePressableProps>(
186
+ ({ asChild, onPress: onPressProp, disabled, ...props }, ref) => {
187
+ const augmentedRef = useAugmentedRef({ ref });
188
+ const { onOpenChange, open } = useRootContext();
189
+
190
+ function onPress(ev: GestureResponderEvent) {
191
+ if (onPressProp) {
192
+ onPressProp(ev);
193
+ }
194
+ onOpenChange(!open);
195
+ }
196
+
197
+ React.useLayoutEffect(() => {
198
+ if (augmentedRef.current) {
199
+ const augRef = augmentedRef.current as unknown as HTMLButtonElement;
200
+ augRef.type = 'button';
201
+ }
202
+ }, []);
203
+
204
+ const Component = asChild ? Slot.Pressable : Pressable;
205
+ return (
206
+ <>
207
+ <AlertDialog.Action disabled={disabled ?? undefined} asChild>
208
+ <Component
209
+ ref={augmentedRef}
210
+ onPress={onPress}
211
+ role='button'
212
+ disabled={disabled}
213
+ {...props}
214
+ />
215
+ </AlertDialog.Action>
216
+ </>
217
+ );
218
+ }
219
+ );
220
+
221
+ Action.displayName = 'ActionAlertWebDialog';
222
+
223
+ const Title = React.forwardRef<TextRef, SlottableTextProps>(({ asChild, ...props }, ref) => {
224
+ const Component = asChild ? Slot.Text : Text;
225
+ return (
226
+ <AlertDialog.Title asChild>
227
+ <Component ref={ref} {...props} />
228
+ </AlertDialog.Title>
229
+ );
230
+ });
231
+
232
+ Title.displayName = 'TitleAlertWebDialog';
233
+
234
+ const Description = React.forwardRef<TextRef, SlottableTextProps>(({ asChild, ...props }, ref) => {
235
+ const Component = asChild ? Slot.Text : Text;
236
+ return (
237
+ <AlertDialog.Description asChild>
238
+ <Component ref={ref} {...props} />
239
+ </AlertDialog.Description>
240
+ );
241
+ });
242
+
243
+ Description.displayName = 'DescriptionAlertWebDialog';
244
+
245
+ export {
246
+ Action,
247
+ Cancel,
248
+ Content,
249
+ Description,
250
+ Overlay,
251
+ Portal,
252
+ Root,
253
+ Title,
254
+ Trigger,
255
+ useRootContext,
256
+ };
@@ -0,0 +1 @@
1
+ export * from './alert-dialog';
@@ -0,0 +1,48 @@
1
+ import type { ForceMountable } from '@rnr/types';
2
+
3
+ type AlertDialogRootProps = {
4
+ open?: boolean;
5
+ onOpenChange?: (value: boolean) => void;
6
+ defaultOpen?: boolean;
7
+ };
8
+
9
+ interface RootContext {
10
+ open: boolean;
11
+ onOpenChange: (value: boolean) => void;
12
+ }
13
+
14
+ interface AlertDialogPortalProps extends ForceMountable {
15
+ children: React.ReactNode;
16
+ /**
17
+ * Platform: NATIVE ONLY
18
+ */
19
+ hostName?: string;
20
+ /**
21
+ * Platform: WEB ONLY
22
+ */
23
+ container?: HTMLElement | null | undefined;
24
+ }
25
+ type AlertDialogOverlayProps = ForceMountable;
26
+
27
+ type AlertDialogContentProps = ForceMountable & {
28
+ /**
29
+ * Platform: WEB ONLY
30
+ */
31
+ onOpenAutoFocus?: (ev: Event) => void;
32
+ /**
33
+ * Platform: WEB ONLY
34
+ */
35
+ onCloseAutoFocus?: (ev: Event) => void;
36
+ /**
37
+ * Platform: WEB ONLY
38
+ */
39
+ onEscapeKeyDown?: (ev: Event) => void;
40
+ };
41
+
42
+ export type {
43
+ AlertDialogRootProps,
44
+ AlertDialogPortalProps,
45
+ AlertDialogOverlayProps,
46
+ AlertDialogContentProps,
47
+ RootContext,
48
+ };
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ import { View, type ViewStyle } from 'react-native';
3
+ import * as Slot from '@rnr/slot';
4
+ import type { SlottableViewProps } from '@rnr/types';
5
+
6
+ interface AspectRatioRootProps {
7
+ ratio?: number;
8
+ style?: ViewStyle;
9
+ }
10
+
11
+ export type { AspectRatioRootProps };
12
+
13
+ const Root = React.forwardRef<
14
+ React.ElementRef<typeof View>,
15
+ Omit<SlottableViewProps, 'style'> & AspectRatioRootProps
16
+ >(({ asChild, ratio = 1, style, ...props }, ref) => {
17
+ const Component = asChild ? Slot.View : View;
18
+ return <Component ref={ref} style={[style, { aspectRatio: ratio }]} {...props} />;
19
+ });
20
+
21
+ Root.displayName = 'RootAspectRatio';
22
+
23
+ export { Root };
@@ -0,0 +1,10 @@
1
+ interface AvatarRootProps {
2
+ alt: string;
3
+ }
4
+
5
+ interface AvatarImageProps {
6
+ children?: React.ReactNode;
7
+ onLoadingStatusChange?: (status: 'error' | 'loaded') => void;
8
+ }
9
+
10
+ export type { AvatarRootProps, AvatarImageProps };
@@ -0,0 +1,95 @@
1
+ import * as React from 'react';
2
+ import {
3
+ ImageErrorEventData,
4
+ ImageLoadEventData,
5
+ NativeSyntheticEvent,
6
+ Image as RNImage,
7
+ View,
8
+ } from 'react-native';
9
+ import * as Slot from '@rnr/slot';
10
+ import { ComponentPropsWithAsChild, SlottableViewProps, ViewRef } from '@rnr/types';
11
+ import { AvatarImageProps, AvatarRootProps } from './types';
12
+
13
+ type AvatarState = 'loading' | 'error' | 'loaded';
14
+
15
+ interface IRootContext extends AvatarRootProps {
16
+ status: AvatarState;
17
+ setStatus: (status: AvatarState) => void;
18
+ }
19
+
20
+ const RootContext = React.createContext<IRootContext | null>(null);
21
+
22
+ const Root = React.forwardRef<ViewRef, SlottableViewProps & AvatarRootProps>(
23
+ ({ asChild, alt, ...viewProps }, ref) => {
24
+ const [status, setStatus] = React.useState<AvatarState>('loading');
25
+ const Component = asChild ? Slot.View : View;
26
+ return (
27
+ <RootContext.Provider value={{ alt, status, setStatus }}>
28
+ <Component ref={ref} {...viewProps} />
29
+ </RootContext.Provider>
30
+ );
31
+ }
32
+ );
33
+
34
+ Root.displayName = 'RootAvatar';
35
+
36
+ function useRootContext() {
37
+ const context = React.useContext(RootContext);
38
+ if (!context) {
39
+ throw new Error('Avatar compound components cannot be rendered outside the Avatar component');
40
+ }
41
+ return context;
42
+ }
43
+
44
+ const Image = React.forwardRef<
45
+ React.ElementRef<typeof RNImage>,
46
+ Omit<ComponentPropsWithAsChild<typeof RNImage>, 'alt'> & AvatarImageProps
47
+ >(
48
+ (
49
+ { asChild, onLoad: onLoadProps, onError: onErrorProps, onLoadingStatusChange, ...props },
50
+ ref
51
+ ) => {
52
+ const { alt, setStatus, status } = useRootContext();
53
+
54
+ const onLoad = React.useCallback(
55
+ (e: NativeSyntheticEvent<ImageLoadEventData>) => {
56
+ setStatus('loaded');
57
+ onLoadingStatusChange?.('loaded');
58
+ onLoadProps?.(e);
59
+ },
60
+ [onLoadProps]
61
+ );
62
+
63
+ const onError = React.useCallback(
64
+ (e: NativeSyntheticEvent<ImageErrorEventData>) => {
65
+ setStatus('error');
66
+ onLoadingStatusChange?.('error');
67
+ onErrorProps?.(e);
68
+ },
69
+ [onErrorProps]
70
+ );
71
+
72
+ if (status === 'error') {
73
+ return null;
74
+ }
75
+
76
+ const Component = asChild ? Slot.Image : RNImage;
77
+ return <Component ref={ref} alt={alt} onLoad={onLoad} onError={onError} {...props} />;
78
+ }
79
+ );
80
+
81
+ Image.displayName = 'ImageAvatar';
82
+
83
+ const Fallback = React.forwardRef<ViewRef, SlottableViewProps>(({ asChild, ...props }, ref) => {
84
+ const { alt, status } = useRootContext();
85
+
86
+ if (status !== 'error') {
87
+ return null;
88
+ }
89
+ const Component = asChild ? Slot.View : View;
90
+ return <Component ref={ref} role={'img'} aria-label={alt} {...props} />;
91
+ });
92
+
93
+ Fallback.displayName = 'FallbackAvatar';
94
+
95
+ export { Fallback, Image, Root };