@idealyst/cli 1.0.45 → 1.0.46
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.
- package/dist/templates/native/src/App-with-trpc-and-shared.tsx +4 -258
- package/dist/templates/shared/README.md +31 -5
- package/dist/templates/shared/__tests__/shared.test.ts +17 -5
- package/dist/templates/shared/package.json +7 -28
- package/dist/templates/shared/src/components/HelloWorld.tsx +117 -0
- package/dist/templates/shared/src/components/index.ts +1 -392
- package/dist/templates/shared/src/index.ts +6 -58
- package/dist/templates/shared/tsconfig.json +3 -6
- package/dist/templates/web/src/App-with-trpc-and-shared.tsx +4 -296
- package/package.json +1 -1
- package/templates/native/src/App-with-trpc-and-shared.tsx +4 -258
- package/templates/shared/README.md +31 -5
- package/templates/shared/__tests__/shared.test.ts +17 -5
- package/templates/shared/package.json +7 -28
- package/templates/shared/src/components/HelloWorld.tsx +117 -0
- package/templates/shared/src/components/index.ts +1 -392
- package/templates/shared/src/index.ts +6 -58
- package/templates/shared/tsconfig.json +3 -6
- package/templates/web/src/App-with-trpc-and-shared.tsx +4 -296
- package/dist/templates/shared/rollup.config.js +0 -43
- package/dist/templates/shared/src/types/index.ts +0 -148
- package/dist/templates/shared/src/utils/index.ts +0 -278
- package/templates/shared/rollup.config.js +0 -43
- package/templates/shared/src/types/index.ts +0 -148
- package/templates/shared/src/utils/index.ts +0 -278
|
@@ -2,44 +2,25 @@
|
|
|
2
2
|
"name": "{{packageName}}",
|
|
3
3
|
"version": "{{version}}",
|
|
4
4
|
"description": "{{description}}",
|
|
5
|
-
"main": "
|
|
6
|
-
"module": "
|
|
7
|
-
"types": "
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"module": "src/index.ts",
|
|
7
|
+
"types": "src/index.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"import": "./
|
|
11
|
-
"require": "./
|
|
12
|
-
"types": "./
|
|
13
|
-
},
|
|
14
|
-
"./types": {
|
|
15
|
-
"import": "./dist/types/index.js",
|
|
16
|
-
"require": "./dist/types/index.js",
|
|
17
|
-
"types": "./dist/types/index.d.ts"
|
|
18
|
-
},
|
|
19
|
-
"./components": {
|
|
20
|
-
"import": "./dist/components/index.js",
|
|
21
|
-
"require": "./dist/components/index.js",
|
|
22
|
-
"types": "./dist/components/index.d.ts"
|
|
23
|
-
},
|
|
24
|
-
"./utils": {
|
|
25
|
-
"import": "./dist/utils/index.js",
|
|
26
|
-
"require": "./dist/utils/index.js",
|
|
27
|
-
"types": "./dist/utils/index.d.ts"
|
|
10
|
+
"import": "./src/index.ts",
|
|
11
|
+
"require": "./src/index.ts",
|
|
12
|
+
"types": "./src/index.ts"
|
|
28
13
|
}
|
|
29
14
|
},
|
|
30
15
|
"scripts": {
|
|
31
|
-
"build": "tsc",
|
|
32
16
|
"test": "jest",
|
|
33
17
|
"test:watch": "jest --watch",
|
|
34
18
|
"test:coverage": "jest --coverage",
|
|
35
19
|
"type-check": "tsc --noEmit"
|
|
36
20
|
},
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"zod": "^3.22.4"
|
|
39
|
-
},
|
|
21
|
+
"dependencies": {},
|
|
40
22
|
"peerDependencies": {
|
|
41
23
|
"@idealyst/components": "^1.0.21",
|
|
42
|
-
"@idealyst/navigation": "^1.0.21",
|
|
43
24
|
"@idealyst/theme": "^1.0.21",
|
|
44
25
|
"react": "^19.1.0",
|
|
45
26
|
"react-native": "^0.80.1"
|
|
@@ -51,7 +32,6 @@
|
|
|
51
32
|
},
|
|
52
33
|
"devDependencies": {
|
|
53
34
|
"@idealyst/components": "^1.0.21",
|
|
54
|
-
"@idealyst/navigation": "^1.0.21",
|
|
55
35
|
"@idealyst/theme": "^1.0.21",
|
|
56
36
|
"@types/jest": "^29.5.12",
|
|
57
37
|
"@types/react": "^19.1.0",
|
|
@@ -62,7 +42,6 @@
|
|
|
62
42
|
"typescript": "^5.0.0"
|
|
63
43
|
},
|
|
64
44
|
"files": [
|
|
65
|
-
"dist",
|
|
66
45
|
"src"
|
|
67
46
|
],
|
|
68
47
|
"keywords": [
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Text, Card, Screen } from '@idealyst/components';
|
|
3
|
+
|
|
4
|
+
interface HelloWorldProps {
|
|
5
|
+
name?: string;
|
|
6
|
+
platform?: 'web' | 'mobile';
|
|
7
|
+
projectName?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const HelloWorld: React.FC<HelloWorldProps> = ({
|
|
11
|
+
name = 'World',
|
|
12
|
+
platform = 'web',
|
|
13
|
+
projectName = 'Your Project'
|
|
14
|
+
}) => {
|
|
15
|
+
const platformEmoji = platform === 'mobile' ? '📱' : '🌐';
|
|
16
|
+
const platformText = platform === 'mobile'
|
|
17
|
+
? 'Your mobile development environment is ready. This shared component works seamlessly across mobile and web platforms.'
|
|
18
|
+
: 'Your web development environment is ready. This shared component works seamlessly across web and mobile platforms.';
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Screen style={{ flex: 1, padding: 20 }}>
|
|
22
|
+
<View style={{ maxWidth: 600, alignSelf: 'center' }}>
|
|
23
|
+
<Text size="xlarge" weight="bold" style={{
|
|
24
|
+
marginBottom: 16,
|
|
25
|
+
textAlign: 'center',
|
|
26
|
+
color: '#1e293b'
|
|
27
|
+
}}>
|
|
28
|
+
Welcome to {projectName}! {platformEmoji}
|
|
29
|
+
</Text>
|
|
30
|
+
|
|
31
|
+
<Text size="large" style={{
|
|
32
|
+
marginBottom: 32,
|
|
33
|
+
textAlign: 'center',
|
|
34
|
+
color: '#64748b',
|
|
35
|
+
lineHeight: 24,
|
|
36
|
+
paddingHorizontal: 16
|
|
37
|
+
}}>
|
|
38
|
+
{platformText}
|
|
39
|
+
</Text>
|
|
40
|
+
{/* Framework Branding Card */}
|
|
41
|
+
<Card variant="elevated" padding="large" intent="primary">
|
|
42
|
+
<View style={{ alignItems: 'center' }}>
|
|
43
|
+
<Text style={{ fontSize: 32, marginBottom: 16 }}>🚀</Text>
|
|
44
|
+
<Text size="xlarge" weight="bold" style={{ marginBottom: 8, textAlign: 'center' }}>
|
|
45
|
+
Idealyst Framework
|
|
46
|
+
</Text>
|
|
47
|
+
<Text size="medium" style={{ marginBottom: 16, textAlign: 'center' }}>
|
|
48
|
+
Hello, {name}! Welcome to your cross-platform workspace.
|
|
49
|
+
</Text>
|
|
50
|
+
|
|
51
|
+
{/* Technology Tags */}
|
|
52
|
+
<View style={{ flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', gap: 8 }}>
|
|
53
|
+
<Card variant="filled" padding="small" style={{ backgroundColor: 'rgba(255, 255, 255, 0.2)' }}>
|
|
54
|
+
<Text size="small" weight="semibold">React</Text>
|
|
55
|
+
</Card>
|
|
56
|
+
<Card variant="filled" padding="small" style={{ backgroundColor: 'rgba(255, 255, 255, 0.2)' }}>
|
|
57
|
+
<Text size="small" weight="semibold">TypeScript</Text>
|
|
58
|
+
</Card>
|
|
59
|
+
<Card variant="filled" padding="small" style={{ backgroundColor: 'rgba(255, 255, 255, 0.2)' }}>
|
|
60
|
+
<Text size="small" weight="semibold">Cross-Platform</Text>
|
|
61
|
+
</Card>
|
|
62
|
+
</View>
|
|
63
|
+
</View>
|
|
64
|
+
</Card>
|
|
65
|
+
|
|
66
|
+
{/* Quick Start Guide Card */}
|
|
67
|
+
<Card variant="outlined" padding="large" style={{ marginTop: 16 }}>
|
|
68
|
+
<Text size="large" weight="bold" style={{ marginBottom: 16 }}>
|
|
69
|
+
🎯 Quick Start Guide
|
|
70
|
+
</Text>
|
|
71
|
+
|
|
72
|
+
<View style={{ marginBottom: 16 }}>
|
|
73
|
+
<Text size="medium" weight="semibold" style={{ marginBottom: 8 }}>
|
|
74
|
+
Your Workspace Overview:
|
|
75
|
+
</Text>
|
|
76
|
+
<Text size="small" style={{ marginBottom: 4 }}>
|
|
77
|
+
• <Text weight="semibold">packages/web/</Text> - React web application
|
|
78
|
+
</Text>
|
|
79
|
+
<Text size="small" style={{ marginBottom: 4 }}>
|
|
80
|
+
• <Text weight="semibold">packages/mobile/</Text> - React Native mobile app
|
|
81
|
+
</Text>
|
|
82
|
+
<Text size="small" style={{ marginBottom: 4 }}>
|
|
83
|
+
• <Text weight="semibold">packages/shared/</Text> - Cross-platform components
|
|
84
|
+
</Text>
|
|
85
|
+
<Text size="small" style={{ marginBottom: 4 }}>
|
|
86
|
+
• <Text weight="semibold">packages/api/</Text> - tRPC API server
|
|
87
|
+
</Text>
|
|
88
|
+
</View>
|
|
89
|
+
|
|
90
|
+
<View style={{ marginBottom: 16 }}>
|
|
91
|
+
<Text size="medium" weight="semibold" style={{ marginBottom: 8 }}>
|
|
92
|
+
Try Editing:
|
|
93
|
+
</Text>
|
|
94
|
+
<Text size="small" style={{ marginBottom: 4 }}>
|
|
95
|
+
1. Edit this component in <Text weight="semibold">packages/shared/src/components/HelloWorld.tsx</Text>
|
|
96
|
+
</Text>
|
|
97
|
+
<Text size="small" style={{ marginBottom: 4 }}>
|
|
98
|
+
2. Watch changes appear in both web and mobile apps instantly!
|
|
99
|
+
</Text>
|
|
100
|
+
<Text size="small" style={{ marginBottom: 4 }}>
|
|
101
|
+
3. Run <Text weight="semibold">yarn dev</Text> to start all development servers
|
|
102
|
+
</Text>
|
|
103
|
+
</View>
|
|
104
|
+
|
|
105
|
+
<Card variant="filled" intent="success" padding="medium">
|
|
106
|
+
<Text size="small" weight="semibold" style={{ marginBottom: 4 }}>
|
|
107
|
+
✨ Framework Features:
|
|
108
|
+
</Text>
|
|
109
|
+
<Text size="small">
|
|
110
|
+
Shared components • Type safety • Hot reload • Cross-platform compatibility
|
|
111
|
+
</Text>
|
|
112
|
+
</Card>
|
|
113
|
+
</Card>
|
|
114
|
+
</View>
|
|
115
|
+
</Screen>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
@@ -1,392 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { View, Text, Button, Image } from '@idealyst/components';
|
|
3
|
-
import type { User, Post, Comment } from '../types';
|
|
4
|
-
|
|
5
|
-
interface UserCardProps {
|
|
6
|
-
user: User;
|
|
7
|
-
onPress?: () => void;
|
|
8
|
-
showBio?: boolean;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const UserCard: React.FC<UserCardProps> = ({
|
|
12
|
-
user,
|
|
13
|
-
onPress,
|
|
14
|
-
showBio = false
|
|
15
|
-
}) => {
|
|
16
|
-
return (
|
|
17
|
-
<View
|
|
18
|
-
style={{
|
|
19
|
-
padding: 16,
|
|
20
|
-
borderRadius: 8,
|
|
21
|
-
backgroundColor: 'white',
|
|
22
|
-
shadowColor: '#000',
|
|
23
|
-
shadowOffset: { width: 0, height: 2 },
|
|
24
|
-
shadowOpacity: 0.1,
|
|
25
|
-
shadowRadius: 4,
|
|
26
|
-
elevation: 2,
|
|
27
|
-
marginBottom: 8
|
|
28
|
-
}}
|
|
29
|
-
>
|
|
30
|
-
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
31
|
-
{user.avatar && (
|
|
32
|
-
<Image
|
|
33
|
-
source={{ uri: user.avatar }}
|
|
34
|
-
style={{
|
|
35
|
-
width: 50,
|
|
36
|
-
height: 50,
|
|
37
|
-
borderRadius: 25,
|
|
38
|
-
marginRight: 12
|
|
39
|
-
}}
|
|
40
|
-
/>
|
|
41
|
-
)}
|
|
42
|
-
<View style={{ flex: 1 }}>
|
|
43
|
-
<Text variant="h3" style={{ marginBottom: 4 }}>
|
|
44
|
-
{user.name || 'Anonymous User'}
|
|
45
|
-
</Text>
|
|
46
|
-
<Text variant="caption" style={{ color: 'gray' }}>
|
|
47
|
-
{user.email}
|
|
48
|
-
</Text>
|
|
49
|
-
{user.location && (
|
|
50
|
-
<Text variant="caption" style={{ color: 'gray', marginTop: 2 }}>
|
|
51
|
-
📍 {user.location}
|
|
52
|
-
</Text>
|
|
53
|
-
)}
|
|
54
|
-
</View>
|
|
55
|
-
{onPress && (
|
|
56
|
-
<Button
|
|
57
|
-
title="View Profile"
|
|
58
|
-
onPress={onPress}
|
|
59
|
-
size="small"
|
|
60
|
-
/>
|
|
61
|
-
)}
|
|
62
|
-
</View>
|
|
63
|
-
|
|
64
|
-
{showBio && user.bio && (
|
|
65
|
-
<Text variant="body" style={{ marginTop: 12, fontStyle: 'italic' }}>
|
|
66
|
-
{user.bio}
|
|
67
|
-
</Text>
|
|
68
|
-
)}
|
|
69
|
-
|
|
70
|
-
{user.website && (
|
|
71
|
-
<Text variant="caption" style={{ marginTop: 8, color: 'blue' }}>
|
|
72
|
-
🌐 {user.website}
|
|
73
|
-
</Text>
|
|
74
|
-
)}
|
|
75
|
-
</View>
|
|
76
|
-
);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
interface PostCardProps {
|
|
80
|
-
post: Post;
|
|
81
|
-
author?: User;
|
|
82
|
-
onPress?: () => void;
|
|
83
|
-
onLike?: () => void;
|
|
84
|
-
showFullContent?: boolean;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export const PostCard: React.FC<PostCardProps> = ({
|
|
88
|
-
post,
|
|
89
|
-
author,
|
|
90
|
-
onPress,
|
|
91
|
-
onLike,
|
|
92
|
-
showFullContent = false
|
|
93
|
-
}) => {
|
|
94
|
-
const content = showFullContent ? post.content : (post.excerpt || post.content.substring(0, 150) + '...');
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<View
|
|
98
|
-
style={{
|
|
99
|
-
padding: 16,
|
|
100
|
-
borderRadius: 8,
|
|
101
|
-
backgroundColor: 'white',
|
|
102
|
-
shadowColor: '#000',
|
|
103
|
-
shadowOffset: { width: 0, height: 2 },
|
|
104
|
-
shadowOpacity: 0.1,
|
|
105
|
-
shadowRadius: 4,
|
|
106
|
-
elevation: 2,
|
|
107
|
-
marginBottom: 12
|
|
108
|
-
}}
|
|
109
|
-
>
|
|
110
|
-
{/* Post Header */}
|
|
111
|
-
{author && (
|
|
112
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 12 }}>
|
|
113
|
-
{author.avatar && (
|
|
114
|
-
<Image
|
|
115
|
-
source={{ uri: author.avatar }}
|
|
116
|
-
style={{
|
|
117
|
-
width: 32,
|
|
118
|
-
height: 32,
|
|
119
|
-
borderRadius: 16,
|
|
120
|
-
marginRight: 8
|
|
121
|
-
}}
|
|
122
|
-
/>
|
|
123
|
-
)}
|
|
124
|
-
<View>
|
|
125
|
-
<Text variant="body" style={{ fontWeight: 'bold' }}>
|
|
126
|
-
{author.name || 'Anonymous'}
|
|
127
|
-
</Text>
|
|
128
|
-
<Text variant="caption" style={{ color: 'gray' }}>
|
|
129
|
-
{new Date(post.createdAt).toLocaleDateString()}
|
|
130
|
-
</Text>
|
|
131
|
-
</View>
|
|
132
|
-
</View>
|
|
133
|
-
)}
|
|
134
|
-
|
|
135
|
-
{/* Post Content */}
|
|
136
|
-
<Text variant="h2" style={{ marginBottom: 8 }}>
|
|
137
|
-
{post.title}
|
|
138
|
-
</Text>
|
|
139
|
-
|
|
140
|
-
<Text variant="body" style={{ marginBottom: 12 }}>
|
|
141
|
-
{content}
|
|
142
|
-
</Text>
|
|
143
|
-
|
|
144
|
-
{/* Tags */}
|
|
145
|
-
{post.tags.length > 0 && (
|
|
146
|
-
<View style={{ flexDirection: 'row', flexWrap: 'wrap', marginBottom: 12 }}>
|
|
147
|
-
{post.tags.map((tag, index) => (
|
|
148
|
-
<View
|
|
149
|
-
key={index}
|
|
150
|
-
style={{
|
|
151
|
-
backgroundColor: '#e3f2fd',
|
|
152
|
-
paddingHorizontal: 8,
|
|
153
|
-
paddingVertical: 4,
|
|
154
|
-
borderRadius: 12,
|
|
155
|
-
marginRight: 6,
|
|
156
|
-
marginBottom: 4
|
|
157
|
-
}}
|
|
158
|
-
>
|
|
159
|
-
<Text variant="caption" style={{ color: '#1976d2' }}>
|
|
160
|
-
#{tag}
|
|
161
|
-
</Text>
|
|
162
|
-
</View>
|
|
163
|
-
))}
|
|
164
|
-
</View>
|
|
165
|
-
)}
|
|
166
|
-
|
|
167
|
-
{/* Post Stats and Actions */}
|
|
168
|
-
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
169
|
-
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
|
170
|
-
<Text variant="caption" style={{ color: 'gray', marginRight: 12 }}>
|
|
171
|
-
👁️ {post.views} views
|
|
172
|
-
</Text>
|
|
173
|
-
<Text variant="caption" style={{ color: 'gray' }}>
|
|
174
|
-
❤️ {post.likes} likes
|
|
175
|
-
</Text>
|
|
176
|
-
</View>
|
|
177
|
-
|
|
178
|
-
<View style={{ flexDirection: 'row' }}>
|
|
179
|
-
{onLike && (
|
|
180
|
-
<Button
|
|
181
|
-
title="Like"
|
|
182
|
-
onPress={onLike}
|
|
183
|
-
size="small"
|
|
184
|
-
variant="outline"
|
|
185
|
-
style={{ marginRight: 8 }}
|
|
186
|
-
/>
|
|
187
|
-
)}
|
|
188
|
-
{onPress && (
|
|
189
|
-
<Button
|
|
190
|
-
title="Read More"
|
|
191
|
-
onPress={onPress}
|
|
192
|
-
size="small"
|
|
193
|
-
/>
|
|
194
|
-
)}
|
|
195
|
-
</View>
|
|
196
|
-
</View>
|
|
197
|
-
</View>
|
|
198
|
-
);
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
interface CommentCardProps {
|
|
202
|
-
comment: Comment;
|
|
203
|
-
author?: User;
|
|
204
|
-
onReply?: () => void;
|
|
205
|
-
level?: number;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export const CommentCard: React.FC<CommentCardProps> = ({
|
|
209
|
-
comment,
|
|
210
|
-
author,
|
|
211
|
-
onReply,
|
|
212
|
-
level = 0
|
|
213
|
-
}) => {
|
|
214
|
-
const indentStyle = {
|
|
215
|
-
marginLeft: level * 20,
|
|
216
|
-
maxWidth: level > 2 ? '90%' : '100%'
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
return (
|
|
220
|
-
<View
|
|
221
|
-
style={[
|
|
222
|
-
{
|
|
223
|
-
padding: 12,
|
|
224
|
-
borderRadius: 6,
|
|
225
|
-
backgroundColor: level === 0 ? 'white' : '#f8f9fa',
|
|
226
|
-
borderLeftWidth: level > 0 ? 3 : 0,
|
|
227
|
-
borderLeftColor: '#e3f2fd',
|
|
228
|
-
marginBottom: 8
|
|
229
|
-
},
|
|
230
|
-
indentStyle
|
|
231
|
-
]}
|
|
232
|
-
>
|
|
233
|
-
{/* Comment Header */}
|
|
234
|
-
{author && (
|
|
235
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 8 }}>
|
|
236
|
-
{author.avatar && (
|
|
237
|
-
<Image
|
|
238
|
-
source={{ uri: author.avatar }}
|
|
239
|
-
style={{
|
|
240
|
-
width: 24,
|
|
241
|
-
height: 24,
|
|
242
|
-
borderRadius: 12,
|
|
243
|
-
marginRight: 6
|
|
244
|
-
}}
|
|
245
|
-
/>
|
|
246
|
-
)}
|
|
247
|
-
<Text variant="body" style={{ fontWeight: 'bold', fontSize: 14 }}>
|
|
248
|
-
{author.name || 'Anonymous'}
|
|
249
|
-
</Text>
|
|
250
|
-
<Text variant="caption" style={{ color: 'gray', marginLeft: 8 }}>
|
|
251
|
-
{new Date(comment.createdAt).toLocaleDateString()}
|
|
252
|
-
</Text>
|
|
253
|
-
</View>
|
|
254
|
-
)}
|
|
255
|
-
|
|
256
|
-
{/* Comment Content */}
|
|
257
|
-
<Text variant="body" style={{ marginBottom: 8 }}>
|
|
258
|
-
{comment.content}
|
|
259
|
-
</Text>
|
|
260
|
-
|
|
261
|
-
{/* Comment Actions */}
|
|
262
|
-
{onReply && level < 3 && (
|
|
263
|
-
<Button
|
|
264
|
-
title="Reply"
|
|
265
|
-
onPress={onReply}
|
|
266
|
-
size="small"
|
|
267
|
-
variant="outline"
|
|
268
|
-
/>
|
|
269
|
-
)}
|
|
270
|
-
</View>
|
|
271
|
-
);
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
interface LoadingSpinnerProps {
|
|
275
|
-
size?: 'small' | 'medium' | 'large';
|
|
276
|
-
message?: string;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export const LoadingSpinner: React.FC<LoadingSpinnerProps> = ({
|
|
280
|
-
size = 'medium',
|
|
281
|
-
message
|
|
282
|
-
}) => {
|
|
283
|
-
const sizeMap = {
|
|
284
|
-
small: 20,
|
|
285
|
-
medium: 40,
|
|
286
|
-
large: 60
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
return (
|
|
290
|
-
<View style={{ alignItems: 'center', justifyContent: 'center', padding: 20 }}>
|
|
291
|
-
<View
|
|
292
|
-
style={{
|
|
293
|
-
width: sizeMap[size],
|
|
294
|
-
height: sizeMap[size],
|
|
295
|
-
borderRadius: sizeMap[size] / 2,
|
|
296
|
-
borderWidth: 3,
|
|
297
|
-
borderColor: '#e3f2fd',
|
|
298
|
-
borderTopColor: '#1976d2',
|
|
299
|
-
// Animation would be handled by the platform-specific implementation
|
|
300
|
-
}}
|
|
301
|
-
/>
|
|
302
|
-
{message && (
|
|
303
|
-
<Text variant="body" style={{ marginTop: 12, textAlign: 'center' }}>
|
|
304
|
-
{message}
|
|
305
|
-
</Text>
|
|
306
|
-
)}
|
|
307
|
-
</View>
|
|
308
|
-
);
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
interface ErrorMessageProps {
|
|
312
|
-
message: string;
|
|
313
|
-
onRetry?: () => void;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
export const ErrorMessage: React.FC<ErrorMessageProps> = ({ message, onRetry }) => {
|
|
317
|
-
return (
|
|
318
|
-
<View
|
|
319
|
-
style={{
|
|
320
|
-
padding: 16,
|
|
321
|
-
backgroundColor: '#ffebee',
|
|
322
|
-
borderRadius: 8,
|
|
323
|
-
borderLeftWidth: 4,
|
|
324
|
-
borderLeftColor: '#f44336',
|
|
325
|
-
margin: 16
|
|
326
|
-
}}
|
|
327
|
-
>
|
|
328
|
-
<Text variant="body" style={{ color: '#c62828', marginBottom: onRetry ? 12 : 0 }}>
|
|
329
|
-
⚠️ {message}
|
|
330
|
-
</Text>
|
|
331
|
-
{onRetry && (
|
|
332
|
-
<Button
|
|
333
|
-
title="Try Again"
|
|
334
|
-
onPress={onRetry}
|
|
335
|
-
size="small"
|
|
336
|
-
style={{ backgroundColor: '#f44336' }}
|
|
337
|
-
/>
|
|
338
|
-
)}
|
|
339
|
-
</View>
|
|
340
|
-
);
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
// Feature Card Component - reusable for both web and native
|
|
344
|
-
interface FeatureCardProps {
|
|
345
|
-
icon: string;
|
|
346
|
-
title: string;
|
|
347
|
-
description: string;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
export const FeatureCard: React.FC<FeatureCardProps> = ({ icon, title, description }) => {
|
|
351
|
-
return (
|
|
352
|
-
<View style={{
|
|
353
|
-
padding: 16,
|
|
354
|
-
backgroundColor: 'white',
|
|
355
|
-
borderRadius: 8,
|
|
356
|
-
shadowColor: '#000',
|
|
357
|
-
shadowOffset: { width: 0, height: 2 },
|
|
358
|
-
shadowOpacity: 0.1,
|
|
359
|
-
shadowRadius: 4,
|
|
360
|
-
elevation: 2,
|
|
361
|
-
marginBottom: 12
|
|
362
|
-
}}>
|
|
363
|
-
<Text style={{ fontSize: 24, marginBottom: 8, textAlign: 'center' }}>{icon}</Text>
|
|
364
|
-
<Text variant="h4" style={{ marginBottom: 8, textAlign: 'center' }}>{title}</Text>
|
|
365
|
-
<Text variant="body" style={{ color: '#666', textAlign: 'center' }}>{description}</Text>
|
|
366
|
-
</View>
|
|
367
|
-
);
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
// Tab Button Component - for navigation tabs in mobile/web apps
|
|
371
|
-
interface TabButtonProps {
|
|
372
|
-
title: string;
|
|
373
|
-
icon: string;
|
|
374
|
-
active: boolean;
|
|
375
|
-
onPress: () => void;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
export const TabButton: React.FC<TabButtonProps> = ({ title, icon, active, onPress }) => {
|
|
379
|
-
return (
|
|
380
|
-
<Button
|
|
381
|
-
title={`${icon} ${title}`}
|
|
382
|
-
onPress={onPress}
|
|
383
|
-
variant={active ? 'primary' : 'outline'}
|
|
384
|
-
style={{
|
|
385
|
-
flex: 1,
|
|
386
|
-
marginHorizontal: 4,
|
|
387
|
-
backgroundColor: active ? '#007bff' : 'transparent',
|
|
388
|
-
borderColor: active ? '#007bff' : '#ccc'
|
|
389
|
-
}}
|
|
390
|
-
/>
|
|
391
|
-
);
|
|
392
|
-
};
|
|
1
|
+
export { HelloWorld } from './HelloWorld';
|
|
@@ -1,59 +1,7 @@
|
|
|
1
|
-
// Export
|
|
2
|
-
export
|
|
1
|
+
// Export the HelloWorld component
|
|
2
|
+
export { HelloWorld } from './components';
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export * from './utils';
|
|
9
|
-
|
|
10
|
-
// Re-export commonly used items for convenience
|
|
11
|
-
export type {
|
|
12
|
-
User,
|
|
13
|
-
Post,
|
|
14
|
-
Comment,
|
|
15
|
-
UserSettings,
|
|
16
|
-
CreateUser,
|
|
17
|
-
CreatePost,
|
|
18
|
-
CreateComment,
|
|
19
|
-
PostWithAuthor,
|
|
20
|
-
CommentWithAuthor,
|
|
21
|
-
ApiResponse,
|
|
22
|
-
PaginatedResponse,
|
|
23
|
-
Theme,
|
|
24
|
-
LoadingState,
|
|
25
|
-
PaginationParams
|
|
26
|
-
} from './types';
|
|
27
|
-
|
|
28
|
-
export {
|
|
29
|
-
UserCard,
|
|
30
|
-
PostCard,
|
|
31
|
-
CommentCard,
|
|
32
|
-
LoadingSpinner,
|
|
33
|
-
ErrorMessage,
|
|
34
|
-
FeatureCard,
|
|
35
|
-
TabButton
|
|
36
|
-
} from './components';
|
|
37
|
-
|
|
38
|
-
export {
|
|
39
|
-
formatDate,
|
|
40
|
-
formatDateTime,
|
|
41
|
-
formatRelativeTime,
|
|
42
|
-
truncateText,
|
|
43
|
-
capitalizeFirst,
|
|
44
|
-
slugify,
|
|
45
|
-
paginate,
|
|
46
|
-
sortBy,
|
|
47
|
-
pick,
|
|
48
|
-
omit,
|
|
49
|
-
isValidEmail,
|
|
50
|
-
isValidUrl,
|
|
51
|
-
storage,
|
|
52
|
-
debounce,
|
|
53
|
-
getSystemTheme,
|
|
54
|
-
getErrorMessage,
|
|
55
|
-
isWeb,
|
|
56
|
-
isMobile,
|
|
57
|
-
DEMO_USERS,
|
|
58
|
-
DEMO_POSTS
|
|
59
|
-
} from './utils';
|
|
4
|
+
// Simple type for the HelloWorld component props
|
|
5
|
+
export interface HelloWorldProps {
|
|
6
|
+
name?: string;
|
|
7
|
+
}
|
|
@@ -10,16 +10,13 @@
|
|
|
10
10
|
"skipLibCheck": true,
|
|
11
11
|
"forceConsistentCasingInFileNames": true,
|
|
12
12
|
"declaration": true,
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"rootDir": "./src",
|
|
16
|
-
"jsx": "react-jsx"
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"noEmit": true
|
|
17
15
|
},
|
|
18
16
|
"include": [
|
|
19
17
|
"src/**/*"
|
|
20
18
|
],
|
|
21
19
|
"exclude": [
|
|
22
|
-
"node_modules"
|
|
23
|
-
"dist"
|
|
20
|
+
"node_modules"
|
|
24
21
|
]
|
|
25
22
|
}
|