@medway-ui/native 1.0.2

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 (155) hide show
  1. package/README.md +153 -0
  2. package/lib/commonjs/components/Alert.js +206 -0
  3. package/lib/commonjs/components/Alert.js.map +1 -0
  4. package/lib/commonjs/components/AlertDialog.js +273 -0
  5. package/lib/commonjs/components/AlertDialog.js.map +1 -0
  6. package/lib/commonjs/components/Badge.js +94 -0
  7. package/lib/commonjs/components/Badge.js.map +1 -0
  8. package/lib/commonjs/components/Button.js +181 -0
  9. package/lib/commonjs/components/Button.js.map +1 -0
  10. package/lib/commonjs/components/Checkbox.js +91 -0
  11. package/lib/commonjs/components/Checkbox.js.map +1 -0
  12. package/lib/commonjs/components/Dialog.js +164 -0
  13. package/lib/commonjs/components/Dialog.js.map +1 -0
  14. package/lib/commonjs/components/Input.js +364 -0
  15. package/lib/commonjs/components/Input.js.map +1 -0
  16. package/lib/commonjs/components/Label.js +90 -0
  17. package/lib/commonjs/components/Label.js.map +1 -0
  18. package/lib/commonjs/components/Loading.js +49 -0
  19. package/lib/commonjs/components/Loading.js.map +1 -0
  20. package/lib/commonjs/components/Popover.js +54 -0
  21. package/lib/commonjs/components/Popover.js.map +1 -0
  22. package/lib/commonjs/components/RadioGroup.js +72 -0
  23. package/lib/commonjs/components/RadioGroup.js.map +1 -0
  24. package/lib/commonjs/components/Select.js +234 -0
  25. package/lib/commonjs/components/Select.js.map +1 -0
  26. package/lib/commonjs/components/Separator.js +22 -0
  27. package/lib/commonjs/components/Separator.js.map +1 -0
  28. package/lib/commonjs/components/Sheet.js +148 -0
  29. package/lib/commonjs/components/Sheet.js.map +1 -0
  30. package/lib/commonjs/components/Switch.js +99 -0
  31. package/lib/commonjs/components/Switch.js.map +1 -0
  32. package/lib/commonjs/components/Tag.js +132 -0
  33. package/lib/commonjs/components/Tag.js.map +1 -0
  34. package/lib/commonjs/components/Toast.js +244 -0
  35. package/lib/commonjs/components/Toast.js.map +1 -0
  36. package/lib/commonjs/components/Tooltip.js +54 -0
  37. package/lib/commonjs/components/Tooltip.js.map +1 -0
  38. package/lib/commonjs/hooks/use-toast.js +136 -0
  39. package/lib/commonjs/hooks/use-toast.js.map +1 -0
  40. package/lib/commonjs/index.js +667 -0
  41. package/lib/commonjs/index.js.map +1 -0
  42. package/lib/commonjs/lib/utils.js +22 -0
  43. package/lib/commonjs/lib/utils.js.map +1 -0
  44. package/lib/commonjs/nativewind-env.d.js +3 -0
  45. package/lib/commonjs/nativewind-env.d.js.map +1 -0
  46. package/lib/module/components/Alert.js +195 -0
  47. package/lib/module/components/Alert.js.map +1 -0
  48. package/lib/module/components/AlertDialog.js +257 -0
  49. package/lib/module/components/AlertDialog.js.map +1 -0
  50. package/lib/module/components/Badge.js +90 -0
  51. package/lib/module/components/Badge.js.map +1 -0
  52. package/lib/module/components/Button.js +177 -0
  53. package/lib/module/components/Button.js.map +1 -0
  54. package/lib/module/components/Checkbox.js +86 -0
  55. package/lib/module/components/Checkbox.js.map +1 -0
  56. package/lib/module/components/Dialog.js +150 -0
  57. package/lib/module/components/Dialog.js.map +1 -0
  58. package/lib/module/components/Input.js +349 -0
  59. package/lib/module/components/Input.js.map +1 -0
  60. package/lib/module/components/Label.js +86 -0
  61. package/lib/module/components/Label.js.map +1 -0
  62. package/lib/module/components/Loading.js +45 -0
  63. package/lib/module/components/Loading.js.map +1 -0
  64. package/lib/module/components/Popover.js +47 -0
  65. package/lib/module/components/Popover.js.map +1 -0
  66. package/lib/module/components/RadioGroup.js +66 -0
  67. package/lib/module/components/RadioGroup.js.map +1 -0
  68. package/lib/module/components/Select.js +217 -0
  69. package/lib/module/components/Select.js.map +1 -0
  70. package/lib/module/components/Separator.js +19 -0
  71. package/lib/module/components/Separator.js.map +1 -0
  72. package/lib/module/components/Sheet.js +136 -0
  73. package/lib/module/components/Sheet.js.map +1 -0
  74. package/lib/module/components/Switch.js +94 -0
  75. package/lib/module/components/Switch.js.map +1 -0
  76. package/lib/module/components/Tag.js +128 -0
  77. package/lib/module/components/Tag.js.map +1 -0
  78. package/lib/module/components/Toast.js +233 -0
  79. package/lib/module/components/Toast.js.map +1 -0
  80. package/lib/module/components/Tooltip.js +47 -0
  81. package/lib/module/components/Tooltip.js.map +1 -0
  82. package/lib/module/hooks/use-toast.js +130 -0
  83. package/lib/module/hooks/use-toast.js.map +1 -0
  84. package/lib/module/index.js +41 -0
  85. package/lib/module/index.js.map +1 -0
  86. package/lib/module/lib/utils.js +18 -0
  87. package/lib/module/lib/utils.js.map +1 -0
  88. package/lib/module/nativewind-env.d.js +3 -0
  89. package/lib/module/nativewind-env.d.js.map +1 -0
  90. package/lib/module/package.json +1 -0
  91. package/lib/typescript/components/Alert.d.ts +36 -0
  92. package/lib/typescript/components/Alert.d.ts.map +1 -0
  93. package/lib/typescript/components/AlertDialog.d.ts +44 -0
  94. package/lib/typescript/components/AlertDialog.d.ts.map +1 -0
  95. package/lib/typescript/components/Badge.d.ts +17 -0
  96. package/lib/typescript/components/Badge.d.ts.map +1 -0
  97. package/lib/typescript/components/Button.d.ts +24 -0
  98. package/lib/typescript/components/Button.d.ts.map +1 -0
  99. package/lib/typescript/components/Checkbox.d.ts +20 -0
  100. package/lib/typescript/components/Checkbox.d.ts.map +1 -0
  101. package/lib/typescript/components/Dialog.d.ts +35 -0
  102. package/lib/typescript/components/Dialog.d.ts.map +1 -0
  103. package/lib/typescript/components/Input.d.ts +57 -0
  104. package/lib/typescript/components/Input.d.ts.map +1 -0
  105. package/lib/typescript/components/Label.d.ts +21 -0
  106. package/lib/typescript/components/Label.d.ts.map +1 -0
  107. package/lib/typescript/components/Loading.d.ts +9 -0
  108. package/lib/typescript/components/Loading.d.ts.map +1 -0
  109. package/lib/typescript/components/Popover.d.ts +11 -0
  110. package/lib/typescript/components/Popover.d.ts.map +1 -0
  111. package/lib/typescript/components/RadioGroup.d.ts +13 -0
  112. package/lib/typescript/components/RadioGroup.d.ts.map +1 -0
  113. package/lib/typescript/components/Select.d.ts +37 -0
  114. package/lib/typescript/components/Select.d.ts.map +1 -0
  115. package/lib/typescript/components/Separator.d.ts +9 -0
  116. package/lib/typescript/components/Separator.d.ts.map +1 -0
  117. package/lib/typescript/components/Sheet.d.ts +31 -0
  118. package/lib/typescript/components/Sheet.d.ts.map +1 -0
  119. package/lib/typescript/components/Switch.d.ts +18 -0
  120. package/lib/typescript/components/Switch.d.ts.map +1 -0
  121. package/lib/typescript/components/Tag.d.ts +17 -0
  122. package/lib/typescript/components/Tag.d.ts.map +1 -0
  123. package/lib/typescript/components/Toast.d.ts +42 -0
  124. package/lib/typescript/components/Toast.d.ts.map +1 -0
  125. package/lib/typescript/components/Tooltip.d.ts +14 -0
  126. package/lib/typescript/components/Tooltip.d.ts.map +1 -0
  127. package/lib/typescript/hooks/use-toast.d.ts +46 -0
  128. package/lib/typescript/hooks/use-toast.d.ts.map +1 -0
  129. package/lib/typescript/index.d.ts +38 -0
  130. package/lib/typescript/index.d.ts.map +1 -0
  131. package/lib/typescript/lib/utils.d.ts +3 -0
  132. package/lib/typescript/lib/utils.d.ts.map +1 -0
  133. package/package.json +111 -0
  134. package/src/components/Alert.tsx +185 -0
  135. package/src/components/AlertDialog.tsx +277 -0
  136. package/src/components/Badge.tsx +113 -0
  137. package/src/components/Button.tsx +224 -0
  138. package/src/components/Checkbox.tsx +106 -0
  139. package/src/components/Dialog.tsx +175 -0
  140. package/src/components/Input.tsx +439 -0
  141. package/src/components/Label.tsx +95 -0
  142. package/src/components/Loading.tsx +54 -0
  143. package/src/components/Popover.tsx +46 -0
  144. package/src/components/RadioGroup.tsx +62 -0
  145. package/src/components/Select.tsx +246 -0
  146. package/src/components/Separator.tsx +24 -0
  147. package/src/components/Sheet.tsx +165 -0
  148. package/src/components/Switch.tsx +138 -0
  149. package/src/components/Tag.tsx +116 -0
  150. package/src/components/Toast.tsx +265 -0
  151. package/src/components/Tooltip.tsx +49 -0
  152. package/src/hooks/use-toast.ts +144 -0
  153. package/src/index.ts +193 -0
  154. package/src/lib/utils.ts +63 -0
  155. package/src/nativewind-env.d.ts +1 -0
