@coze-arch/cli 0.0.1-beta.6 → 0.0.2

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 (238) hide show
  1. package/README.md +1 -0
  2. package/lib/__templates__/expo/.coze +7 -2
  3. package/lib/__templates__/expo/.cozeproj/scripts/dev_build.sh +46 -0
  4. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +229 -0
  5. package/lib/__templates__/expo/.cozeproj/scripts/prod_build.sh +47 -0
  6. package/lib/__templates__/expo/.cozeproj/scripts/prod_run.sh +34 -0
  7. package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +46 -0
  8. package/lib/__templates__/expo/README.md +68 -7
  9. package/lib/__templates__/expo/_gitignore +1 -1
  10. package/lib/__templates__/expo/_npmrc +4 -5
  11. package/lib/__templates__/expo/client/app/+not-found.tsx +15 -64
  12. package/lib/__templates__/expo/client/app/_layout.tsx +15 -12
  13. package/lib/__templates__/expo/client/app/index.tsx +1 -0
  14. package/lib/__templates__/expo/client/app.config.ts +76 -0
  15. package/lib/__templates__/expo/client/components/Screen.tsx +3 -19
  16. package/lib/__templates__/expo/client/components/ThemedText.tsx +33 -0
  17. package/lib/__templates__/expo/client/components/ThemedView.tsx +37 -0
  18. package/lib/__templates__/expo/client/constants/theme.ts +117 -58
  19. package/lib/__templates__/expo/client/contexts/AuthContext.tsx +14 -107
  20. package/lib/__templates__/expo/client/declarations.d.ts +5 -0
  21. package/lib/__templates__/expo/{eslint.config.mjs → client/eslint.config.mjs} +40 -10
  22. package/lib/__templates__/expo/client/hooks/useColorScheme.tsx +48 -0
  23. package/lib/__templates__/expo/client/hooks/useSafeRouter.ts +152 -0
  24. package/lib/__templates__/expo/client/hooks/useTheme.ts +26 -6
  25. package/lib/__templates__/expo/client/metro.config.js +124 -0
  26. package/lib/__templates__/expo/client/package.json +95 -0
  27. package/lib/__templates__/expo/client/screens/demo/index.tsx +25 -0
  28. package/lib/__templates__/expo/client/screens/demo/styles.ts +28 -0
  29. package/lib/__templates__/expo/client/scripts/install-missing-deps.js +11 -10
  30. package/lib/__templates__/expo/client/tsconfig.json +24 -0
  31. package/lib/__templates__/expo/client/utils/index.ts +23 -2
  32. package/lib/__templates__/expo/eslint-plugins/fontawesome6/index.js +9 -0
  33. package/lib/__templates__/expo/eslint-plugins/fontawesome6/names.js +1889 -0
  34. package/lib/__templates__/expo/eslint-plugins/fontawesome6/rule.js +174 -0
  35. package/lib/__templates__/expo/eslint-plugins/fontawesome6/v5-only-names.js +388 -0
  36. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/index.js +9 -0
  37. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/rule.js +112 -0
  38. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/tech.md +94 -0
  39. package/lib/__templates__/expo/eslint-plugins/react-native/index.js +9 -0
  40. package/lib/__templates__/expo/eslint-plugins/react-native/rule.js +64 -0
  41. package/lib/__templates__/expo/eslint-plugins/reanimated/index.js +9 -0
  42. package/lib/__templates__/expo/eslint-plugins/reanimated/rule.js +88 -0
  43. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/index.js +9 -0
  44. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/rule.js +120 -0
  45. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/tech.md +58 -0
  46. package/lib/__templates__/expo/package.json +16 -101
  47. package/lib/__templates__/expo/patches/expo@54.0.33.patch +45 -0
  48. package/lib/__templates__/expo/pnpm-lock.yaml +1622 -3274
  49. package/lib/__templates__/expo/pnpm-workspace.yaml +3 -0
  50. package/lib/__templates__/expo/server/build.js +21 -0
  51. package/lib/__templates__/expo/server/package.json +34 -0
  52. package/lib/__templates__/expo/server/src/index.ts +20 -0
  53. package/lib/__templates__/expo/server/tsconfig.json +24 -0
  54. package/lib/__templates__/expo/template.config.js +58 -1
  55. package/lib/__templates__/expo/tsconfig.json +1 -24
  56. package/lib/__templates__/native-static/.coze +11 -0
  57. package/lib/__templates__/native-static/index.html +33 -0
  58. package/lib/__templates__/native-static/styles/main.css +136 -0
  59. package/lib/__templates__/native-static/template.config.js +22 -0
  60. package/lib/__templates__/nextjs/.coze +4 -3
  61. package/lib/__templates__/nextjs/README.md +5 -0
  62. package/lib/__templates__/nextjs/_npmrc +2 -1
  63. package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
  64. package/lib/__templates__/nextjs/next.config.ts +11 -0
  65. package/lib/__templates__/nextjs/package.json +15 -1
  66. package/lib/__templates__/nextjs/pnpm-lock.yaml +7694 -4394
  67. package/lib/__templates__/nextjs/scripts/build.sh +4 -1
  68. package/lib/__templates__/nextjs/scripts/dev.sh +15 -28
  69. package/lib/__templates__/nextjs/scripts/prepare.sh +9 -0
  70. package/lib/__templates__/nextjs/scripts/start.sh +7 -1
  71. package/lib/__templates__/nextjs/src/app/globals.css +109 -89
  72. package/lib/__templates__/nextjs/src/app/layout.tsx +20 -33
  73. package/lib/__templates__/nextjs/src/app/page.tsx +18 -49
  74. package/lib/__templates__/nextjs/src/components/ui/resizable.tsx +29 -22
  75. package/lib/__templates__/nextjs/src/components/ui/sidebar.tsx +228 -230
  76. package/lib/__templates__/nextjs/src/server.ts +35 -0
  77. package/lib/__templates__/nextjs/template.config.js +68 -3
  78. package/lib/__templates__/nextjs/tsconfig.json +1 -1
  79. package/lib/__templates__/nuxt-vue/.coze +12 -0
  80. package/lib/__templates__/nuxt-vue/README.md +73 -0
  81. package/lib/__templates__/nuxt-vue/_gitignore +24 -0
  82. package/lib/__templates__/nuxt-vue/_npmrc +23 -0
  83. package/lib/__templates__/nuxt-vue/app/app.vue +6 -0
  84. package/lib/__templates__/nuxt-vue/app/pages/index.vue +23 -0
  85. package/lib/__templates__/nuxt-vue/assets/css/main.css +24 -0
  86. package/lib/__templates__/nuxt-vue/nuxt.config.ts +116 -0
  87. package/lib/__templates__/nuxt-vue/package.json +35 -0
  88. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +8759 -0
  89. package/lib/__templates__/nuxt-vue/postcss.config.mjs +8 -0
  90. package/lib/__templates__/nuxt-vue/public/favicon.ico +0 -0
  91. package/lib/__templates__/nuxt-vue/public/robots.txt +2 -0
  92. package/lib/__templates__/nuxt-vue/scripts/build.sh +14 -0
  93. package/lib/__templates__/nuxt-vue/scripts/dev.sh +39 -0
  94. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +14 -0
  95. package/lib/__templates__/nuxt-vue/scripts/start.sh +21 -0
  96. package/lib/__templates__/nuxt-vue/server/api/hello.ts +10 -0
  97. package/lib/__templates__/nuxt-vue/server/middleware/logger.ts +10 -0
  98. package/lib/__templates__/nuxt-vue/server/routes/health.ts +10 -0
  99. package/lib/__templates__/nuxt-vue/tailwind.config.js +13 -0
  100. package/lib/__templates__/nuxt-vue/template.config.js +87 -0
  101. package/lib/__templates__/nuxt-vue/tsconfig.json +18 -0
  102. package/lib/__templates__/taro/.coze +14 -0
  103. package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +19 -0
  104. package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +14 -0
  105. package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +2 -0
  106. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +151 -0
  107. package/lib/__templates__/taro/.cozeproj/scripts/init_env.sh +5 -0
  108. package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +24 -0
  109. package/lib/__templates__/taro/README.md +763 -0
  110. package/lib/__templates__/taro/_gitignore +40 -0
  111. package/lib/__templates__/taro/_npmrc +18 -0
  112. package/lib/__templates__/taro/babel.config.js +12 -0
  113. package/lib/__templates__/taro/config/dev.ts +9 -0
  114. package/lib/__templates__/taro/config/index.ts +238 -0
  115. package/lib/__templates__/taro/config/prod.ts +34 -0
  116. package/lib/__templates__/taro/eslint.config.mjs +135 -0
  117. package/lib/__templates__/taro/key/private.appid.key +0 -0
  118. package/lib/__templates__/taro/package.json +112 -0
  119. package/lib/__templates__/taro/patches/@tarojs__plugin-mini-ci@4.1.9.patch +30 -0
  120. package/lib/__templates__/taro/pnpm-lock.yaml +23412 -0
  121. package/lib/__templates__/taro/pnpm-workspace.yaml +2 -0
  122. package/lib/__templates__/taro/project.config.json +15 -0
  123. package/lib/__templates__/taro/server/nest-cli.json +10 -0
  124. package/lib/__templates__/taro/server/package.json +40 -0
  125. package/lib/__templates__/taro/server/src/app.controller.ts +23 -0
  126. package/lib/__templates__/taro/server/src/app.module.ts +10 -0
  127. package/lib/__templates__/taro/server/src/app.service.ts +8 -0
  128. package/lib/__templates__/taro/server/src/interceptors/http-status.interceptor.ts +23 -0
  129. package/lib/__templates__/taro/server/src/main.ts +49 -0
  130. package/lib/__templates__/taro/server/tsconfig.json +24 -0
  131. package/lib/__templates__/taro/src/app.config.ts +11 -0
  132. package/lib/__templates__/taro/src/app.css +156 -0
  133. package/lib/__templates__/taro/src/app.tsx +9 -0
  134. package/lib/__templates__/taro/src/components/ui/accordion.tsx +159 -0
  135. package/lib/__templates__/taro/src/components/ui/alert-dialog.tsx +260 -0
  136. package/lib/__templates__/taro/src/components/ui/alert.tsx +60 -0
  137. package/lib/__templates__/taro/src/components/ui/aspect-ratio.tsx +36 -0
  138. package/lib/__templates__/taro/src/components/ui/avatar.tsx +84 -0
  139. package/lib/__templates__/taro/src/components/ui/badge.tsx +37 -0
  140. package/lib/__templates__/taro/src/components/ui/breadcrumb.tsx +117 -0
  141. package/lib/__templates__/taro/src/components/ui/button-group.tsx +83 -0
  142. package/lib/__templates__/taro/src/components/ui/button.tsx +67 -0
  143. package/lib/__templates__/taro/src/components/ui/calendar.tsx +394 -0
  144. package/lib/__templates__/taro/src/components/ui/card.tsx +108 -0
  145. package/lib/__templates__/taro/src/components/ui/carousel.tsx +228 -0
  146. package/lib/__templates__/taro/src/components/ui/checkbox.tsx +58 -0
  147. package/lib/__templates__/taro/src/components/ui/code-block.tsx +169 -0
  148. package/lib/__templates__/taro/src/components/ui/collapsible.tsx +71 -0
  149. package/lib/__templates__/taro/src/components/ui/command.tsx +385 -0
  150. package/lib/__templates__/taro/src/components/ui/context-menu.tsx +614 -0
  151. package/lib/__templates__/taro/src/components/ui/dialog.tsx +256 -0
  152. package/lib/__templates__/taro/src/components/ui/drawer.tsx +192 -0
  153. package/lib/__templates__/taro/src/components/ui/dropdown-menu.tsx +561 -0
  154. package/lib/__templates__/taro/src/components/ui/field.tsx +228 -0
  155. package/lib/__templates__/taro/src/components/ui/hover-card.tsx +282 -0
  156. package/lib/__templates__/taro/src/components/ui/input-group.tsx +197 -0
  157. package/lib/__templates__/taro/src/components/ui/input-otp.tsx +136 -0
  158. package/lib/__templates__/taro/src/components/ui/input.tsx +56 -0
  159. package/lib/__templates__/taro/src/components/ui/label.tsx +24 -0
  160. package/lib/__templates__/taro/src/components/ui/menubar.tsx +595 -0
  161. package/lib/__templates__/taro/src/components/ui/navigation-menu.tsx +264 -0
  162. package/lib/__templates__/taro/src/components/ui/pagination.tsx +118 -0
  163. package/lib/__templates__/taro/src/components/ui/popover.tsx +291 -0
  164. package/lib/__templates__/taro/src/components/ui/portal.tsx +19 -0
  165. package/lib/__templates__/taro/src/components/ui/progress.tsx +28 -0
  166. package/lib/__templates__/taro/src/components/ui/radio-group.tsx +64 -0
  167. package/lib/__templates__/taro/src/components/ui/resizable.tsx +346 -0
  168. package/lib/__templates__/taro/src/components/ui/scroll-area.tsx +34 -0
  169. package/lib/__templates__/taro/src/components/ui/select.tsx +438 -0
  170. package/lib/__templates__/taro/src/components/ui/separator.tsx +30 -0
  171. package/lib/__templates__/taro/src/components/ui/sheet.tsx +262 -0
  172. package/lib/__templates__/taro/src/components/ui/skeleton.tsx +17 -0
  173. package/lib/__templates__/taro/src/components/ui/slider.tsx +203 -0
  174. package/lib/__templates__/taro/src/components/ui/sonner.tsx +1 -0
  175. package/lib/__templates__/taro/src/components/ui/switch.tsx +55 -0
  176. package/lib/__templates__/taro/src/components/ui/table.tsx +142 -0
  177. package/lib/__templates__/taro/src/components/ui/tabs.tsx +114 -0
  178. package/lib/__templates__/taro/src/components/ui/textarea.tsx +54 -0
  179. package/lib/__templates__/taro/src/components/ui/toast.tsx +517 -0
  180. package/lib/__templates__/taro/src/components/ui/toggle-group.tsx +120 -0
  181. package/lib/__templates__/taro/src/components/ui/toggle.tsx +77 -0
  182. package/lib/__templates__/taro/src/components/ui/tooltip.tsx +455 -0
  183. package/lib/__templates__/taro/src/index.html +39 -0
  184. package/lib/__templates__/taro/src/lib/hooks/use-keyboard-offset.ts +37 -0
  185. package/lib/__templates__/taro/src/lib/measure.ts +115 -0
  186. package/lib/__templates__/taro/src/lib/platform.ts +12 -0
  187. package/lib/__templates__/taro/src/lib/utils.ts +6 -0
  188. package/lib/__templates__/taro/src/network.ts +39 -0
  189. package/lib/__templates__/taro/src/pages/index/index.config.ts +3 -0
  190. package/lib/__templates__/taro/src/pages/index/index.css +1 -0
  191. package/lib/__templates__/taro/src/pages/index/index.tsx +33 -0
  192. package/lib/__templates__/taro/src/presets/dev-debug.ts +23 -0
  193. package/lib/__templates__/taro/src/presets/h5-container.tsx +15 -0
  194. package/lib/__templates__/taro/src/presets/h5-navbar.tsx +238 -0
  195. package/lib/__templates__/taro/src/presets/h5-styles.ts +220 -0
  196. package/lib/__templates__/taro/src/presets/index.tsx +18 -0
  197. package/lib/__templates__/taro/stylelint.config.mjs +4 -0
  198. package/lib/__templates__/taro/template.config.js +68 -0
  199. package/lib/__templates__/taro/tsconfig.json +29 -0
  200. package/lib/__templates__/taro/types/global.d.ts +32 -0
  201. package/lib/__templates__/templates.json +136 -36
  202. package/lib/__templates__/vite/.coze +4 -3
  203. package/lib/__templates__/vite/README.md +383 -26
  204. package/lib/__templates__/vite/_gitignore +1 -0
  205. package/lib/__templates__/vite/_npmrc +2 -1
  206. package/lib/__templates__/vite/eslint.config.mjs +14 -0
  207. package/lib/__templates__/vite/package.json +23 -3
  208. package/lib/__templates__/vite/pnpm-lock.yaml +2509 -293
  209. package/lib/__templates__/vite/scripts/build.sh +4 -1
  210. package/lib/__templates__/vite/scripts/dev.sh +16 -28
  211. package/lib/__templates__/vite/scripts/prepare.sh +9 -0
  212. package/lib/__templates__/vite/scripts/start.sh +9 -3
  213. package/lib/__templates__/vite/server/routes/index.ts +31 -0
  214. package/lib/__templates__/vite/server/server.ts +65 -0
  215. package/lib/__templates__/vite/server/vite.ts +67 -0
  216. package/lib/__templates__/vite/src/main.ts +17 -48
  217. package/lib/__templates__/vite/template.config.js +77 -7
  218. package/lib/__templates__/vite/tsconfig.json +4 -3
  219. package/lib/__templates__/vite/vite.config.ts +8 -3
  220. package/lib/cli.js +1545 -526
  221. package/package.json +17 -6
  222. package/lib/__templates__/expo/.cozeproj/scripts/deploy_build.sh +0 -109
  223. package/lib/__templates__/expo/.cozeproj/scripts/deploy_run.sh +0 -257
  224. package/lib/__templates__/expo/app.json +0 -63
  225. package/lib/__templates__/expo/babel.config.js +0 -9
  226. package/lib/__templates__/expo/client/app/(tabs)/_layout.tsx +0 -43
  227. package/lib/__templates__/expo/client/app/(tabs)/home.tsx +0 -1
  228. package/lib/__templates__/expo/client/app/(tabs)/index.tsx +0 -7
  229. package/lib/__templates__/expo/client/hooks/useColorScheme.ts +0 -1
  230. package/lib/__templates__/expo/client/index.js +0 -12
  231. package/lib/__templates__/expo/client/screens/home/index.tsx +0 -54
  232. package/lib/__templates__/expo/client/screens/home/styles.ts +0 -332
  233. package/lib/__templates__/expo/metro.config.js +0 -53
  234. package/lib/__templates__/expo/src/index.ts +0 -12
  235. package/lib/__templates__/nextjs/.vscode/settings.json +0 -121
  236. package/lib/__templates__/nextjs/server.mjs +0 -50
  237. package/lib/__templates__/vite/.vscode/settings.json +0 -7
  238. /package/lib/__templates__/expo/{eslint-formatter-simple.mjs → client/eslint-formatter-simple.mjs} +0 -0
@@ -0,0 +1,37 @@
1
+ import * as React from 'react'
2
+ import Taro from '@tarojs/taro'
3
+
4
+ // Global state to track keyboard height across the app
5
+ let globalKeyboardHeight = 0
6
+ const listeners = new Set<(height: number) => void>()
7
+
8
+ const isNotWeb = Taro.getEnv() !== Taro.ENV_TYPE.WEB
9
+
10
+ if (isNotWeb && typeof Taro.onKeyboardHeightChange === 'function') {
11
+ Taro.onKeyboardHeightChange(res => {
12
+ globalKeyboardHeight = res.height
13
+ listeners.forEach(listener => listener(globalKeyboardHeight))
14
+ })
15
+ }
16
+
17
+ export function useKeyboardOffset() {
18
+ const [offset, setOffset] = React.useState(globalKeyboardHeight)
19
+
20
+ React.useEffect(() => {
21
+ if (!isNotWeb) return
22
+
23
+ const handler = (height: number) => {
24
+ setOffset(height)
25
+ }
26
+
27
+ listeners.add(handler)
28
+ // Update immediately with current global value in case it changed
29
+ setOffset(globalKeyboardHeight)
30
+
31
+ return () => {
32
+ listeners.delete(handler)
33
+ }
34
+ }, [])
35
+
36
+ return offset
37
+ }
@@ -0,0 +1,115 @@
1
+ import Taro from '@tarojs/taro'
2
+ import { canUseDOM, isH5 } from './platform'
3
+
4
+ export type Rect = { left: number; top: number; width: number; height: number }
5
+
6
+ const toNumber = (v: unknown) => {
7
+ if (typeof v === 'number') return v
8
+ if (typeof v === 'string') {
9
+ const n = parseFloat(v)
10
+ return Number.isFinite(n) ? n : 0
11
+ }
12
+ return 0
13
+ }
14
+
15
+ const normalizeRect = (r: any): Rect | null => {
16
+ if (!r) return null
17
+ return {
18
+ left: toNumber(r.left),
19
+ top: toNumber(r.top),
20
+ width: toNumber(r.width),
21
+ height: toNumber(r.height),
22
+ }
23
+ }
24
+
25
+ export const getViewport = () => {
26
+ if (isH5() && canUseDOM()) {
27
+ return { width: window.innerWidth, height: window.innerHeight }
28
+ }
29
+ try {
30
+ const info = Taro.getSystemInfoSync()
31
+ return {
32
+ width: toNumber(info.windowWidth),
33
+ height: toNumber(info.windowHeight),
34
+ }
35
+ } catch {
36
+ return { width: 375, height: 667 }
37
+ }
38
+ }
39
+
40
+ const getRectH5 = (id: string): Rect | null => {
41
+ if (!isH5() || !canUseDOM()) return null
42
+ const el = document.getElementById(id)
43
+ if (!el) return null
44
+ const r = el.getBoundingClientRect()
45
+ return normalizeRect(r)
46
+ }
47
+
48
+ export const getRectById = (id: string): Promise<Rect | null> => {
49
+ const h5Rect = getRectH5(id)
50
+ if (h5Rect) return Promise.resolve(h5Rect)
51
+ return new Promise(resolve => {
52
+ const query = Taro.createSelectorQuery()
53
+ query
54
+ .select(`#${id}`)
55
+ .boundingClientRect(res => {
56
+ const rect = Array.isArray(res) ? res[0] : res
57
+ resolve(normalizeRect(rect))
58
+ })
59
+ .exec()
60
+ })
61
+ }
62
+
63
+ export const computePosition = (params: {
64
+ triggerRect: Rect
65
+ contentRect: Rect
66
+ align: 'start' | 'center' | 'end'
67
+ side: 'top' | 'bottom' | 'left' | 'right'
68
+ sideOffset: number
69
+ }) => {
70
+ const { triggerRect, contentRect, align, side, sideOffset } = params
71
+ const { width: vw, height: vh } = getViewport()
72
+ const margin = 8
73
+
74
+ const crossStart =
75
+ side === 'left' || side === 'right' ? triggerRect.top : triggerRect.left
76
+ const crossSize =
77
+ side === 'left' || side === 'right'
78
+ ? triggerRect.height
79
+ : triggerRect.width
80
+ const contentCrossSize =
81
+ side === 'left' || side === 'right'
82
+ ? contentRect.height
83
+ : contentRect.width
84
+
85
+ const cross = (() => {
86
+ if (align === 'start') return crossStart
87
+ if (align === 'end') return crossStart + crossSize - contentCrossSize
88
+ return crossStart + crossSize / 2 - contentCrossSize / 2
89
+ })()
90
+
91
+ let left = 0
92
+ let top = 0
93
+
94
+ if (side === 'bottom' || side === 'top') {
95
+ left = cross
96
+ top =
97
+ side === 'bottom'
98
+ ? triggerRect.top + triggerRect.height + sideOffset
99
+ : triggerRect.top - contentRect.height - sideOffset
100
+ } else {
101
+ top = cross
102
+ left =
103
+ side === 'right'
104
+ ? triggerRect.left + triggerRect.width + sideOffset
105
+ : triggerRect.left - contentRect.width - sideOffset
106
+ }
107
+
108
+ const maxLeft = Math.max(margin, vw - contentRect.width - margin)
109
+ const maxTop = Math.max(margin, vh - contentRect.height - margin)
110
+
111
+ left = Math.min(Math.max(left, margin), maxLeft)
112
+ top = Math.min(Math.max(top, margin), maxTop)
113
+
114
+ return { left, top }
115
+ }
@@ -0,0 +1,12 @@
1
+ import Taro from "@tarojs/taro"
2
+
3
+ export const canUseDOM = () => typeof window !== "undefined" && typeof document !== "undefined"
4
+
5
+ export const isH5 = () => {
6
+ try {
7
+ return Taro.getEnv() === Taro.ENV_TYPE.WEB
8
+ } catch {
9
+ return canUseDOM()
10
+ }
11
+ }
12
+
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,39 @@
1
+ import Taro from '@tarojs/taro'
2
+
3
+ /**
4
+ * 网络请求模块
5
+ * 封装 Taro.request、Taro.uploadFile、Taro.downloadFile,自动添加项目域名前缀
6
+ * 如果请求的 url 以 http:// 或 https:// 开头,则不会添加域名前缀
7
+ *
8
+ * IMPORTANT: 项目已经全局注入 PROJECT_DOMAIN
9
+ * IMPORTANT: 除非你需要添加全局参数,如给所有请求加上 header,否则不能修改此文件
10
+ */
11
+ export namespace Network {
12
+ const createUrl = (url: string): string => {
13
+ if (url.startsWith('http://') || url.startsWith('https://')) {
14
+ return url
15
+ }
16
+ return `${PROJECT_DOMAIN}${url}`
17
+ }
18
+
19
+ export const request: typeof Taro.request = option => {
20
+ return Taro.request({
21
+ ...option,
22
+ url: createUrl(option.url),
23
+ })
24
+ }
25
+
26
+ export const uploadFile: typeof Taro.uploadFile = option => {
27
+ return Taro.uploadFile({
28
+ ...option,
29
+ url: createUrl(option.url),
30
+ })
31
+ }
32
+
33
+ export const downloadFile: typeof Taro.downloadFile = option => {
34
+ return Taro.downloadFile({
35
+ ...option,
36
+ url: createUrl(option.url),
37
+ })
38
+ }
39
+ }
@@ -0,0 +1,3 @@
1
+ export default definePageConfig({
2
+ navigationBarTitleText: '首页'
3
+ })
@@ -0,0 +1 @@
1
+ /* 优先使用 tailwindcss,如无必要请不要使用css */
@@ -0,0 +1,33 @@
1
+ import { View, Text, Image } from '@tarojs/components';
2
+ import { useLoad } from '@tarojs/taro';
3
+ import { Network } from '@/network';
4
+ import './index.css';
5
+
6
+ /**
7
+ * 默认首页,直接覆盖本页内容
8
+ */
9
+ const IndexPage = () => {
10
+ useLoad(async () => {
11
+ const res = await Network.request({ url: '/api/hello' });
12
+ console.log(res.data);
13
+ });
14
+
15
+ return (
16
+ <View className="w-full h-full flex flex-col justify-center items-center gap-1">
17
+ <Image
18
+ className="w-32 h-28"
19
+ src="https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze-coding/icon/coze-coding.gif"
20
+ />
21
+ <View className="self-stretch flex flex-col justify-start items-start gap-2">
22
+ <Text className="self-stretch text-center justify-start text-base-accent-foreground text-base font-bold">
23
+ 应用开发中
24
+ </Text>
25
+ <Text className="self-stretch text-center justify-start text-base-muted-foreground text-sm font-normal">
26
+ 请稍候,界面即将呈现
27
+ </Text>
28
+ </View>
29
+ </View>
30
+ );
31
+ };
32
+
33
+ export default IndexPage;
@@ -0,0 +1,23 @@
1
+ import Taro from '@tarojs/taro';
2
+
3
+ /**
4
+ * 小程序调试工具
5
+ * 在开发版/体验版自动开启调试模式
6
+ * 支持微信小程序和抖音小程序
7
+ */
8
+ export function devDebug() {
9
+ const env = Taro.getEnv();
10
+ if (env === Taro.ENV_TYPE.WEAPP || env === Taro.ENV_TYPE.TT) {
11
+ try {
12
+ const accountInfo = Taro.getAccountInfoSync();
13
+ const envVersion = accountInfo.miniProgram.envVersion;
14
+ console.log('[Debug] envVersion:', envVersion);
15
+
16
+ if (envVersion !== 'release') {
17
+ Taro.setEnableDebug({ enableDebug: true });
18
+ }
19
+ } catch (error) {
20
+ console.error('[Debug] 开启调试模式失败:', error);
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,15 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { H5NavBar } from './h5-navbar';
3
+
4
+ export const H5Container = ({ children }: PropsWithChildren) => {
5
+ if (TARO_ENV !== 'h5') {
6
+ return <>{children}</>;
7
+ }
8
+
9
+ return (
10
+ <>
11
+ <H5NavBar />
12
+ {children}
13
+ </>
14
+ );
15
+ };
@@ -0,0 +1,238 @@
1
+ import { View, Text } from '@tarojs/components';
2
+ import Taro, { useDidShow, usePageScroll } from '@tarojs/taro';
3
+ import { useState, useEffect, useCallback } from 'react';
4
+ import { ChevronLeft, House } from 'lucide-react-taro';
5
+
6
+ interface NavConfig {
7
+ navigationBarTitleText?: string;
8
+ navigationBarBackgroundColor?: string;
9
+ navigationBarTextStyle?: 'black' | 'white';
10
+ navigationStyle?: 'default' | 'custom';
11
+ transparentTitle?: 'none' | 'always' | 'auto';
12
+ }
13
+
14
+ enum LeftIcon {
15
+ Back = 'back',
16
+ Home = 'home',
17
+ None = 'none',
18
+ }
19
+
20
+ interface NavState {
21
+ visible: boolean;
22
+ title: string;
23
+ bgColor: string;
24
+ textStyle: 'black' | 'white';
25
+ navStyle: 'default' | 'custom';
26
+ transparent: 'none' | 'always' | 'auto';
27
+ leftIcon: LeftIcon;
28
+ }
29
+
30
+ const DEFAULT_NAV_STATE: NavState = {
31
+ visible: false,
32
+ title: '',
33
+ bgColor: '#ffffff',
34
+ textStyle: 'black',
35
+ navStyle: 'default',
36
+ transparent: 'none',
37
+ leftIcon: LeftIcon.None,
38
+ };
39
+
40
+ const getGlobalWindowConfig = (): Partial<NavConfig> => {
41
+ const app = Taro.getApp();
42
+ return app?.config?.window || {};
43
+ };
44
+
45
+ const getTabBarPages = (): Set<string> => {
46
+ const tabBar = Taro.getApp()?.config?.tabBar;
47
+ return new Set(
48
+ tabBar?.list?.map((item: { pagePath: string }) => item.pagePath) || [],
49
+ );
50
+ };
51
+
52
+ const getHomePage = (): string => {
53
+ const app = Taro.getApp();
54
+ return app?.config?.pages?.[0] || 'pages/index/index';
55
+ };
56
+
57
+ const cleanPath = (path: string): string => path.replace(/^\//, '');
58
+
59
+ const computeLeftIcon = (
60
+ route: string,
61
+ tabBarPages: Set<string>,
62
+ historyLength: number,
63
+ homePage: string,
64
+ ): LeftIcon => {
65
+ if (!route) return LeftIcon.None;
66
+
67
+ const cleanRoute = cleanPath(route);
68
+ const cleanHomePage = cleanPath(homePage);
69
+ const isHomePage = cleanRoute === cleanHomePage;
70
+ const isTabBarPage =
71
+ tabBarPages.has(cleanRoute) || tabBarPages.has(`/${cleanRoute}`);
72
+ const hasHistory = historyLength > 1;
73
+
74
+ if (isTabBarPage || isHomePage) return LeftIcon.None;
75
+ if (hasHistory) return LeftIcon.Back;
76
+ return LeftIcon.Home;
77
+ };
78
+
79
+ export const H5NavBar = () => {
80
+ const [navState, setNavState] = useState<NavState>(DEFAULT_NAV_STATE);
81
+ const [scrollOpacity, setScrollOpacity] = useState(0);
82
+
83
+ const updateNavState = useCallback(() => {
84
+ const pages = Taro.getCurrentPages();
85
+ if (pages.length === 0) {
86
+ setNavState(prev => ({ ...prev, visible: false }));
87
+ return;
88
+ }
89
+
90
+ const currentPage = pages[pages.length - 1];
91
+ const route = currentPage?.route || '';
92
+ if (!route) return;
93
+
94
+ const pageConfig: NavConfig = (currentPage as any)?.config || {};
95
+ const globalConfig = getGlobalWindowConfig();
96
+ const tabBarPages = getTabBarPages();
97
+ const homePage = getHomePage();
98
+
99
+ const cleanRoute = cleanPath(route);
100
+ const cleanHomePage = cleanPath(homePage);
101
+
102
+ const isHomePage = cleanRoute === cleanHomePage;
103
+ const isTabBarPage =
104
+ tabBarPages.has(cleanRoute) || tabBarPages.has(`/${cleanRoute}`);
105
+
106
+ const shouldHideNav =
107
+ tabBarPages.size <= 1 &&
108
+ pages.length <= 1 &&
109
+ (isHomePage || isTabBarPage);
110
+
111
+ setNavState({
112
+ visible: !shouldHideNav,
113
+ title:
114
+ document.title ||
115
+ pageConfig.navigationBarTitleText ||
116
+ globalConfig.navigationBarTitleText ||
117
+ '',
118
+ bgColor:
119
+ pageConfig.navigationBarBackgroundColor ||
120
+ globalConfig.navigationBarBackgroundColor ||
121
+ '#ffffff',
122
+ textStyle:
123
+ pageConfig.navigationBarTextStyle ||
124
+ globalConfig.navigationBarTextStyle ||
125
+ 'black',
126
+ navStyle:
127
+ pageConfig.navigationStyle || globalConfig.navigationStyle || 'default',
128
+ transparent:
129
+ pageConfig.transparentTitle || globalConfig.transparentTitle || 'none',
130
+ leftIcon: shouldHideNav
131
+ ? LeftIcon.None
132
+ : computeLeftIcon(cleanRoute, tabBarPages, pages.length, cleanHomePage),
133
+ });
134
+ }, []);
135
+
136
+ useDidShow(() => {
137
+ updateNavState();
138
+ });
139
+
140
+ usePageScroll(({ scrollTop }) => {
141
+ if (navState.transparent === 'auto') {
142
+ setScrollOpacity(Math.min(scrollTop / 100, 1));
143
+ }
144
+ });
145
+
146
+ useEffect(() => {
147
+ if (TARO_ENV !== 'h5') return;
148
+
149
+ let timer: NodeJS.Timeout | null = null;
150
+ const observer = new MutationObserver(() => {
151
+ if (timer) clearTimeout(timer);
152
+ timer = setTimeout(() => {
153
+ updateNavState();
154
+ }, 50);
155
+ });
156
+
157
+ observer.observe(document.head, {
158
+ subtree: true,
159
+ childList: true,
160
+ characterData: true,
161
+ });
162
+
163
+ updateNavState();
164
+
165
+ return () => {
166
+ observer.disconnect();
167
+ if (timer) clearTimeout(timer);
168
+ };
169
+ }, [updateNavState]);
170
+
171
+ const shouldRender =
172
+ TARO_ENV === 'h5' && navState.visible && navState.navStyle !== 'custom';
173
+
174
+ useEffect(() => {
175
+ if (TARO_ENV !== 'h5') return;
176
+ if (shouldRender) {
177
+ document.body.classList.add('h5-navbar-visible');
178
+ } else {
179
+ document.body.classList.remove('h5-navbar-visible');
180
+ }
181
+ }, [shouldRender]);
182
+
183
+ if (!shouldRender) {
184
+ return <></>;
185
+ }
186
+
187
+ const iconColor = navState.textStyle === 'white' ? '#fff' : '#333';
188
+ const textColorClass =
189
+ navState.textStyle === 'white' ? 'text-white' : 'text-gray-800';
190
+
191
+ const getBgStyle = () => {
192
+ if (navState.transparent === 'always') {
193
+ return { backgroundColor: 'transparent' };
194
+ }
195
+ if (navState.transparent === 'auto') {
196
+ return { backgroundColor: navState.bgColor, opacity: scrollOpacity };
197
+ }
198
+ return { backgroundColor: navState.bgColor };
199
+ };
200
+
201
+ const handleBack = () => Taro.navigateBack();
202
+ const handleGoHome = () => {
203
+ const homePage = getHomePage();
204
+ Taro.reLaunch({ url: `/${homePage}` });
205
+ };
206
+
207
+ return (
208
+ <>
209
+ <View
210
+ className="fixed top-0 left-0 right-0 h-11 flex items-center justify-center z-1000"
211
+ style={getBgStyle()}
212
+ >
213
+ {navState.leftIcon === LeftIcon.Back && (
214
+ <View
215
+ className="absolute left-2 top-1/2 -translate-y-1/2 p-1 flex items-center justify-center"
216
+ onClick={handleBack}
217
+ >
218
+ <ChevronLeft size={24} color={iconColor} />
219
+ </View>
220
+ )}
221
+ {navState.leftIcon === LeftIcon.Home && (
222
+ <View
223
+ className="absolute left-2 top-1/2 -translate-y-1/2 p-1 flex items-center justify-center"
224
+ onClick={handleGoHome}
225
+ >
226
+ <House size={22} color={iconColor} />
227
+ </View>
228
+ )}
229
+ <Text
230
+ className={`text-base font-medium max-w-3/5 truncate ${textColorClass}`}
231
+ >
232
+ {navState.title}
233
+ </Text>
234
+ </View>
235
+ <View className="h-11 shrink-0" />
236
+ </>
237
+ );
238
+ };