getlotui 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 (128) hide show
  1. package/README.md +78 -0
  2. package/dist/bin.d.ts +2 -0
  3. package/dist/bin.js +5 -0
  4. package/dist/commands/add.d.ts +1 -0
  5. package/dist/commands/add.js +37 -0
  6. package/dist/commands/init.d.ts +1 -0
  7. package/dist/commands/init.js +93 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +22 -0
  10. package/dist/templates/expo/Accordion.d.ts +14 -0
  11. package/dist/templates/expo/Accordion.js +118 -0
  12. package/dist/templates/expo/Accordion.tsx +152 -0
  13. package/dist/templates/expo/AlertDialog.d.ts +12 -0
  14. package/dist/templates/expo/AlertDialog.js +126 -0
  15. package/dist/templates/expo/AlertDialog.tsx +147 -0
  16. package/dist/templates/expo/Avatar.d.ts +8 -0
  17. package/dist/templates/expo/Avatar.js +81 -0
  18. package/dist/templates/expo/Avatar.tsx +78 -0
  19. package/dist/templates/expo/Badge.d.ts +6 -0
  20. package/dist/templates/expo/Badge.js +60 -0
  21. package/dist/templates/expo/Badge.tsx +67 -0
  22. package/dist/templates/expo/Button.d.ts +9 -0
  23. package/dist/templates/expo/Button.js +37 -0
  24. package/dist/templates/expo/Button.tsx +53 -0
  25. package/dist/templates/expo/Dropdown.d.ts +12 -0
  26. package/dist/templates/expo/Dropdown.js +91 -0
  27. package/dist/templates/expo/Dropdown.tsx +100 -0
  28. package/dist/templates/expo/Input.d.ts +11 -0
  29. package/dist/templates/expo/Input.js +43 -0
  30. package/dist/templates/expo/Input.tsx +67 -0
  31. package/dist/templates/expo/Toast.d.ts +16 -0
  32. package/dist/templates/expo/Toast.js +142 -0
  33. package/dist/templates/expo/Toast.tsx +161 -0
  34. package/dist/templates/expo/utils.d.ts +4 -0
  35. package/dist/templates/expo/utils.js +10 -0
  36. package/dist/templates/expo/utils.ts +8 -0
  37. package/dist/templates/flutter/Accordion.dart +142 -0
  38. package/dist/templates/flutter/Alert.dart +96 -0
  39. package/dist/templates/flutter/AlertDialog.dart +175 -0
  40. package/dist/templates/flutter/Avatar.dart +82 -0
  41. package/dist/templates/flutter/Badge.dart +89 -0
  42. package/dist/templates/flutter/Button.dart +116 -0
  43. package/dist/templates/flutter/Card.dart +91 -0
  44. package/dist/templates/flutter/Input.dart +73 -0
  45. package/dist/templates/flutter/Text.dart +87 -0
  46. package/dist/templates/flutter/utils.dart +13 -0
  47. package/dist/templates/templates/expo/Button.tsx +50 -0
  48. package/dist/templates/templates/expo/Input.tsx +67 -0
  49. package/dist/templates/web/Accordion.d.ts +7 -0
  50. package/dist/templates/web/Accordion.js +59 -0
  51. package/dist/templates/web/Accordion.tsx +64 -0
  52. package/dist/templates/web/Alert.d.ts +9 -0
  53. package/dist/templates/web/Alert.js +64 -0
  54. package/dist/templates/web/Alert.tsx +71 -0
  55. package/dist/templates/web/AlertDialog.d.ts +14 -0
  56. package/dist/templates/web/AlertDialog.js +85 -0
  57. package/dist/templates/web/AlertDialog.tsx +164 -0
  58. package/dist/templates/web/Avatar.d.ts +6 -0
  59. package/dist/templates/web/Avatar.js +50 -0
  60. package/dist/templates/web/Avatar.tsx +51 -0
  61. package/dist/templates/web/Badge.d.ts +9 -0
  62. package/dist/templates/web/Badge.js +59 -0
  63. package/dist/templates/web/Badge.tsx +38 -0
  64. package/dist/templates/web/Button.d.ts +10 -0
  65. package/dist/templates/web/Button.js +70 -0
  66. package/dist/templates/web/Button.tsx +60 -0
  67. package/dist/templates/web/Card.d.ts +9 -0
  68. package/dist/templates/web/Card.js +65 -0
  69. package/dist/templates/web/Card.tsx +92 -0
  70. package/dist/templates/web/Dropdown.d.ts +27 -0
  71. package/dist/templates/web/Dropdown.js +95 -0
  72. package/dist/templates/web/Dropdown.tsx +198 -0
  73. package/dist/templates/web/Input.d.ts +3 -0
  74. package/dist/templates/web/Input.js +41 -0
  75. package/dist/templates/web/Input.tsx +21 -0
  76. package/dist/templates/web/Tabs.d.ts +7 -0
  77. package/dist/templates/web/Tabs.js +55 -0
  78. package/dist/templates/web/Tabs.tsx +66 -0
  79. package/dist/templates/web/Toast.d.ts +15 -0
  80. package/dist/templates/web/Toast.js +75 -0
  81. package/dist/templates/web/Toast.tsx +126 -0
  82. package/dist/templates/web/utils.d.ts +2 -0
  83. package/dist/templates/web/utils.js +8 -0
  84. package/dist/templates/web/utils.ts +6 -0
  85. package/dist/utils/detect.d.ts +19 -0
  86. package/dist/utils/detect.js +90 -0
  87. package/dist/utils/fs.d.ts +5 -0
  88. package/dist/utils/fs.js +35 -0
  89. package/getlotui.config.json +4 -0
  90. package/package.json +31 -0
  91. package/src/bin.ts +5 -0
  92. package/src/commands/add.ts +50 -0
  93. package/src/commands/init.ts +108 -0
  94. package/src/index.ts +23 -0
  95. package/src/templates/expo/Accordion.tsx +152 -0
  96. package/src/templates/expo/AlertDialog.tsx +147 -0
  97. package/src/templates/expo/Avatar.tsx +78 -0
  98. package/src/templates/expo/Badge.tsx +67 -0
  99. package/src/templates/expo/Button.tsx +53 -0
  100. package/src/templates/expo/Dropdown.tsx +100 -0
  101. package/src/templates/expo/Input.tsx +67 -0
  102. package/src/templates/expo/Toast.tsx +161 -0
  103. package/src/templates/expo/utils.ts +8 -0
  104. package/src/templates/flutter/Accordion.dart +142 -0
  105. package/src/templates/flutter/Alert.dart +96 -0
  106. package/src/templates/flutter/AlertDialog.dart +175 -0
  107. package/src/templates/flutter/Avatar.dart +82 -0
  108. package/src/templates/flutter/Badge.dart +89 -0
  109. package/src/templates/flutter/Button.dart +116 -0
  110. package/src/templates/flutter/Card.dart +91 -0
  111. package/src/templates/flutter/Input.dart +73 -0
  112. package/src/templates/flutter/Text.dart +87 -0
  113. package/src/templates/flutter/utils.dart +13 -0
  114. package/src/templates/web/Accordion.tsx +64 -0
  115. package/src/templates/web/Alert.tsx +71 -0
  116. package/src/templates/web/AlertDialog.tsx +164 -0
  117. package/src/templates/web/Avatar.tsx +51 -0
  118. package/src/templates/web/Badge.tsx +38 -0
  119. package/src/templates/web/Button.tsx +60 -0
  120. package/src/templates/web/Card.tsx +92 -0
  121. package/src/templates/web/Dropdown.tsx +198 -0
  122. package/src/templates/web/Input.tsx +21 -0
  123. package/src/templates/web/Tabs.tsx +66 -0
  124. package/src/templates/web/Toast.tsx +126 -0
  125. package/src/templates/web/utils.ts +6 -0
  126. package/src/utils/detect.ts +81 -0
  127. package/src/utils/fs.ts +32 -0
  128. package/tsconfig.json +17 -0
