@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
|
@@ -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
|
}
|