@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,228 @@
1
+ import * as React from "react"
2
+ import { View, Swiper, SwiperItem } from "@tarojs/components"
3
+ import { ArrowLeft, ArrowRight } from "lucide-react-taro"
4
+ import { cn } from "@/lib/utils"
5
+ import { Button } from "@/components/ui/button"
6
+
7
+ type CarouselProps = {
8
+ opts?: {
9
+ loop?: boolean
10
+ autoplay?: boolean
11
+ interval?: number
12
+ duration?: number
13
+ displayMultipleItems?: number
14
+ }
15
+ orientation?: "horizontal" | "vertical"
16
+ setApi?: (api: CarouselApi) => void
17
+ className?: string
18
+ children?: React.ReactNode
19
+ }
20
+
21
+ export type CarouselApi = {
22
+ scrollPrev: () => void
23
+ scrollNext: () => void
24
+ canScrollPrev: boolean
25
+ canScrollNext: boolean
26
+ scrollTo: (index: number) => void
27
+ selectedScrollSnap: () => number
28
+ }
29
+
30
+ type CarouselContextProps = {
31
+ orientation: "horizontal" | "vertical"
32
+ current: number
33
+ setCurrent: (index: number) => void
34
+ count: number
35
+ setCount: (count: number) => void
36
+ scrollPrev: () => void
37
+ scrollNext: () => void
38
+ canScrollPrev: boolean
39
+ canScrollNext: boolean
40
+ opts?: CarouselProps["opts"]
41
+ }
42
+
43
+ const CarouselContext = React.createContext<CarouselContextProps | null>(null)
44
+
45
+ function useCarousel() {
46
+ const context = React.useContext(CarouselContext)
47
+ if (!context) {
48
+ throw new Error("useCarousel must be used within a <Carousel />")
49
+ }
50
+ return context
51
+ }
52
+
53
+ const Carousel = React.forwardRef<
54
+ React.ElementRef<typeof View>,
55
+ CarouselProps
56
+ >(({ opts, orientation = "horizontal", setApi, className, children, ...props }, ref) => {
57
+ const [current, setCurrent] = React.useState(0)
58
+ const [count, setCount] = React.useState(0)
59
+
60
+ const scrollPrev = React.useCallback(() => {
61
+ setCurrent((prev) => Math.max(0, prev - 1))
62
+ }, [])
63
+
64
+ const scrollNext = React.useCallback(() => {
65
+ setCurrent((prev) => Math.min(count - 1, prev + 1))
66
+ }, [count])
67
+
68
+ const canScrollPrev = current > 0
69
+ const canScrollNext = current < count - 1
70
+
71
+ const scrollTo = React.useCallback((index: number) => {
72
+ setCurrent(index)
73
+ }, [])
74
+
75
+ const selectedScrollSnap = React.useCallback(() => current, [current])
76
+
77
+ React.useEffect(() => {
78
+ if (setApi) {
79
+ setApi({
80
+ scrollPrev,
81
+ scrollNext,
82
+ canScrollPrev,
83
+ canScrollNext,
84
+ scrollTo,
85
+ selectedScrollSnap,
86
+ })
87
+ }
88
+ }, [setApi, scrollPrev, scrollNext, canScrollPrev, canScrollNext, scrollTo, selectedScrollSnap])
89
+
90
+ return (
91
+ <CarouselContext.Provider
92
+ value={{
93
+ orientation,
94
+ current,
95
+ setCurrent,
96
+ count,
97
+ setCount,
98
+ scrollPrev,
99
+ scrollNext,
100
+ canScrollPrev,
101
+ canScrollNext,
102
+ opts,
103
+ }}
104
+ >
105
+ <View
106
+ ref={ref}
107
+ className={cn("relative w-full", className)}
108
+ {...props}
109
+ >
110
+ {children}
111
+ </View>
112
+ </CarouselContext.Provider>
113
+ )
114
+ })
115
+ Carousel.displayName = "Carousel"
116
+
117
+ const CarouselContent = React.forwardRef<
118
+ React.ElementRef<typeof Swiper>,
119
+ React.ComponentPropsWithoutRef<typeof Swiper>
120
+ >(({ className, children, ...props }, ref) => {
121
+ const { orientation, current, setCurrent, setCount, opts } = useCarousel()
122
+
123
+ React.useEffect(() => {
124
+ const childCount = React.Children.count(children)
125
+ setCount(childCount)
126
+ }, [children, setCount])
127
+
128
+ return (
129
+ <View className={cn("overflow-hidden", className)}>
130
+ <Swiper
131
+ ref={ref}
132
+ className="h-full w-full"
133
+ vertical={orientation === "vertical"}
134
+ current={current}
135
+ onChange={(e) => setCurrent(e.detail.current)}
136
+ circular={opts?.loop}
137
+ autoplay={opts?.autoplay}
138
+ interval={opts?.interval || 5000}
139
+ duration={opts?.duration || 500}
140
+ displayMultipleItems={opts?.displayMultipleItems || 1}
141
+ {...props}
142
+ >
143
+ {React.Children.map(children, (child) => {
144
+ if (React.isValidElement(child)) {
145
+ return <SwiperItem className="h-full w-full">{child}</SwiperItem>
146
+ }
147
+ return null
148
+ })}
149
+ </Swiper>
150
+ </View>
151
+ )
152
+ })
153
+ CarouselContent.displayName = "CarouselContent"
154
+
155
+ const CarouselItem = ({ className, children, ...props }: React.ComponentProps<typeof View>) => {
156
+ return (
157
+ <View className={cn("h-full w-full", className)} {...props}>
158
+ {children}
159
+ </View>
160
+ )
161
+ }
162
+ CarouselItem.displayName = "CarouselItem"
163
+
164
+ const CarouselPrevious = React.forwardRef<
165
+ React.ElementRef<typeof Button>,
166
+ React.ComponentProps<typeof Button>
167
+ >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
168
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel()
169
+
170
+ return (
171
+ <Button
172
+ ref={ref}
173
+ variant={variant}
174
+ size={size}
175
+ className={cn(
176
+ "absolute h-8 w-8 rounded-full z-10 bg-background bg-opacity-80 backdrop-blur-sm",
177
+ orientation === "horizontal"
178
+ ? "-left-12 top-1/2 -translate-y-1/2"
179
+ : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
180
+ className
181
+ )}
182
+ disabled={!canScrollPrev}
183
+ onClick={scrollPrev}
184
+ {...props}
185
+ >
186
+ <ArrowLeft size={16} />
187
+ <View className="sr-only">Previous slide</View>
188
+ </Button>
189
+ )
190
+ })
191
+ CarouselPrevious.displayName = "CarouselPrevious"
192
+
193
+ const CarouselNext = React.forwardRef<
194
+ React.ElementRef<typeof Button>,
195
+ React.ComponentProps<typeof Button>
196
+ >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
197
+ const { orientation, scrollNext, canScrollNext } = useCarousel()
198
+
199
+ return (
200
+ <Button
201
+ ref={ref}
202
+ variant={variant}
203
+ size={size}
204
+ className={cn(
205
+ "absolute h-8 w-8 rounded-full z-10 bg-background bg-opacity-80 backdrop-blur-sm",
206
+ orientation === "horizontal"
207
+ ? "-right-12 top-1/2 -translate-y-1/2"
208
+ : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
209
+ className
210
+ )}
211
+ disabled={!canScrollNext}
212
+ onClick={scrollNext}
213
+ {...props}
214
+ >
215
+ <ArrowRight size={16} />
216
+ <View className="sr-only">Next slide</View>
217
+ </Button>
218
+ )
219
+ })
220
+ CarouselNext.displayName = "CarouselNext"
221
+
222
+ export {
223
+ Carousel,
224
+ CarouselContent,
225
+ CarouselItem,
226
+ CarouselPrevious,
227
+ CarouselNext,
228
+ }
@@ -0,0 +1,58 @@
1
+ import * as React from "react"
2
+ import { View } from "@tarojs/components"
3
+ import { Check } from "lucide-react-taro"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Checkbox = React.forwardRef<
8
+ React.ElementRef<typeof View>,
9
+ Omit<React.ComponentPropsWithoutRef<typeof View>, "onClick"> & {
10
+ checked?: boolean
11
+ defaultChecked?: boolean
12
+ onCheckedChange?: (checked: boolean) => void
13
+ disabled?: boolean
14
+ }
15
+ >(({ className, checked: checkedProp, defaultChecked, onCheckedChange, disabled, ...props }, ref) => {
16
+ const [checkedState, setCheckedState] = React.useState<boolean>(
17
+ defaultChecked ?? false
18
+ )
19
+
20
+ const isControlled = checkedProp !== undefined
21
+ const checked = isControlled ? checkedProp : checkedState
22
+
23
+ const handleClick = (e) => {
24
+ if (disabled) return
25
+ e.stopPropagation()
26
+ const newChecked = !checked
27
+ if (!isControlled) {
28
+ setCheckedState(newChecked)
29
+ }
30
+ onCheckedChange?.(newChecked)
31
+ }
32
+
33
+ const tabIndex = (props as any).tabIndex ?? (disabled ? -1 : 0)
34
+
35
+ return (
36
+ <View
37
+ ref={ref}
38
+ className={cn(
39
+ "h-4 w-4 shrink-0 rounded-sm border-2 border-primary ring-offset-background flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
40
+ checked ? "bg-primary text-primary-foreground" : "bg-transparent",
41
+ className
42
+ )}
43
+ {...({ tabIndex } as any)}
44
+ hoverClass={
45
+ disabled
46
+ ? undefined
47
+ : "border-ring ring-2 ring-ring ring-offset-2 ring-offset-background"
48
+ }
49
+ onClick={handleClick}
50
+ {...props}
51
+ >
52
+ {checked && <Check color="#fff" size={12} strokeWidth={3} className="text-current" />}
53
+ </View>
54
+ )
55
+ })
56
+ Checkbox.displayName = "Checkbox"
57
+
58
+ export { Checkbox }
@@ -0,0 +1,169 @@
1
+ import { View, Text } from '@tarojs/components'
2
+ import { useMemo } from 'react'
3
+ import { Copy } from 'lucide-react-taro'
4
+ import { Button } from '@/components/ui/button'
5
+ import { ScrollArea } from '@/components/ui/scroll-area'
6
+ import { cn } from '@/lib/utils'
7
+ import Taro from '@tarojs/taro'
8
+ import type { FC } from 'react'
9
+
10
+ type TokenType =
11
+ | 'keyword'
12
+ | 'string'
13
+ | 'comment'
14
+ | 'number'
15
+ | 'function'
16
+ | 'tag'
17
+ | 'attr'
18
+ | 'operator'
19
+ | 'plain'
20
+
21
+ interface Token {
22
+ type: TokenType
23
+ content: string
24
+ }
25
+
26
+ const RULES: { type: TokenType; regex: RegExp }[] = (
27
+ [
28
+ { type: 'comment', regex: /\/\/.*/ },
29
+ { type: 'comment', regex: /\/\*[\s\S]*?\*\// },
30
+ {
31
+ type: 'string',
32
+ regex: /"(?:\\.|[^\\"])*"|'(?:\\.|[^\\'])*'|`(?:\\.|[^\\`])*`/,
33
+ },
34
+ {
35
+ type: 'keyword',
36
+ regex: /\b(?:import|from|export|default|const|let|var|function|return|if|else|switch|case|break|continue|for|while|do|try|catch|finally|throw|new|this|super|class|extends|implements|interface|type|enum|namespace|as|async|await|yield|void|delete|typeof|instanceof|in|of|null|undefined|true|false)\b/,
37
+ },
38
+ { type: 'number', regex: /\b\d+(\.\d+)?\b/ },
39
+ { type: 'tag', regex: /<\/?[a-zA-Z][a-zA-Z0-9]*\b/ },
40
+ { type: 'attr', regex: /\b[a-z][a-z0-9]*(?==)/i },
41
+ { type: 'function', regex: /\b[a-zA-Z_$][a-zA-Z0-9_$]*(?=\s*\()/ },
42
+ { type: 'operator', regex: /[+\-*/%=<>!&|^~]/ },
43
+ ] as { type: TokenType; regex: RegExp }[]
44
+ ).map(rule => ({
45
+ ...rule,
46
+ regex: new RegExp(rule.regex.source, (rule.regex.flags || '') + 'y'),
47
+ }))
48
+
49
+ function tokenize(code: string): Token[] {
50
+ const tokens: Token[] = []
51
+ let lastIndex = 0
52
+
53
+ while (lastIndex < code.length) {
54
+ let matchFound = false
55
+
56
+ for (const rule of RULES) {
57
+ rule.regex.lastIndex = lastIndex
58
+ const match = rule.regex.exec(code)
59
+ if (match) {
60
+ tokens.push({ type: rule.type, content: match[0] })
61
+ lastIndex += match[0].length
62
+ matchFound = true
63
+ break
64
+ }
65
+ }
66
+
67
+ if (!matchFound) {
68
+ let plainContent = code[lastIndex]
69
+ lastIndex++
70
+
71
+ // Look ahead for next match to group plain text
72
+ while (lastIndex < code.length) {
73
+ let nextMatch = false
74
+ for (const rule of RULES) {
75
+ rule.regex.lastIndex = lastIndex
76
+ const match = rule.regex.exec(code)
77
+ if (match) {
78
+ nextMatch = true
79
+ break
80
+ }
81
+ }
82
+ if (nextMatch) break
83
+ plainContent += code[lastIndex]
84
+ lastIndex++
85
+ }
86
+ tokens.push({ type: 'plain', content: plainContent })
87
+ }
88
+ }
89
+
90
+ return tokens
91
+ }
92
+
93
+ interface CodeBlockProps {
94
+ code: string
95
+ className?: string
96
+ style?: React.CSSProperties
97
+ scrollAreaClassName?: string
98
+ showCopyButton?: boolean
99
+ language?: string
100
+ }
101
+
102
+ const getTokenColor = (type: TokenType) => {
103
+ switch (type) {
104
+ case 'keyword': return '#D73A49' // red
105
+ case 'string': return '#032F62' // dark blue
106
+ case 'comment': return '#6A737D' // gray
107
+ case 'number': return '#005CC5' // blue
108
+ case 'function': return '#6F42C1' // purple
109
+ case 'tag': return '#005CC5' // blue
110
+ case 'attr': return '#6F42C1' // purple
111
+ case 'operator': return '#D73A49' // red
112
+ default: return '#24292E'
113
+ }
114
+ }
115
+
116
+ const CodeBlock: FC<CodeBlockProps> = ({
117
+ code,
118
+ className,
119
+ style,
120
+ scrollAreaClassName,
121
+ showCopyButton = true,
122
+ language
123
+ }) => {
124
+ const tokens = useMemo(() => tokenize(code), [code])
125
+
126
+ const copyCode = async () => {
127
+ await Taro.setClipboardData({ data: code })
128
+ Taro.showToast({ title: '已复制', icon: 'success' })
129
+ }
130
+
131
+ return (
132
+ <View className={cn("relative w-full overflow-hidden", className)} style={style}>
133
+ <ScrollArea
134
+ orientation="both"
135
+ className={cn("bg-code rounded-lg w-full", scrollAreaClassName)}
136
+ >
137
+ <View className="p-4 inline-block box-border min-w-full">
138
+ {language && (
139
+ <Text className="absolute top-2 left-2 text-xs text-muted-foreground uppercase font-mono pointer-events-none">
140
+ {language}
141
+ </Text>
142
+ )}
143
+ <Text className="text-xs font-mono whitespace-pre">
144
+ {tokens.map((token, i) => (
145
+ <Text
146
+ key={i}
147
+ style={{ color: getTokenColor(token.type) }}
148
+ >
149
+ {token.content}
150
+ </Text>
151
+ ))}
152
+ </Text>
153
+ </View>
154
+ </ScrollArea>
155
+ {showCopyButton && (
156
+ <Button
157
+ variant="ghost"
158
+ size="icon"
159
+ className="absolute top-1 right-1 h-6 w-6"
160
+ onClick={copyCode}
161
+ >
162
+ <Copy size={12} color="#a3a3a3" />
163
+ </Button>
164
+ )}
165
+ </View>
166
+ )
167
+ }
168
+
169
+ export { CodeBlock }
@@ -0,0 +1,71 @@
1
+ import * as React from "react"
2
+ import { View } from "@tarojs/components"
3
+
4
+ const CollapsibleContext = React.createContext<{
5
+ open: boolean
6
+ onOpenChange: (open: boolean) => void
7
+ } | null>(null)
8
+
9
+ const Collapsible = React.forwardRef<
10
+ React.ElementRef<typeof View>,
11
+ React.ComponentPropsWithoutRef<typeof View> & {
12
+ open?: boolean
13
+ defaultOpen?: boolean
14
+ onOpenChange?: (open: boolean) => void
15
+ disabled?: boolean
16
+ }
17
+ >(({ open: openProp, defaultOpen, onOpenChange, disabled, ...props }, ref) => {
18
+ const [openState, setOpenState] = React.useState(defaultOpen || false)
19
+ const open = openProp !== undefined ? openProp : openState
20
+
21
+ const handleOpenChange = (newOpen: boolean) => {
22
+ if (disabled) return
23
+ if (openProp === undefined) {
24
+ setOpenState(newOpen)
25
+ }
26
+ onOpenChange?.(newOpen)
27
+ }
28
+
29
+ return (
30
+ <CollapsibleContext.Provider value={{ open, onOpenChange: handleOpenChange }}>
31
+ <View ref={ref} {...props} />
32
+ </CollapsibleContext.Provider>
33
+ )
34
+ })
35
+ Collapsible.displayName = "Collapsible"
36
+
37
+ const CollapsibleTrigger = React.forwardRef<
38
+ React.ElementRef<typeof View>,
39
+ React.ComponentPropsWithoutRef<typeof View> & {
40
+ asChild?: boolean
41
+ }
42
+ >(({ className, onClick, asChild, ...props }, ref) => {
43
+ const context = React.useContext(CollapsibleContext)
44
+
45
+ return (
46
+ <View
47
+ ref={ref}
48
+ className={className}
49
+ onClick={(e: any) => {
50
+ context?.onOpenChange(!context.open)
51
+ onClick?.(e)
52
+ }}
53
+ {...(props as any)}
54
+ />
55
+ )
56
+ })
57
+ CollapsibleTrigger.displayName = "CollapsibleTrigger"
58
+
59
+ const CollapsibleContent = React.forwardRef<
60
+ React.ElementRef<typeof View>,
61
+ React.ComponentPropsWithoutRef<typeof View>
62
+ >(({ className, ...props }, ref) => {
63
+ const context = React.useContext(CollapsibleContext)
64
+
65
+ if (!context?.open) return null
66
+
67
+ return <View ref={ref} className={className} {...props} />
68
+ })
69
+ CollapsibleContent.displayName = "CollapsibleContent"
70
+
71
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }