@medway-ui/native 1.1.2 → 1.2.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 (215) hide show
  1. package/lib/commonjs/components/Alert.js +5 -4
  2. package/lib/commonjs/components/Alert.js.map +1 -1
  3. package/lib/commonjs/components/Avatar.js +2 -1
  4. package/lib/commonjs/components/Avatar.js.map +1 -1
  5. package/lib/commonjs/components/Badge.js +2 -1
  6. package/lib/commonjs/components/Badge.js.map +1 -1
  7. package/lib/commonjs/components/Button.js +3 -2
  8. package/lib/commonjs/components/Button.js.map +1 -1
  9. package/lib/commonjs/components/CardNews.js +7 -6
  10. package/lib/commonjs/components/CardNews.js.map +1 -1
  11. package/lib/commonjs/components/Carousel.js +122 -0
  12. package/lib/commonjs/components/Carousel.js.map +1 -0
  13. package/lib/commonjs/components/Checkbox.js +11 -2
  14. package/lib/commonjs/components/Checkbox.js.map +1 -1
  15. package/lib/commonjs/components/DropdownMenu.js +225 -0
  16. package/lib/commonjs/components/DropdownMenu.js.map +1 -0
  17. package/lib/commonjs/components/EmptyState.js +19 -20
  18. package/lib/commonjs/components/EmptyState.js.map +1 -1
  19. package/lib/commonjs/components/Feed.js +82 -0
  20. package/lib/commonjs/components/Feed.js.map +1 -0
  21. package/lib/commonjs/components/FeedNotice.js +76 -0
  22. package/lib/commonjs/components/FeedNotice.js.map +1 -0
  23. package/lib/commonjs/components/Input.js +21 -9
  24. package/lib/commonjs/components/Input.js.map +1 -1
  25. package/lib/commonjs/components/InvitePopover.js +196 -0
  26. package/lib/commonjs/components/InvitePopover.js.map +1 -0
  27. package/lib/commonjs/components/Label.js +2 -1
  28. package/lib/commonjs/components/Label.js.map +1 -1
  29. package/lib/commonjs/components/LeaderboardCard.js +58 -0
  30. package/lib/commonjs/components/LeaderboardCard.js.map +1 -0
  31. package/lib/commonjs/components/MemberRow.js +131 -0
  32. package/lib/commonjs/components/MemberRow.js.map +1 -0
  33. package/lib/commonjs/components/PageHeader.js +3 -2
  34. package/lib/commonjs/components/PageHeader.js.map +1 -1
  35. package/lib/commonjs/components/PostForm.js +182 -0
  36. package/lib/commonjs/components/PostForm.js.map +1 -0
  37. package/lib/commonjs/components/PrizeCollection.js +135 -0
  38. package/lib/commonjs/components/PrizeCollection.js.map +1 -0
  39. package/lib/commonjs/components/RadioGroup.js +22 -0
  40. package/lib/commonjs/components/RadioGroup.js.map +1 -1
  41. package/lib/commonjs/components/SectionHeader.js +36 -0
  42. package/lib/commonjs/components/SectionHeader.js.map +1 -0
  43. package/lib/commonjs/components/Switch.js +33 -19
  44. package/lib/commonjs/components/Switch.js.map +1 -1
  45. package/lib/commonjs/components/Tabs.js +156 -0
  46. package/lib/commonjs/components/Tabs.js.map +1 -0
  47. package/lib/commonjs/components/Tag.js +2 -1
  48. package/lib/commonjs/components/Tag.js.map +1 -1
  49. package/lib/commonjs/components/Text.js +60 -0
  50. package/lib/commonjs/components/Text.js.map +1 -0
  51. package/lib/commonjs/components/Toast.js +3 -2
  52. package/lib/commonjs/components/Toast.js.map +1 -1
  53. package/lib/commonjs/components/Tooltip.js +2 -2
  54. package/lib/commonjs/components/Tooltip.js.map +1 -1
  55. package/lib/commonjs/hooks/useThemeColor.js +66 -29
  56. package/lib/commonjs/hooks/useThemeColor.js.map +1 -1
  57. package/lib/commonjs/index.js +319 -1
  58. package/lib/commonjs/index.js.map +1 -1
  59. package/lib/commonjs/lib/overlay-host.js +101 -0
  60. package/lib/commonjs/lib/overlay-host.js.map +1 -0
  61. package/lib/commonjs/lib/typography.js +26 -0
  62. package/lib/commonjs/lib/typography.js.map +1 -0
  63. package/lib/commonjs/nativewind-env.d.js +0 -1
  64. package/lib/commonjs/nativewind-env.d.js.map +1 -1
  65. package/lib/module/components/Alert.js +3 -2
  66. package/lib/module/components/Alert.js.map +1 -1
  67. package/lib/module/components/Avatar.js +2 -1
  68. package/lib/module/components/Avatar.js.map +1 -1
  69. package/lib/module/components/Badge.js +2 -1
  70. package/lib/module/components/Badge.js.map +1 -1
  71. package/lib/module/components/Button.js +2 -1
  72. package/lib/module/components/Button.js.map +1 -1
  73. package/lib/module/components/CardNews.js +2 -1
  74. package/lib/module/components/CardNews.js.map +1 -1
  75. package/lib/module/components/Carousel.js +117 -0
  76. package/lib/module/components/Carousel.js.map +1 -0
  77. package/lib/module/components/Checkbox.js +12 -2
  78. package/lib/module/components/Checkbox.js.map +1 -1
  79. package/lib/module/components/DropdownMenu.js +216 -0
  80. package/lib/module/components/DropdownMenu.js.map +1 -0
  81. package/lib/module/components/EmptyState.js +19 -20
  82. package/lib/module/components/EmptyState.js.map +1 -1
  83. package/lib/module/components/Feed.js +77 -0
  84. package/lib/module/components/Feed.js.map +1 -0
  85. package/lib/module/components/FeedNotice.js +73 -0
  86. package/lib/module/components/FeedNotice.js.map +1 -0
  87. package/lib/module/components/Input.js +21 -9
  88. package/lib/module/components/Input.js.map +1 -1
  89. package/lib/module/components/InvitePopover.js +183 -0
  90. package/lib/module/components/InvitePopover.js.map +1 -0
  91. package/lib/module/components/Label.js +2 -1
  92. package/lib/module/components/Label.js.map +1 -1
  93. package/lib/module/components/LeaderboardCard.js +53 -0
  94. package/lib/module/components/LeaderboardCard.js.map +1 -0
  95. package/lib/module/components/MemberRow.js +127 -0
  96. package/lib/module/components/MemberRow.js.map +1 -0
  97. package/lib/module/components/PageHeader.js +2 -1
  98. package/lib/module/components/PageHeader.js.map +1 -1
  99. package/lib/module/components/PostForm.js +174 -0
  100. package/lib/module/components/PostForm.js.map +1 -0
  101. package/lib/module/components/PrizeCollection.js +127 -0
  102. package/lib/module/components/PrizeCollection.js.map +1 -0
  103. package/lib/module/components/RadioGroup.js +21 -1
  104. package/lib/module/components/RadioGroup.js.map +1 -1
  105. package/lib/module/components/SectionHeader.js +33 -0
  106. package/lib/module/components/SectionHeader.js.map +1 -0
  107. package/lib/module/components/Switch.js +34 -20
  108. package/lib/module/components/Switch.js.map +1 -1
  109. package/lib/module/components/Tabs.js +148 -0
  110. package/lib/module/components/Tabs.js.map +1 -0
  111. package/lib/module/components/Tag.js +2 -1
  112. package/lib/module/components/Tag.js.map +1 -1
  113. package/lib/module/components/Text.js +58 -0
  114. package/lib/module/components/Text.js.map +1 -0
  115. package/lib/module/components/Toast.js +2 -1
  116. package/lib/module/components/Toast.js.map +1 -1
  117. package/lib/module/components/Tooltip.js +1 -1
  118. package/lib/module/components/Tooltip.js.map +1 -1
  119. package/lib/module/hooks/useThemeColor.js +66 -31
  120. package/lib/module/hooks/useThemeColor.js.map +1 -1
  121. package/lib/module/index.js +27 -3
  122. package/lib/module/index.js.map +1 -1
  123. package/lib/module/lib/overlay-host.js +96 -0
  124. package/lib/module/lib/overlay-host.js.map +1 -0
  125. package/lib/module/lib/typography.js +22 -0
  126. package/lib/module/lib/typography.js.map +1 -0
  127. package/lib/module/nativewind-env.d.js +0 -1
  128. package/lib/module/nativewind-env.d.js.map +1 -1
  129. package/lib/typescript/components/Alert.d.ts.map +1 -1
  130. package/lib/typescript/components/Avatar.d.ts.map +1 -1
  131. package/lib/typescript/components/Badge.d.ts.map +1 -1
  132. package/lib/typescript/components/Button.d.ts.map +1 -1
  133. package/lib/typescript/components/CardNews.d.ts.map +1 -1
  134. package/lib/typescript/components/Carousel.d.ts +29 -0
  135. package/lib/typescript/components/Carousel.d.ts.map +1 -0
  136. package/lib/typescript/components/Checkbox.d.ts.map +1 -1
  137. package/lib/typescript/components/DropdownMenu.d.ts +39 -0
  138. package/lib/typescript/components/DropdownMenu.d.ts.map +1 -0
  139. package/lib/typescript/components/EmptyState.d.ts +1 -1
  140. package/lib/typescript/components/EmptyState.d.ts.map +1 -1
  141. package/lib/typescript/components/Feed.d.ts +22 -0
  142. package/lib/typescript/components/Feed.d.ts.map +1 -0
  143. package/lib/typescript/components/FeedNotice.d.ts +17 -0
  144. package/lib/typescript/components/FeedNotice.d.ts.map +1 -0
  145. package/lib/typescript/components/Input.d.ts +3 -2
  146. package/lib/typescript/components/Input.d.ts.map +1 -1
  147. package/lib/typescript/components/InvitePopover.d.ts +46 -0
  148. package/lib/typescript/components/InvitePopover.d.ts.map +1 -0
  149. package/lib/typescript/components/Label.d.ts.map +1 -1
  150. package/lib/typescript/components/LeaderboardCard.d.ts +16 -0
  151. package/lib/typescript/components/LeaderboardCard.d.ts.map +1 -0
  152. package/lib/typescript/components/MemberRow.d.ts +40 -0
  153. package/lib/typescript/components/MemberRow.d.ts.map +1 -0
  154. package/lib/typescript/components/PageHeader.d.ts.map +1 -1
  155. package/lib/typescript/components/PostForm.d.ts +50 -0
  156. package/lib/typescript/components/PostForm.d.ts.map +1 -0
  157. package/lib/typescript/components/PrizeCollection.d.ts +35 -0
  158. package/lib/typescript/components/PrizeCollection.d.ts.map +1 -0
  159. package/lib/typescript/components/RadioGroup.d.ts +10 -2
  160. package/lib/typescript/components/RadioGroup.d.ts.map +1 -1
  161. package/lib/typescript/components/SectionHeader.d.ts +12 -0
  162. package/lib/typescript/components/SectionHeader.d.ts.map +1 -0
  163. package/lib/typescript/components/Switch.d.ts.map +1 -1
  164. package/lib/typescript/components/Tabs.d.ts +32 -0
  165. package/lib/typescript/components/Tabs.d.ts.map +1 -0
  166. package/lib/typescript/components/Tag.d.ts.map +1 -1
  167. package/lib/typescript/components/Text.d.ts +23 -0
  168. package/lib/typescript/components/Text.d.ts.map +1 -0
  169. package/lib/typescript/components/Toast.d.ts +1 -1
  170. package/lib/typescript/components/Toast.d.ts.map +1 -1
  171. package/lib/typescript/components/Tooltip.d.ts.map +1 -1
  172. package/lib/typescript/hooks/useThemeColor.d.ts +4 -2
  173. package/lib/typescript/hooks/useThemeColor.d.ts.map +1 -1
  174. package/lib/typescript/index.d.ts +28 -4
  175. package/lib/typescript/index.d.ts.map +1 -1
  176. package/lib/typescript/lib/overlay-host.d.ts +23 -0
  177. package/lib/typescript/lib/overlay-host.d.ts.map +1 -0
  178. package/lib/typescript/lib/typography.d.ts +12 -0
  179. package/lib/typescript/lib/typography.d.ts.map +1 -0
  180. package/package.json +13 -3
  181. package/setup/MedwayUiProvider.tsx +15 -3
  182. package/setup/tailwind.js +52 -4
  183. package/setup/tokens.native.css +8 -3
  184. package/src/components/Alert.tsx +4 -2
  185. package/src/components/Avatar.tsx +3 -1
  186. package/src/components/Badge.tsx +3 -1
  187. package/src/components/Button.tsx +3 -7
  188. package/src/components/CardNews.tsx +2 -1
  189. package/src/components/Carousel.tsx +152 -0
  190. package/src/components/Checkbox.tsx +14 -4
  191. package/src/components/DropdownMenu.tsx +312 -0
  192. package/src/components/EmptyState.tsx +21 -23
  193. package/src/components/Feed.tsx +96 -0
  194. package/src/components/FeedNotice.tsx +112 -0
  195. package/src/components/Input.tsx +11 -6
  196. package/src/components/InvitePopover.tsx +240 -0
  197. package/src/components/Label.tsx +3 -1
  198. package/src/components/LeaderboardCard.tsx +70 -0
  199. package/src/components/MemberRow.tsx +157 -0
  200. package/src/components/PageHeader.tsx +3 -1
  201. package/src/components/PostForm.tsx +250 -0
  202. package/src/components/PrizeCollection.tsx +190 -0
  203. package/src/components/RadioGroup.tsx +32 -3
  204. package/src/components/SectionHeader.tsx +45 -0
  205. package/src/components/Switch.tsx +65 -59
  206. package/src/components/Tabs.tsx +182 -0
  207. package/src/components/Tag.tsx +3 -1
  208. package/src/components/Text.tsx +66 -0
  209. package/src/components/Toast.tsx +3 -1
  210. package/src/components/Tooltip.tsx +2 -1
  211. package/src/hooks/useThemeColor.ts +77 -32
  212. package/src/index.ts +147 -6
  213. package/src/lib/overlay-host.tsx +102 -0
  214. package/src/lib/typography.ts +21 -0
  215. package/src/nativewind-env.d.ts +2 -0
