@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,120 @@
1
+ import * as React from "react"
2
+ import { View } from "@tarojs/components"
3
+ import { type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "@/lib/utils"
6
+ import { toggleVariants } from "@/components/ui/toggle"
7
+
8
+ const ToggleGroupContext = React.createContext<
9
+ VariantProps<typeof toggleVariants> & {
10
+ value?: string | string[]
11
+ onValueChange?: (value: string) => void
12
+ type: "single" | "multiple"
13
+ }
14
+ >({
15
+ size: "default",
16
+ variant: "default",
17
+ type: "single"
18
+ })
19
+
20
+ const ToggleGroup = React.forwardRef<
21
+ React.ElementRef<typeof View>,
22
+ React.ComponentPropsWithoutRef<typeof View> &
23
+ VariantProps<typeof toggleVariants> & {
24
+ type?: "single" | "multiple"
25
+ value?: string | string[]
26
+ defaultValue?: string | string[]
27
+ onValueChange?: (value: string | string[]) => void
28
+ }
29
+ >(({ className, variant, size, children, type = "single", value: valueProp, defaultValue, onValueChange, ...props }, ref) => {
30
+ const [valueState, setValueState] = React.useState<string | string[]>(
31
+ defaultValue || (type === "multiple" ? [] : "")
32
+ )
33
+ const value = valueProp !== undefined ? valueProp : valueState
34
+
35
+ const handleValueChange = (itemValue: string) => {
36
+ let newValue: string | string[]
37
+ if (type === "multiple") {
38
+ const current = Array.isArray(value) ? value : []
39
+ if (current.includes(itemValue)) {
40
+ newValue = current.filter(v => v !== itemValue)
41
+ } else {
42
+ newValue = [...current, itemValue]
43
+ }
44
+ } else {
45
+ // In Radix ToggleGroup "single", clicking active item deselects it?
46
+ // Actually yes, unless `rovingFocus` logic etc.
47
+ // But usually it behaves like radio if required=true.
48
+ // Radix primitive has `rovingFocus` and `loop`.
49
+ // We'll implement simple toggle logic.
50
+ if (value === itemValue) {
51
+ newValue = "" // Deselect
52
+ } else {
53
+ newValue = itemValue
54
+ }
55
+ }
56
+
57
+ if (valueProp === undefined) {
58
+ setValueState(newValue)
59
+ }
60
+ onValueChange?.(newValue)
61
+ }
62
+
63
+ return (
64
+ <View
65
+ ref={ref}
66
+ className={cn("flex items-center justify-center gap-1", className)}
67
+ {...props}
68
+ >
69
+ <ToggleGroupContext.Provider value={{ variant, size, value, onValueChange: handleValueChange, type }}>
70
+ {children}
71
+ </ToggleGroupContext.Provider>
72
+ </View>
73
+ )
74
+ })
75
+
76
+ ToggleGroup.displayName = "ToggleGroup"
77
+
78
+ const ToggleGroupItem = React.forwardRef<
79
+ React.ElementRef<typeof View>,
80
+ React.ComponentPropsWithoutRef<typeof View> &
81
+ VariantProps<typeof toggleVariants> & {
82
+ value: string
83
+ disabled?: boolean
84
+ }
85
+ >(({ className, children, variant, size, value, disabled, ...props }, ref) => {
86
+ const context = React.useContext(ToggleGroupContext)
87
+
88
+ const checked = context.type === "multiple"
89
+ ? Array.isArray(context.value) && context.value.includes(value)
90
+ : context.value === value
91
+
92
+ return (
93
+ <View
94
+ ref={ref}
95
+ className={cn(
96
+ toggleVariants({
97
+ variant: context.variant || variant,
98
+ size: context.size || size,
99
+ }),
100
+ className,
101
+ checked && "bg-accent text-accent-foreground",
102
+ disabled && "opacity-50 pointer-events-none"
103
+ )}
104
+ data-state={checked ? "on" : "off"}
105
+ data-disabled={disabled ? "" : undefined}
106
+ onClick={(e) => {
107
+ if (disabled) return
108
+ context.onValueChange?.(value)
109
+ props.onClick?.(e)
110
+ }}
111
+ {...props}
112
+ >
113
+ {children}
114
+ </View>
115
+ )
116
+ })
117
+
118
+ ToggleGroupItem.displayName = "ToggleGroupItem"
119
+
120
+ export { ToggleGroup, ToggleGroupItem }
@@ -0,0 +1,77 @@
1
+ import * as React from "react"
2
+ import { View } from "@tarojs/components"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const toggleVariants = cva(
8
+ "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-transparent",
13
+ outline:
14
+ "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
15
+ },
16
+ size: {
17
+ default: "h-10 px-3 min-w-10",
18
+ sm: "h-9 px-3 min-w-9",
19
+ lg: "h-11 px-5 min-w-11",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ variant: "default",
24
+ size: "default",
25
+ },
26
+ }
27
+ )
28
+
29
+ const Toggle = React.forwardRef<
30
+ React.ElementRef<typeof View>,
31
+ React.ComponentPropsWithoutRef<typeof View> &
32
+ VariantProps<typeof toggleVariants> & {
33
+ pressed?: boolean
34
+ onPressedChange?: (pressed: boolean) => void
35
+ defaultPressed?: boolean
36
+ disabled?: boolean
37
+ }
38
+ >(({ className, variant, size, pressed: pressedProp, defaultPressed, onPressedChange, disabled, ...props }, ref) => {
39
+ const [pressedState, setPressedState] = React.useState(defaultPressed || false)
40
+ const pressed = pressedProp !== undefined ? pressedProp : pressedState
41
+
42
+ const handleClick = (e) => {
43
+ if (disabled) return
44
+ const newPressed = !pressed
45
+ if (pressedProp === undefined) {
46
+ setPressedState(newPressed)
47
+ }
48
+ onPressedChange?.(newPressed)
49
+ props.onClick?.(e)
50
+ }
51
+ const tabIndex = (props as { tabIndex?: number }).tabIndex ?? (disabled ? -1 : 0)
52
+
53
+ return (
54
+ <View
55
+ ref={ref}
56
+ className={cn(
57
+ toggleVariants({ variant, size, className }),
58
+ pressed && "bg-accent text-accent-foreground",
59
+ disabled && "opacity-50 pointer-events-none"
60
+ )}
61
+ data-state={pressed ? "on" : "off"}
62
+ data-disabled={disabled ? "" : undefined}
63
+ {...({ tabIndex } as { tabIndex?: number })}
64
+ hoverClass={
65
+ disabled
66
+ ? undefined
67
+ : "border-ring ring-2 ring-ring ring-offset-2 ring-offset-background"
68
+ }
69
+ onClick={handleClick}
70
+ {...props}
71
+ />
72
+ )
73
+ })
74
+
75
+ Toggle.displayName = "Toggle"
76
+
77
+ export { Toggle, toggleVariants }
@@ -0,0 +1,455 @@
1
+ import * as React from "react"
2
+ import { View } from "@tarojs/components"
3
+ import { cn } from "@/lib/utils"
4
+ import { isH5 } from "@/lib/platform"
5
+ import { getRectById, getViewport } from "@/lib/measure"
6
+ import { Portal } from "@/components/ui/portal"
7
+
8
+ type TooltipProviderProps = {
9
+ children: React.ReactNode
10
+ }
11
+
12
+ type TooltipProps = {
13
+ children: React.ReactNode
14
+ open?: boolean
15
+ defaultOpen?: boolean
16
+ onOpenChange?: (open: boolean) => void
17
+ }
18
+
19
+ type TooltipSide = "top" | "bottom" | "left" | "right"
20
+ type TooltipAlign = "start" | "center" | "end"
21
+
22
+ const TooltipContext = React.createContext<{
23
+ open: boolean
24
+ onOpenChange: (open: boolean) => void
25
+ triggerId: string
26
+ setHoverPart?: (part: "trigger" | "content", hovering: boolean) => void
27
+ } | null>(null)
28
+
29
+ const TooltipProvider = ({ children }: TooltipProviderProps) => <>{children}</>
30
+
31
+ const Tooltip = ({
32
+ children,
33
+ open: openProp,
34
+ defaultOpen = false,
35
+ onOpenChange,
36
+ }: TooltipProps) => {
37
+ const baseIdRef = React.useRef(
38
+ `tooltip-${Math.random().toString(36).slice(2, 10)}`
39
+ )
40
+ const [openState, setOpenState] = React.useState(defaultOpen)
41
+ const open = openProp !== undefined ? openProp : openState
42
+ const hoverRef = React.useRef({ trigger: false, content: false })
43
+ const closeTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)
44
+
45
+ const handleOpenChange = (newOpen: boolean) => {
46
+ if (openProp === undefined) {
47
+ setOpenState(newOpen)
48
+ }
49
+ onOpenChange?.(newOpen)
50
+ }
51
+
52
+ const setHoverPart = React.useCallback(
53
+ (part: "trigger" | "content", hovering: boolean) => {
54
+ if (!isH5()) return
55
+ hoverRef.current[part] = hovering
56
+ if (hovering) {
57
+ if (closeTimerRef.current) clearTimeout(closeTimerRef.current)
58
+ closeTimerRef.current = null
59
+ handleOpenChange(true)
60
+ return
61
+ }
62
+ if (closeTimerRef.current) clearTimeout(closeTimerRef.current)
63
+ closeTimerRef.current = setTimeout(() => {
64
+ if (!hoverRef.current.trigger && !hoverRef.current.content) {
65
+ handleOpenChange(false)
66
+ }
67
+ }, 80)
68
+ },
69
+ [handleOpenChange]
70
+ )
71
+
72
+ React.useEffect(() => {
73
+ return () => {
74
+ if (closeTimerRef.current) clearTimeout(closeTimerRef.current)
75
+ }
76
+ }, [])
77
+
78
+ return (
79
+ <TooltipContext.Provider
80
+ value={{
81
+ open,
82
+ onOpenChange: handleOpenChange,
83
+ triggerId: baseIdRef.current,
84
+ setHoverPart,
85
+ }}
86
+ >
87
+ {children}
88
+ </TooltipContext.Provider>
89
+ )
90
+ }
91
+
92
+ const TooltipTrigger = React.forwardRef<
93
+ React.ElementRef<typeof View>,
94
+ React.ComponentPropsWithoutRef<typeof View> & {
95
+ onMouseEnter?: (e: any) => void
96
+ onMouseLeave?: (e: any) => void
97
+ }
98
+ >(
99
+ (
100
+ { className, children, onClick, onMouseEnter, onMouseLeave, ...props },
101
+ ref
102
+ ) => {
103
+ const context = React.useContext(TooltipContext)
104
+ return (
105
+ <View
106
+ ref={ref}
107
+ id={context?.triggerId}
108
+ className={cn("inline-flex w-fit justify-self-start", className)}
109
+ onClick={(e) => {
110
+ onClick?.(e)
111
+ e.stopPropagation()
112
+ context?.onOpenChange(!context.open)
113
+ }}
114
+ {...(isH5()
115
+ ? ({
116
+ onMouseEnter: (e: any) => {
117
+ onMouseEnter?.(e)
118
+ context?.setHoverPart?.("trigger", true)
119
+ },
120
+ onMouseLeave: (e: any) => {
121
+ onMouseLeave?.(e)
122
+ context?.setHoverPart?.("trigger", false)
123
+ },
124
+ } as any)
125
+ : {})}
126
+ {...props}
127
+ >
128
+ {children}
129
+ </View>
130
+ )
131
+ }
132
+ )
133
+ TooltipTrigger.displayName = "TooltipTrigger"
134
+
135
+ const TooltipContent = React.forwardRef<
136
+ React.ElementRef<typeof View>,
137
+ React.ComponentPropsWithoutRef<typeof View> & {
138
+ align?: TooltipAlign
139
+ side?: TooltipSide
140
+ sideOffset?: number
141
+ avoidCollisions?: boolean
142
+ collisionPadding?: number
143
+ showArrow?: boolean
144
+ arrowSize?: number
145
+ onMouseEnter?: (e: any) => void
146
+ onMouseLeave?: (e: any) => void
147
+ }
148
+ >(
149
+ (
150
+ {
151
+ children,
152
+ className,
153
+ align = "center",
154
+ side = "top",
155
+ sideOffset = 4,
156
+ avoidCollisions = true,
157
+ collisionPadding = 8,
158
+ showArrow = true,
159
+ arrowSize = 8,
160
+ onMouseEnter,
161
+ onMouseLeave,
162
+ ...props
163
+ },
164
+ ref
165
+ ) => {
166
+ const context = React.useContext(TooltipContext)
167
+ const contentId = React.useRef(
168
+ `tooltip-content-${Math.random().toString(36).slice(2, 10)}`
169
+ )
170
+ const [layout, setLayout] = React.useState<
171
+ | {
172
+ left: number
173
+ top: number
174
+ side: TooltipSide
175
+ arrowLeft?: number
176
+ arrowTop?: number
177
+ }
178
+ | null
179
+ >(null)
180
+
181
+ React.useEffect(() => {
182
+ if (!context?.open) {
183
+ setLayout(null)
184
+ return
185
+ }
186
+
187
+ let cancelled = false
188
+
189
+ let rafId: number | null = null
190
+
191
+ const compute = async () => {
192
+ const [triggerRect, contentRect] = await Promise.all([
193
+ getRectById(context.triggerId),
194
+ getRectById(contentId.current),
195
+ ])
196
+
197
+ if (cancelled) return
198
+ if (!triggerRect?.width || !contentRect?.width) return
199
+
200
+ const vw = getViewport().width
201
+ const vh = getViewport().height
202
+ const padding = Math.max(0, collisionPadding)
203
+
204
+ const computeForSide = (s: TooltipSide) => {
205
+ const isLR = s === "left" || s === "right"
206
+ const crossStart = isLR ? triggerRect.top : triggerRect.left
207
+ const crossSize = isLR ? triggerRect.height : triggerRect.width
208
+ const contentCrossSize = isLR ? contentRect.height : contentRect.width
209
+ const mainOffset = sideOffset + (showArrow ? arrowSize / 2 : 0)
210
+
211
+ const cross = (() => {
212
+ if (align === "start") return crossStart
213
+ if (align === "end") return crossStart + crossSize - contentCrossSize
214
+ return crossStart + crossSize / 2 - contentCrossSize / 2
215
+ })()
216
+
217
+ if (s === "bottom" || s === "top") {
218
+ const left = cross
219
+ const top =
220
+ s === "bottom"
221
+ ? triggerRect.top + triggerRect.height + mainOffset
222
+ : triggerRect.top - contentRect.height - mainOffset
223
+ return { left, top }
224
+ }
225
+
226
+ const top = cross
227
+ const left =
228
+ s === "right"
229
+ ? triggerRect.left + triggerRect.width + mainOffset
230
+ : triggerRect.left - contentRect.width - mainOffset
231
+ return { left, top }
232
+ }
233
+
234
+ const oppositeSide = (s: TooltipSide): TooltipSide => {
235
+ if (s === "top") return "bottom"
236
+ if (s === "bottom") return "top"
237
+ if (s === "left") return "right"
238
+ return "left"
239
+ }
240
+
241
+ const wouldOverflowMainAxis = (s: TooltipSide, left: number, top: number) => {
242
+ if (s === "top") return top < padding
243
+ if (s === "bottom") return top + contentRect.height > vh - padding
244
+ if (s === "left") return left < padding
245
+ return left + contentRect.width > vw - padding
246
+ }
247
+
248
+ let resolvedSide: TooltipSide = side
249
+ let { left, top } = computeForSide(resolvedSide)
250
+
251
+ if (avoidCollisions && wouldOverflowMainAxis(resolvedSide, left, top)) {
252
+ const flipped = oppositeSide(resolvedSide)
253
+ const flippedPos = computeForSide(flipped)
254
+ if (!wouldOverflowMainAxis(flipped, flippedPos.left, flippedPos.top)) {
255
+ resolvedSide = flipped
256
+ left = flippedPos.left
257
+ top = flippedPos.top
258
+ }
259
+ }
260
+
261
+ const maxLeft = Math.max(padding, vw - contentRect.width - padding)
262
+ const maxTop = Math.max(padding, vh - contentRect.height - padding)
263
+ left = Math.min(Math.max(left, padding), maxLeft)
264
+ top = Math.min(Math.max(top, padding), maxTop)
265
+
266
+ const triggerCenterX = triggerRect.left + triggerRect.width / 2
267
+ const triggerCenterY = triggerRect.top + triggerRect.height / 2
268
+ const arrowGap = 6
269
+
270
+ if (resolvedSide === "top" || resolvedSide === "bottom") {
271
+ const rawArrowLeft = triggerCenterX - left - arrowSize / 2
272
+ const minArrowLeft = arrowGap
273
+ const maxArrowLeft = contentRect.width - arrowSize - arrowGap
274
+ const arrowLeft = Math.min(Math.max(rawArrowLeft, minArrowLeft), maxArrowLeft)
275
+ setLayout({ left, top, side: resolvedSide, arrowLeft })
276
+ return
277
+ }
278
+
279
+ const rawArrowTop = triggerCenterY - top - arrowSize / 2
280
+ const minArrowTop = arrowGap
281
+ const maxArrowTop = contentRect.height - arrowSize - arrowGap
282
+ const arrowTop = Math.min(Math.max(rawArrowTop, minArrowTop), maxArrowTop)
283
+ setLayout({ left, top, side: resolvedSide, arrowTop })
284
+ }
285
+
286
+ const schedule = () => {
287
+ if (rafId != null) {
288
+ if (typeof cancelAnimationFrame !== "undefined") {
289
+ cancelAnimationFrame(rafId)
290
+ } else {
291
+ clearTimeout(rafId)
292
+ }
293
+ rafId = null
294
+ }
295
+ if (typeof requestAnimationFrame !== "undefined") {
296
+ rafId = requestAnimationFrame(() => compute())
297
+ } else {
298
+ rafId = setTimeout(() => compute(), 0) as unknown as number
299
+ }
300
+ }
301
+
302
+ schedule()
303
+
304
+ const onWindowChange = () => schedule()
305
+
306
+ if (isH5() && typeof window !== "undefined") {
307
+ window.addEventListener("resize", onWindowChange)
308
+ window.addEventListener("scroll", onWindowChange, true)
309
+ }
310
+
311
+ return () => {
312
+ cancelled = true
313
+ if (rafId != null) {
314
+ if (typeof cancelAnimationFrame !== "undefined") {
315
+ cancelAnimationFrame(rafId)
316
+ } else {
317
+ clearTimeout(rafId)
318
+ }
319
+ }
320
+ if (isH5() && typeof window !== "undefined") {
321
+ window.removeEventListener("resize", onWindowChange)
322
+ window.removeEventListener("scroll", onWindowChange, true)
323
+ }
324
+ }
325
+ }, [
326
+ align,
327
+ avoidCollisions,
328
+ collisionPadding,
329
+ context?.open,
330
+ context?.triggerId,
331
+ side,
332
+ sideOffset,
333
+ arrowSize,
334
+ ])
335
+
336
+ if (!context?.open) return null
337
+
338
+ const baseClassName =
339
+ "fixed z-50 overflow-visible rounded-md bg-black px-3 py-2 text-sm text-white shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
340
+
341
+ const px = (n: number) => `${n}px`
342
+
343
+ const contentStyle = layout
344
+ ? (isH5()
345
+ ? ({ left: px(layout.left), top: px(layout.top) } as React.CSSProperties)
346
+ : ({ left: layout.left, top: layout.top } as React.CSSProperties))
347
+ : ({
348
+ left: 0,
349
+ top: 0,
350
+ opacity: 0,
351
+ pointerEvents: "none",
352
+ } as React.CSSProperties)
353
+
354
+ const arrow =
355
+ showArrow && layout ? (
356
+ <View
357
+ className="absolute rotate-45 bg-black"
358
+ style={
359
+ layout.side === "top"
360
+ ? (isH5()
361
+ ? ({
362
+ width: px(arrowSize),
363
+ height: px(arrowSize),
364
+ bottom: px(-arrowSize / 2),
365
+ left: px(layout.arrowLeft ?? 0),
366
+ } as React.CSSProperties)
367
+ : ({
368
+ width: arrowSize,
369
+ height: arrowSize,
370
+ bottom: -arrowSize / 2,
371
+ left: layout.arrowLeft ?? 0,
372
+ } as React.CSSProperties))
373
+ : layout.side === "bottom"
374
+ ? (isH5()
375
+ ? ({
376
+ width: px(arrowSize),
377
+ height: px(arrowSize),
378
+ top: px(-arrowSize / 2),
379
+ left: px(layout.arrowLeft ?? 0),
380
+ } as React.CSSProperties)
381
+ : ({
382
+ width: arrowSize,
383
+ height: arrowSize,
384
+ top: -arrowSize / 2,
385
+ left: layout.arrowLeft ?? 0,
386
+ } as React.CSSProperties))
387
+ : layout.side === "left"
388
+ ? (isH5()
389
+ ? ({
390
+ width: px(arrowSize),
391
+ height: px(arrowSize),
392
+ right: px(-arrowSize / 2),
393
+ top: px(layout.arrowTop ?? 0),
394
+ } as React.CSSProperties)
395
+ : ({
396
+ width: arrowSize,
397
+ height: arrowSize,
398
+ right: -arrowSize / 2,
399
+ top: layout.arrowTop ?? 0,
400
+ } as React.CSSProperties))
401
+ : (isH5()
402
+ ? ({
403
+ width: px(arrowSize),
404
+ height: px(arrowSize),
405
+ left: px(-arrowSize / 2),
406
+ top: px(layout.arrowTop ?? 0),
407
+ } as React.CSSProperties)
408
+ : ({
409
+ width: arrowSize,
410
+ height: arrowSize,
411
+ left: -arrowSize / 2,
412
+ top: layout.arrowTop ?? 0,
413
+ } as React.CSSProperties))
414
+ }
415
+ />
416
+ ) : null
417
+
418
+ const overlay = !isH5() ? (
419
+ <View
420
+ className="fixed inset-0 z-50 bg-transparent"
421
+ onClick={() => context.onOpenChange(false)}
422
+ />
423
+ ) : null
424
+
425
+ return (
426
+ <Portal>
427
+ {overlay}
428
+ <View
429
+ ref={ref}
430
+ id={contentId.current}
431
+ className={cn(baseClassName, className)}
432
+ style={contentStyle}
433
+ {...(isH5()
434
+ ? ({
435
+ onMouseEnter: (e: any) => {
436
+ onMouseEnter?.(e)
437
+ context?.setHoverPart?.("content", true)
438
+ },
439
+ onMouseLeave: (e: any) => {
440
+ onMouseLeave?.(e)
441
+ context?.setHoverPart?.("content", false)
442
+ },
443
+ } as any)
444
+ : {})}
445
+ {...props}
446
+ >
447
+ {arrow}
448
+ {children}
449
+ </View>
450
+ </Portal>
451
+ )
452
+ })
453
+ TooltipContent.displayName = "TooltipContent"
454
+
455
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
6
+ <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
7
+ <meta name="apple-mobile-web-app-capable" content="yes">
8
+ <meta name="apple-touch-fullscreen" content="yes">
9
+ <meta name="format-detection" content="telephone=no,address=no">
10
+ <meta name="apple-mobile-web-app-status-bar-style" content="white">
11
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
12
+ <title><%= appName %></title>
13
+ <script><%%= htmlWebpackPlugin.options.script %></script>
14
+ </head>
15
+
16
+ <body>
17
+ <div id="app">
18
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="lab(2.86037 0.455312 0.568903)"
19
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="
20
+ position: fixed;
21
+ inset: 0;
22
+ margin: auto;
23
+ width: 24px;
24
+ height: 24px;
25
+ animation: __app-loading-spin 1s linear infinite;
26
+ ">
27
+ <path d="M21 12a9 9 0 1 1-6.219-8.56" />
28
+ </svg>
29
+ <style>
30
+ @keyframes __app-loading-spin {
31
+ to {
32
+ transform: rotate(360deg);
33
+ }
34
+ }
35
+ </style>
36
+ </div>
37
+ </body>
38
+
39
+ </html>