@@ -0,0 +1,224 @@
1
+ import { type ReactNode } from "react";
2
+ import {
3
+ Pressable,
4
+ View,
5
+ Text,
6
+ type PressableProps,
7
+ type ViewStyle,
8
+ } from "react-native";
9
+ import { cva, type VariantProps } from "class-variance-authority";
10
+ import { cn } from "@/lib/utils";
11
+ import { Loading } from "@/components/Loading";
12
+ import { Badge as BadgeComponent } from "@/components/Badge";
13
+
14
+ interface ButtonProps extends Omit<PressableProps, "children">, VariantProps<typeof buttonVariants> {
15
+ children?: ReactNode;
16
+ containerStyle?: ViewStyle;
17
+ iconRight?: ReactNode;
18
+ iconLeft?: ReactNode;
19
+ badge?: number | string;
20
+ loading?: boolean;
21
+ alert?: string;
22
+ }
23
+
24
+ const ICON_ONLY_SIZES: Record<"sm" | "md" | "lg" | "xl", string> = {
25
+ sm: "h-8 min-h-8 w-8",
26
+ md: "h-10 min-h-10 w-10",
27
+ lg: "h-12 min-h-12 w-12",
28
+ xl: "h-14 min-h-14 w-14",
29
+ };
30
+
31
+ const badgeSizeMap: Record<"sm" | "md" | "lg" | "xl", "sm" | "md" | "lg" | "xl"> = {
32
+ sm: "sm",
33
+ md: "md",
34
+ lg: "md",
35
+ xl: "lg",
36
+ };
37
+
38
+ const ALERT_DOT_SIZES: Record<"sm" | "md" | "lg" | "xl", number> = {
39
+ sm: 8,
40
+ md: 10,
41
+ lg: 10,
42
+ xl: 12,
43
+ };
44
+
45
+ const buttonVariants = cva(
46
+ "flex-row items-center justify-center gap-2 rounded-pill font-semibold",
47
+ {
48
+ variants: {
49
+ variant: {
50
+ regular:
51
+ "bg-primary-background-fill active:bg-primary-background-fill-emphasis disabled:bg-gray-background-fill-muted",
52
+ "regular-soft":
53
+ "bg-primary-background-soft active:bg-primary-background-soft-emphasis disabled:bg-gray-background-soft-muted",
54
+ "regular-basic":
55
+ "bg-transparent active:bg-primary-background-soft-emphasis disabled:bg-transparent",
56
+ emphasis:
57
+ "bg-secondary-background-fill active:bg-secondary-background-fill-emphasis disabled:bg-gray-background-fill-muted",
58
+ "emphasis-soft":
59
+ "bg-secondary-background-soft active:bg-secondary-background-soft-emphasis disabled:bg-gray-background-soft-muted",
60
+ "emphasis-basic":
61
+ "bg-transparent active:bg-secondary-background-soft-emphasis disabled:bg-transparent",
62
+ error:
63
+ "bg-red-background-fill active:bg-red-background-fill-emphasis disabled:bg-gray-background-fill-muted",
64
+ "error-soft":
65
+ "bg-red-background-soft active:bg-red-background-soft-emphasis disabled:bg-gray-background-soft-muted",
66
+ "error-basic":
67
+ "bg-transparent active:bg-red-background-soft-emphasis disabled:bg-transparent",
68
+ warning:
69
+ "bg-yellow-background-fill active:bg-yellow-background-fill-emphasis disabled:bg-gray-background-fill-muted",
70
+ "warning-soft":
71
+ "bg-yellow-background-soft active:bg-yellow-background-soft-emphasis disabled:bg-gray-background-soft-muted",
72
+ "warning-basic":
73
+ "bg-transparent active:bg-yellow-background-soft-emphasis disabled:bg-transparent",
74
+ success:
75
+ "bg-green-background-fill active:bg-green-background-fill-emphasis disabled:bg-gray-background-fill-muted",
76
+ "success-soft":
77
+ "bg-green-background-soft active:bg-green-background-soft-emphasis disabled:bg-gray-background-soft-muted",
78
+ "success-basic":
79
+ "bg-transparent active:bg-green-background-soft-emphasis disabled:bg-transparent",
80
+ outlined:
81
+ "border border-gray-stroke-muted bg-transparent active:bg-gray-50 disabled:border-gray-stroke-muted",
82
+ gradient:
83
+ "bg-primary active:opacity-90 disabled:bg-gray-background-fill-muted",
84
+ medbrain:
85
+ "bg-surface-card border-2 border-secondary active:bg-secondary-background-soft disabled:bg-gray-background-fill-muted disabled:border-transparent",
86
+ },
87
+ size: {
88
+ sm: "min-h-8 min-w-8 px-3 py-1",
89
+ md: "min-h-10 min-w-10 px-3.5 py-2",
90
+ lg: "min-h-12 min-w-12 px-4 py-3",
91
+ xl: "min-h-14 min-w-14 px-[18px] py-3.5",
92
+ },
93
+ },
94
+ defaultVariants: {
95
+ variant: "regular",
96
+ size: "md",
97
+ },
98
+ }
99
+ );
100
+
101
+ const buttonTextVariants = cva("font-semibold shrink-0", {
102
+ variants: {
103
+ variant: {
104
+ regular: "text-primary-foreground-onfill disabled:text-gray-foreground-onfill",
105
+ "regular-soft": "text-primary-foreground disabled:text-gray-foreground-muted",
106
+ "regular-basic": "text-primary-foreground disabled:text-gray-foreground-muted",
107
+ emphasis: "text-secondary-foreground-onfill disabled:text-gray-foreground-onfill",
108
+ "emphasis-soft": "text-secondary-foreground disabled:text-gray-foreground-muted",
109
+ "emphasis-basic": "text-secondary-foreground disabled:text-gray-foreground-muted",
110
+ error: "text-red-foreground-onfill disabled:text-gray-foreground-onfill",
111
+ "error-soft": "text-red-foreground disabled:text-gray-foreground-muted",
112
+ "error-basic": "text-red-foreground disabled:text-gray-foreground-muted",
113
+ warning: "text-yellow-foreground-onfill disabled:text-gray-foreground-onfill",
114
+ "warning-soft": "text-yellow-foreground disabled:text-gray-foreground-muted",
115
+ "warning-basic": "text-yellow-foreground disabled:text-gray-foreground-muted",
116
+ success: "text-green-foreground-onfill disabled:text-gray-foreground-onfill",
117
+ "success-soft": "text-green-foreground disabled:text-gray-foreground-muted",
118
+ "success-basic": "text-green-foreground disabled:text-gray-foreground-muted",
119
+ outlined: "text-foreground disabled:text-gray-foreground-muted",
120
+ gradient: "text-white disabled:text-gray-foreground-onfill",
121
+ medbrain: "text-secondary disabled:text-gray-foreground-onfill",
122
+ },
123
+ size: {
124
+ sm: "text-xs",
125
+ md: "text-sm",
126
+ lg: "text-md",
127
+ xl: "text-lg",
128
+ },
129
+ },
130
+ defaultVariants: {
131
+ variant: "regular",
132
+ size: "md",
133
+ },
134
+ });
135
+
136
+ function shouldShowBadge(value: number | string | undefined) {
137
+ return value != null && value !== 0 && value !== "" && value !== "0";
138
+ }
139
+
140
+ function Button({
141
+ className,
142
+ containerStyle,
143
+ variant = "regular",
144
+ size = "md",
145
+ iconRight,
146
+ iconLeft,
147
+ badge,
148
+ loading = false,
149
+ alert,
150
+ disabled,
151
+ children,
152
+ ...props
153
+ }: ButtonProps) {
154
+ const resolvedSize = size ?? "md";
155
+ const resolvedVariant = variant ?? "regular";
156
+ const isIconOnly = !children && !alert && (!!iconLeft || !!iconRight);
157
+
158
+ return (
159
+ <View style={[{ position: "relative" }, containerStyle]}>
160
+ {shouldShowBadge(badge) && (
161
+ <View className="absolute -right-2 -top-1 z-10">
162
+ <BadgeComponent size={badgeSizeMap[resolvedSize]} variant="regular">
163
+ {String(badge)}
164
+ </BadgeComponent>
165
+ </View>
166
+ )}
167
+
168
+ <Pressable
169
+ disabled={disabled || loading}
170
+ accessibilityRole="button"
171
+ accessibilityState={{ disabled: disabled || loading, busy: loading }}
172
+ className={cn(
173
+ buttonVariants({ variant, size }),
174
+ isIconOnly && ICON_ONLY_SIZES[resolvedSize],
175
+ className
176
+ )}
177
+ {...props}
178
+ >
179
+ {loading ? (
180
+ <>
181
+ <View className="absolute">
182
+ <Loading size={resolvedSize === "sm" ? 16 : resolvedSize === "xl" ? 24 : 20} />
183
+ </View>
184
+ <View className="opacity-0 flex-row items-center gap-2">
185
+ {iconLeft}
186
+ {children != null && (
187
+ <Text className={cn(buttonTextVariants({ variant: resolvedVariant, size }))}>
188
+ {children}
189
+ </Text>
190
+ )}
191
+ {iconRight}
192
+ </View>
193
+ </>
194
+ ) : (
195
+ <>
196
+ {alert ? (
197
+ <View className="relative mr-1 flex-row items-center">
198
+ <View
199
+ className="rounded-full opacity-75"
200
+ style={{
201
+ width: ALERT_DOT_SIZES[resolvedSize],
202
+ height: ALERT_DOT_SIZES[resolvedSize],
203
+ backgroundColor: alert,
204
+ }}
205
+ />
206
+ </View>
207
+ ) : (
208
+ iconLeft
209
+ )}
210
+ {children != null && (
211
+ <Text className={cn(buttonTextVariants({ variant: resolvedVariant, size }))}>
212
+ {children}
213
+ </Text>
214
+ )}
215
+ {iconRight}
216
+ </>
217
+ )}
218
+ </Pressable>
219
+ </View>
220
+ );
221
+ }
222
+
223
+ export { Button, buttonVariants, buttonTextVariants };
224
+ export type { ButtonProps };
@@ -0,0 +1,106 @@
1
+ import { useState } from "react";
2
+ import * as CheckboxPrimitive from "@rn-primitives/checkbox";
3
+ import { Check, RemoveMinus } from "@medway-ui/icons/native";
4
+ import { cva } from "class-variance-authority";
5
+ import { cn } from "@/lib/utils";
6
+
7
+ interface CheckboxProps extends Omit<CheckboxPrimitive.RootProps, "checked" | "disabled" | "onCheckedChange"> {
8
+ checked?: boolean;
9
+ defaultChecked?: boolean;
10
+ onCheckedChange?: (checked: boolean) => void;
11
+ disabled?: boolean;
12
+ size?: "sm" | "md" | "lg";
13
+ variant?: "regular";
14
+ uncheckIcon?: boolean;
15
+ }
16
+
17
+ const ICON_SIZES: Record<"sm" | "md" | "lg", number> = {
18
+ sm: 12,
19
+ md: 16,
20
+ lg: 20,
21
+ };
22
+
23
+ const checkboxVariants = cva(
24
+ "items-center justify-center rounded-sm border-2 shrink-0",
25
+ {
26
+ variants: {
27
+ variant: {
28
+ regular: "bg-surface-card border-gray-stroke-muted",
29
+ },
30
+ size: {
31
+ sm: "h-4 w-4",
32
+ md: "h-5 w-5",
33
+ lg: "h-6 w-6",
34
+ },
35
+ checked: {
36
+ true: "bg-primary-background-fill border-primary-background-fill",
37
+ false: "",
38
+ },
39
+ disabled: {
40
+ true: "bg-gray-background-soft-muted border-gray-stroke-muted",
41
+ false: "",
42
+ },
43
+ },
44
+ defaultVariants: {
45
+ variant: "regular",
46
+ size: "md",
47
+ checked: false,
48
+ disabled: false,
49
+ },
50
+ }
51
+ );
52
+
53
+ function Checkbox({
54
+ className,
55
+ size = "md",
56
+ variant,
57
+ uncheckIcon,
58
+ checked,
59
+ defaultChecked = false,
60
+ onCheckedChange,
61
+ disabled,
62
+ ...props
63
+ }: CheckboxProps) {
64
+ const resolvedSize = size ?? "md";
65
+ const iconSize = ICON_SIZES[resolvedSize];
66
+ const [internalChecked, setInternalChecked] = useState(defaultChecked);
67
+ const isControlled = checked !== undefined;
68
+ const isChecked = isControlled ? checked : internalChecked;
69
+
70
+ const handleCheckedChange = (val: boolean) => {
71
+ if (!isControlled) setInternalChecked(val);
72
+ onCheckedChange?.(val);
73
+ };
74
+
75
+ return (
76
+ <CheckboxPrimitive.Root
77
+ checked={isChecked}
78
+ onCheckedChange={handleCheckedChange}
79
+ disabled={disabled}
80
+ className={cn(
81
+ checkboxVariants({ size, variant, checked: isChecked, disabled: disabled ?? false }),
82
+ className
83
+ )}
84
+ {...props}
85
+ >
86
+ <CheckboxPrimitive.Indicator className="items-center justify-center">
87
+ {uncheckIcon ? (
88
+ <RemoveMinus
89
+ size={iconSize}
90
+ strokeWidth={2.6}
91
+ className="text-primary-foreground-onfill"
92
+ />
93
+ ) : (
94
+ <Check
95
+ size={iconSize}
96
+ strokeWidth={2.6}
97
+ className="text-primary-foreground-onfill"
98
+ />
99
+ )}
100
+ </CheckboxPrimitive.Indicator>
101
+ </CheckboxPrimitive.Root>
102
+ );
103
+ }
104
+
105
+ export { Checkbox, checkboxVariants };
106
+ export type { CheckboxProps };
@@ -0,0 +1,175 @@
1
+ import { type ReactNode, isValidElement, cloneElement, type ReactElement } from "react";
2
+ import { View, Text, ScrollView, type ViewProps } from "react-native";
3
+ import * as DialogPrimitive from "@rn-primitives/dialog";
4
+ import { CloseMd } from "@medway-ui/icons/native";
5
+ import { cn } from "@/lib/utils";
6
+ import { Separator } from "@/components/Separator";
7
+
8
+ interface DialogContainerProps extends DialogPrimitive.ContentProps {
9
+ showCloseButton?: boolean;
10
+ overlayClassName?: string;
11
+ }
12
+
13
+ interface DialogHeaderProps extends ViewProps {
14
+ separator?: boolean;
15
+ }
16
+
17
+ interface DialogFooterProps extends ViewProps {
18
+ separator?: boolean;
19
+ }
20
+
21
+ interface DialogTitleProps extends DialogPrimitive.TitleProps {
22
+ iconLeft?: ReactNode;
23
+ iconRight?: ReactNode;
24
+ }
25
+
26
+ function Dialog({ ...props }: DialogPrimitive.RootProps) {
27
+ return <DialogPrimitive.Root {...props} />;
28
+ }
29
+
30
+ function DialogTrigger({ ...props }: DialogPrimitive.TriggerProps) {
31
+ return <DialogPrimitive.Trigger {...props} />;
32
+ }
33
+
34
+ function DialogPortal({ ...props }: DialogPrimitive.PortalProps) {
35
+ return <DialogPrimitive.Portal {...props} />;
36
+ }
37
+
38
+ function DialogClose({ ...props }: DialogPrimitive.CloseProps) {
39
+ return <DialogPrimitive.Close {...props} />;
40
+ }
41
+
42
+ function DialogOverlay({ className, ...props }: DialogPrimitive.OverlayProps) {
43
+ return (
44
+ <DialogPrimitive.Overlay
45
+ className={cn("absolute inset-0 bg-black/50", className)}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ function DialogContainer({
52
+ className,
53
+ overlayClassName,
54
+ children,
55
+ showCloseButton = true,
56
+ ...props
57
+ }: DialogContainerProps) {
58
+ return (
59
+ <DialogPrimitive.Portal>
60
+ <DialogPrimitive.Overlay
61
+ className={cn("absolute inset-0 items-center justify-center bg-black/50", overlayClassName)}
62
+ >
63
+ <DialogPrimitive.Content
64
+ className={cn(
65
+ "relative flex-col max-h-[90%] w-full max-w-[calc(100%-2rem)] rounded-xl bg-background shadow-lg overflow-hidden",
66
+ className
67
+ )}
68
+ {...props}
69
+ >
70
+ {children}
71
+ {showCloseButton && (
72
+ <DialogPrimitive.Close className="absolute right-3 top-3 rounded-pill p-1.5 active:bg-gray-background-soft">
73
+ <CloseMd size={16} className="text-gray-foreground" />
74
+ </DialogPrimitive.Close>
75
+ )}
76
+ </DialogPrimitive.Content>
77
+ </DialogPrimitive.Overlay>
78
+ </DialogPrimitive.Portal>
79
+ );
80
+ }
81
+
82
+ function DialogContent({
83
+ containerClassName,
84
+ className,
85
+ children,
86
+ }: {
87
+ containerClassName?: string;
88
+ className?: string;
89
+ children: ReactNode;
90
+ }) {
91
+ return (
92
+ <ScrollView
93
+ className={cn("flex-1", containerClassName)}
94
+ contentContainerStyle={{ flexGrow: 1 }}
95
+ >
96
+ <View className={cn("px-8 py-6", className)}>
97
+ {children}
98
+ </View>
99
+ </ScrollView>
100
+ );
101
+ }
102
+
103
+ function DialogHeader({ className, separator = false, children, ...props }: DialogHeaderProps) {
104
+ return (
105
+ <>
106
+ <View className={cn("flex-col gap-2 px-8 pt-8 pb-4", className)} {...props}>
107
+ {children}
108
+ </View>
109
+ {separator && <Separator />}
110
+ </>
111
+ );
112
+ }
113
+
114
+ function DialogFooter({ className, separator = false, children, ...props }: DialogFooterProps) {
115
+ return (
116
+ <>
117
+ {separator && <Separator />}
118
+ <View
119
+ className={cn("flex-col gap-2 px-8 py-6", className)}
120
+ {...props}
121
+ >
122
+ {children}
123
+ </View>
124
+ </>
125
+ );
126
+ }
127
+
128
+ function DialogTitle({ className, iconLeft, iconRight, children, ...props }: DialogTitleProps) {
129
+ const renderIcon = (icon: ReactNode) => {
130
+ if (isValidElement(icon)) {
131
+ return cloneElement(icon as ReactElement<{ size?: number; strokeWidth?: number }>, {
132
+ size: 32,
133
+ strokeWidth: 2.2,
134
+ });
135
+ }
136
+ return icon;
137
+ };
138
+
139
+ return (
140
+ <DialogPrimitive.Title
141
+ className={cn("flex-row items-center gap-3", className)}
142
+ {...props}
143
+ >
144
+ {iconLeft && renderIcon(iconLeft)}
145
+ <Text className="text-title-md font-semibold leading-title-md text-content-title flex-1">
146
+ {children as string}
147
+ </Text>
148
+ {iconRight && renderIcon(iconRight)}
149
+ </DialogPrimitive.Title>
150
+ );
151
+ }
152
+
153
+ function DialogDescription({ className, ...props }: DialogPrimitive.DescriptionProps) {
154
+ return (
155
+ <DialogPrimitive.Description
156
+ className={cn("text-md leading-md text-content-paragraph", className)}
157
+ {...props}
158
+ />
159
+ );
160
+ }
161
+
162
+ export {
163
+ Dialog,
164
+ DialogClose,
165
+ DialogContainer,
166
+ DialogContent,
167
+ DialogDescription,
168
+ DialogFooter,
169
+ DialogHeader,
170
+ DialogOverlay,
171
+ DialogPortal,
172
+ DialogTitle,
173
+ DialogTrigger,
174
+ };
175
+ export type { DialogContainerProps, DialogHeaderProps, DialogFooterProps, DialogTitleProps };