@@ -0,0 +1,112 @@
1
+ import { type ReactNode } from "react";
2
+ import { View, type ViewProps } from "react-native";
3
+
4
+ import { Text } from "@/components/Text";
5
+
6
+ import {
7
+ bodySmMediumStyle,
8
+ bodySmSemiboldStyle,
9
+ bodyXsMediumStyle,
10
+ } from "@/lib/typography";
11
+ import { cn } from "@/lib/utils";
12
+
13
+ type FeedNoticeSecondaryMessage = {
14
+ prefix: string;
15
+ highlight: string;
16
+ };
17
+
18
+ interface FeedNoticeProps extends ViewProps {
19
+ icon?: ReactNode;
20
+ message: string;
21
+ secondaryMessage?: FeedNoticeSecondaryMessage;
22
+ date: string;
23
+ time: string;
24
+ }
25
+
26
+ function FeedNoticeMessage({
27
+ message,
28
+ secondaryMessage,
29
+ }: {
30
+ message: string;
31
+ secondaryMessage?: FeedNoticeSecondaryMessage;
32
+ }) {
33
+ if (!secondaryMessage) {
34
+ return (
35
+ <Text
36
+ className="text-center text-sm font-medium leading-sm text-gray-foreground"
37
+ style={bodySmMediumStyle}
38
+ >
39
+ {message}
40
+ </Text>
41
+ );
42
+ }
43
+
44
+ return (
45
+ <View className="items-center">
46
+ <Text
47
+ className="text-center text-sm font-medium leading-sm text-gray-foreground"
48
+ style={bodySmMediumStyle}
49
+ >
50
+ {message}
51
+ </Text>
52
+ <Text
53
+ className="text-center text-sm font-medium leading-sm text-gray-foreground"
54
+ style={bodySmMediumStyle}
55
+ >
56
+ {secondaryMessage.prefix}
57
+ <Text
58
+ className="text-sm font-semibold leading-sm text-gray-foreground"
59
+ style={bodySmSemiboldStyle}
60
+ >
61
+ {secondaryMessage.highlight}
62
+ </Text>
63
+ </Text>
64
+ </View>
65
+ );
66
+ }
67
+
68
+ function FeedNotice({
69
+ className,
70
+ icon,
71
+ message,
72
+ secondaryMessage,
73
+ date,
74
+ time,
75
+ ...props
76
+ }: FeedNoticeProps) {
77
+ return (
78
+ <View
79
+ className={cn(
80
+ "items-center gap-1 rounded-lg bg-gray-background-soft px-6 py-2",
81
+ className
82
+ )}
83
+ {...props}
84
+ >
85
+ {icon ? <View className="size-5">{icon}</View> : null}
86
+ <FeedNoticeMessage message={message} secondaryMessage={secondaryMessage} />
87
+ <View className="flex-row items-center gap-1">
88
+ <Text
89
+ className="text-xs font-medium leading-xs text-gray-foreground-muted"
90
+ style={bodyXsMediumStyle}
91
+ >
92
+ {date}
93
+ </Text>
94
+ <Text
95
+ className="text-xs font-medium leading-xs text-gray-foreground-muted"
96
+ style={bodyXsMediumStyle}
97
+ >
98
+ •
99
+ </Text>
100
+ <Text
101
+ className="text-xs font-medium leading-xs text-gray-foreground-muted"
102
+ style={bodyXsMediumStyle}
103
+ >
104
+ {time}
105
+ </Text>
106
+ </View>
107
+ </View>
108
+ );
109
+ }
110
+
111
+ export { FeedNotice };
112
+ export type { FeedNoticeProps, FeedNoticeSecondaryMessage };
@@ -10,11 +10,9 @@ import {
10
10
  import {
11
11
  View,
12
12
  TextInput,
13
- Text,
14
13
  Pressable,
15
14
  type TextInputProps,
16
15
  type ViewProps,
17
- type TextProps,
18
16
  } from "react-native";
19
17
  import Animated, {
20
18
  useSharedValue,
@@ -32,7 +30,9 @@ import {
32
30
  Show,
33
31
  TriangleWarning,
34
32
  } from "@medway-ui/icons/native";
33
+ import { Text, type TextComponentProps } from "@/components/Text";
35
34
  import { useThemeColor } from "@/hooks/useThemeColor";
35
+ import { fontFamilyMedium } from "@/lib/typography";
36
36
  import { cn } from "@/lib/utils";
37
37
 
38
38
  export type InputType = "text" | "email" | "numeric" | "password";
@@ -78,7 +78,7 @@ export interface InputLabelProps {
78
78
  disabled?: boolean;
79
79
  }
80
80
 
81
- export interface InputTextProps extends TextProps {
81
+ export interface InputTextProps extends TextComponentProps {
82
82
  invalid?: boolean;
83
83
  }
84
84
 
@@ -147,6 +147,7 @@ function FloatingLabel({ children, floated = false, disabled = false }: InputLab
147
147
  left: 16,
148
148
  top: "50%",
149
149
  zIndex: 10,
150
+ fontFamily: fontFamilyMedium,
150
151
  },
151
152
  ]}
152
153
  className={cn(
@@ -167,7 +168,7 @@ function InputText({ invalid = false, className, ...props }: InputTextProps) {
167
168
  return (
168
169
  <Text
169
170
  className={cn(
170
- "text-xs -mt-1",
171
+ "text-xs font-medium -mt-1",
171
172
  invalid ? "text-feedback-error-foreground" : "text-gray-foreground",
172
173
  className
173
174
  )}
@@ -238,13 +239,14 @@ function InputPassword({ className, size = "lg", invalid = false, label, ...prop
238
239
  secureTextEntry={!visible}
239
240
  className={cn(
240
241
  inputVariants({ size, invalid, focused, disabled: props.editable === false }),
241
- "pl-12 pr-12",
242
+ "pl-12 pr-12 font-medium",
242
243
  className
243
244
  )}
244
245
  onFocus={() => setFocused(true)}
245
246
  onBlur={() => setFocused(false)}
246
247
  accessibilityLabel={label}
247
248
  {...props}
249
+ style={[{ fontFamily: fontFamilyMedium }, props.style]}
248
250
  />
249
251
  </View>
250
252
  <InputEndIcon>
@@ -325,11 +327,12 @@ function InputNumeric({
325
327
  className={cn(
326
328
  inputVariants({ size, invalid, focused, disabled: !editable }),
327
329
  iconLeft ? "pl-12" : "",
328
- "pr-12",
330
+ "pr-12 font-medium",
329
331
  className
330
332
  )}
331
333
  accessibilityLabel={label}
332
334
  {...props}
335
+ style={[{ fontFamily: fontFamilyMedium }, props.style]}
333
336
  />
334
337
  </View>
335
338
  <InputEndIcon>
@@ -454,10 +457,12 @@ function Input({
454
457
  inputVariants({ size, invalid, focused, disabled: !editable }),
455
458
  resolvedIconLeft ? "pl-12" : "",
456
459
  resolvedIconRight ? "pr-12" : "",
460
+ "font-medium",
457
461
  className
458
462
  )}
459
463
  accessibilityLabel={label}
460
464
  {...props}
465
+ style={[{ fontFamily: fontFamilyMedium }, props.style]}
461
466
  />
462
467
  </View>
463
468
  {resolvedIconRight && (
@@ -0,0 +1,240 @@
1
+ import { type ReactNode } from "react";
2
+ import { View, type ViewProps } from "react-native";
3
+
4
+ import { Text } from "@/components/Text";
5
+ import * as PopoverPrimitive from "@rn-primitives/popover";
6
+ import { CloseMd } from "@medway-ui/icons/native";
7
+
8
+ import { Button } from "@/components/Button";
9
+ import { Input } from "@/components/Input";
10
+ import { Separator } from "@/components/Separator";
11
+ import { cn } from "@/lib/utils";
12
+
13
+ interface InvitePopoverProps extends PopoverPrimitive.RootProps {
14
+ children?: ReactNode;
15
+ }
16
+
17
+ interface InvitePopoverTriggerProps extends PopoverPrimitive.TriggerProps {
18
+ children?: ReactNode;
19
+ className?: string;
20
+ }
21
+
22
+ interface InvitePopoverContentProps extends PopoverPrimitive.ContentProps {
23
+ className?: string;
24
+ children?: ReactNode;
25
+ align?: "start" | "center" | "end";
26
+ sideOffset?: number;
27
+ }
28
+
29
+ interface InvitePopoverEmailRowProps extends ViewProps {
30
+ value?: string;
31
+ defaultValue?: string;
32
+ onChangeText?: (value: string) => void;
33
+ onAddPress?: () => void;
34
+ addIcon?: ReactNode;
35
+ placeholder?: string;
36
+ label?: string;
37
+ }
38
+
39
+ interface InvitePopoverActionProps extends ViewProps {
40
+ children?: ReactNode;
41
+ iconLeft?: ReactNode;
42
+ iconRight?: ReactNode;
43
+ onPress?: () => void;
44
+ loading?: boolean;
45
+ disabled?: boolean;
46
+ }
47
+
48
+ function InvitePopover({ children, ...props }: InvitePopoverProps) {
49
+ return <PopoverPrimitive.Root {...props}>{children}</PopoverPrimitive.Root>;
50
+ }
51
+
52
+ function InvitePopoverTrigger({
53
+ className,
54
+ children,
55
+ ...props
56
+ }: InvitePopoverTriggerProps) {
57
+ return (
58
+ <PopoverPrimitive.Trigger className={cn(className)} {...props}>
59
+ {children}
60
+ </PopoverPrimitive.Trigger>
61
+ );
62
+ }
63
+
64
+ function InvitePopoverContent({
65
+ className,
66
+ align = "end",
67
+ sideOffset = 8,
68
+ children,
69
+ ...props
70
+ }: InvitePopoverContentProps) {
71
+ return (
72
+ <PopoverPrimitive.Portal>
73
+ <PopoverPrimitive.Overlay className="absolute inset-0" />
74
+ <PopoverPrimitive.Content
75
+ align={align}
76
+ sideOffset={sideOffset}
77
+ className={cn(
78
+ "z-50 w-[min(370px,100vw-2rem)] border-0 bg-transparent p-0 shadow-none",
79
+ className
80
+ )}
81
+ {...props}
82
+ >
83
+ {children}
84
+ </PopoverPrimitive.Content>
85
+ </PopoverPrimitive.Portal>
86
+ );
87
+ }
88
+
89
+ function InvitePopoverClose({ className, ...props }: PopoverPrimitive.CloseProps) {
90
+ return (
91
+ <PopoverPrimitive.Close
92
+ className={cn(
93
+ "mb-4 size-12 items-center justify-center self-end rounded-pill bg-primary-background-fill active:bg-primary-background-fill-emphasis",
94
+ className
95
+ )}
96
+ accessibilityLabel="Fechar"
97
+ {...props}
98
+ >
99
+ <View className="size-6">
100
+ <CloseMd width={24} height={24} color="#FFFFFF" strokeWidth={2.2} />
101
+ </View>
102
+ </PopoverPrimitive.Close>
103
+ );
104
+ }
105
+
106
+ function InvitePopoverCard({ className, children, ...props }: ViewProps) {
107
+ return (
108
+ <View
109
+ className={cn(
110
+ "gap-6 rounded-lg border border-gray-stroke-muted bg-gray-foreground-onfill p-4",
111
+ className
112
+ )}
113
+ {...props}
114
+ >
115
+ {children}
116
+ </View>
117
+ );
118
+ }
119
+
120
+ function InvitePopoverTitle({ className, children, ...props }: ViewProps) {
121
+ return (
122
+ <Text
123
+ className={cn("text-title-xs font-semibold text-primary-foreground", className)}
124
+ {...props}
125
+ >
126
+ {children}
127
+ </Text>
128
+ );
129
+ }
130
+
131
+ function InvitePopoverEmailRow({
132
+ className,
133
+ value,
134
+ defaultValue,
135
+ onChangeText,
136
+ onAddPress,
137
+ addIcon,
138
+ placeholder = "usuario@mail.com",
139
+ label = "Digite um e-mail",
140
+ ...props
141
+ }: InvitePopoverEmailRowProps) {
142
+ return (
143
+ <View className={cn("gap-2", className)} {...props}>
144
+ <Text className="pb-2 text-sm font-medium text-gray-foreground">{label}</Text>
145
+ <View className="flex-row items-end gap-4">
146
+ <View className="min-w-0 flex-1">
147
+ <Input
148
+ type="email"
149
+ size="lg"
150
+ value={value}
151
+ defaultValue={defaultValue}
152
+ onChangeText={onChangeText}
153
+ placeholder={placeholder}
154
+ keyboardType="email-address"
155
+ autoCapitalize="none"
156
+ autoCorrect={false}
157
+ />
158
+ </View>
159
+ {onAddPress ? (
160
+ <Button
161
+ variant="regular-soft"
162
+ size="lg"
163
+ className="size-12 min-h-12 min-w-12 max-w-12 p-0"
164
+ iconLeft={addIcon}
165
+ onPress={onAddPress}
166
+ accessibilityLabel="Adicionar e-mail"
167
+ />
168
+ ) : null}
169
+ </View>
170
+ </View>
171
+ );
172
+ }
173
+
174
+ function InvitePopoverSendButton({
175
+ className,
176
+ children = "Enviar",
177
+ iconRight,
178
+ ...props
179
+ }: InvitePopoverActionProps) {
180
+ return (
181
+ <Button
182
+ variant="regular"
183
+ size="lg"
184
+ className={cn("w-full", className)}
185
+ iconRight={iconRight}
186
+ {...props}
187
+ >
188
+ {children}
189
+ </Button>
190
+ );
191
+ }
192
+
193
+ function InvitePopoverDivider({ className, ...props }: ViewProps) {
194
+ return (
195
+ <View className={cn("flex-row items-center gap-4 py-6", className)} {...props}>
196
+ <Separator className="flex-1" />
197
+ <Text className="text-xs font-semibold text-primary-foreground">ou</Text>
198
+ <Separator className="flex-1" />
199
+ </View>
200
+ );
201
+ }
202
+
203
+ function InvitePopoverShareButton({
204
+ className,
205
+ children = "Compartilhar link",
206
+ iconLeft,
207
+ ...props
208
+ }: InvitePopoverActionProps) {
209
+ return (
210
+ <Button
211
+ variant="regular"
212
+ size="lg"
213
+ className={cn("w-full", className)}
214
+ iconLeft={iconLeft}
215
+ {...props}
216
+ >
217
+ {children}
218
+ </Button>
219
+ );
220
+ }
221
+
222
+ export {
223
+ InvitePopover,
224
+ InvitePopoverCard,
225
+ InvitePopoverClose,
226
+ InvitePopoverContent,
227
+ InvitePopoverDivider,
228
+ InvitePopoverEmailRow,
229
+ InvitePopoverSendButton,
230
+ InvitePopoverShareButton,
231
+ InvitePopoverTitle,
232
+ InvitePopoverTrigger,
233
+ };
234
+ export type {
235
+ InvitePopoverActionProps,
236
+ InvitePopoverContentProps,
237
+ InvitePopoverEmailRowProps,
238
+ InvitePopoverProps,
239
+ InvitePopoverTriggerProps,
240
+ };
@@ -1,5 +1,7 @@
1
1
  import { type ReactNode } from "react";
2
- import { Pressable, Text, type PressableProps } from "react-native";
2
+ import { Pressable, type PressableProps } from "react-native";
3
+
4
+ import { Text } from "@/components/Text";
3
5
  import { cva, type VariantProps } from "class-variance-authority";
4
6
  import { cn } from "@/lib/utils";
5
7
 
@@ -0,0 +1,70 @@
1
+ import { type ReactNode } from "react";
2
+ import { View, type ViewProps } from "react-native";
3
+
4
+ import { Text } from "@/components/Text";
5
+
6
+ import { cn } from "@/lib/utils";
7
+
8
+ interface LeaderboardCardProps extends ViewProps {
9
+ children?: ReactNode;
10
+ }
11
+
12
+ interface LeaderboardCardHeaderProps extends ViewProps {
13
+ icon?: ReactNode;
14
+ title: string;
15
+ badge?: ReactNode;
16
+ }
17
+
18
+ function LeaderboardCard({ className, children, ...props }: LeaderboardCardProps) {
19
+ return (
20
+ <View
21
+ className={cn(
22
+ "gap-8 rounded-lg border border-gray-stroke-muted bg-surface-card p-6",
23
+ className
24
+ )}
25
+ {...props}
26
+ >
27
+ {children}
28
+ </View>
29
+ );
30
+ }
31
+
32
+ function LeaderboardCardHeader({
33
+ className,
34
+ icon,
35
+ title,
36
+ badge,
37
+ ...props
38
+ }: LeaderboardCardHeaderProps) {
39
+ return (
40
+ <View
41
+ className={cn("flex-row items-center gap-3", className)}
42
+ {...props}
43
+ >
44
+ {icon ? (
45
+ <View className="size-8 items-center justify-center rounded-full bg-gray-background-soft p-2">
46
+ {icon}
47
+ </View>
48
+ ) : null}
49
+ <View className="min-w-0 flex-1 flex-row items-center justify-between gap-2">
50
+ <Text className="text-lg font-semibold text-primary-foreground">
51
+ {title}
52
+ </Text>
53
+ {typeof badge === "string" ? (
54
+ <Text className="text-xs font-semibold text-primary-foreground">
55
+ {badge}
56
+ </Text>
57
+ ) : (
58
+ badge
59
+ )}
60
+ </View>
61
+ </View>
62
+ );
63
+ }
64
+
65
+ function LeaderboardCardList({ className, ...props }: ViewProps) {
66
+ return <View className={cn("gap-2", className)} {...props} />;
67
+ }
68
+
69
+ export { LeaderboardCard, LeaderboardCardHeader, LeaderboardCardList };
70
+ export type { LeaderboardCardHeaderProps, LeaderboardCardProps };
@@ -0,0 +1,157 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+ import { type ReactNode } from "react";
3
+ import { View, type ViewProps } from "react-native";
4
+
5
+ import { Text } from "@/components/Text";
6
+
7
+ import { Avatar, AvatarFallback, AvatarImage } from "@/components/Avatar";
8
+ import { RadioGroupItem } from "@/components/RadioGroup";
9
+ import { cn } from "@/lib/utils";
10
+
11
+ const rankIndicatorVariants = cva("size-[22px] rounded-full", {
12
+ variants: {
13
+ rank: {
14
+ 1: "bg-yellow-background-fill",
15
+ 2: "bg-gray-background-fill",
16
+ 3: "bg-warning-background-fill",
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ rank: 1,
21
+ },
22
+ });
23
+
24
+ const memberRowVariants = cva("w-full flex-row items-center p-2", {
25
+ variants: {
26
+ variant: {
27
+ ranked: "",
28
+ selectable: "px-4 py-4",
29
+ },
30
+ highlighted: {
31
+ true: "rounded-md bg-secondary-background-soft",
32
+ false: "",
33
+ },
34
+ },
35
+ defaultVariants: {
36
+ variant: "ranked",
37
+ highlighted: false,
38
+ },
39
+ });
40
+
41
+ interface MemberRowRankedProps extends ViewProps {
42
+ variant?: "ranked";
43
+ rank: 1 | 2 | 3;
44
+ rankLabel: string;
45
+ name: string;
46
+ subtitle?: string;
47
+ avatarSrc?: string;
48
+ avatarAlt?: string;
49
+ avatarFallback?: string;
50
+ highlighted?: boolean;
51
+ leading?: ReactNode;
52
+ value?: never;
53
+ }
54
+
55
+ interface MemberRowSelectableProps extends ViewProps {
56
+ variant: "selectable";
57
+ value: string;
58
+ name: string;
59
+ avatarSrc?: string;
60
+ avatarAlt?: string;
61
+ avatarFallback?: string;
62
+ highlighted?: boolean;
63
+ rank?: never;
64
+ rankLabel?: never;
65
+ subtitle?: never;
66
+ leading?: never;
67
+ }
68
+
69
+ type MemberRowProps = MemberRowRankedProps | MemberRowSelectableProps;
70
+
71
+ function getInitials(name: string): string {
72
+ return name
73
+ .trim()
74
+ .split(/\s+/)
75
+ .slice(0, 2)
76
+ .map((word) => word[0] ?? "")
77
+ .join("")
78
+ .toUpperCase();
79
+ }
80
+
81
+ function MemberRow({
82
+ className,
83
+ variant = "ranked",
84
+ rank = 1,
85
+ rankLabel,
86
+ name,
87
+ subtitle,
88
+ avatarSrc,
89
+ avatarAlt,
90
+ avatarFallback,
91
+ value,
92
+ highlighted = false,
93
+ leading,
94
+ ...props
95
+ }: MemberRowProps) {
96
+ const initials = avatarFallback ?? getInitials(name);
97
+
98
+ if (variant === "selectable") {
99
+ const selectionValue = (props as MemberRowSelectableProps).value;
100
+
101
+ return (
102
+ <View
103
+ className={cn(memberRowVariants({ variant, highlighted }), className)}
104
+ {...props}
105
+ >
106
+ <View className="min-w-0 flex-1 flex-row items-center gap-4">
107
+ <RadioGroupItem value={selectionValue} size="md" />
108
+ <View className="min-w-0 flex-1 flex-row items-center gap-2">
109
+ <Avatar size="sm" alt={avatarAlt ?? name}>
110
+ {avatarSrc ? <AvatarImage src={avatarSrc} /> : null}
111
+ <AvatarFallback>{initials}</AvatarFallback>
112
+ </Avatar>
113
+ <Text className="text-md font-semibold text-primary-foreground">
114
+ {name}
115
+ </Text>
116
+ </View>
117
+ </View>
118
+ </View>
119
+ );
120
+ }
121
+
122
+ return (
123
+ <View
124
+ className={cn(memberRowVariants({ variant, highlighted }), className)}
125
+ {...props}
126
+ >
127
+ <View className="min-w-0 flex-1 flex-row items-center gap-2">
128
+ {leading}
129
+ <View className={cn(rankIndicatorVariants({ rank }))} />
130
+ <View className="flex-row items-center gap-2">
131
+ {rankLabel ? (
132
+ <Text className="w-7 text-md font-semibold text-primary-foreground">
133
+ {rankLabel}
134
+ </Text>
135
+ ) : null}
136
+ <Avatar size="sm" alt={avatarAlt ?? name}>
137
+ {avatarSrc ? <AvatarImage src={avatarSrc} /> : null}
138
+ <AvatarFallback>{initials}</AvatarFallback>
139
+ </Avatar>
140
+ <View>
141
+ <Text className="text-md font-semibold text-primary-foreground">
142
+ {name}
143
+ </Text>
144
+ {subtitle ? (
145
+ <Text className="text-xs font-medium text-primary-foreground">
146
+ {subtitle}
147
+ </Text>
148
+ ) : null}
149
+ </View>
150
+ </View>
151
+ </View>
152
+ </View>
153
+ );
154
+ }
155
+
156
+ export { MemberRow, memberRowVariants, rankIndicatorVariants };
157
+ export type { MemberRowProps };
@@ -1,5 +1,7 @@
1
1
  import { type ReactNode } from "react";
2
- import { Text, View, type ViewProps } from "react-native";
2
+ import { View, type ViewProps } from "react-native";
3
+
4
+ import { Text } from "@/components/Text";
3
5
 
4
6
  import { cn } from "@/lib/utils";
5
7