@campxdev/react-native-blueprint 0.1.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 (178) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +358 -0
  3. package/lib/module/app/_layout.js +23 -0
  4. package/lib/module/app/_layout.js.map +1 -0
  5. package/lib/module/assets/icons/weather_icons/drizzle.png +0 -0
  6. package/lib/module/assets/icons/weather_icons/foggy.png +0 -0
  7. package/lib/module/assets/icons/weather_icons/freezing_rain.png +0 -0
  8. package/lib/module/assets/icons/weather_icons/partly_cloudy.png +0 -0
  9. package/lib/module/assets/icons/weather_icons/rainy.png +0 -0
  10. package/lib/module/assets/icons/weather_icons/showers.png +0 -0
  11. package/lib/module/assets/icons/weather_icons/sunny_weather.png +0 -0
  12. package/lib/module/assets/icons/weather_icons/thunderstorm.png +0 -0
  13. package/lib/module/assets/icons/weather_icons/thunderstorm_hail.png +0 -0
  14. package/lib/module/components/theme-config.js +265 -0
  15. package/lib/module/components/theme-config.js.map +1 -0
  16. package/lib/module/components/ui/Accordion.js +228 -0
  17. package/lib/module/components/ui/Accordion.js.map +1 -0
  18. package/lib/module/components/ui/Alert-Dialog.js +266 -0
  19. package/lib/module/components/ui/Alert-Dialog.js.map +1 -0
  20. package/lib/module/components/ui/Alert.js +107 -0
  21. package/lib/module/components/ui/Alert.js.map +1 -0
  22. package/lib/module/components/ui/AppBar.js +403 -0
  23. package/lib/module/components/ui/AppBar.js.map +1 -0
  24. package/lib/module/components/ui/Aspect-Ratio.js +27 -0
  25. package/lib/module/components/ui/Aspect-Ratio.js.map +1 -0
  26. package/lib/module/components/ui/Avatar.js +97 -0
  27. package/lib/module/components/ui/Avatar.js.map +1 -0
  28. package/lib/module/components/ui/Badge.js +127 -0
  29. package/lib/module/components/ui/Badge.js.map +1 -0
  30. package/lib/module/components/ui/Bottom-Sheet.js +144 -0
  31. package/lib/module/components/ui/Bottom-Sheet.js.map +1 -0
  32. package/lib/module/components/ui/Button.js +88 -0
  33. package/lib/module/components/ui/Button.js.map +1 -0
  34. package/lib/module/components/ui/Card.js +176 -0
  35. package/lib/module/components/ui/Card.js.map +1 -0
  36. package/lib/module/components/ui/Checkbox.js +65 -0
  37. package/lib/module/components/ui/Checkbox.js.map +1 -0
  38. package/lib/module/components/ui/Collapsible.js +42 -0
  39. package/lib/module/components/ui/Collapsible.js.map +1 -0
  40. package/lib/module/components/ui/Context-Menu.js +287 -0
  41. package/lib/module/components/ui/Context-Menu.js.map +1 -0
  42. package/lib/module/components/ui/Custom-Card.js +202 -0
  43. package/lib/module/components/ui/Custom-Card.js.map +1 -0
  44. package/lib/module/components/ui/Dialog.js +202 -0
  45. package/lib/module/components/ui/Dialog.js.map +1 -0
  46. package/lib/module/components/ui/Dropdown-Menu.js +421 -0
  47. package/lib/module/components/ui/Dropdown-Menu.js.map +1 -0
  48. package/lib/module/components/ui/Floating-Action.js +50 -0
  49. package/lib/module/components/ui/Floating-Action.js.map +1 -0
  50. package/lib/module/components/ui/Greeting-Card.js +392 -0
  51. package/lib/module/components/ui/Greeting-Card.js.map +1 -0
  52. package/lib/module/components/ui/Hover-Card.js +96 -0
  53. package/lib/module/components/ui/Hover-Card.js.map +1 -0
  54. package/lib/module/components/ui/Icon.js +73 -0
  55. package/lib/module/components/ui/Icon.js.map +1 -0
  56. package/lib/module/components/ui/Input.js +74 -0
  57. package/lib/module/components/ui/Input.js.map +1 -0
  58. package/lib/module/components/ui/Label.js +44 -0
  59. package/lib/module/components/ui/Label.js.map +1 -0
  60. package/lib/module/components/ui/Menubar.js +375 -0
  61. package/lib/module/components/ui/Menubar.js.map +1 -0
  62. package/lib/module/components/ui/Native-Only-Animated-View.js +41 -0
  63. package/lib/module/components/ui/Native-Only-Animated-View.js.map +1 -0
  64. package/lib/module/components/ui/NavBar.js +352 -0
  65. package/lib/module/components/ui/NavBar.js.map +1 -0
  66. package/lib/module/components/ui/Popover.js +101 -0
  67. package/lib/module/components/ui/Popover.js.map +1 -0
  68. package/lib/module/components/ui/Progress.js +124 -0
  69. package/lib/module/components/ui/Progress.js.map +1 -0
  70. package/lib/module/components/ui/Radio-Group.js +75 -0
  71. package/lib/module/components/ui/Radio-Group.js.map +1 -0
  72. package/lib/module/components/ui/Select.js +269 -0
  73. package/lib/module/components/ui/Select.js.map +1 -0
  74. package/lib/module/components/ui/Separator.js +58 -0
  75. package/lib/module/components/ui/Separator.js.map +1 -0
  76. package/lib/module/components/ui/SizedBox.js +101 -0
  77. package/lib/module/components/ui/SizedBox.js.map +1 -0
  78. package/lib/module/components/ui/Skeleton.js +57 -0
  79. package/lib/module/components/ui/Skeleton.js.map +1 -0
  80. package/lib/module/components/ui/Slider.js +169 -0
  81. package/lib/module/components/ui/Slider.js.map +1 -0
  82. package/lib/module/components/ui/Switch.js +55 -0
  83. package/lib/module/components/ui/Switch.js.map +1 -0
  84. package/lib/module/components/ui/Table.js +150 -0
  85. package/lib/module/components/ui/Table.js.map +1 -0
  86. package/lib/module/components/ui/Tabs.js +106 -0
  87. package/lib/module/components/ui/Tabs.js.map +1 -0
  88. package/lib/module/components/ui/Text.js +69 -0
  89. package/lib/module/components/ui/Text.js.map +1 -0
  90. package/lib/module/components/ui/Textarea.js +88 -0
  91. package/lib/module/components/ui/Textarea.js.map +1 -0
  92. package/lib/module/components/ui/Theme-Toggle.js +156 -0
  93. package/lib/module/components/ui/Theme-Toggle.js.map +1 -0
  94. package/lib/module/components/ui/Toast.js +101 -0
  95. package/lib/module/components/ui/Toast.js.map +1 -0
  96. package/lib/module/components/ui/Toggle-Group.js +129 -0
  97. package/lib/module/components/ui/Toggle-Group.js.map +1 -0
  98. package/lib/module/components/ui/Toggle.js +106 -0
  99. package/lib/module/components/ui/Toggle.js.map +1 -0
  100. package/lib/module/components/ui/Tooltip.js +106 -0
  101. package/lib/module/components/ui/Tooltip.js.map +1 -0
  102. package/lib/module/components/ui/index.js +45 -0
  103. package/lib/module/components/ui/index.js.map +1 -0
  104. package/lib/module/index.js +19 -0
  105. package/lib/module/index.js.map +1 -0
  106. package/lib/module/lib/ThemeProvider.js +173 -0
  107. package/lib/module/lib/ThemeProvider.js.map +1 -0
  108. package/lib/module/lib/cornerRadius.js +164 -0
  109. package/lib/module/lib/cornerRadius.js.map +1 -0
  110. package/lib/module/lib/fonts.js +25 -0
  111. package/lib/module/lib/fonts.js.map +1 -0
  112. package/lib/module/lib/theme.js +212 -0
  113. package/lib/module/lib/theme.js.map +1 -0
  114. package/lib/module/lib/utils.js +137 -0
  115. package/lib/module/lib/utils.js.map +1 -0
  116. package/lib/module/package.json +1 -0
  117. package/package.json +208 -0
  118. package/src/app/_layout.tsx +25 -0
  119. package/src/assets/icons/weather_icons/drizzle.png +0 -0
  120. package/src/assets/icons/weather_icons/foggy.png +0 -0
  121. package/src/assets/icons/weather_icons/freezing_rain.png +0 -0
  122. package/src/assets/icons/weather_icons/partly_cloudy.png +0 -0
  123. package/src/assets/icons/weather_icons/rainy.png +0 -0
  124. package/src/assets/icons/weather_icons/showers.png +0 -0
  125. package/src/assets/icons/weather_icons/sunny_weather.png +0 -0
  126. package/src/assets/icons/weather_icons/thunderstorm.png +0 -0
  127. package/src/assets/icons/weather_icons/thunderstorm_hail.png +0 -0
  128. package/src/components/theme-config.ts +331 -0
  129. package/src/components/ui/Accordion.tsx +253 -0
  130. package/src/components/ui/Alert-Dialog.tsx +295 -0
  131. package/src/components/ui/Alert.tsx +137 -0
  132. package/src/components/ui/AppBar.tsx +551 -0
  133. package/src/components/ui/Aspect-Ratio.tsx +25 -0
  134. package/src/components/ui/Avatar.tsx +103 -0
  135. package/src/components/ui/Badge.tsx +121 -0
  136. package/src/components/ui/Bottom-Sheet.tsx +224 -0
  137. package/src/components/ui/Button.tsx +100 -0
  138. package/src/components/ui/Card.tsx +185 -0
  139. package/src/components/ui/Checkbox.tsx +81 -0
  140. package/src/components/ui/Collapsible.tsx +40 -0
  141. package/src/components/ui/Context-Menu.tsx +407 -0
  142. package/src/components/ui/Custom-Card.tsx +226 -0
  143. package/src/components/ui/Dialog.tsx +240 -0
  144. package/src/components/ui/Dropdown-Menu.tsx +544 -0
  145. package/src/components/ui/Floating-Action.tsx +54 -0
  146. package/src/components/ui/Greeting-Card.tsx +471 -0
  147. package/src/components/ui/Hover-Card.tsx +101 -0
  148. package/src/components/ui/Icon.tsx +75 -0
  149. package/src/components/ui/Input.tsx +90 -0
  150. package/src/components/ui/Label.tsx +48 -0
  151. package/src/components/ui/Menubar.tsx +509 -0
  152. package/src/components/ui/Native-Only-Animated-View.tsx +37 -0
  153. package/src/components/ui/NavBar.tsx +397 -0
  154. package/src/components/ui/Popover.tsx +110 -0
  155. package/src/components/ui/Progress.tsx +138 -0
  156. package/src/components/ui/Radio-Group.tsx +79 -0
  157. package/src/components/ui/Select.tsx +344 -0
  158. package/src/components/ui/Separator.tsx +68 -0
  159. package/src/components/ui/SizedBox.tsx +116 -0
  160. package/src/components/ui/Skeleton.tsx +55 -0
  161. package/src/components/ui/Slider.tsx +222 -0
  162. package/src/components/ui/Switch.tsx +67 -0
  163. package/src/components/ui/Table.tsx +170 -0
  164. package/src/components/ui/Tabs.tsx +119 -0
  165. package/src/components/ui/Text.tsx +73 -0
  166. package/src/components/ui/Textarea.tsx +93 -0
  167. package/src/components/ui/Theme-Toggle.tsx +204 -0
  168. package/src/components/ui/Toast.tsx +127 -0
  169. package/src/components/ui/Toggle-Group.tsx +160 -0
  170. package/src/components/ui/Toggle.tsx +122 -0
  171. package/src/components/ui/Tooltip.tsx +117 -0
  172. package/src/components/ui/index.ts +42 -0
  173. package/src/index.tsx +24 -0
  174. package/src/lib/ThemeProvider.tsx +204 -0
  175. package/src/lib/cornerRadius.ts +160 -0
  176. package/src/lib/fonts.ts +28 -0
  177. package/src/lib/theme.ts +151 -0
  178. package/src/lib/utils.ts +146 -0
