@teardown/cli 2.0.67 → 2.0.69
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/package.json +7 -2
- package/src/config/schema.ts +8 -0
- package/templates/package.json +1 -1
- package/templates/src/app/index.tsx +4 -9
- package/templates/src/components/ui/card.tsx +32 -8
- package/templates/src/components/ui/text.tsx +117 -0
- package/templates/src/navigation/navigation-provider.tsx +6 -22
- package/templates/src/routes/home.tsx +6 -8
- package/templates/tsconfig.json +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teardown/cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.69",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
"import": "./src/config/index.ts",
|
|
26
26
|
"default": "./src/config/index.ts"
|
|
27
27
|
},
|
|
28
|
+
"./config/schema": {
|
|
29
|
+
"types": "./src/config/schema.ts",
|
|
30
|
+
"import": "./src/config/schema.ts",
|
|
31
|
+
"default": "./src/config/schema.ts"
|
|
32
|
+
},
|
|
28
33
|
"./plugins": {
|
|
29
34
|
"types": "./src/plugins/index.ts",
|
|
30
35
|
"import": "./src/plugins/index.ts",
|
|
@@ -71,7 +76,7 @@
|
|
|
71
76
|
},
|
|
72
77
|
"devDependencies": {
|
|
73
78
|
"@biomejs/biome": "2.3.11",
|
|
74
|
-
"@teardown/tsconfig": "2.0.
|
|
79
|
+
"@teardown/tsconfig": "2.0.69",
|
|
75
80
|
"@types/bun": "1.3.5",
|
|
76
81
|
"@types/ejs": "^3.1.5",
|
|
77
82
|
"typescript": "5.9.3"
|
package/src/config/schema.ts
CHANGED
|
@@ -233,3 +233,11 @@ export function defineConfig(config: z.input<typeof TeardownConfigSchema>): z.in
|
|
|
233
233
|
const result = TeardownConfigSchema.parse(config);
|
|
234
234
|
return result;
|
|
235
235
|
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Inferred types from schemas for React Native-safe imports
|
|
239
|
+
*/
|
|
240
|
+
export type TeardownConfig = z.infer<typeof TeardownConfigSchema>;
|
|
241
|
+
export type iOSConfig = z.infer<typeof iOSConfigSchema>;
|
|
242
|
+
export type AndroidConfig = z.infer<typeof AndroidConfigSchema>;
|
|
243
|
+
export type SplashConfig = z.infer<typeof SplashConfigSchema>;
|
package/templates/package.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "<%= slug %>",
|
|
3
|
-
"version": "<%= version %>",
|
|
4
3
|
"private": true,
|
|
5
4
|
"main": "./src/index.tsx",
|
|
6
5
|
"scripts": {
|
|
@@ -16,6 +15,7 @@
|
|
|
16
15
|
"@react-navigation/bottom-tabs": "^7.2.0",
|
|
17
16
|
"@react-navigation/native": "^7.0.14",
|
|
18
17
|
"@react-navigation/native-stack": "^7.2.0",
|
|
18
|
+
"class-variance-authority": "^0.7.1",
|
|
19
19
|
"@teardown/dev-client": "<%= cliVersion %>",
|
|
20
20
|
"@teardown/navigation": "<%= cliVersion %>",
|
|
21
21
|
"heroui-native": "^1.0.0-beta.12",
|
|
@@ -10,22 +10,17 @@
|
|
|
10
10
|
|
|
11
11
|
import "../global.css";
|
|
12
12
|
|
|
13
|
-
import React from "react";
|
|
14
|
-
import {
|
|
13
|
+
import type React from "react";
|
|
14
|
+
import { StatusBar, View } from "react-native";
|
|
15
15
|
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
|
|
16
|
-
import { AppProviders } from "@/providers";
|
|
17
16
|
import { Router } from "@/navigation";
|
|
17
|
+
import { AppProviders } from "@/providers";
|
|
18
18
|
|
|
19
19
|
export function App(): React.JSX.Element {
|
|
20
20
|
return (
|
|
21
21
|
<SafeAreaProvider>
|
|
22
22
|
<AppProviders>
|
|
23
|
-
<
|
|
24
|
-
<StatusBar barStyle="dark-content" backgroundColor="transparent" translucent />
|
|
25
|
-
<SafeAreaView className="flex-1">
|
|
26
|
-
<Router />
|
|
27
|
-
</SafeAreaView>
|
|
28
|
-
</View>
|
|
23
|
+
<Router />
|
|
29
24
|
</AppProviders>
|
|
30
25
|
</SafeAreaProvider>
|
|
31
26
|
);
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* ```tsx
|
|
8
8
|
* <Card>
|
|
9
9
|
* <Card.Body>
|
|
10
|
-
* <
|
|
10
|
+
* <Card.Title>Card Title</Card.Title>
|
|
11
|
+
* <Card.Description>Card content goes here</Card.Description>
|
|
11
12
|
* </Card.Body>
|
|
12
13
|
* </Card>
|
|
13
14
|
* ```
|
|
@@ -16,10 +17,11 @@
|
|
|
16
17
|
* ```tsx
|
|
17
18
|
* <Card>
|
|
18
19
|
* <Card.Header>
|
|
19
|
-
* <
|
|
20
|
+
* <Avatar src="https://example.com/avatar.png" />
|
|
20
21
|
* </Card.Header>
|
|
21
22
|
* <Card.Body>
|
|
22
|
-
* <
|
|
23
|
+
* <Card.Title>Card Title</Card.Title>
|
|
24
|
+
* <Card.Description>Card content goes here</Card.Description>
|
|
23
25
|
* </Card.Body>
|
|
24
26
|
* </Card>
|
|
25
27
|
* ```
|
|
@@ -28,10 +30,11 @@
|
|
|
28
30
|
* ```tsx
|
|
29
31
|
* <Card>
|
|
30
32
|
* <Card.Header>
|
|
31
|
-
* <
|
|
33
|
+
* <Icon name="star" />
|
|
32
34
|
* </Card.Header>
|
|
33
35
|
* <Card.Body>
|
|
34
|
-
* <
|
|
36
|
+
* <Card.Title>Card Title</Card.Title>
|
|
37
|
+
* <Card.Description>Main content area</Card.Description>
|
|
35
38
|
* </Card.Body>
|
|
36
39
|
* <Card.Footer>
|
|
37
40
|
* <Button>Action</Button>
|
|
@@ -52,7 +55,7 @@
|
|
|
52
55
|
* ```tsx
|
|
53
56
|
* <Card isPressable onPress={() => console.log('Card pressed!')}>
|
|
54
57
|
* <Card.Body>
|
|
55
|
-
* <
|
|
58
|
+
* <Card.Title>Pressable Card</Card.Title>
|
|
56
59
|
* </Card.Body>
|
|
57
60
|
* </Card>
|
|
58
61
|
* ```
|
|
@@ -61,7 +64,7 @@
|
|
|
61
64
|
* ```tsx
|
|
62
65
|
* <Card isDisabled>
|
|
63
66
|
* <Card.Body>
|
|
64
|
-
* <
|
|
67
|
+
* <Card.Title>Disabled Card</Card.Title>
|
|
65
68
|
* </Card.Body>
|
|
66
69
|
* </Card>
|
|
67
70
|
* ```
|
|
@@ -69,18 +72,23 @@
|
|
|
69
72
|
|
|
70
73
|
import type {
|
|
71
74
|
CardBodyProps as HeroCardBodyProps,
|
|
75
|
+
CardDescriptionProps as HeroCardDescriptionProps,
|
|
72
76
|
CardFooterProps as HeroCardFooterProps,
|
|
73
77
|
CardHeaderProps as HeroCardHeaderProps,
|
|
74
78
|
CardProps as HeroCardProps,
|
|
79
|
+
CardTitleProps as HeroCardTitleProps,
|
|
75
80
|
} from "heroui-native";
|
|
76
81
|
import {
|
|
77
82
|
Card as HeroCard,
|
|
78
83
|
CardBody as HeroCardBody,
|
|
84
|
+
CardDescription as HeroCardDescription,
|
|
79
85
|
CardFooter as HeroCardFooter,
|
|
80
86
|
CardHeader as HeroCardHeader,
|
|
87
|
+
CardTitle as HeroCardTitle,
|
|
81
88
|
} from "heroui-native";
|
|
82
89
|
import { forwardRef } from "react";
|
|
83
90
|
import type { View as ViewRef } from "react-native";
|
|
91
|
+
import type { Text as TextRef } from "react-native";
|
|
84
92
|
|
|
85
93
|
// Card Root component
|
|
86
94
|
const CardRoot = forwardRef<ViewRef, HeroCardProps>((props, ref) => {
|
|
@@ -100,17 +108,31 @@ const CardBody = forwardRef<ViewRef, HeroCardBodyProps>((props, ref) => {
|
|
|
100
108
|
});
|
|
101
109
|
CardBody.displayName = "Card.Body";
|
|
102
110
|
|
|
103
|
-
// Card Footer
|
|
111
|
+
// Card Footer componentc
|
|
104
112
|
const CardFooter = forwardRef<ViewRef, HeroCardFooterProps>((props, ref) => {
|
|
105
113
|
return <HeroCardFooter ref={ref} {...props} />;
|
|
106
114
|
});
|
|
107
115
|
CardFooter.displayName = "Card.Footer";
|
|
108
116
|
|
|
117
|
+
// Card Title component
|
|
118
|
+
const CardTitle = forwardRef<TextRef, HeroCardTitleProps>((props, ref) => {
|
|
119
|
+
return <HeroCardTitle ref={ref} {...props} />;
|
|
120
|
+
});
|
|
121
|
+
CardTitle.displayName = "Card.Title";
|
|
122
|
+
|
|
123
|
+
// Card Description component
|
|
124
|
+
const CardDescription = forwardRef<TextRef, HeroCardDescriptionProps>((props, ref) => {
|
|
125
|
+
return <HeroCardDescription ref={ref} {...props} />;
|
|
126
|
+
});
|
|
127
|
+
CardDescription.displayName = "Card.Description";
|
|
128
|
+
|
|
109
129
|
// Compound Card component with Object.assign pattern
|
|
110
130
|
export const Card = Object.assign(CardRoot, {
|
|
111
131
|
Header: CardHeader,
|
|
112
132
|
Body: CardBody,
|
|
113
133
|
Footer: CardFooter,
|
|
134
|
+
Title: CardTitle,
|
|
135
|
+
Description: CardDescription,
|
|
114
136
|
});
|
|
115
137
|
|
|
116
138
|
// Re-export types for convenience
|
|
@@ -119,4 +141,6 @@ export type {
|
|
|
119
141
|
HeroCardHeaderProps as CardHeaderProps,
|
|
120
142
|
HeroCardBodyProps as CardBodyProps,
|
|
121
143
|
HeroCardFooterProps as CardFooterProps,
|
|
144
|
+
HeroCardTitleProps as CardTitleProps,
|
|
145
|
+
HeroCardDescriptionProps as CardDescriptionProps,
|
|
122
146
|
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Component
|
|
3
|
+
*
|
|
4
|
+
* A styled text component with variants for typography, color, and other text styles.
|
|
5
|
+
*
|
|
6
|
+
* @example Basic Usage
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <Text>Hello World</Text>
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* @example Variants
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Text variant="body">Body text</Text>
|
|
14
|
+
* <Text variant="header">Header text</Text>
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @example Colors
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <Text color="primary">Primary text</Text>
|
|
20
|
+
* <Text color="secondary">Secondary text</Text>
|
|
21
|
+
* <Text color="muted">Muted text</Text>
|
|
22
|
+
* <Text color="tertiary">Tertiary text</Text>
|
|
23
|
+
* <Text color="quaternary">Quaternary text</Text>
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example Inverted (for dark backgrounds)
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <Text invert>Inverted text</Text>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example Combining Props
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <Text variant="header" color="secondary">
|
|
34
|
+
* Secondary Header
|
|
35
|
+
* </Text>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
40
|
+
import * as React from "react";
|
|
41
|
+
import Animated from "react-native-reanimated";
|
|
42
|
+
import { twMerge } from "tailwind-merge";
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Merge class names with Tailwind CSS class conflict resolution
|
|
46
|
+
*/
|
|
47
|
+
function cn(...inputs: (string | undefined | null | false)[]): string {
|
|
48
|
+
return twMerge(inputs.filter(Boolean).join(" "));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const textVariants = cva("text-foreground font-sans text-base", {
|
|
52
|
+
variants: {
|
|
53
|
+
variant: {
|
|
54
|
+
body: "",
|
|
55
|
+
header: "font-semibold text-lg text-foreground",
|
|
56
|
+
},
|
|
57
|
+
color: {
|
|
58
|
+
primary: "text-foreground",
|
|
59
|
+
secondary: "text-secondary-foreground/90",
|
|
60
|
+
muted: "text-muted",
|
|
61
|
+
tertiary: "text-muted-foreground/70",
|
|
62
|
+
quaternary: "text-muted-foreground/50",
|
|
63
|
+
},
|
|
64
|
+
invert: {
|
|
65
|
+
true: "text-background dark:text-background",
|
|
66
|
+
false: "",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
defaultVariants: {
|
|
70
|
+
variant: "body",
|
|
71
|
+
color: "primary",
|
|
72
|
+
invert: false,
|
|
73
|
+
},
|
|
74
|
+
compoundVariants: [],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const TextClassContext = React.createContext<string | undefined>(undefined);
|
|
78
|
+
|
|
79
|
+
export type TextVariant = VariantProps<typeof textVariants>["variant"];
|
|
80
|
+
|
|
81
|
+
/** Props for Text component */
|
|
82
|
+
export type TextProps = React.ComponentProps<typeof Animated.Text> &
|
|
83
|
+
VariantProps<typeof textVariants> & {
|
|
84
|
+
/** Text variant */
|
|
85
|
+
variant?: TextVariant;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const Text = (props: TextProps) => {
|
|
89
|
+
const { className, variant, color, invert, ...otherProps } = props;
|
|
90
|
+
const textClassName = React.useContext(TextClassContext);
|
|
91
|
+
|
|
92
|
+
const classNames = React.useMemo(() => {
|
|
93
|
+
return cn(
|
|
94
|
+
textVariants({
|
|
95
|
+
variant: variant,
|
|
96
|
+
color: color,
|
|
97
|
+
invert: invert,
|
|
98
|
+
}),
|
|
99
|
+
textClassName,
|
|
100
|
+
className,
|
|
101
|
+
);
|
|
102
|
+
}, [variant, color, invert, textClassName, className]);
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<TextClassContext.Provider value={classNames}>
|
|
106
|
+
<Animated.Text
|
|
107
|
+
{...otherProps}
|
|
108
|
+
className={classNames}
|
|
109
|
+
allowFontScaling={false}
|
|
110
|
+
/>
|
|
111
|
+
</TextClassContext.Provider>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
Text.displayName = "Text";
|
|
116
|
+
|
|
117
|
+
export { TextClassContext, Text, textVariants };
|
|
@@ -4,38 +4,22 @@
|
|
|
4
4
|
* Wraps the app with NavigationContainer and linking configuration.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import type { LinkingOptions } from "@react-navigation/native";
|
|
8
8
|
import { NavigationContainer } from "@react-navigation/native";
|
|
9
|
-
import
|
|
9
|
+
import type React from "react";
|
|
10
|
+
import { defaultPrefixes, generatedLinkingConfig } from "@/.teardown/linking.generated";
|
|
10
11
|
|
|
11
12
|
interface NavigationProviderProps {
|
|
12
13
|
children: React.ReactNode;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
/**
|
|
16
|
-
* Get the deep link scheme from config.
|
|
17
|
-
* Uses `scheme` if specified, otherwise falls back to `slug`.
|
|
18
|
-
*/
|
|
19
|
-
const scheme = config.scheme ?? config.slug;
|
|
20
|
-
|
|
21
16
|
/**
|
|
22
17
|
* Linking configuration for deep links.
|
|
23
18
|
* Routes are automatically generated by @teardown/navigation-metro.
|
|
24
19
|
*/
|
|
25
|
-
const linking = {
|
|
26
|
-
prefixes:
|
|
27
|
-
config:
|
|
28
|
-
screens: {
|
|
29
|
-
"(tabs)": {
|
|
30
|
-
screens: {
|
|
31
|
-
home: "home",
|
|
32
|
-
explore: "explore",
|
|
33
|
-
profile: "profile",
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
settings: "settings",
|
|
37
|
-
},
|
|
38
|
-
},
|
|
20
|
+
const linking: LinkingOptions<object> = {
|
|
21
|
+
prefixes: defaultPrefixes,
|
|
22
|
+
config: generatedLinkingConfig,
|
|
39
23
|
};
|
|
40
24
|
|
|
41
25
|
export function NavigationProvider({ children }: NavigationProviderProps): React.JSX.Element {
|
|
@@ -31,10 +31,8 @@ function HomeScreen(): React.JSX.Element {
|
|
|
31
31
|
|
|
32
32
|
{/* Quick Actions */}
|
|
33
33
|
<Card>
|
|
34
|
-
<Card.Header>
|
|
35
|
-
<Text className="text-lg font-semibold text-foreground">Quick Actions</Text>
|
|
36
|
-
</Card.Header>
|
|
37
34
|
<Card.Body className="gap-3">
|
|
35
|
+
<Card.Title>Quick Actions</Card.Title>
|
|
38
36
|
<Button onPress={() => console.log("Primary action")} fullWidth>
|
|
39
37
|
Get Started
|
|
40
38
|
</Button>
|
|
@@ -67,13 +65,13 @@ function HomeScreen(): React.JSX.Element {
|
|
|
67
65
|
{/* Getting Started */}
|
|
68
66
|
<Card className="bg-primary/5 border-primary/20">
|
|
69
67
|
<Card.Body className="py-4">
|
|
70
|
-
<
|
|
71
|
-
<
|
|
68
|
+
<Card.Title>Getting Started</Card.Title>
|
|
69
|
+
<Card.Description>
|
|
72
70
|
1. Explore the components in src/components/ui/{"\n"}
|
|
73
71
|
2. Add new routes in src/routes/{"\n"}
|
|
74
72
|
3. Customize the theme in global.css{"\n"}
|
|
75
73
|
4. Build your app!
|
|
76
|
-
</
|
|
74
|
+
</Card.Description>
|
|
77
75
|
</Card.Body>
|
|
78
76
|
</Card>
|
|
79
77
|
</ScrollView>
|
|
@@ -96,8 +94,8 @@ function FeatureCard({
|
|
|
96
94
|
<Text className="text-2xl">{icon}</Text>
|
|
97
95
|
</View>
|
|
98
96
|
<View className="flex-1">
|
|
99
|
-
<
|
|
100
|
-
<
|
|
97
|
+
<Card.Title>{title}</Card.Title>
|
|
98
|
+
<Card.Description>{description}</Card.Description>
|
|
101
99
|
</View>
|
|
102
100
|
</Card.Body>
|
|
103
101
|
</Card>
|