@@ -0,0 +1,147 @@
1
+ import React, { useState } from "react";
2
+ import {
3
+ View,
4
+ Text,
5
+ Modal,
6
+ StyleSheet,
7
+ Pressable,
8
+ Dimensions,
9
+ } from "react-native";
10
+
11
+ export interface AlertDialogProps {
12
+ open?: boolean;
13
+ onOpenChange?: (open: boolean) => void;
14
+ trigger?: React.ReactNode;
15
+ title: string;
16
+ description: string;
17
+ cancelText?: string;
18
+ actionText?: string;
19
+ onAction?: () => void;
20
+ }
21
+
22
+ export const AlertDialog = ({
23
+ open: controlledOpen,
24
+ onOpenChange,
25
+ trigger,
26
+ title,
27
+ description,
28
+ cancelText = "Cancel",
29
+ actionText = "Continue",
30
+ onAction,
31
+ }: AlertDialogProps) => {
32
+ const [internalOpen, setInternalOpen] = useState(false);
33
+ const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;
34
+
35
+ const setOpen = (val: boolean) => {
36
+ if (onOpenChange) onOpenChange(val);
37
+ setInternalOpen(val);
38
+ };
39
+
40
+ return (
41
+ <>
42
+ {trigger && (
43
+ <Pressable onPress={() => setOpen(true)}>{trigger}</Pressable>
44
+ )}
45
+
46
+ <Modal
47
+ transparent
48
+ visible={isOpen}
49
+ animationType="fade"
50
+ onRequestClose={() => setOpen(false)}
51
+ >
52
+ <Pressable style={styles.overlay} onPress={() => setOpen(false)}>
53
+ <Pressable
54
+ style={styles.content}
55
+ onPress={(e) => e.stopPropagation()}
56
+ >
57
+ <Text style={styles.title}>{title}</Text>
58
+ <Text style={styles.description}>{description}</Text>
59
+
60
+ <View style={styles.footer}>
61
+ <Pressable
62
+ style={[styles.button, styles.cancelButton]}
63
+ onPress={() => setOpen(false)}
64
+ >
65
+ <Text style={styles.cancelButtonText}>{cancelText}</Text>
66
+ </Pressable>
67
+
68
+ <Pressable
69
+ style={[styles.button, styles.actionButton]}
70
+ onPress={() => {
71
+ onAction?.();
72
+ setOpen(false);
73
+ }}
74
+ >
75
+ <Text style={styles.actionButtonText}>{actionText}</Text>
76
+ </Pressable>
77
+ </View>
78
+ </Pressable>
79
+ </Pressable>
80
+ </Modal>
81
+ </>
82
+ );
83
+ };
84
+
85
+ const styles = StyleSheet.create({
86
+ overlay: {
87
+ flex: 1,
88
+ backgroundColor: "rgba(0,0,0,0.5)",
89
+ justifyContent: "center",
90
+ alignItems: "center",
91
+ padding: 20,
92
+ },
93
+ content: {
94
+ backgroundColor: "white",
95
+ borderRadius: 12,
96
+ padding: 24,
97
+ width: "100%",
98
+ maxWidth: 400,
99
+ shadowColor: "#000",
100
+ shadowOffset: { width: 0, height: 2 },
101
+ shadowOpacity: 0.25,
102
+ shadowRadius: 4,
103
+ elevation: 5,
104
+ },
105
+ title: {
106
+ fontSize: 18,
107
+ fontWeight: "600",
108
+ color: "#18181b",
109
+ marginBottom: 8,
110
+ },
111
+ description: {
112
+ fontSize: 14,
113
+ color: "#71717a",
114
+ lineHeight: 20,
115
+ marginBottom: 24,
116
+ },
117
+ footer: {
118
+ flexDirection: "row",
119
+ justifyContent: "flex-end",
120
+ gap: 12,
121
+ },
122
+ button: {
123
+ paddingHorizontal: 16,
124
+ paddingVertical: 10,
125
+ borderRadius: 6,
126
+ minWidth: 80,
127
+ alignItems: "center",
128
+ },
129
+ cancelButton: {
130
+ backgroundColor: "white",
131
+ borderWidth: 1,
132
+ borderColor: "#e4e4e7",
133
+ },
134
+ actionButton: {
135
+ backgroundColor: "#18181b",
136
+ },
137
+ cancelButtonText: {
138
+ fontSize: 14,
139
+ fontWeight: "500",
140
+ color: "#18181b",
141
+ },
142
+ actionButtonText: {
143
+ fontSize: 14,
144
+ fontWeight: "500",
145
+ color: "white",
146
+ },
147
+ });
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export interface AvatarProps {
3
+ src?: string;
4
+ fallback?: string;
5
+ size?: "sm" | "md" | "lg";
6
+ shape?: "circle" | "square";
7
+ }
8
+ export declare const Avatar: ({ src, fallback, size, shape, }: AvatarProps) => React.JSX.Element;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Avatar = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const Avatar = ({ src, fallback, size = "md", shape = "circle", }) => {
40
+ const [hasError, setHasError] = (0, react_1.useState)(false);
41
+ const sizes = {
42
+ sm: 32,
43
+ md: 40,
44
+ lg: 56,
45
+ };
46
+ const currentSize = sizes[size];
47
+ return (react_1.default.createElement(react_native_1.View, { style: [
48
+ styles.container,
49
+ {
50
+ width: currentSize,
51
+ height: currentSize,
52
+ borderRadius: shape === "circle" ? currentSize / 2 : 8,
53
+ },
54
+ ] }, src && !hasError ? (react_1.default.createElement(react_native_1.Image, { source: { uri: src }, style: styles.image, onError: () => setHasError(true) })) : (react_1.default.createElement(react_native_1.View, { style: styles.fallback },
55
+ react_1.default.createElement(react_native_1.Text, { style: [styles.fallbackText, { fontSize: currentSize * 0.4 }] }, fallback?.substring(0, 2).toUpperCase() || "??")))));
56
+ };
57
+ exports.Avatar = Avatar;
58
+ const styles = react_native_1.StyleSheet.create({
59
+ container: {
60
+ overflow: "hidden",
61
+ backgroundColor: "#f3f4f6",
62
+ justifyContent: "center",
63
+ alignItems: "center",
64
+ borderWidth: 1,
65
+ borderColor: "rgba(0,0,0,0.05)",
66
+ },
67
+ image: {
68
+ width: "100%",
69
+ height: "100%",
70
+ },
71
+ fallback: {
72
+ width: "100%",
73
+ height: "100%",
74
+ justifyContent: "center",
75
+ alignItems: "center",
76
+ },
77
+ fallbackText: {
78
+ fontWeight: "600",
79
+ color: "#4b5563",
80
+ },
81
+ });
@@ -0,0 +1,78 @@
1
+ import React, { useState } from "react";
2
+ import { View, Image, Text, StyleSheet, Pressable } from "react-native";
3
+
4
+ export interface AvatarProps {
5
+ src?: string;
6
+ fallback?: string;
7
+ size?: "sm" | "md" | "lg";
8
+ shape?: "circle" | "square";
9
+ }
10
+
11
+ export const Avatar = ({
12
+ src,
13
+ fallback,
14
+ size = "md",
15
+ shape = "circle",
16
+ }: AvatarProps) => {
17
+ const [hasError, setHasError] = useState(false);
18
+
19
+ const sizes = {
20
+ sm: 32,
21
+ md: 40,
22
+ lg: 56,
23
+ };
24
+
25
+ const currentSize = sizes[size];
26
+
27
+ return (
28
+ <View
29
+ style={[
30
+ styles.container,
31
+ {
32
+ width: currentSize,
33
+ height: currentSize,
34
+ borderRadius: shape === "circle" ? currentSize / 2 : 8,
35
+ },
36
+ ]}
37
+ >
38
+ {src && !hasError ? (
39
+ <Image
40
+ source={{ uri: src }}
41
+ style={styles.image}
42
+ onError={() => setHasError(true)}
43
+ />
44
+ ) : (
45
+ <View style={styles.fallback}>
46
+ <Text style={[styles.fallbackText, { fontSize: currentSize * 0.4 }]}>
47
+ {fallback?.substring(0, 2).toUpperCase() || "??"}
48
+ </Text>
49
+ </View>
50
+ )}
51
+ </View>
52
+ );
53
+ };
54
+
55
+ const styles = StyleSheet.create({
56
+ container: {
57
+ overflow: "hidden",
58
+ backgroundColor: "#f3f4f6",
59
+ justifyContent: "center",
60
+ alignItems: "center",
61
+ borderWidth: 1,
62
+ borderColor: "rgba(0,0,0,0.05)",
63
+ },
64
+ image: {
65
+ width: "100%",
66
+ height: "100%",
67
+ },
68
+ fallback: {
69
+ width: "100%",
70
+ height: "100%",
71
+ justifyContent: "center",
72
+ alignItems: "center",
73
+ },
74
+ fallbackText: {
75
+ fontWeight: "600",
76
+ color: "#4b5563",
77
+ },
78
+ });
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export interface BadgeProps {
3
+ children: React.ReactNode;
4
+ variant?: "default" | "secondary" | "outline" | "destructive" | "success";
5
+ }
6
+ export declare const Badge: ({ children, variant }: BadgeProps) => React.JSX.Element;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Badge = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const Badge = ({ children, variant = "default" }) => {
10
+ const variantStyles = {
11
+ default: {
12
+ bg: "#18181b",
13
+ text: "#ffffff",
14
+ border: "transparent",
15
+ },
16
+ secondary: {
17
+ bg: "#f4f4f5",
18
+ text: "#18181b",
19
+ border: "transparent",
20
+ },
21
+ outline: {
22
+ bg: "transparent",
23
+ text: "#18181b",
24
+ border: "#e4e4e7",
25
+ },
26
+ destructive: {
27
+ bg: "#ef4444",
28
+ text: "#ffffff",
29
+ border: "transparent",
30
+ },
31
+ success: {
32
+ bg: "#22c55e",
33
+ text: "#ffffff",
34
+ border: "transparent",
35
+ },
36
+ };
37
+ const style = variantStyles[variant];
38
+ return (react_1.default.createElement(react_native_1.View, { style: [
39
+ styles.badge,
40
+ {
41
+ backgroundColor: style.bg,
42
+ borderColor: style.border,
43
+ borderWidth: style.border === "transparent" ? 0 : 1,
44
+ },
45
+ ] },
46
+ react_1.default.createElement(react_native_1.Text, { style: [styles.text, { color: style.text }] }, children)));
47
+ };
48
+ exports.Badge = Badge;
49
+ const styles = react_native_1.StyleSheet.create({
50
+ badge: {
51
+ paddingHorizontal: 8,
52
+ paddingVertical: 2,
53
+ borderRadius: 9999,
54
+ alignSelf: "flex-start",
55
+ },
56
+ text: {
57
+ fontSize: 12,
58
+ fontWeight: "600",
59
+ },
60
+ });
@@ -0,0 +1,67 @@
1
+ import React from "react";
2
+ import { View, Text, StyleSheet } from "react-native";
3
+
4
+ export interface BadgeProps {
5
+ children: React.ReactNode;
6
+ variant?: "default" | "secondary" | "outline" | "destructive" | "success";
7
+ }
8
+
9
+ export const Badge = ({ children, variant = "default" }: BadgeProps) => {
10
+ const variantStyles = {
11
+ default: {
12
+ bg: "#18181b",
13
+ text: "#ffffff",
14
+ border: "transparent",
15
+ },
16
+ secondary: {
17
+ bg: "#f4f4f5",
18
+ text: "#18181b",
19
+ border: "transparent",
20
+ },
21
+ outline: {
22
+ bg: "transparent",
23
+ text: "#18181b",
24
+ border: "#e4e4e7",
25
+ },
26
+ destructive: {
27
+ bg: "#ef4444",
28
+ text: "#ffffff",
29
+ border: "transparent",
30
+ },
31
+ success: {
32
+ bg: "#22c55e",
33
+ text: "#ffffff",
34
+ border: "transparent",
35
+ },
36
+ };
37
+
38
+ const style = variantStyles[variant];
39
+
40
+ return (
41
+ <View
42
+ style={[
43
+ styles.badge,
44
+ {
45
+ backgroundColor: style.bg,
46
+ borderColor: style.border,
47
+ borderWidth: style.border === "transparent" ? 0 : 1,
48
+ },
49
+ ]}
50
+ >
51
+ <Text style={[styles.text, { color: style.text }]}>{children}</Text>
52
+ </View>
53
+ );
54
+ };
55
+
56
+ const styles = StyleSheet.create({
57
+ badge: {
58
+ paddingHorizontal: 8,
59
+ paddingVertical: 2,
60
+ borderRadius: 9999,
61
+ alignSelf: "flex-start",
62
+ },
63
+ text: {
64
+ fontSize: 12,
65
+ fontWeight: "600",
66
+ },
67
+ });
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface ButtonProps {
3
+ title: string;
4
+ onPress: () => void;
5
+ variant?: "default" | "primary" | "secondary";
6
+ disabled?: boolean;
7
+ }
8
+ export declare const Button: React.FC<ButtonProps>;
9
+ export {};
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Button = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_native_1 = require("react-native");
9
+ const config_1 = require("../../theme/config");
10
+ const Button = ({ title, onPress, variant = "default", disabled = false, }) => {
11
+ const backgroundColor = variant === "primary"
12
+ ? config_1.theme.colors.primary
13
+ : variant === "secondary"
14
+ ? config_1.theme.colors.secondary || "#94a3b8"
15
+ : config_1.theme.colors.background === "#ffffff"
16
+ ? "#e5e7eb"
17
+ : config_1.theme.colors.background;
18
+ return (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.button, { backgroundColor }, disabled && styles.disabled], onPress: onPress, disabled: disabled },
19
+ react_1.default.createElement(react_native_1.Text, { style: styles.text }, title)));
20
+ };
21
+ exports.Button = Button;
22
+ const styles = react_native_1.StyleSheet.create({
23
+ button: {
24
+ paddingVertical: 12,
25
+ paddingHorizontal: 24,
26
+ borderRadius: 4,
27
+ alignItems: "center",
28
+ justifyContent: "center",
29
+ },
30
+ text: {
31
+ color: "#fff",
32
+ fontWeight: "600",
33
+ },
34
+ disabled: {
35
+ opacity: 0.6,
36
+ },
37
+ });
@@ -0,0 +1,53 @@
1
+ import React from "react";
2
+ import { TouchableOpacity, Text, StyleSheet } from "react-native";
3
+ import { theme } from "../../theme/config";
4
+
5
+ interface ButtonProps {
6
+ title: string;
7
+ onPress: () => void;
8
+ variant?: "default" | "primary" | "secondary";
9
+ disabled?: boolean;
10
+ }
11
+
12
+ export const Button: React.FC<ButtonProps> = ({
13
+ title,
14
+ onPress,
15
+ variant = "default",
16
+ disabled = false,
17
+ }) => {
18
+ const backgroundColor =
19
+ variant === "primary"
20
+ ? theme.colors.primary
21
+ : variant === "secondary"
22
+ ? theme.colors.secondary || "#94a3b8"
23
+ : theme.colors.background === "#ffffff"
24
+ ? "#e5e7eb"
25
+ : theme.colors.background;
26
+
27
+ return (
28
+ <TouchableOpacity
29
+ style={[styles.button, { backgroundColor }, disabled && styles.disabled]}
30
+ onPress={onPress}
31
+ disabled={disabled}
32
+ >
33
+ <Text style={styles.text}>{title}</Text>
34
+ </TouchableOpacity>
35
+ );
36
+ };
37
+
38
+ const styles = StyleSheet.create({
39
+ button: {
40
+ paddingVertical: 12,
41
+ paddingHorizontal: 24,
42
+ borderRadius: 4,
43
+ alignItems: "center",
44
+ justifyContent: "center",
45
+ },
46
+ text: {
47
+ color: "#fff",
48
+ fontWeight: "600",
49
+ },
50
+ disabled: {
51
+ opacity: 0.6,
52
+ },
53
+ });
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ export interface DropdownItem {
3
+ label: string;
4
+ value: string;
5
+ icon?: React.ReactNode;
6
+ }
7
+ export interface DropdownProps {
8
+ trigger: React.ReactNode;
9
+ items: DropdownItem[];
10
+ onSelect: (value: string) => void;
11
+ }
12
+ export declare const Dropdown: ({ trigger, items, onSelect }: DropdownProps) => React.JSX.Element;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Dropdown = void 0;
37
+ const react_1 = __importStar(require("react"));
38
+ const react_native_1 = require("react-native");
39
+ const Dropdown = ({ trigger, items, onSelect }) => {
40
+ const [open, setOpen] = (0, react_1.useState)(false);
41
+ const [layout, setLayout] = (0, react_1.useState)({ x: 0, y: 0, width: 0, height: 0 });
42
+ const onTriggerLayout = (event) => {
43
+ // In a real implementation, we'd use measure() to get page position
44
+ // For the template, we'll simplify
45
+ };
46
+ return (react_1.default.createElement(react_native_1.View, null,
47
+ react_1.default.createElement(react_native_1.Pressable, { onPress: () => setOpen(true), onLayout: onTriggerLayout }, trigger),
48
+ react_1.default.createElement(react_native_1.Modal, { visible: open, transparent: true, animationType: "none", onRequestClose: () => setOpen(false) },
49
+ react_1.default.createElement(react_native_1.Pressable, { style: styles.overlay, onPress: () => setOpen(false) },
50
+ react_1.default.createElement(react_native_1.View, { style: styles.menu }, items.map((item) => (react_1.default.createElement(react_native_1.Pressable, { key: item.value, style: styles.item, onPress: () => {
51
+ onSelect(item.value);
52
+ setOpen(false);
53
+ } },
54
+ item.icon && react_1.default.createElement(react_native_1.View, { style: styles.icon }, item.icon),
55
+ react_1.default.createElement(react_native_1.Text, { style: styles.label }, item.label)))))))));
56
+ };
57
+ exports.Dropdown = Dropdown;
58
+ const styles = react_native_1.StyleSheet.create({
59
+ overlay: {
60
+ flex: 1,
61
+ backgroundColor: "transparent",
62
+ justifyContent: "center", // Should be positioned near trigger
63
+ alignItems: "center",
64
+ },
65
+ menu: {
66
+ backgroundColor: "white",
67
+ borderRadius: 8,
68
+ padding: 4,
69
+ minWidth: 160,
70
+ shadowColor: "#000",
71
+ shadowOffset: { width: 0, height: 4 },
72
+ shadowOpacity: 0.1,
73
+ shadowRadius: 8,
74
+ elevation: 8,
75
+ borderWidth: 1,
76
+ borderColor: "#e4e4e7",
77
+ },
78
+ item: {
79
+ flexDirection: "row",
80
+ alignItems: "center",
81
+ padding: 8,
82
+ borderRadius: 4,
83
+ },
84
+ icon: {
85
+ marginRight: 8,
86
+ },
87
+ label: {
88
+ fontSize: 14,
89
+ color: "#18181b",
90
+ },
91
+ });