@coze-arch/cli 0.0.1-alpha.bd5b49 → 0.0.1-alpha.c199b3
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/README.md +1 -0
- package/lib/__templates__/expo/README.md +16 -13
- package/lib/__templates__/expo/_npmrc +1 -0
- package/lib/__templates__/expo/client/app/+not-found.tsx +19 -4
- package/lib/__templates__/expo/client/app/_layout.tsx +17 -16
- package/lib/__templates__/expo/client/components/Screen.tsx +2 -2
- package/lib/__templates__/expo/client/constants/theme.ts +177 -0
- package/lib/__templates__/expo/client/eslint.config.mjs +7 -0
- package/lib/__templates__/expo/client/hooks/useColorScheme.tsx +48 -0
- package/lib/__templates__/expo/client/hooks/useTheme.ts +33 -0
- package/lib/__templates__/expo/client/metro.config.js +4 -8
- package/lib/__templates__/expo/client/package.json +1 -3
- package/lib/__templates__/expo/client/screens/demo/index.tsx +13 -7
- package/lib/__templates__/expo/client/screens/demo/styles.ts +28 -0
- package/lib/__templates__/expo/client/scripts/install-missing-deps.js +10 -10
- package/lib/__templates__/expo/eslint-plugins/forbid-emoji/index.js +9 -0
- package/lib/__templates__/expo/eslint-plugins/forbid-emoji/rule.js +112 -0
- package/lib/__templates__/expo/eslint-plugins/forbid-emoji/tech.md +94 -0
- package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/index.js +9 -0
- package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/rule.js +120 -0
- package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/tech.md +58 -0
- package/lib/__templates__/native-static/.coze +11 -0
- package/lib/__templates__/native-static/index.html +33 -0
- package/lib/__templates__/native-static/styles/main.css +136 -0
- package/lib/__templates__/native-static/template.config.js +22 -0
- package/lib/__templates__/nextjs/AGENTS.md +54 -0
- package/lib/__templates__/nextjs/README.md +5 -0
- package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
- package/lib/__templates__/nextjs/next.config.ts +1 -2
- package/lib/__templates__/nextjs/package.json +2 -5
- package/lib/__templates__/nextjs/pnpm-lock.yaml +1028 -5
- package/lib/__templates__/nextjs/scripts/build.sh +4 -1
- package/lib/__templates__/nextjs/scripts/dev.sh +8 -2
- package/lib/__templates__/nextjs/scripts/start.sh +7 -1
- package/lib/__templates__/nextjs/src/app/layout.tsx +1 -1
- package/lib/__templates__/nextjs/src/app/page.tsx +1 -2
- package/lib/__templates__/nextjs/src/server.ts +35 -0
- package/lib/__templates__/nextjs/tsconfig.json +1 -1
- package/lib/__templates__/nuxt-vue/.coze +12 -0
- package/lib/__templates__/nuxt-vue/AGENTS.md +42 -0
- package/lib/__templates__/nuxt-vue/README.md +73 -0
- package/lib/__templates__/nuxt-vue/_gitignore +24 -0
- package/lib/__templates__/nuxt-vue/_npmrc +23 -0
- package/lib/__templates__/nuxt-vue/app/app.vue +6 -0
- package/lib/__templates__/nuxt-vue/app/pages/index.vue +23 -0
- package/lib/__templates__/nuxt-vue/assets/css/main.css +24 -0
- package/lib/__templates__/nuxt-vue/nuxt.config.ts +116 -0
- package/lib/__templates__/nuxt-vue/package.json +35 -0
- package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +8759 -0
- package/lib/__templates__/nuxt-vue/postcss.config.mjs +8 -0
- package/lib/__templates__/nuxt-vue/public/favicon.ico +0 -0
- package/lib/__templates__/nuxt-vue/public/robots.txt +2 -0
- package/lib/__templates__/nuxt-vue/scripts/build.sh +14 -0
- package/lib/__templates__/nuxt-vue/scripts/dev.sh +39 -0
- package/lib/__templates__/nuxt-vue/scripts/prepare.sh +14 -0
- package/lib/__templates__/nuxt-vue/scripts/start.sh +21 -0
- package/lib/__templates__/nuxt-vue/server/api/hello.ts +10 -0
- package/lib/__templates__/nuxt-vue/server/middleware/logger.ts +10 -0
- package/lib/__templates__/nuxt-vue/server/routes/health.ts +10 -0
- package/lib/__templates__/nuxt-vue/tailwind.config.js +13 -0
- package/lib/__templates__/nuxt-vue/template.config.js +87 -0
- package/lib/__templates__/nuxt-vue/tsconfig.json +18 -0
- package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +107 -36
- package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +24 -1
- package/lib/__templates__/taro/README.md +61 -45
- package/lib/__templates__/taro/config/index.ts +106 -41
- package/lib/__templates__/taro/config/prod.ts +4 -5
- package/lib/__templates__/taro/eslint.config.mjs +82 -4
- package/lib/__templates__/taro/package.json +22 -7
- package/lib/__templates__/taro/patches/@tarojs__plugin-mini-ci@4.1.9.patch +30 -0
- package/lib/__templates__/taro/pnpm-lock.yaml +924 -220
- package/lib/__templates__/taro/server/package.json +0 -1
- package/lib/__templates__/taro/src/app.css +140 -36
- package/lib/__templates__/taro/src/app.tsx +9 -0
- package/lib/__templates__/taro/src/components/ui/accordion.tsx +159 -0
- package/lib/__templates__/taro/src/components/ui/alert-dialog.tsx +260 -0
- package/lib/__templates__/taro/src/components/ui/alert.tsx +60 -0
- package/lib/__templates__/taro/src/components/ui/aspect-ratio.tsx +36 -0
- package/lib/__templates__/taro/src/components/ui/avatar.tsx +84 -0
- package/lib/__templates__/taro/src/components/ui/badge.tsx +37 -0
- package/lib/__templates__/taro/src/components/ui/breadcrumb.tsx +117 -0
- package/lib/__templates__/taro/src/components/ui/button-group.tsx +83 -0
- package/lib/__templates__/taro/src/components/ui/button.tsx +67 -0
- package/lib/__templates__/taro/src/components/ui/calendar.tsx +394 -0
- package/lib/__templates__/taro/src/components/ui/card.tsx +108 -0
- package/lib/__templates__/taro/src/components/ui/carousel.tsx +228 -0
- package/lib/__templates__/taro/src/components/ui/checkbox.tsx +58 -0
- package/lib/__templates__/taro/src/components/ui/code-block.tsx +169 -0
- package/lib/__templates__/taro/src/components/ui/collapsible.tsx +71 -0
- package/lib/__templates__/taro/src/components/ui/command.tsx +385 -0
- package/lib/__templates__/taro/src/components/ui/context-menu.tsx +614 -0
- package/lib/__templates__/taro/src/components/ui/dialog.tsx +256 -0
- package/lib/__templates__/taro/src/components/ui/drawer.tsx +192 -0
- package/lib/__templates__/taro/src/components/ui/dropdown-menu.tsx +561 -0
- package/lib/__templates__/taro/src/components/ui/field.tsx +228 -0
- package/lib/__templates__/taro/src/components/ui/hover-card.tsx +282 -0
- package/lib/__templates__/taro/src/components/ui/input-group.tsx +197 -0
- package/lib/__templates__/taro/src/components/ui/input-otp.tsx +136 -0
- package/lib/__templates__/taro/src/components/ui/input.tsx +56 -0
- package/lib/__templates__/taro/src/components/ui/label.tsx +24 -0
- package/lib/__templates__/taro/src/components/ui/menubar.tsx +595 -0
- package/lib/__templates__/taro/src/components/ui/navigation-menu.tsx +264 -0
- package/lib/__templates__/taro/src/components/ui/pagination.tsx +118 -0
- package/lib/__templates__/taro/src/components/ui/popover.tsx +291 -0
- package/lib/__templates__/taro/src/components/ui/portal.tsx +19 -0
- package/lib/__templates__/taro/src/components/ui/progress.tsx +28 -0
- package/lib/__templates__/taro/src/components/ui/radio-group.tsx +64 -0
- package/lib/__templates__/taro/src/components/ui/resizable.tsx +346 -0
- package/lib/__templates__/taro/src/components/ui/scroll-area.tsx +34 -0
- package/lib/__templates__/taro/src/components/ui/select.tsx +438 -0
- package/lib/__templates__/taro/src/components/ui/separator.tsx +30 -0
- package/lib/__templates__/taro/src/components/ui/sheet.tsx +262 -0
- package/lib/__templates__/taro/src/components/ui/skeleton.tsx +17 -0
- package/lib/__templates__/taro/src/components/ui/slider.tsx +203 -0
- package/lib/__templates__/taro/src/components/ui/sonner.tsx +1 -0
- package/lib/__templates__/taro/src/components/ui/switch.tsx +55 -0
- package/lib/__templates__/taro/src/components/ui/table.tsx +142 -0
- package/lib/__templates__/taro/src/components/ui/tabs.tsx +114 -0
- package/lib/__templates__/taro/src/components/ui/textarea.tsx +54 -0
- package/lib/__templates__/taro/src/components/ui/toast.tsx +517 -0
- package/lib/__templates__/taro/src/components/ui/toggle-group.tsx +120 -0
- package/lib/__templates__/taro/src/components/ui/toggle.tsx +77 -0
- package/lib/__templates__/taro/src/components/ui/tooltip.tsx +455 -0
- package/lib/__templates__/taro/src/lib/hooks/use-keyboard-offset.ts +37 -0
- package/lib/__templates__/taro/src/lib/measure.ts +115 -0
- package/lib/__templates__/taro/src/lib/platform.ts +12 -0
- package/lib/__templates__/taro/src/lib/utils.ts +6 -0
- package/lib/__templates__/taro/src/presets/dev-debug.ts +23 -0
- package/lib/__templates__/taro/src/presets/h5-container.tsx +15 -0
- package/lib/__templates__/taro/src/presets/h5-navbar.tsx +238 -0
- package/lib/__templates__/taro/src/presets/h5-styles.ts +220 -0
- package/lib/__templates__/taro/src/presets/index.tsx +18 -0
- package/lib/__templates__/templates.json +43 -0
- package/lib/__templates__/vite/AGENTS.md +41 -0
- package/lib/__templates__/vite/README.md +190 -11
- package/lib/__templates__/vite/_gitignore +1 -0
- package/lib/__templates__/vite/eslint.config.mjs +6 -1
- package/lib/__templates__/vite/package.json +10 -3
- package/lib/__templates__/vite/pnpm-lock.yaml +755 -15
- package/lib/__templates__/vite/scripts/build.sh +4 -1
- package/lib/__templates__/vite/scripts/dev.sh +9 -2
- package/lib/__templates__/vite/scripts/start.sh +9 -3
- package/lib/__templates__/vite/server/routes/index.ts +31 -0
- package/lib/__templates__/vite/server/server.ts +65 -0
- package/lib/__templates__/vite/server/vite.ts +67 -0
- package/lib/__templates__/vite/tsconfig.json +4 -3
- package/lib/__templates__/vite/vite.config.ts +5 -0
- package/lib/cli.js +3037 -535
- package/package.json +10 -3
- package/lib/__templates__/expo/client/global.css +0 -78
- package/lib/__templates__/expo/client/styles.css +0 -263
- package/lib/__templates__/expo/client/uniwind-types.d.ts +0 -10
- package/lib/__templates__/taro/src/app.ts +0 -14
- package/lib/__templates__/taro/src/utils/h5-styles.ts +0 -33
- package/lib/__templates__/taro/src/utils/wx-debug.ts +0 -23
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Expo App + Express.js
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 目录结构规范(严格遵循)
|
|
4
4
|
|
|
5
5
|
当前仓库是一个 monorepo(基于 pnpm 的 workspace)
|
|
6
6
|
|
|
@@ -16,14 +16,17 @@
|
|
|
16
16
|
├── client/ # React Native 前端代码
|
|
17
17
|
│ ├── app/ # Expo Router 路由目录(仅路由配置)
|
|
18
18
|
│ │ ├── _layout.tsx # 根布局文件(必需,务必阅读)
|
|
19
|
-
│ │
|
|
19
|
+
│ │ ├── home.tsx # 首页
|
|
20
|
+
│ │ └── index.tsx # re-export home.tsx
|
|
20
21
|
│ ├── screens/ # 页面实现目录(与 app/ 路由对应)
|
|
21
|
-
│ │ └── demo/
|
|
22
|
-
│ │
|
|
22
|
+
│ │ └── demo/ # demo 示例页面
|
|
23
|
+
│ │ ├── index.tsx # 页面组件实现
|
|
24
|
+
│ │ └── styles.ts # 页面样式
|
|
23
25
|
│ ├── components/ # 可复用组件
|
|
24
26
|
│ │ └── Screen.tsx # 页面容器组件(必用)
|
|
25
27
|
│ ├── hooks/ # 自定义 Hooks
|
|
26
28
|
│ ├── contexts/ # React Context 代码
|
|
29
|
+
│ ├── constants/ # 常量定义(如主题配置)
|
|
27
30
|
│ ├── utils/ # 工具函数
|
|
28
31
|
│ ├── assets/ # 静态资源
|
|
29
32
|
| └── package.json # Expo 应用 package.json
|
|
@@ -31,15 +34,6 @@
|
|
|
31
34
|
├── .cozeproj # 预置脚手架脚本(禁止修改)
|
|
32
35
|
└── .coze # 配置文件(禁止修改)
|
|
33
36
|
|
|
34
|
-
## 技术选型(严格遵循)
|
|
35
|
-
|
|
36
|
-
- 前端:Expo + React Native + TailwindCSS
|
|
37
|
-
- 后端:Express.js
|
|
38
|
-
|
|
39
|
-
本项目通过 uniwind 实现了 react-native 对 TailwindCSS v4 的支持,在编写样式时应使用 TailwindCSS 写法
|
|
40
|
-
|
|
41
|
-
在开始开发前,先查看 client/global.css 了解必要的信息
|
|
42
|
-
|
|
43
37
|
## 安装依赖
|
|
44
38
|
|
|
45
39
|
### 命令
|
|
@@ -48,6 +42,15 @@
|
|
|
48
42
|
pnpm i
|
|
49
43
|
```
|
|
50
44
|
|
|
45
|
+
### 新增依赖约束
|
|
46
|
+
|
|
47
|
+
如果需要新增依赖,需在 client 和 server 各自的目录添加(原因:隔离前后端的依赖),禁止在根目录直接安装依赖
|
|
48
|
+
|
|
49
|
+
### 新增依赖标准流程
|
|
50
|
+
|
|
51
|
+
- 编辑 `client/package.json` 或 `server/package.json`
|
|
52
|
+
- 在根目录执行 `pnpm i`
|
|
53
|
+
|
|
51
54
|
## Expo 开发规范
|
|
52
55
|
|
|
53
56
|
### 路径别名
|
|
@@ -1,15 +1,30 @@
|
|
|
1
|
-
import { View, Text } from 'react-native';
|
|
1
|
+
import { View, Text, StyleSheet } from 'react-native';
|
|
2
2
|
import { Link } from 'expo-router';
|
|
3
|
+
import { useTheme } from '@/hooks/useTheme';
|
|
4
|
+
import { Spacing } from '@/constants/theme';
|
|
3
5
|
|
|
4
6
|
export default function NotFoundScreen() {
|
|
7
|
+
const { theme } = useTheme();
|
|
8
|
+
|
|
5
9
|
return (
|
|
6
|
-
<View
|
|
7
|
-
<Text
|
|
10
|
+
<View style={[styles.container, { backgroundColor: theme.backgroundRoot }]}>
|
|
11
|
+
<Text>
|
|
8
12
|
页面不存在
|
|
9
13
|
</Text>
|
|
10
|
-
<Link href="/"
|
|
14
|
+
<Link href="/" style={[styles.gohome]}>
|
|
11
15
|
返回首页
|
|
12
16
|
</Link>
|
|
13
17
|
</View>
|
|
14
18
|
);
|
|
15
19
|
}
|
|
20
|
+
|
|
21
|
+
const styles = StyleSheet.create({
|
|
22
|
+
container: {
|
|
23
|
+
flex: 1,
|
|
24
|
+
justifyContent: 'center',
|
|
25
|
+
alignItems: 'center',
|
|
26
|
+
},
|
|
27
|
+
gohome: {
|
|
28
|
+
marginTop: Spacing['2xl'],
|
|
29
|
+
},
|
|
30
|
+
});
|
|
@@ -5,8 +5,7 @@ import { StatusBar } from 'expo-status-bar';
|
|
|
5
5
|
import { LogBox } from 'react-native';
|
|
6
6
|
import Toast from 'react-native-toast-message';
|
|
7
7
|
import { AuthProvider } from "@/contexts/AuthContext";
|
|
8
|
-
|
|
9
|
-
import '../global.css';
|
|
8
|
+
import { ColorSchemeProvider } from '@/hooks/useColorScheme';
|
|
10
9
|
|
|
11
10
|
LogBox.ignoreLogs([
|
|
12
11
|
"TurboModuleRegistry.getEnforcing(...): 'RNMapsAirModule' could not be found",
|
|
@@ -16,20 +15,22 @@ LogBox.ignoreLogs([
|
|
|
16
15
|
export default function RootLayout() {
|
|
17
16
|
return (
|
|
18
17
|
<AuthProvider>
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
<ColorSchemeProvider>
|
|
19
|
+
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
20
|
+
<StatusBar style="dark"></StatusBar>
|
|
21
|
+
<Stack screenOptions={{
|
|
22
|
+
// 设置所有页面的切换动画为从右侧滑入,适用于iOS 和 Android
|
|
23
|
+
animation: 'slide_from_right',
|
|
24
|
+
gestureEnabled: true,
|
|
25
|
+
gestureDirection: 'horizontal',
|
|
26
|
+
// 隐藏自带的头部
|
|
27
|
+
headerShown: false
|
|
28
|
+
}}>
|
|
29
|
+
<Stack.Screen name="index" options={{ title: "" }} />
|
|
30
|
+
</Stack>
|
|
31
|
+
<Toast />
|
|
32
|
+
</GestureHandlerRootView>
|
|
33
|
+
</ColorSchemeProvider>
|
|
33
34
|
</AuthProvider>
|
|
34
35
|
);
|
|
35
36
|
}
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
*
|
|
33
33
|
* ## 2. 沉浸式 Header (推荐)
|
|
34
34
|
* - 场景:Header 背景色/图片需要延伸到状态栏 (如首页、个人中心)。
|
|
35
|
-
* - 用法:`<Screen safeAreaEdges={['left', 'right', 'bottom']}>` (
|
|
35
|
+
* - 用法:`<Screen safeAreaEdges={['left', 'right', 'bottom']}>` (去掉 'top')
|
|
36
36
|
* - 配合:页面内部 Header 组件必须手动添加 paddingTop:
|
|
37
37
|
* ```tsx
|
|
38
38
|
* const insets = useSafeAreaInsets();
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
*
|
|
42
42
|
* ## 3. 底部有 TabBar 或 悬浮按钮
|
|
43
43
|
* - 场景:页面底部有固定导航栏,或者需要精细控制底部留白。
|
|
44
|
-
* - 用法:`<Screen safeAreaEdges={['top', 'left', 'right']}>` (
|
|
44
|
+
* - 用法:`<Screen safeAreaEdges={['top', 'left', 'right']}>` (去掉 'bottom')
|
|
45
45
|
* - 配合:
|
|
46
46
|
* - 若是滚动页:`<ScrollView contentContainerStyle={{ paddingBottom: insets.bottom + 80 }}>`
|
|
47
47
|
* - 若是固定页:`<View style={{ paddingBottom: insets.bottom + 60 }}>`
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export const Colors = {
|
|
2
|
+
light: {
|
|
3
|
+
textPrimary: "#1C1917",
|
|
4
|
+
textSecondary: "#78716c",
|
|
5
|
+
textMuted: "#9CA3AF",
|
|
6
|
+
primary: "#4F46E5", // Indigo-600 - 品牌主色,代表科技与智能
|
|
7
|
+
accent: "#8B5CF6", // Violet-500 - 辅助色,代表创造力
|
|
8
|
+
success: "#10B981", // Emerald-500
|
|
9
|
+
error: "#EF4444",
|
|
10
|
+
backgroundRoot: "#FAFAFA",
|
|
11
|
+
backgroundDefault: "#FFFFFF",
|
|
12
|
+
backgroundTertiary: "#F9FAFB", // 更浅的背景色,用于去线留白
|
|
13
|
+
buttonPrimaryText: "#FFFFFF",
|
|
14
|
+
tabIconSelected: "#4F46E5",
|
|
15
|
+
border: "#E5E7EB",
|
|
16
|
+
borderLight: "#F3F4F6",
|
|
17
|
+
},
|
|
18
|
+
dark: {
|
|
19
|
+
textPrimary: "#FAFAF9",
|
|
20
|
+
textSecondary: "#A8A29E",
|
|
21
|
+
textMuted: "#6F767E",
|
|
22
|
+
primary: "#818CF8", // Indigo-400 - 暗色模式品牌主色
|
|
23
|
+
accent: "#A78BFA", // Violet-400
|
|
24
|
+
success: "#34D399",
|
|
25
|
+
error: "#F87171",
|
|
26
|
+
backgroundRoot: "#09090B", // 更深的背景色
|
|
27
|
+
backgroundDefault: "#1C1C1E",
|
|
28
|
+
backgroundTertiary: "#1F1F22", // 暗色模式去线留白背景
|
|
29
|
+
buttonPrimaryText: "#09090B",
|
|
30
|
+
tabIconSelected: "#818CF8",
|
|
31
|
+
border: "#3F3F46",
|
|
32
|
+
borderLight: "#27272A",
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const Spacing = {
|
|
37
|
+
xs: 4,
|
|
38
|
+
sm: 8,
|
|
39
|
+
md: 12,
|
|
40
|
+
lg: 16,
|
|
41
|
+
xl: 20,
|
|
42
|
+
"2xl": 24,
|
|
43
|
+
"3xl": 32,
|
|
44
|
+
"4xl": 40,
|
|
45
|
+
"5xl": 48,
|
|
46
|
+
"6xl": 64,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const BorderRadius = {
|
|
50
|
+
xs: 4,
|
|
51
|
+
sm: 8,
|
|
52
|
+
md: 12,
|
|
53
|
+
lg: 16,
|
|
54
|
+
xl: 20,
|
|
55
|
+
"2xl": 24,
|
|
56
|
+
"3xl": 28,
|
|
57
|
+
"4xl": 32,
|
|
58
|
+
full: 9999,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const Typography = {
|
|
62
|
+
display: {
|
|
63
|
+
fontSize: 112,
|
|
64
|
+
lineHeight: 112,
|
|
65
|
+
fontWeight: "200" as const,
|
|
66
|
+
letterSpacing: -4,
|
|
67
|
+
},
|
|
68
|
+
displayLarge: {
|
|
69
|
+
fontSize: 112,
|
|
70
|
+
lineHeight: 112,
|
|
71
|
+
fontWeight: "200" as const,
|
|
72
|
+
letterSpacing: -2,
|
|
73
|
+
},
|
|
74
|
+
displayMedium: {
|
|
75
|
+
fontSize: 48,
|
|
76
|
+
lineHeight: 56,
|
|
77
|
+
fontWeight: "200" as const,
|
|
78
|
+
},
|
|
79
|
+
h1: {
|
|
80
|
+
fontSize: 32,
|
|
81
|
+
lineHeight: 40,
|
|
82
|
+
fontWeight: "700" as const,
|
|
83
|
+
},
|
|
84
|
+
h2: {
|
|
85
|
+
fontSize: 28,
|
|
86
|
+
lineHeight: 36,
|
|
87
|
+
fontWeight: "700" as const,
|
|
88
|
+
},
|
|
89
|
+
h3: {
|
|
90
|
+
fontSize: 24,
|
|
91
|
+
lineHeight: 32,
|
|
92
|
+
fontWeight: "300" as const,
|
|
93
|
+
},
|
|
94
|
+
h4: {
|
|
95
|
+
fontSize: 20,
|
|
96
|
+
lineHeight: 28,
|
|
97
|
+
fontWeight: "600" as const,
|
|
98
|
+
},
|
|
99
|
+
title: {
|
|
100
|
+
fontSize: 18,
|
|
101
|
+
lineHeight: 24,
|
|
102
|
+
fontWeight: "700" as const,
|
|
103
|
+
},
|
|
104
|
+
body: {
|
|
105
|
+
fontSize: 16,
|
|
106
|
+
lineHeight: 24,
|
|
107
|
+
fontWeight: "400" as const,
|
|
108
|
+
},
|
|
109
|
+
bodyMedium: {
|
|
110
|
+
fontSize: 16,
|
|
111
|
+
lineHeight: 24,
|
|
112
|
+
fontWeight: "500" as const,
|
|
113
|
+
},
|
|
114
|
+
small: {
|
|
115
|
+
fontSize: 14,
|
|
116
|
+
lineHeight: 20,
|
|
117
|
+
fontWeight: "400" as const,
|
|
118
|
+
},
|
|
119
|
+
smallMedium: {
|
|
120
|
+
fontSize: 14,
|
|
121
|
+
lineHeight: 20,
|
|
122
|
+
fontWeight: "500" as const,
|
|
123
|
+
},
|
|
124
|
+
caption: {
|
|
125
|
+
fontSize: 12,
|
|
126
|
+
lineHeight: 16,
|
|
127
|
+
fontWeight: "400" as const,
|
|
128
|
+
},
|
|
129
|
+
captionMedium: {
|
|
130
|
+
fontSize: 12,
|
|
131
|
+
lineHeight: 16,
|
|
132
|
+
fontWeight: "500" as const,
|
|
133
|
+
},
|
|
134
|
+
label: {
|
|
135
|
+
fontSize: 14,
|
|
136
|
+
lineHeight: 20,
|
|
137
|
+
fontWeight: "500" as const,
|
|
138
|
+
letterSpacing: 2,
|
|
139
|
+
textTransform: "uppercase" as const,
|
|
140
|
+
},
|
|
141
|
+
labelSmall: {
|
|
142
|
+
fontSize: 12,
|
|
143
|
+
lineHeight: 16,
|
|
144
|
+
fontWeight: "500" as const,
|
|
145
|
+
letterSpacing: 1,
|
|
146
|
+
textTransform: "uppercase" as const,
|
|
147
|
+
},
|
|
148
|
+
labelTitle: {
|
|
149
|
+
fontSize: 14,
|
|
150
|
+
lineHeight: 20,
|
|
151
|
+
fontWeight: "700" as const,
|
|
152
|
+
letterSpacing: 2,
|
|
153
|
+
textTransform: "uppercase" as const,
|
|
154
|
+
},
|
|
155
|
+
link: {
|
|
156
|
+
fontSize: 16,
|
|
157
|
+
lineHeight: 24,
|
|
158
|
+
fontWeight: "400" as const,
|
|
159
|
+
},
|
|
160
|
+
stat: {
|
|
161
|
+
fontSize: 30,
|
|
162
|
+
lineHeight: 36,
|
|
163
|
+
fontWeight: "300" as const,
|
|
164
|
+
},
|
|
165
|
+
tiny: {
|
|
166
|
+
fontSize: 10,
|
|
167
|
+
lineHeight: 14,
|
|
168
|
+
fontWeight: "400" as const,
|
|
169
|
+
},
|
|
170
|
+
navLabel: {
|
|
171
|
+
fontSize: 10,
|
|
172
|
+
lineHeight: 14,
|
|
173
|
+
fontWeight: "500" as const,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export type Theme = typeof Colors.light;
|
|
@@ -8,6 +8,8 @@ import pluginImport from 'eslint-plugin-import';
|
|
|
8
8
|
import fontawesome6 from '../eslint-plugins/fontawesome6/index.js';
|
|
9
9
|
import reanimated from '../eslint-plugins/reanimated/index.js';
|
|
10
10
|
import reactnative from '../eslint-plugins/react-native/index.js';
|
|
11
|
+
import forbidEmoji from '../eslint-plugins/forbid-emoji/index.js';
|
|
12
|
+
import restrictLinearGradient from '../eslint-plugins/restrict-linear-gradient/index.js';
|
|
11
13
|
|
|
12
14
|
export default [
|
|
13
15
|
{
|
|
@@ -20,6 +22,7 @@ export default [
|
|
|
20
22
|
'tailwind.config.js', // 排除 Tailwind 配置文件
|
|
21
23
|
'**/*.d.ts',
|
|
22
24
|
'eslint.config.*',
|
|
25
|
+
'metro.config.*',
|
|
23
26
|
],
|
|
24
27
|
},
|
|
25
28
|
regexp.configs["flat/recommended"],
|
|
@@ -60,6 +63,8 @@ export default [
|
|
|
60
63
|
fontawesome6,
|
|
61
64
|
reanimated,
|
|
62
65
|
reactnative,
|
|
66
|
+
forbidEmoji,
|
|
67
|
+
restrictLinearGradient,
|
|
63
68
|
},
|
|
64
69
|
rules: {
|
|
65
70
|
// 关闭代码风格规则
|
|
@@ -80,6 +85,8 @@ export default [
|
|
|
80
85
|
'react/jsx-uses-react': 'off',
|
|
81
86
|
'fontawesome6/valid-name': 'error',
|
|
82
87
|
'reanimated/ban-mix-use': 'error',
|
|
88
|
+
'forbidEmoji/no-emoji': 'error',
|
|
89
|
+
'restrictLinearGradient/no-linear-gradient-backgroundcolor': 'error',
|
|
83
90
|
// 禁止使用 via.placeholder.com 服务
|
|
84
91
|
'no-restricted-syntax': [
|
|
85
92
|
'error',
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createContext, Dispatch, ReactNode, SetStateAction, useContext, useEffect, useState } from 'react';
|
|
2
|
+
import { ColorSchemeName, useColorScheme as useReactNativeColorScheme, Platform } from 'react-native';
|
|
3
|
+
|
|
4
|
+
const ColorSchemeContext = createContext<'light' | 'dark' | null | undefined>(null);
|
|
5
|
+
|
|
6
|
+
const ColorSchemeProvider = function ({ children }: { children?: ReactNode }) {
|
|
7
|
+
const systemColorScheme = useReactNativeColorScheme();
|
|
8
|
+
const [colorScheme, setColorScheme] = useState(systemColorScheme);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
setColorScheme(systemColorScheme);
|
|
12
|
+
}, [systemColorScheme]);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
function handleMessage(e: MessageEvent<{ event: string; colorScheme: ColorSchemeName; } | undefined>) {
|
|
16
|
+
if (e.data?.event === 'coze.workbench.colorScheme') {
|
|
17
|
+
const cs = e.data.colorScheme;
|
|
18
|
+
if (typeof cs === 'string' && typeof setColorScheme === 'function') {
|
|
19
|
+
setColorScheme(cs);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (Platform.OS === 'web') {
|
|
25
|
+
window.addEventListener('message', handleMessage, false);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return () => {
|
|
29
|
+
if (Platform.OS === 'web') {
|
|
30
|
+
window.removeEventListener('message', handleMessage, false);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}, [setColorScheme]);
|
|
34
|
+
|
|
35
|
+
return <ColorSchemeContext.Provider value={colorScheme}>
|
|
36
|
+
{children}
|
|
37
|
+
</ColorSchemeContext.Provider>
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function useColorScheme() {
|
|
41
|
+
const colorScheme = useContext(ColorSchemeContext);
|
|
42
|
+
return colorScheme;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
ColorSchemeProvider,
|
|
47
|
+
useColorScheme,
|
|
48
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Colors } from '@/constants/theme';
|
|
2
|
+
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
3
|
+
|
|
4
|
+
enum COLOR_SCHEME_CHOICE {
|
|
5
|
+
FOLLOW_SYSTEM = 'follow-system', // 跟随系统自动变化
|
|
6
|
+
DARK = 'dark', // 固定为 dark 主题,不随系统变化
|
|
7
|
+
LIGHT = 'light', // 固定为 light 主题,不随系统变化
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const userPreferColorScheme: COLOR_SCHEME_CHOICE = COLOR_SCHEME_CHOICE.FOLLOW_SYSTEM;
|
|
11
|
+
|
|
12
|
+
function getTheme(colorScheme?: 'dark' | 'light' | null) {
|
|
13
|
+
const isDark = colorScheme === 'dark';
|
|
14
|
+
const theme = Colors[colorScheme ?? 'light'];
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
theme,
|
|
18
|
+
isDark,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function useTheme() {
|
|
23
|
+
const systemColorScheme = useColorScheme()
|
|
24
|
+
const colorScheme = userPreferColorScheme === COLOR_SCHEME_CHOICE.FOLLOW_SYSTEM ?
|
|
25
|
+
systemColorScheme :
|
|
26
|
+
userPreferColorScheme;
|
|
27
|
+
|
|
28
|
+
return getTheme(colorScheme);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
useTheme,
|
|
33
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const { getDefaultConfig } = require('expo/metro-config');
|
|
2
2
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
3
3
|
const connect = require('connect');
|
|
4
|
-
const { withUniwindConfig } = require('uniwind/metro');
|
|
5
4
|
|
|
6
5
|
const config = getDefaultConfig(__dirname);
|
|
7
6
|
|
|
@@ -27,6 +26,9 @@ config.resolver.blockList = [
|
|
|
27
26
|
// 4. 通用规则
|
|
28
27
|
/.*\/__tests__\/.*/, // 排除所有测试目录
|
|
29
28
|
/.*\.git\/.*/, // 排除 Git 目录
|
|
29
|
+
|
|
30
|
+
// 5. pnpm 临时目录(避免 ENOENT 错误)
|
|
31
|
+
/.*node_modules\/\.pnpm\/.*_tmp_\d+.*/,
|
|
30
32
|
];
|
|
31
33
|
|
|
32
34
|
const BACKEND_TARGET = 'http://localhost:9091';
|
|
@@ -119,10 +121,4 @@ config.server = {
|
|
|
119
121
|
},
|
|
120
122
|
};
|
|
121
123
|
|
|
122
|
-
module.exports =
|
|
123
|
-
// relative path to your global.css file (from previous step)
|
|
124
|
-
cssEntryFile: './global.css',
|
|
125
|
-
// (optional) path where we gonna auto-generate typings
|
|
126
|
-
// defaults to project's root
|
|
127
|
-
dtsFile: './uniwind-types.d.ts'
|
|
128
|
-
});
|
|
124
|
+
module.exports = config;
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { View, Text } from 'react-native';
|
|
2
2
|
import { Image } from 'expo-image';
|
|
3
3
|
|
|
4
|
+
import { useTheme } from '@/hooks/useTheme';
|
|
4
5
|
import { Screen } from '@/components/Screen';
|
|
6
|
+
import { styles } from './styles';
|
|
5
7
|
|
|
6
8
|
export default function DemoPage() {
|
|
9
|
+
const { theme, isDark } = useTheme();
|
|
10
|
+
|
|
7
11
|
return (
|
|
8
|
-
<Screen backgroundColor=
|
|
9
|
-
<View
|
|
12
|
+
<Screen backgroundColor={theme.backgroundRoot} statusBarStyle={isDark ? 'light' : 'dark'}>
|
|
13
|
+
<View
|
|
14
|
+
style={styles.container}
|
|
15
|
+
>
|
|
10
16
|
<Image
|
|
11
|
-
|
|
12
|
-
source="https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze-coding/
|
|
13
|
-
|
|
14
|
-
<Text
|
|
15
|
-
<Text
|
|
17
|
+
style={styles.logo}
|
|
18
|
+
source="https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze-coding/icon/coze-coding.gif"
|
|
19
|
+
></Image>
|
|
20
|
+
<Text style={{...styles.title, color: theme.textPrimary}}>应用开发中</Text>
|
|
21
|
+
<Text style={{...styles.description, color: theme.textSecondary}}>请稍候,界面即将呈现</Text>
|
|
16
22
|
</View>
|
|
17
23
|
</Screen>
|
|
18
24
|
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Spacing } from '@/constants/theme';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export const styles = StyleSheet.create({
|
|
5
|
+
container: {
|
|
6
|
+
position: 'absolute',
|
|
7
|
+
top: 0,
|
|
8
|
+
left: 0,
|
|
9
|
+
width: '100%',
|
|
10
|
+
height: '100%',
|
|
11
|
+
display: 'flex',
|
|
12
|
+
flexDirection: 'column',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
justifyContent: 'center',
|
|
15
|
+
},
|
|
16
|
+
logo: {
|
|
17
|
+
width: 130,
|
|
18
|
+
height: 109,
|
|
19
|
+
},
|
|
20
|
+
title: {
|
|
21
|
+
fontSize: 16,
|
|
22
|
+
fontWeight: 'bold',
|
|
23
|
+
},
|
|
24
|
+
description: {
|
|
25
|
+
fontSize: 14,
|
|
26
|
+
marginTop: Spacing.sm,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -9,7 +9,7 @@ const { execSync } = require('child_process');
|
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
const path = require('path');
|
|
11
11
|
|
|
12
|
-
console.log('
|
|
12
|
+
console.log('检测缺失的依赖...\n');
|
|
13
13
|
|
|
14
14
|
try {
|
|
15
15
|
// 运行 depcheck 并获取 JSON 输出
|
|
@@ -61,11 +61,11 @@ try {
|
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
if (missingPackages.length === 0) {
|
|
64
|
-
console.log('
|
|
64
|
+
console.log('没有发现缺失的依赖');
|
|
65
65
|
process.exit(0);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
console.log('
|
|
68
|
+
console.log('发现以下缺失的依赖:');
|
|
69
69
|
missingPackages.forEach((pkg, index) => {
|
|
70
70
|
const files = missing[pkg];
|
|
71
71
|
console.log(` ${index + 1}. ${pkg}`);
|
|
@@ -74,7 +74,7 @@ try {
|
|
|
74
74
|
);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
console.log('\n
|
|
77
|
+
console.log('\n开始安装...\n');
|
|
78
78
|
|
|
79
79
|
// 使用 expo install 安装所有缺失的包
|
|
80
80
|
const packagesToInstall = missingPackages.join(' ');
|
|
@@ -84,22 +84,22 @@ try {
|
|
|
84
84
|
stdio: 'inherit',
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
console.log('\n
|
|
87
|
+
console.log('\n所有缺失的依赖已安装完成');
|
|
88
88
|
} catch (installError) {
|
|
89
|
-
console.log('\
|
|
89
|
+
console.log('\nexpo install 失败,尝试使用 npm install...\n');
|
|
90
90
|
|
|
91
91
|
execSync(`npm install ${packagesToInstall}`, {
|
|
92
92
|
stdio: 'inherit',
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
-
console.log('\n
|
|
95
|
+
console.log('\n所有缺失的依赖已通过 npm 安装完成');
|
|
96
96
|
}
|
|
97
97
|
} catch (error) {
|
|
98
98
|
if (error.message.includes('depcheck')) {
|
|
99
|
-
console.error('
|
|
100
|
-
console.log('
|
|
99
|
+
console.error('depcheck 未安装或运行失败');
|
|
100
|
+
console.log('尝试运行: npm install -g depcheck');
|
|
101
101
|
} else {
|
|
102
|
-
console.error('
|
|
102
|
+
console.error('发生错误:', error.message);
|
|
103
103
|
}
|
|
104
104
|
process.exit(1);
|
|
105
105
|
}
|