@@ -0,0 +1,544 @@
1
+ import { Icon } from './Icon';
2
+ import { NativeOnlyAnimatedView } from './Native-Only-Animated-View';
3
+ import { TextClassContext } from './Text';
4
+ import { cn } from '../../lib/utils';
5
+ import * as DropdownMenuPrimitive from '@rn-primitives/dropdown-menu';
6
+ import {
7
+ Check,
8
+ ChevronDown,
9
+ ChevronRight,
10
+ ChevronUp,
11
+ } from 'lucide-react-native';
12
+ import * as React from 'react';
13
+ import {
14
+ Platform,
15
+ type StyleProp,
16
+ StyleSheet,
17
+ Text,
18
+ type TextProps,
19
+ View,
20
+ type ViewStyle,
21
+ } from 'react-native';
22
+ import { cssInterop } from 'nativewind';
23
+ import { FadeIn } from 'react-native-reanimated';
24
+ import { FullWindowOverlay as RNFullWindowOverlay } from 'react-native-screens';
25
+
26
+ cssInterop(View, { className: 'style' });
27
+ cssInterop(Text, { className: 'style' });
28
+
29
+ /**
30
+ * Root component for dropdown menu - provides context for all dropdown menu children
31
+ *
32
+ * @component
33
+ * @example
34
+ * ```tsx
35
+ * <DropdownMenu>
36
+ * <DropdownMenuTrigger>
37
+ * <Button variant="outline">
38
+ * <Text>Open Menu</Text>
39
+ * </Button>
40
+ * </DropdownMenuTrigger>
41
+ * <DropdownMenuContent>
42
+ * <DropdownMenuItem>
43
+ * <Text>Profile</Text>
44
+ * </DropdownMenuItem>
45
+ * </DropdownMenuContent>
46
+ * </DropdownMenu>
47
+ * ```
48
+ */
49
+ const DropdownMenu = DropdownMenuPrimitive.Root;
50
+
51
+ /**
52
+ * Trigger component that opens the dropdown menu when pressed
53
+ *
54
+ * @component
55
+ */
56
+ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
57
+
58
+ /**
59
+ * Groups related menu items together
60
+ *
61
+ * @component
62
+ */
63
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group;
64
+
65
+ /**
66
+ * Portal component to render menu content outside the DOM hierarchy
67
+ *
68
+ * @component
69
+ */
70
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
71
+
72
+ /**
73
+ * Root component for nested submenu
74
+ *
75
+ * @component
76
+ */
77
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
78
+
79
+ /**
80
+ * Groups radio items together with single selection
81
+ *
82
+ * @component
83
+ */
84
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
85
+
86
+ /**
87
+ * Trigger for opening a nested submenu
88
+ *
89
+ * Displays a chevron icon that indicates expandable content. The icon direction
90
+ * changes based on platform and submenu state.
91
+ *
92
+ * @component
93
+ * @example
94
+ * ```tsx
95
+ * <DropdownMenuSub>
96
+ * <DropdownMenuSubTrigger>
97
+ * <Text>More Options</Text>
98
+ * </DropdownMenuSubTrigger>
99
+ * <DropdownMenuSubContent>
100
+ * <DropdownMenuItem>
101
+ * <Text>Nested Item</Text>
102
+ * </DropdownMenuItem>
103
+ * </DropdownMenuSubContent>
104
+ * </DropdownMenuSub>
105
+ * ```
106
+ */
107
+ function DropdownMenuSubTrigger({
108
+ className: _className,
109
+ inset,
110
+ children,
111
+ iconClassName,
112
+ ...props
113
+ }: DropdownMenuPrimitive.SubTriggerProps &
114
+ React.RefAttributes<DropdownMenuPrimitive.SubTriggerRef> & {
115
+ children?: React.ReactNode;
116
+ iconClassName?: string;
117
+ inset?: boolean;
118
+ }) {
119
+ const { open } = DropdownMenuPrimitive.useSubContext();
120
+ const icon =
121
+ Platform.OS === 'web' ? ChevronRight : open ? ChevronUp : ChevronDown;
122
+ return (
123
+ <TextClassContext.Provider
124
+ value={cn(
125
+ 'text-sm select-none group-active:text-accent-foreground',
126
+ open && 'text-accent-foreground'
127
+ )}
128
+ >
129
+ <DropdownMenuPrimitive.SubTrigger
130
+ className={cn(
131
+ 'active:bg-accent group flex flex-row items-center rounded-sm px-2 py-2 sm:py-1.5',
132
+ Platform.select({
133
+ web: 'focus:bg-accent focus:text-accent-foreground cursor-default outline-none [&_svg]:pointer-events-none',
134
+ }),
135
+ open && 'bg-accent',
136
+ inset && 'pl-8'
137
+ )}
138
+ {...props}
139
+ >
140
+ <>{children}</>
141
+ <Icon
142
+ as={icon}
143
+ className={cn(
144
+ 'text-foreground ml-auto size-4 shrink-0',
145
+ iconClassName
146
+ )}
147
+ />
148
+ </DropdownMenuPrimitive.SubTrigger>
149
+ </TextClassContext.Provider>
150
+ );
151
+ }
152
+
153
+ /**
154
+ * Content container for nested submenu items
155
+ *
156
+ * @component
157
+ * @example
158
+ * ```tsx
159
+ * <DropdownMenuSubContent>
160
+ * <DropdownMenuItem>
161
+ * <Text>Submenu Item</Text>
162
+ * </DropdownMenuItem>
163
+ * </DropdownMenuSubContent>
164
+ * ```
165
+ */
166
+ function DropdownMenuSubContent({
167
+ className,
168
+ ...props
169
+ }: DropdownMenuPrimitive.SubContentProps &
170
+ React.RefAttributes<DropdownMenuPrimitive.SubContentRef>) {
171
+ return (
172
+ <NativeOnlyAnimatedView entering={FadeIn}>
173
+ <DropdownMenuPrimitive.SubContent
174
+ className={cn(
175
+ 'bg-popover border-border overflow-hidden rounded-md border p-1 shadow-lg shadow-black/5',
176
+ Platform.select({
177
+ web: 'animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 fade-in-0 data-[state=closed]:zoom-out-95 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-context-menu-content-transform-origin) z-50 min-w-[8rem]',
178
+ }),
179
+ className
180
+ )}
181
+ {...props}
182
+ />
183
+ </NativeOnlyAnimatedView>
184
+ );
185
+ }
186
+
187
+ /**
188
+ * Full window overlay wrapper for iOS, Fragment for other platforms
189
+ */
190
+ const FullWindowOverlay =
191
+ Platform.OS === 'ios' ? RNFullWindowOverlay : React.Fragment;
192
+
193
+ /**
194
+ * Main content container for dropdown menu items
195
+ *
196
+ * Renders menu items in a popover with proper positioning, animations,
197
+ * and overlay handling. Uses a portal to render outside the parent hierarchy.
198
+ *
199
+ * @component
200
+ * @example
201
+ * ```tsx
202
+ * <DropdownMenuContent>
203
+ * <DropdownMenuItem>
204
+ * <Text>Profile</Text>
205
+ * </DropdownMenuItem>
206
+ * <DropdownMenuSeparator />
207
+ * <DropdownMenuItem>
208
+ * <Text>Settings</Text>
209
+ * </DropdownMenuItem>
210
+ * </DropdownMenuContent>
211
+ * ```
212
+ *
213
+ * @accessibility
214
+ * - Properly handles focus management
215
+ * - Supports keyboard navigation
216
+ * - Screen reader friendly menu structure
217
+ */
218
+ function DropdownMenuContent({
219
+ className,
220
+ overlayClassName,
221
+ overlayStyle,
222
+ portalHost,
223
+ ...props
224
+ }: DropdownMenuPrimitive.ContentProps &
225
+ React.RefAttributes<DropdownMenuPrimitive.ContentRef> & {
226
+ overlayStyle?: StyleProp<ViewStyle>;
227
+ overlayClassName?: string;
228
+ portalHost?: string;
229
+ }) {
230
+ return (
231
+ <DropdownMenuPrimitive.Portal hostName={portalHost}>
232
+ <FullWindowOverlay>
233
+ <DropdownMenuPrimitive.Overlay
234
+ style={Platform.select({
235
+ web: overlayStyle ?? undefined,
236
+ native: overlayStyle
237
+ ? StyleSheet.flatten([
238
+ StyleSheet.absoluteFill,
239
+ overlayStyle as typeof StyleSheet.absoluteFill,
240
+ ])
241
+ : StyleSheet.absoluteFill,
242
+ })}
243
+ className={overlayClassName}
244
+ >
245
+ <NativeOnlyAnimatedView entering={FadeIn}>
246
+ <TextClassContext.Provider value="text-popover-foreground">
247
+ <DropdownMenuPrimitive.Content
248
+ className={cn(
249
+ 'bg-popover border-border min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg shadow-black/5',
250
+ Platform.select({
251
+ web: cn(
252
+ 'animate-in fade-in-0 zoom-in-95 max-h-(--radix-context-menu-content-available-height) origin-(--radix-context-menu-content-transform-origin) z-50 cursor-default',
253
+ props.side === 'bottom' && 'slide-in-from-top-2',
254
+ props.side === 'top' && 'slide-in-from-bottom-2'
255
+ ),
256
+ }),
257
+ className
258
+ )}
259
+ {...props}
260
+ />
261
+ </TextClassContext.Provider>
262
+ </NativeOnlyAnimatedView>
263
+ </DropdownMenuPrimitive.Overlay>
264
+ </FullWindowOverlay>
265
+ </DropdownMenuPrimitive.Portal>
266
+ );
267
+ }
268
+
269
+ /**
270
+ * Individual menu item component
271
+ *
272
+ * Supports both default and destructive variants for different actions.
273
+ * Includes proper hover, active, and focus states.
274
+ *
275
+ * @component
276
+ * @example
277
+ * ```tsx
278
+ * <DropdownMenuItem onSelect={() => console.log('Selected')}>
279
+ * <Text>Edit Profile</Text>
280
+ * </DropdownMenuItem>
281
+ *
282
+ * <DropdownMenuItem variant="destructive">
283
+ * <Text>Delete Account</Text>
284
+ * </DropdownMenuItem>
285
+ * ```
286
+ *
287
+ * @accessibility
288
+ * - Disabled items cannot be interacted with
289
+ * - Proper focus indicators on web
290
+ */
291
+ function DropdownMenuItem({
292
+ className,
293
+ inset,
294
+ variant,
295
+ ...props
296
+ }: DropdownMenuPrimitive.ItemProps &
297
+ React.RefAttributes<DropdownMenuPrimitive.ItemRef> & {
298
+ className?: string;
299
+ inset?: boolean;
300
+ variant?: 'default' | 'destructive';
301
+ }) {
302
+ return (
303
+ <TextClassContext.Provider
304
+ value={cn(
305
+ 'select-none text-sm text-popover-foreground group-active:text-popover-foreground',
306
+ variant === 'destructive' &&
307
+ 'text-destructive group-active:text-destructive'
308
+ )}
309
+ >
310
+ <DropdownMenuPrimitive.Item
311
+ className={cn(
312
+ 'active:bg-accent group relative flex flex-row items-center gap-2 rounded-sm px-2 py-2 sm:py-1.5',
313
+ Platform.select({
314
+ web: cn(
315
+ 'focus:bg-accent focus:text-accent-foreground cursor-default outline-none data-[disabled]:pointer-events-none',
316
+ variant === 'destructive' &&
317
+ 'focus:bg-destructive/10 dark:focus:bg-destructive/20'
318
+ ),
319
+ }),
320
+ variant === 'destructive' &&
321
+ 'active:bg-destructive/10 dark:active:bg-destructive/20',
322
+ props.disabled && 'opacity-50',
323
+ inset && 'pl-8',
324
+ className
325
+ )}
326
+ {...props}
327
+ />
328
+ </TextClassContext.Provider>
329
+ );
330
+ }
331
+
332
+ /**
333
+ * Menu item with checkbox for multi-selection
334
+ *
335
+ * Shows a checkmark when selected. Useful for toggling multiple options.
336
+ *
337
+ * @component
338
+ * @example
339
+ * ```tsx
340
+ * <DropdownMenuCheckboxItem
341
+ * checked={showPanel}
342
+ * onCheckedChange={setShowPanel}
343
+ * >
344
+ * <Text>Show Side Panel</Text>
345
+ * </DropdownMenuCheckboxItem>
346
+ * ```
347
+ */
348
+ function DropdownMenuCheckboxItem({
349
+ className,
350
+ children,
351
+ ...props
352
+ }: DropdownMenuPrimitive.CheckboxItemProps &
353
+ React.RefAttributes<DropdownMenuPrimitive.CheckboxItemRef> & {
354
+ children?: React.ReactNode;
355
+ }) {
356
+ return (
357
+ <TextClassContext.Provider value="text-sm text-popover-foreground select-none group-active:text-accent-foreground">
358
+ <DropdownMenuPrimitive.CheckboxItem
359
+ className={cn(
360
+ 'active:bg-accent group relative flex flex-row items-center gap-2 rounded-sm py-2 pl-8 pr-2 sm:py-1.5',
361
+ Platform.select({
362
+ web: 'focus:bg-accent focus:text-accent-foreground cursor-default outline-none data-[disabled]:pointer-events-none',
363
+ }),
364
+ props.disabled && 'opacity-50',
365
+ className
366
+ )}
367
+ {...props}
368
+ >
369
+ <View className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
370
+ <DropdownMenuPrimitive.ItemIndicator>
371
+ <Icon
372
+ as={Check}
373
+ className={cn(
374
+ 'text-foreground size-4',
375
+ Platform.select({ web: 'pointer-events-none' })
376
+ )}
377
+ />
378
+ </DropdownMenuPrimitive.ItemIndicator>
379
+ </View>
380
+ <>{children}</>
381
+ </DropdownMenuPrimitive.CheckboxItem>
382
+ </TextClassContext.Provider>
383
+ );
384
+ }
385
+
386
+ /**
387
+ * Menu item with radio button for single selection within a group
388
+ *
389
+ * Shows a filled circle when selected. Use within DropdownMenuRadioGroup.
390
+ *
391
+ * @component
392
+ * @example
393
+ * ```tsx
394
+ * <DropdownMenuRadioGroup value={sortBy} onValueChange={setSortBy}>
395
+ * <DropdownMenuRadioItem value="name">
396
+ * <Text>Sort by Name</Text>
397
+ * </DropdownMenuRadioItem>
398
+ * <DropdownMenuRadioItem value="date">
399
+ * <Text>Sort by Date</Text>
400
+ * </DropdownMenuRadioItem>
401
+ * </DropdownMenuRadioGroup>
402
+ * ```
403
+ */
404
+ function DropdownMenuRadioItem({
405
+ className,
406
+ children,
407
+ ...props
408
+ }: DropdownMenuPrimitive.RadioItemProps &
409
+ React.RefAttributes<DropdownMenuPrimitive.RadioItemRef> & {
410
+ children?: React.ReactNode;
411
+ }) {
412
+ return (
413
+ <TextClassContext.Provider value="text-sm text-popover-foreground select-none group-active:text-accent-foreground">
414
+ <DropdownMenuPrimitive.RadioItem
415
+ className={cn(
416
+ 'active:bg-accent group relative flex flex-row items-center gap-2 rounded-sm py-2 pl-8 pr-2 sm:py-1.5',
417
+ Platform.select({
418
+ web: 'focus:bg-accent focus:text-accent-foreground cursor-default outline-none data-[disabled]:pointer-events-none',
419
+ }),
420
+ props.disabled && 'opacity-50',
421
+ className
422
+ )}
423
+ {...props}
424
+ >
425
+ <View className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
426
+ <DropdownMenuPrimitive.ItemIndicator>
427
+ <View className="bg-foreground h-2 w-2 rounded-full" />
428
+ </DropdownMenuPrimitive.ItemIndicator>
429
+ </View>
430
+ <>{children}</>
431
+ </DropdownMenuPrimitive.RadioItem>
432
+ </TextClassContext.Provider>
433
+ );
434
+ }
435
+
436
+ /**
437
+ * Label component for grouping and describing menu sections
438
+ *
439
+ * @component
440
+ * @example
441
+ * ```tsx
442
+ * <DropdownMenuLabel>
443
+ * <Text>Account</Text>
444
+ * </DropdownMenuLabel>
445
+ * <DropdownMenuItem>
446
+ * <Text>Profile</Text>
447
+ * </DropdownMenuItem>
448
+ * ```
449
+ */
450
+ function DropdownMenuLabel({
451
+ className,
452
+ inset,
453
+ ...props
454
+ }: DropdownMenuPrimitive.LabelProps &
455
+ React.RefAttributes<DropdownMenuPrimitive.LabelRef> & {
456
+ className?: string;
457
+ inset?: boolean;
458
+ }) {
459
+ return (
460
+ <DropdownMenuPrimitive.Label
461
+ className={cn(
462
+ 'text-foreground px-2 py-2 text-sm font-medium sm:py-1.5',
463
+ inset && 'pl-8',
464
+ className
465
+ )}
466
+ {...props}
467
+ />
468
+ );
469
+ }
470
+
471
+ /**
472
+ * Visual separator between menu items or sections
473
+ *
474
+ * @component
475
+ * @example
476
+ * ```tsx
477
+ * <DropdownMenuItem>
478
+ * <Text>Edit</Text>
479
+ * </DropdownMenuItem>
480
+ * <DropdownMenuSeparator />
481
+ * <DropdownMenuItem variant="destructive">
482
+ * <Text>Delete</Text>
483
+ * </DropdownMenuItem>
484
+ * ```
485
+ */
486
+ function DropdownMenuSeparator({
487
+ className,
488
+ ...props
489
+ }: DropdownMenuPrimitive.SeparatorProps &
490
+ React.RefAttributes<DropdownMenuPrimitive.SeparatorRef>) {
491
+ return (
492
+ <DropdownMenuPrimitive.Separator
493
+ className={cn('bg-border -mx-1 my-1 h-px', className)}
494
+ {...props}
495
+ />
496
+ );
497
+ }
498
+
499
+ /**
500
+ * Displays keyboard shortcut hint for menu items
501
+ *
502
+ * @component
503
+ * @example
504
+ * ```tsx
505
+ * <DropdownMenuItem>
506
+ * <Text>Save</Text>
507
+ * <DropdownMenuShortcut>
508
+ * <Text>⌘S</Text>
509
+ * </DropdownMenuShortcut>
510
+ * </DropdownMenuItem>
511
+ * ```
512
+ */
513
+ function DropdownMenuShortcut({
514
+ className,
515
+ ...props
516
+ }: TextProps & React.RefAttributes<Text>) {
517
+ return (
518
+ <Text
519
+ className={cn(
520
+ 'text-muted-foreground ml-auto text-xs tracking-widest',
521
+ className
522
+ )}
523
+ {...props}
524
+ />
525
+ );
526
+ }
527
+
528
+ export {
529
+ DropdownMenu,
530
+ DropdownMenuCheckboxItem,
531
+ DropdownMenuContent,
532
+ DropdownMenuGroup,
533
+ DropdownMenuItem,
534
+ DropdownMenuLabel,
535
+ DropdownMenuPortal,
536
+ DropdownMenuRadioGroup,
537
+ DropdownMenuRadioItem,
538
+ DropdownMenuSeparator,
539
+ DropdownMenuShortcut,
540
+ DropdownMenuSub,
541
+ DropdownMenuSubContent,
542
+ DropdownMenuSubTrigger,
543
+ DropdownMenuTrigger,
544
+ };
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import type { IFloatingActionProps as RNFloatingActionProps } from 'react-native-floating-action';
3
+ import { FloatingAction as RNFloatingAction } from 'react-native-floating-action';
4
+
5
+ export interface FloatingActionProps extends RNFloatingActionProps {
6
+ /**
7
+ * Custom className for styling (if using NativeWind)
8
+ */
9
+ className?: string;
10
+ }
11
+
12
+ /**
13
+ * FloatingAction Component
14
+ *
15
+ * A customizable floating action button (FAB) component with support for multiple actions.
16
+ * Based on react-native-floating-action with additional styling capabilities.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { FloatingAction } from 'react-native-blueprint';
21
+ *
22
+ * const actions = [
23
+ * {
24
+ * text: 'Add',
25
+ * icon: require('./add-icon.png'),
26
+ * name: 'bt_add',
27
+ * position: 1
28
+ * },
29
+ * {
30
+ * text: 'Delete',
31
+ * icon: require('./delete-icon.png'),
32
+ * name: 'bt_delete',
33
+ * position: 2
34
+ * }
35
+ * ];
36
+ *
37
+ * <FloatingAction
38
+ * actions={actions}
39
+ * onPressItem={(name) => {
40
+ * console.log(`Selected button: ${name}`);
41
+ * }}
42
+ * />
43
+ * ```
44
+ */
45
+ export const FloatingAction: React.FC<FloatingActionProps> = React.forwardRef<
46
+ RNFloatingAction,
47
+ FloatingActionProps
48
+ >(({ className: _className, ...props }, ref) => {
49
+ return <RNFloatingAction ref={ref} {...props} />;
50
+ });
51
+
52
+ FloatingAction.displayName = 'FloatingAction';
53
+
54
+ export default FloatingAction;