@skyroc/scripts 2.5.0

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 (333) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +508 -0
  3. package/dist/cli.mjs +78 -0
  4. package/dist/config-BKkdncJS.mjs +987 -0
  5. package/dist/index.mjs +14 -0
  6. package/package.json +83 -0
  7. package/templates/admin/.env +62 -0
  8. package/templates/admin/.env.prod +7 -0
  9. package/templates/admin/.env.test +7 -0
  10. package/templates/admin/.oxlintrc.json +6 -0
  11. package/templates/admin/README.md +508 -0
  12. package/templates/admin/index.html +14 -0
  13. package/templates/admin/package.json +105 -0
  14. package/templates/admin/public/favicon.svg +3 -0
  15. package/templates/admin/src/App.tsx +71 -0
  16. package/templates/admin/src/assets/audio/wechat-style-notification.wav +0 -0
  17. package/templates/admin/src/assets/imgs/skyroc.jpg +0 -0
  18. package/templates/admin/src/assets/svg-icon/activity.svg +1 -0
  19. package/templates/admin/src/assets/svg-icon/at-sign.svg +1 -0
  20. package/templates/admin/src/assets/svg-icon/avatar.svg +1 -0
  21. package/templates/admin/src/assets/svg-icon/banner.svg +1 -0
  22. package/templates/admin/src/assets/svg-icon/cast.svg +1 -0
  23. package/templates/admin/src/assets/svg-icon/chrome.svg +1 -0
  24. package/templates/admin/src/assets/svg-icon/copy.svg +1 -0
  25. package/templates/admin/src/assets/svg-icon/custom-icon.svg +1 -0
  26. package/templates/admin/src/assets/svg-icon/empty-data.svg +1 -0
  27. package/templates/admin/src/assets/svg-icon/error.svg +1 -0
  28. package/templates/admin/src/assets/svg-icon/expectation.svg +1 -0
  29. package/templates/admin/src/assets/svg-icon/heart.svg +1 -0
  30. package/templates/admin/src/assets/svg-icon/logo.svg +15 -0
  31. package/templates/admin/src/assets/svg-icon/network-error.svg +1 -0
  32. package/templates/admin/src/assets/svg-icon/no-icon.svg +1 -0
  33. package/templates/admin/src/assets/svg-icon/no-permission.svg +1 -0
  34. package/templates/admin/src/assets/svg-icon/not-found.svg +1 -0
  35. package/templates/admin/src/assets/svg-icon/service-error.svg +1 -0
  36. package/templates/admin/src/bootstrap.tsx +60 -0
  37. package/templates/admin/src/components/SkyrocAvatar.tsx +13 -0
  38. package/templates/admin/src/components/SystemLogo.tsx +7 -0
  39. package/templates/admin/src/config.ts +125 -0
  40. package/templates/admin/src/features/antd/AntdProvider.tsx +21 -0
  41. package/templates/admin/src/features/auth/components/UserAvatar.tsx +76 -0
  42. package/templates/admin/src/features/auth/use-auth-form-rules.ts +83 -0
  43. package/templates/admin/src/features/auth/use-auth.ts +96 -0
  44. package/templates/admin/src/features/auth/use-login.ts +72 -0
  45. package/templates/admin/src/features/effects/GlobalEffect.tsx +15 -0
  46. package/templates/admin/src/features/menus/dynamic-routes.ts +10 -0
  47. package/templates/admin/src/features/menus/extras.ts +3 -0
  48. package/templates/admin/src/features/menus/menu-category.ts +14 -0
  49. package/templates/admin/src/features/menus/menu-config.ts +5 -0
  50. package/templates/admin/src/features/router/RouterProvider.tsx +18 -0
  51. package/templates/admin/src/features/router/guard.ts +97 -0
  52. package/templates/admin/src/features/router/index.ts +52 -0
  53. package/templates/admin/src/features/router/routeTree.gen.ts +237 -0
  54. package/templates/admin/src/features/router/router-ref.ts +24 -0
  55. package/templates/admin/src/locales/antd.ts +8 -0
  56. package/templates/admin/src/locales/index.ts +22 -0
  57. package/templates/admin/src/locales/sync.ts +14 -0
  58. package/templates/admin/src/main.tsx +9 -0
  59. package/templates/admin/src/pages/(admin)/home/index.tsx +46 -0
  60. package/templates/admin/src/pages/(admin)/layout.tsx +44 -0
  61. package/templates/admin/src/pages/(auth)/login/index.tsx +102 -0
  62. package/templates/admin/src/pages/(auth)/login/layout.tsx +71 -0
  63. package/templates/admin/src/pages/(auth)/login-out.tsx +27 -0
  64. package/templates/admin/src/pages/(errors)/403.tsx +16 -0
  65. package/templates/admin/src/pages/(errors)/404.tsx +16 -0
  66. package/templates/admin/src/pages/(errors)/500.tsx +16 -0
  67. package/templates/admin/src/pages/__root.tsx +54 -0
  68. package/templates/admin/src/pages/error.tsx +19 -0
  69. package/templates/admin/src/pages/index.tsx +14 -0
  70. package/templates/admin/src/pages/loading.tsx +45 -0
  71. package/templates/admin/src/pages/not-found.tsx +9 -0
  72. package/templates/admin/src/plugins/app.tsx +47 -0
  73. package/templates/admin/src/plugins/assets.ts +4 -0
  74. package/templates/admin/src/plugins/index.ts +32 -0
  75. package/templates/admin/src/service/adapter.ts +63 -0
  76. package/templates/admin/src/service/api/auth/api.ts +31 -0
  77. package/templates/admin/src/service/api/auth/hooks.ts +28 -0
  78. package/templates/admin/src/service/api/auth/index.ts +10 -0
  79. package/templates/admin/src/service/api/auth/keys.ts +7 -0
  80. package/templates/admin/src/service/api/auth/urls.ts +7 -0
  81. package/templates/admin/src/service/api/index.ts +2 -0
  82. package/templates/admin/src/service/api/route/api.ts +7 -0
  83. package/templates/admin/src/service/api/route/hooks.ts +21 -0
  84. package/templates/admin/src/service/api/route/index.ts +10 -0
  85. package/templates/admin/src/service/api/route/keys.ts +3 -0
  86. package/templates/admin/src/service/api/route/urls.ts +5 -0
  87. package/templates/admin/src/service/queryClient.ts +13 -0
  88. package/templates/admin/src/service/request/index.ts +62 -0
  89. package/templates/admin/src/styles/scss/global.scss +1 -0
  90. package/templates/admin/src/styles/scss/scrollbar.scss +28 -0
  91. package/templates/admin/src/types/auto-imports.d.ts +186 -0
  92. package/templates/admin/src/types/global.d.ts +16 -0
  93. package/templates/admin/src/types/router.d.ts +14 -0
  94. package/templates/admin/src/types/storage.d.ts +17 -0
  95. package/templates/admin/src/types/vite-env.d.ts +117 -0
  96. package/templates/admin/src/utils/common.tsx +38 -0
  97. package/templates/admin/src/utils/icon.ts +9 -0
  98. package/templates/admin/src/utils/service.ts +75 -0
  99. package/templates/admin/src/utils/storage.ts +7 -0
  100. package/templates/admin/tsconfig.json +22 -0
  101. package/templates/admin/uno.config.ts +18 -0
  102. package/templates/admin/vite.config.ts +13 -0
  103. package/templates/admin-shell/i18n/atoms/lang.ts +20 -0
  104. package/templates/admin-shell/i18n/config/default.ts +11 -0
  105. package/templates/admin-shell/i18n/features/lang/LangEffect.tsx +25 -0
  106. package/templates/admin-shell/i18n/features/lang/LangSwitch.tsx +49 -0
  107. package/templates/admin-shell/i18n/hooks/use-lang.ts +47 -0
  108. package/templates/admin-shell/i18n/i18n.ts +116 -0
  109. package/templates/admin-shell/i18n/index.ts +23 -0
  110. package/templates/admin-shell/i18n/langs/en-us/common.json +49 -0
  111. package/templates/admin-shell/i18n/langs/en-us/datatable.json +8 -0
  112. package/templates/admin-shell/i18n/langs/en-us/dropdown.json +9 -0
  113. package/templates/admin-shell/i18n/langs/en-us/form.json +27 -0
  114. package/templates/admin-shell/i18n/langs/en-us/icon.json +13 -0
  115. package/templates/admin-shell/i18n/langs/en-us/notification.json +20 -0
  116. package/templates/admin-shell/i18n/langs/en-us/page.json +442 -0
  117. package/templates/admin-shell/i18n/langs/en-us/request.json +8 -0
  118. package/templates/admin-shell/i18n/langs/en-us/route.json +84 -0
  119. package/templates/admin-shell/i18n/langs/en-us/system.json +9 -0
  120. package/templates/admin-shell/i18n/langs/en-us/theme.json +173 -0
  121. package/templates/admin-shell/i18n/langs/index.ts +63 -0
  122. package/templates/admin-shell/i18n/langs/zh-cn/common.json +49 -0
  123. package/templates/admin-shell/i18n/langs/zh-cn/datatable.json +8 -0
  124. package/templates/admin-shell/i18n/langs/zh-cn/dropdown.json +9 -0
  125. package/templates/admin-shell/i18n/langs/zh-cn/form.json +27 -0
  126. package/templates/admin-shell/i18n/langs/zh-cn/icon.json +13 -0
  127. package/templates/admin-shell/i18n/langs/zh-cn/notification.json +20 -0
  128. package/templates/admin-shell/i18n/langs/zh-cn/page.json +442 -0
  129. package/templates/admin-shell/i18n/langs/zh-cn/request.json +8 -0
  130. package/templates/admin-shell/i18n/langs/zh-cn/route.json +84 -0
  131. package/templates/admin-shell/i18n/langs/zh-cn/system.json +9 -0
  132. package/templates/admin-shell/i18n/langs/zh-cn/theme.json +173 -0
  133. package/templates/admin-shell/i18n/types/i18n.ts +29 -0
  134. package/templates/admin-shell/i18n/types.ts +53 -0
  135. package/templates/admin-shell/i18n/utils/helpers.ts +18 -0
  136. package/templates/admin-shell/layouts/AdminLayout.tsx +161 -0
  137. package/templates/admin-shell/layouts/constant.ts +56 -0
  138. package/templates/admin-shell/layouts/context.tsx +101 -0
  139. package/templates/admin-shell/layouts/features/menus/MenuBadge.tsx +76 -0
  140. package/templates/admin-shell/layouts/features/menus/dynamic-routes.ts +146 -0
  141. package/templates/admin-shell/layouts/features/menus/menu-generator.tsx +444 -0
  142. package/templates/admin-shell/layouts/features/menus/menu-renderer.tsx +149 -0
  143. package/templates/admin-shell/layouts/features/menus/permissions.ts +28 -0
  144. package/templates/admin-shell/layouts/features/menus/use-menus.ts +98 -0
  145. package/templates/admin-shell/layouts/features/use-route.ts +30 -0
  146. package/templates/admin-shell/layouts/index.ts +44 -0
  147. package/templates/admin-shell/layouts/materials/index.ts +6 -0
  148. package/templates/admin-shell/layouts/materials/libs/admin-layout/index.module.css +63 -0
  149. package/templates/admin-shell/layouts/materials/libs/admin-layout/index.module.css.d.ts +18 -0
  150. package/templates/admin-shell/layouts/materials/libs/admin-layout/index.tsx +238 -0
  151. package/templates/admin-shell/layouts/materials/libs/admin-layout/shared.ts +67 -0
  152. package/templates/admin-shell/layouts/materials/libs/page-tab/ButtonTab.tsx +44 -0
  153. package/templates/admin-shell/layouts/materials/libs/page-tab/ChromeTab.tsx +54 -0
  154. package/templates/admin-shell/layouts/materials/libs/page-tab/ChromeTabBg.tsx +30 -0
  155. package/templates/admin-shell/layouts/materials/libs/page-tab/SliderTab.tsx +44 -0
  156. package/templates/admin-shell/layouts/materials/libs/page-tab/SvgClose.tsx +51 -0
  157. package/templates/admin-shell/layouts/materials/libs/page-tab/hook.ts +34 -0
  158. package/templates/admin-shell/layouts/materials/libs/page-tab/index.module.css +120 -0
  159. package/templates/admin-shell/layouts/materials/libs/page-tab/index.module.css.d.ts +18 -0
  160. package/templates/admin-shell/layouts/materials/libs/page-tab/index.tsx +76 -0
  161. package/templates/admin-shell/layouts/materials/libs/page-tab/shared.ts +32 -0
  162. package/templates/admin-shell/layouts/materials/types/index.ts +322 -0
  163. package/templates/admin-shell/layouts/modules/AdminContent.tsx +285 -0
  164. package/templates/admin-shell/layouts/modules/AdminFooter.tsx +13 -0
  165. package/templates/admin-shell/layouts/modules/AdminLogo.tsx +28 -0
  166. package/templates/admin-shell/layouts/modules/AdminSider.tsx +50 -0
  167. package/templates/admin-shell/layouts/modules/admin-header/AdminHeader.tsx +132 -0
  168. package/templates/admin-shell/layouts/modules/admin-header/components/Breadcrumb.tsx +62 -0
  169. package/templates/admin-shell/layouts/modules/admin-header/components/ThemeButton.tsx +24 -0
  170. package/templates/admin-shell/layouts/modules/admin-menu/AdminMenu.tsx +37 -0
  171. package/templates/admin-shell/layouts/modules/admin-menu/components/FirstLevelMenu.tsx +156 -0
  172. package/templates/admin-shell/layouts/modules/admin-menu/components/HorizontalMenu.tsx +88 -0
  173. package/templates/admin-shell/layouts/modules/admin-menu/components/MenuPortal.tsx +28 -0
  174. package/templates/admin-shell/layouts/modules/admin-menu/components/VerticalMenu.tsx +123 -0
  175. package/templates/admin-shell/layouts/modules/admin-menu/enum.ts +47 -0
  176. package/templates/admin-shell/layouts/modules/admin-menu/modules/Horizontal.tsx +22 -0
  177. package/templates/admin-shell/layouts/modules/admin-menu/modules/TopHybridHeaderFirst.tsx +15 -0
  178. package/templates/admin-shell/layouts/modules/admin-menu/modules/TopHybridSidebarFirst.tsx +18 -0
  179. package/templates/admin-shell/layouts/modules/admin-menu/modules/Vertical.tsx +14 -0
  180. package/templates/admin-shell/layouts/modules/admin-menu/modules/VerticalHybridHeaderFirst.tsx +18 -0
  181. package/templates/admin-shell/layouts/modules/admin-menu/modules/VerticalMix.tsx +132 -0
  182. package/templates/admin-shell/layouts/modules/admin-search/AdminSearch.tsx +36 -0
  183. package/templates/admin-shell/layouts/modules/admin-search/components/SearchFooter.tsx +38 -0
  184. package/templates/admin-shell/layouts/modules/admin-search/components/SearchModal.tsx +171 -0
  185. package/templates/admin-shell/layouts/modules/admin-search/components/SearchResult.tsx +43 -0
  186. package/templates/admin-shell/layouts/modules/admin-tab/AdminTab.tsx +125 -0
  187. package/templates/admin-shell/layouts/modules/admin-tab/components/TabContextMenu.tsx +107 -0
  188. package/templates/admin-shell/layouts/modules/admin-tab/hooks/useTabScroll.ts +86 -0
  189. package/templates/admin-shell/layouts/modules/shared/logo.ts +42 -0
  190. package/templates/admin-shell/layouts/modules/theme-drawer/ThemeDrawer.tsx +68 -0
  191. package/templates/admin-shell/layouts/modules/theme-drawer/components/AnimatedCollapse.tsx +36 -0
  192. package/templates/admin-shell/layouts/modules/theme-drawer/components/AnimatedItem.tsx +35 -0
  193. package/templates/admin-shell/layouts/modules/theme-drawer/components/LayoutModeCard.tsx +110 -0
  194. package/templates/admin-shell/layouts/modules/theme-drawer/components/SettingItem.tsx +31 -0
  195. package/templates/admin-shell/layouts/modules/theme-drawer/modules/ConfigOperation.tsx +53 -0
  196. package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/CustomPicker.tsx +105 -0
  197. package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/ThemeColor.tsx +58 -0
  198. package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/ThemeSchema.tsx +42 -0
  199. package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/ThemeToken.tsx +44 -0
  200. package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/index.tsx +23 -0
  201. package/templates/admin-shell/layouts/modules/theme-drawer/modules/general/GlobalSettings.tsx +57 -0
  202. package/templates/admin-shell/layouts/modules/theme-drawer/modules/general/ThemeGeneral.tsx +20 -0
  203. package/templates/admin-shell/layouts/modules/theme-drawer/modules/general/WatermarkSettings.tsx +103 -0
  204. package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/ContentSettings.tsx +100 -0
  205. package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/FooterSettings.tsx +71 -0
  206. package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/HeaderSettings.tsx +63 -0
  207. package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/LayoutMode.tsx +73 -0
  208. package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/SiderSettings.tsx +124 -0
  209. package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/TabSettings.tsx +95 -0
  210. package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/ThemeLayout.tsx +32 -0
  211. package/templates/admin-shell/layouts/modules/theme-drawer/modules/preset/ThemePreset.tsx +132 -0
  212. package/templates/admin-shell/layouts/options.tsx +79 -0
  213. package/templates/admin-shell/layouts/setup.ts +102 -0
  214. package/templates/admin-shell/layouts/state/AdminEffect.tsx +56 -0
  215. package/templates/admin-shell/layouts/state/AdminTabEffect.tsx +28 -0
  216. package/templates/admin-shell/layouts/state/index.ts +3 -0
  217. package/templates/admin-shell/layouts/state/menus/MenuToggler.tsx +53 -0
  218. package/templates/admin-shell/layouts/state/menus/use-admin-menu-badges.ts +46 -0
  219. package/templates/admin-shell/layouts/state/menus/use-admin-menus.tsx +164 -0
  220. package/templates/admin-shell/layouts/state/tabs/index.ts +1 -0
  221. package/templates/admin-shell/layouts/state/tabs/shared.tsx +148 -0
  222. package/templates/admin-shell/layouts/state/tabs/use-admin-tab.ts +377 -0
  223. package/templates/admin-shell/layouts/state/use-admin-state.ts +118 -0
  224. package/templates/admin-shell/layouts/types/router.d.ts +10 -0
  225. package/templates/admin-shell/layouts/types/storage.ts +18 -0
  226. package/templates/admin-shell/notification/NotificationButton.tsx +91 -0
  227. package/templates/admin-shell/notification/NotificationContext.ts +8 -0
  228. package/templates/admin-shell/notification/NotificationPanel.tsx +194 -0
  229. package/templates/admin-shell/notification/NotificationProvider.tsx +59 -0
  230. package/templates/admin-shell/notification/index.ts +12 -0
  231. package/templates/admin-shell/notification/mock.ts +59 -0
  232. package/templates/admin-shell/notification/notification-store.ts +438 -0
  233. package/templates/admin-shell/notification/notification.css +60 -0
  234. package/templates/admin-shell/notification/types.ts +104 -0
  235. package/templates/admin-shell/notification/use-notification.ts +51 -0
  236. package/templates/admin-shell/notification/useNotificationContext.ts +14 -0
  237. package/templates/admin-shell/runtime/app-update.ts +156 -0
  238. package/templates/admin-shell/runtime/dayjs.ts +20 -0
  239. package/templates/admin-shell/runtime/iconify.ts +17 -0
  240. package/templates/admin-shell/runtime/index.ts +10 -0
  241. package/templates/admin-shell/runtime/nprogress.ts +25 -0
  242. package/templates/admin-shell/runtime/plugins.ts +62 -0
  243. package/templates/admin-shell/styles/global.css +54 -0
  244. package/templates/admin-shell/styles/nprogress.css +85 -0
  245. package/templates/admin-shell/styles/reset.css +378 -0
  246. package/templates/admin-shell/theme/antd/AntdProvider.tsx +106 -0
  247. package/templates/admin-shell/theme/antd/index.ts +23 -0
  248. package/templates/admin-shell/theme/antd/shared.ts +80 -0
  249. package/templates/admin-shell/theme/antd/ui.ts +250 -0
  250. package/templates/admin-shell/theme/antd-algorithm/algorithm/dark/colors.ts +99 -0
  251. package/templates/admin-shell/theme/antd-algorithm/algorithm/dark/index.ts +87 -0
  252. package/templates/admin-shell/theme/antd-algorithm/algorithm/default/colors.ts +91 -0
  253. package/templates/admin-shell/theme/antd-algorithm/algorithm/default/index.ts +77 -0
  254. package/templates/admin-shell/theme/antd-algorithm/index.ts +80 -0
  255. package/templates/admin-shell/theme/antd-algorithm/seed/index.ts +41 -0
  256. package/templates/admin-shell/theme/antd-algorithm/shared/colorAlgorithm.ts +10 -0
  257. package/templates/admin-shell/theme/antd-algorithm/shared/genColorMapToken.ts +165 -0
  258. package/templates/admin-shell/theme/antd-algorithm/shared/genCommonMapToken.ts +23 -0
  259. package/templates/admin-shell/theme/antd-algorithm/shared/genControlHeight.ts +14 -0
  260. package/templates/admin-shell/theme/antd-algorithm/shared/genFontMapToken.ts +274 -0
  261. package/templates/admin-shell/theme/antd-algorithm/shared/genRadiusMapToken.ts +139 -0
  262. package/templates/admin-shell/theme/antd-algorithm/shared/genSizeMapToken.ts +114 -0
  263. package/templates/admin-shell/theme/antd-algorithm/types/index.ts +20 -0
  264. package/templates/admin-shell/theme/components/ThemeEffect.tsx +55 -0
  265. package/templates/admin-shell/theme/components/ThemeSchemaSegmented.tsx +27 -0
  266. package/templates/admin-shell/theme/components/ThemeSchemaSwitch.tsx +77 -0
  267. package/templates/admin-shell/theme/components/shared.ts +5 -0
  268. package/templates/admin-shell/theme/config/default.ts +108 -0
  269. package/templates/admin-shell/theme/config/index.ts +1 -0
  270. package/templates/admin-shell/theme/hooks/index.ts +2 -0
  271. package/templates/admin-shell/theme/hooks/use-theme.ts +244 -0
  272. package/templates/admin-shell/theme/index.ts +78 -0
  273. package/templates/admin-shell/theme/presets/azir.json +39 -0
  274. package/templates/admin-shell/theme/presets/compact.json +38 -0
  275. package/templates/admin-shell/theme/presets/dark.json +93 -0
  276. package/templates/admin-shell/theme/presets/default.json +95 -0
  277. package/templates/admin-shell/theme/presets/index.ts +29 -0
  278. package/templates/admin-shell/theme/presets/shadcn.json +99 -0
  279. package/templates/admin-shell/theme/setup.ts +115 -0
  280. package/templates/admin-shell/theme/types/index.ts +27 -0
  281. package/templates/admin-shell/theme/types/theme.d.ts +316 -0
  282. package/templates/admin-shell/theme/utils/dark-mode.ts +46 -0
  283. package/templates/admin-shell/theme/utils/filters.ts +20 -0
  284. package/templates/admin-shell/theme/utils/index.ts +3 -0
  285. package/templates/admin-shell/theme/utils/settings.ts +43 -0
  286. package/templates/admin-shell/types/api/auth.d.ts +148 -0
  287. package/templates/admin-shell/types/api/common.d.ts +54 -0
  288. package/templates/admin-shell/types/api/route.d.ts +104 -0
  289. package/templates/admin-shell/types/api/service.d.ts +51 -0
  290. package/templates/admin-shell/types/api/system-manage.d.ts +160 -0
  291. package/templates/admin-shell/types/app/common.d.ts +31 -0
  292. package/templates/admin-shell/types/app/global.d.ts +71 -0
  293. package/templates/admin-shell/types/app/menu.d.ts +57 -0
  294. package/templates/admin-shell/types/app/router.d.ts +201 -0
  295. package/templates/admin-shell/types/app/storage.d.ts +10 -0
  296. package/templates/admin-shell/types/app/union-key.d.ts +156 -0
  297. package/templates/admin-shell/types/locales/i18n.d.ts +135 -0
  298. package/templates/admin-shell/ui/antd/components/AppTree.tsx +62 -0
  299. package/templates/admin-shell/ui/antd/components/BeyondHiding.tsx +42 -0
  300. package/templates/admin-shell/ui/antd/components/ButtonIcon.tsx +123 -0
  301. package/templates/admin-shell/ui/antd/components/ButtonLink.tsx +30 -0
  302. package/templates/admin-shell/ui/antd/components/ErrorBoundary.tsx +45 -0
  303. package/templates/admin-shell/ui/antd/components/ExceptionBase.tsx +69 -0
  304. package/templates/admin-shell/ui/antd/components/FullScreen.tsx +33 -0
  305. package/templates/admin-shell/ui/antd/components/PinToggler.tsx +35 -0
  306. package/templates/admin-shell/ui/antd/components/ReloadButton.tsx +20 -0
  307. package/templates/admin-shell/ui/antd/components/index.ts +12 -0
  308. package/templates/admin-shell/ui/antd/components/styles/button-icon-animations.css +246 -0
  309. package/templates/admin-shell/ui/antd/index.ts +1 -0
  310. package/templates/admin-shell/ui/antd/styles.d.ts +1 -0
  311. package/templates/admin-shell/ui/compose/animate-feature.ts +5 -0
  312. package/templates/admin-shell/ui/compose/components/BetterScroll.tsx +51 -0
  313. package/templates/admin-shell/ui/compose/components/DarkModeContainer.tsx +22 -0
  314. package/templates/admin-shell/ui/compose/components/FlipText.tsx +41 -0
  315. package/templates/admin-shell/ui/compose/components/I18nLabel.tsx +18 -0
  316. package/templates/admin-shell/ui/compose/components/LazyAnimate.tsx +10 -0
  317. package/templates/admin-shell/ui/compose/components/LookForward.tsx +24 -0
  318. package/templates/admin-shell/ui/compose/components/NumberTicker.tsx +105 -0
  319. package/templates/admin-shell/ui/compose/components/Portal.tsx +74 -0
  320. package/templates/admin-shell/ui/compose/components/SvgIcon.tsx +39 -0
  321. package/templates/admin-shell/ui/compose/components/TypingAnimation.tsx +83 -0
  322. package/templates/admin-shell/ui/compose/components/WaveBg.tsx +56 -0
  323. package/templates/admin-shell/ui/compose/components/index.ts +11 -0
  324. package/templates/admin-shell/ui/compose/index.ts +2 -0
  325. package/templates/admin-shell/ui/compose/table/DragContent.tsx +239 -0
  326. package/templates/admin-shell/ui/compose/table/TableHeaderOperation.tsx +210 -0
  327. package/templates/admin-shell/ui/compose/table/hooks.ts +196 -0
  328. package/templates/admin-shell/ui/compose/table/index.ts +16 -0
  329. package/templates/admin-shell/ui/compose/table/types.ts +244 -0
  330. package/templates/admin-shell/ui/compose/table/use-table-operate.ts +136 -0
  331. package/templates/admin-shell/ui/compose/table/use-table-scroll.ts +49 -0
  332. package/templates/admin-shell/ui/compose/table/use-table.ts +303 -0
  333. package/templates/admin.meta.json +756 -0
@@ -0,0 +1,114 @@
1
+ import type { SizeMapToken } from 'antd/lib/theme/interface';
2
+
3
+ /**
4
+ * Spacing configuration
5
+ *
6
+ * Based on UnoCSS spacing rules, using sizeUnit as base unit Default sizeUnit = 4px
7
+ *
8
+ * | Name | Multiplier | px (sizeUnit=4) |
9
+ * | ---- | ---------- | --------------- |
10
+ * | 3xs | 1 | 4 |
11
+ * | 2xs | 2 | 8 |
12
+ * | xs | 3 | 12 |
13
+ * | md | 4 | 16 |
14
+ * | lg | 5 | 20 |
15
+ * | xl | 6 | 24 |
16
+ * | 2xl | 8 | 32 |
17
+ * | 3xl | 10 | 40 |
18
+ * | 4xl | 12 | 48 |
19
+ * | 5xl | 16 | 64 |
20
+ * | 6xl | 20 | 80 |
21
+ * | 7xl | 24 | 96 |
22
+ * | 8xl | 32 | 128 |
23
+ * | 9xl | 36 | 144 |
24
+ */
25
+
26
+ /** Spacing multipliers (based on sizeUnit) */
27
+ export const SPACING_MULTIPLIERS = {
28
+ '3xs': 1, // 4px (sizeUnit * 1)
29
+ '2xs': 2, // 8px (sizeUnit * 2)
30
+ xs: 3, // 12px (sizeUnit * 3)
31
+ md: 4, // 16px (sizeUnit * 4)
32
+ lg: 5, // 20px (sizeUnit * 5)
33
+ xl: 6, // 24px (sizeUnit * 6)
34
+ '2xl': 8, // 32px (sizeUnit * 8)
35
+ '3xl': 10, // 40px (sizeUnit * 10)
36
+ '4xl': 12, // 48px (sizeUnit * 12)
37
+ '5xl': 16, // 64px (sizeUnit * 16)
38
+ '6xl': 20, // 80px (sizeUnit * 20)
39
+ '7xl': 24, // 96px (sizeUnit * 24)
40
+ '8xl': 32, // 128px (sizeUnit * 32)
41
+ '9xl': 36 // 144px (sizeUnit * 36)
42
+ } as const;
43
+
44
+ export type SpacingSizeKey = keyof typeof SPACING_MULTIPLIERS;
45
+
46
+ /**
47
+ * Calculate spacing size
48
+ *
49
+ * @param multiplier Multiplier
50
+ * @param sizeUnit Base unit (default 4)
51
+ */
52
+ export function calcSpacing(multiplier: number, sizeUnit = 4): number {
53
+ return sizeUnit * multiplier;
54
+ }
55
+
56
+ /**
57
+ * Generate size map token
58
+ *
59
+ * Based on sizeUnit, generate Ant Design style size tokens
60
+ *
61
+ * Mapping (sizeUnit = 4): - sizeXXS: 3xs (4px) = sizeUnit * 1 - sizeXS: 2xs (8px) = sizeUnit * 2 - sizeSM: xs (12px) =
62
+ * sizeUnit * 3 - size/sizeMS: md (16px) = sizeUnit * 4 - sizeMD: lg (20px) = sizeUnit * 5 - sizeLG: xl (24px) =
63
+ * sizeUnit * 6 - sizeXL: 2xl (32px) = sizeUnit * 8 - sizeXXL: 4xl (48px) = sizeUnit * 12
64
+ *
65
+ * @param sizeUnit Base unit (px), default 4
66
+ */
67
+ export function genSizeMapToken(sizeUnit = 4): SizeMapToken {
68
+ return {
69
+ // Ant Design standard size tokens
70
+ sizeXXS: sizeUnit * SPACING_MULTIPLIERS['3xs'], // 4px
71
+ sizeXS: sizeUnit * SPACING_MULTIPLIERS['2xs'], // 8px
72
+ sizeSM: sizeUnit * SPACING_MULTIPLIERS.xs, // 12px
73
+ sizeMS: sizeUnit * SPACING_MULTIPLIERS.md, // 16px
74
+ size: sizeUnit * SPACING_MULTIPLIERS.md, // 16px
75
+ sizeMD: sizeUnit * SPACING_MULTIPLIERS.lg, // 20px
76
+ sizeLG: sizeUnit * SPACING_MULTIPLIERS.xl, // 24px
77
+ sizeXL: sizeUnit * SPACING_MULTIPLIERS['2xl'], // 32px
78
+ sizeXXL: sizeUnit * SPACING_MULTIPLIERS['4xl'] // 48px
79
+ };
80
+ }
81
+
82
+ /**
83
+ * Generate complete spacing table
84
+ *
85
+ * @param sizeUnit Base unit (px), default 4
86
+ */
87
+ export function genSpacingSizes(sizeUnit = 4): Record<SpacingSizeKey, number> {
88
+ return Object.entries(SPACING_MULTIPLIERS).reduce(
89
+ (acc, [key, multiplier]) => {
90
+ acc[key as SpacingSizeKey] = sizeUnit * multiplier;
91
+ return acc;
92
+ },
93
+ {} as Record<SpacingSizeKey, number>
94
+ );
95
+ }
96
+
97
+ /**
98
+ * Generate spacing CSS variables
99
+ *
100
+ * @param sizeUnit Base unit (px), default 4
101
+ */
102
+ export function genSpacingVars(sizeUnit = 4): Record<string, string> {
103
+ const result: Record<string, string> = {};
104
+
105
+ for (const [key, multiplier] of Object.entries(SPACING_MULTIPLIERS)) {
106
+ const px = sizeUnit * multiplier;
107
+ result[`spacing-${key}`] = `${px}px`;
108
+ result[`spacing${key.replace(/^(\d)/, '_$1')}`] = `${px}px`; // spacing_3xs, spacing_2xs, etc.
109
+ }
110
+
111
+ return result;
112
+ }
113
+
114
+ export default genSizeMapToken;
@@ -0,0 +1,20 @@
1
+ import type { ColorNeutralMapToken } from 'antd/lib/theme/interface';
2
+
3
+ // Re-export antd types for convenience
4
+ export type { ColorMapToken, ColorNeutralMapToken, MapToken, SeedToken } from 'antd/lib/theme/interface';
5
+
6
+ /** Color palette mapping (1-10 and 50-950 indexes) antd uses 1-10 indexes, Tailwind uses 50-950 indexes */
7
+ export interface ColorMap {
8
+ [key: number]: string;
9
+ }
10
+
11
+ /** Color palette generator function type */
12
+ export type GenerateColorMap = (baseColor: string) => ColorMap;
13
+
14
+ /** Neutral color generator function type */
15
+ export type GenerateNeutralColorMap = (bgBaseColor: string, textBaseColor: string) => ColorNeutralMapToken;
16
+
17
+ /** Palette generators configuration */
18
+ export interface PaletteGenerators {
19
+ generateNeutralColorPalettes: GenerateNeutralColorMap;
20
+ }
@@ -0,0 +1,55 @@
1
+ import { useEffect } from 'react';
2
+ import { useTheme } from '../hooks/use-theme';
3
+ import { getInternalStorage } from '../setup';
4
+ import { toggleAuxiliaryColorModes, toggleCssDarkMode } from '../utils';
5
+
6
+ const STORAGE_KEYS = {
7
+ darkMode: 'darkMode',
8
+ themeColor: 'themeColor',
9
+ themeSettings: 'themeSettings'
10
+ } as const;
11
+
12
+ const ThemeEffect = () => {
13
+ const { colourWeaknessMode, darkMode, grayscaleMode, settings, themeColors, updateWatermarkTimer, watermark } =
14
+ useTheme();
15
+
16
+ function cacheThemeSettings() {
17
+ if (import.meta.env.DEV) return;
18
+ getInternalStorage()?.set(STORAGE_KEYS.themeSettings, settings);
19
+ }
20
+
21
+ // Cache theme settings when page is closed or refreshed
22
+ useEffect(() => {
23
+ function handleBeforeUnload() {
24
+ cacheThemeSettings();
25
+ }
26
+
27
+ window.addEventListener('beforeunload', handleBeforeUnload);
28
+ return () => window.removeEventListener('beforeunload', handleBeforeUnload);
29
+ }, []);
30
+
31
+ // Watch dark mode
32
+ useEffect(() => {
33
+ toggleCssDarkMode(darkMode);
34
+ getInternalStorage()?.set(STORAGE_KEYS.darkMode, darkMode);
35
+ }, [darkMode]);
36
+
37
+ // Watch grayscale and colour weakness modes
38
+ useEffect(() => {
39
+ toggleAuxiliaryColorModes(grayscaleMode, colourWeaknessMode);
40
+ }, [grayscaleMode, colourWeaknessMode]);
41
+
42
+ // Watch theme colors change, update storage theme color
43
+ useEffect(() => {
44
+ getInternalStorage()?.set(STORAGE_KEYS.themeColor, themeColors.primary);
45
+ }, [themeColors]);
46
+
47
+ // Watch watermark settings to control timer
48
+ useEffect(() => {
49
+ updateWatermarkTimer();
50
+ }, [watermark.visible, watermark.enableTime]);
51
+
52
+ return null;
53
+ };
54
+
55
+ export default ThemeEffect;
@@ -0,0 +1,27 @@
1
+ import { SvgIcon } from '@shell/ui/compose';
2
+ import type { SegmentedOptions } from 'antd/es/segmented';
3
+ import Segmented from 'antd/es/segmented';
4
+ import { useTheme } from '../hooks/use-theme';
5
+ import { icons } from './shared';
6
+
7
+ const ThemeMode = ['auto', 'dark', 'light'] satisfies Theme.ThemeMode[];
8
+
9
+ const OPTIONS = Object.values(ThemeMode).map(item => {
10
+ const key = item;
11
+ return {
12
+ label: (
13
+ <div className="w-[70px] flex justify-center">
14
+ <SvgIcon className="text-icon-small h-28px" icon={icons[key]} />
15
+ </div>
16
+ ),
17
+ value: item
18
+ };
19
+ }) satisfies SegmentedOptions;
20
+
21
+ const ThemeSchemaSegmented = () => {
22
+ const { setThemeScheme, themeScheme } = useTheme();
23
+
24
+ return <Segmented className="bg-layout" options={OPTIONS} value={themeScheme} onChange={setThemeScheme} />;
25
+ };
26
+
27
+ export default ThemeSchemaSegmented;
@@ -0,0 +1,77 @@
1
+ import { ButtonIcon } from '@shell/ui/antd';
2
+ import type { ButtonProps, TooltipProps } from 'antd';
3
+ import type { CSSProperties } from 'react';
4
+ import { memo } from 'react';
5
+ import { useTheme } from '../hooks/use-theme';
6
+ import { icons } from './shared';
7
+
8
+ interface ThemeSchemaSwitchProps {
9
+ /** Custom class name */
10
+ className?: string;
11
+ /** Show tooltip */
12
+ showTooltip?: boolean;
13
+ /** Custom style */
14
+ style?: CSSProperties;
15
+ /** Tooltip content text */
16
+ tooltipContent?: string;
17
+ /** Tooltip placement */
18
+ tooltipPlacement?: TooltipProps['placement'];
19
+ }
20
+
21
+ const DEFAULT_ANIMATION_DURATION = 400;
22
+ const DEFAULT_ANIMATION_EASING = 'ease-in-out';
23
+
24
+ const ThemeSchemaSwitch = memo((props: ThemeSchemaSwitchProps) => {
25
+ const { className, showTooltip = true, style, tooltipContent = 'Theme Schema', tooltipPlacement = 'bottom' } = props;
26
+
27
+ const { themeScheme, toggleThemeScheme } = useTheme();
28
+
29
+ const resolvedTooltip = showTooltip ? tooltipContent : '';
30
+ const hoverAnimation = themeScheme === 'light' ? 'rotate' : 'scale';
31
+
32
+ const toggleDark: ButtonProps['onClick'] = async event => {
33
+ const isAppearanceTransition = !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
34
+
35
+ if (!isAppearanceTransition) {
36
+ toggleThemeScheme();
37
+ return;
38
+ }
39
+
40
+ await document.startViewTransition(() => {
41
+ toggleThemeScheme();
42
+ }).ready;
43
+
44
+ if (themeScheme === 'auto') return;
45
+
46
+ const x = event.clientX;
47
+ const y = event.clientY;
48
+ const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
49
+
50
+ const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`];
51
+
52
+ document.documentElement.animate(
53
+ {
54
+ clipPath
55
+ },
56
+ {
57
+ duration: DEFAULT_ANIMATION_DURATION,
58
+ easing: DEFAULT_ANIMATION_EASING,
59
+ pseudoElement: '::view-transition-new(root)'
60
+ }
61
+ );
62
+ };
63
+
64
+ return (
65
+ <ButtonIcon
66
+ className={className}
67
+ hoverAnimation={hoverAnimation}
68
+ icon={icons[themeScheme]}
69
+ style={style}
70
+ tooltipContent={resolvedTooltip}
71
+ tooltipPlacement={tooltipPlacement}
72
+ onClick={toggleDark}
73
+ />
74
+ );
75
+ });
76
+
77
+ export default ThemeSchemaSwitch;
@@ -0,0 +1,5 @@
1
+ export const icons: Record<Theme.ThemeMode, string> = {
2
+ dark: 'material-symbols:nightlight-rounded',
3
+ light: 'material-symbols:sunny',
4
+ auto: 'material-symbols:hdr-auto'
5
+ };
@@ -0,0 +1,108 @@
1
+ /** Theme scheme icons */
2
+ export const themeSchemeIcons: Record<'auto' | 'dark' | 'light', string> = {
3
+ dark: 'material-symbols:nightlight-rounded',
4
+ light: 'material-symbols:sunny',
5
+ auto: 'material-symbols:hdr-auto'
6
+ };
7
+
8
+ /** Default theme settings */
9
+ export const defaultThemeSettings: Theme.ThemeSetting = {
10
+ themeScheme: 'light',
11
+ grayscale: false,
12
+ colourWeakness: false,
13
+ recommendColor: false,
14
+ themeColor: '#6366F1',
15
+ themeRadius: 6,
16
+ otherColor: {
17
+ info: '#0EA5E9',
18
+ success: '#10B981',
19
+ warning: '#F59E0B',
20
+ error: '#F43F5E'
21
+ },
22
+ isInfoFollowPrimary: false,
23
+ themeTextSize: 14,
24
+ layout: {
25
+ mode: 'vertical',
26
+ scrollMode: 'content'
27
+ },
28
+ page: {
29
+ animate: true,
30
+ animateMode: 'fade-slide'
31
+ },
32
+ header: {
33
+ height: 56,
34
+ breadcrumb: {
35
+ visible: true,
36
+ showIcon: true
37
+ },
38
+ multilingual: {
39
+ visible: true
40
+ },
41
+ globalSearch: {
42
+ visible: true
43
+ }
44
+ },
45
+ tab: {
46
+ visible: true,
47
+ cache: true,
48
+ height: 44,
49
+ mode: 'chrome',
50
+ closeTabByMiddleClick: false
51
+ },
52
+ fixedHeaderAndTab: true,
53
+ sider: {
54
+ inverted: false,
55
+ width: 220,
56
+ collapsedWidth: 64,
57
+ mixWidth: 90,
58
+ mixCollapsedWidth: 64,
59
+ mixChildMenuWidth: 200,
60
+ autoSelectFirstMenu: false
61
+ },
62
+ footer: {
63
+ visible: true,
64
+ fixed: false,
65
+ height: 48,
66
+ right: true
67
+ },
68
+ watermark: {
69
+ visible: false,
70
+ text: 'SkyrocAdmin',
71
+ enableCustomText: true,
72
+ enableUserName: false,
73
+ enableTime: false,
74
+ timeFormat: 'YYYY-MM-DD HH:mm',
75
+ settings: {
76
+ font: {
77
+ fontSize: 16
78
+ },
79
+ height: 64,
80
+ offset: [12, 60],
81
+ rotate: -15,
82
+ width: 344,
83
+ zIndex: 9999
84
+ }
85
+ },
86
+ tokens: {
87
+ light: {
88
+ colors: {
89
+ container: 'rgb(255, 255, 255)',
90
+ layout: 'rgb(247, 250, 252)',
91
+ inverted: 'rgb(0, 20, 40)',
92
+ 'base-text': 'rgb(31, 31, 31)'
93
+ },
94
+ boxShadow: {
95
+ header: '0 1px 2px rgb(0, 21, 41, 0.08)',
96
+ sider: '2px 0 8px 0 rgb(29, 35, 41, 0.05)',
97
+ tab: '0 1px 2px rgb(0, 21, 41, 0.08)'
98
+ }
99
+ },
100
+ dark: {
101
+ colors: {
102
+ container: 'rgb(28, 28, 28)',
103
+ layout: 'rgb(18, 18, 18)',
104
+ 'base-text': 'rgb(224, 224, 224)'
105
+ }
106
+ }
107
+ }
108
+ };
@@ -0,0 +1 @@
1
+ export { defaultThemeSettings, themeSchemeIcons } from './default';
@@ -0,0 +1,2 @@
1
+ export { themeSettingsAtom, themeUserNameAtom, useTheme } from './use-theme';
2
+ export type { UseThemeReturn } from './use-theme';
@@ -0,0 +1,244 @@
1
+ import { getPaletteColorByNumber } from '@skyroc/color';
2
+ import { useNow, useSystemTheme } from '@skyroc/hooks/web';
3
+ import { formatDateTime } from '@skyroc/utils';
4
+ import { atom, useAtom, useAtomValue } from 'jotai';
5
+ import { useMemo } from 'react';
6
+ import { defaultThemeSettings } from '../config/default';
7
+ import type { ThemeColor, ThemeColorKey, ThemeLayoutMode, ThemeMode } from '../types';
8
+
9
+ /** Theme settings atom - single source of truth */
10
+ export const themeSettingsAtom = atom<Theme.ThemeSetting>(defaultThemeSettings);
11
+
12
+ /** 用户名 atom — 由 AntdProvider 写入,useTheme 内部读取 */
13
+ export const themeUserNameAtom = atom<string | undefined>(undefined);
14
+
15
+ /**
16
+ * Web theme hook
17
+ *
18
+ * Provides theme state management with a simple single-atom approach. Derived values (isDarkMode, themeColors, tokens)
19
+ * are computed via useMemo.
20
+ *
21
+ * UserName 通过 themeUserNameAtom 全局共享, 由 AntdProvider 自动写入,所有调用者无需传参即可获取完整的 watermarkContent。
22
+ */
23
+ export function useTheme() {
24
+ const userName = useAtomValue(themeUserNameAtom);
25
+
26
+ const [settings, setSettingsAtom] = useAtom(themeSettingsAtom);
27
+
28
+ const { isDarkMode: systemIsDark } = useSystemTheme();
29
+
30
+ const {
31
+ now: watermarkTime,
32
+ pause: pauseWatermarkTime,
33
+ resume: resumeWatermarkTime
34
+ } = useNow({ interval: 1000, immediate: settings.watermark.visible });
35
+
36
+ /** Dark mode */
37
+ const darkMode = useMemo(() => {
38
+ if (settings.themeScheme === 'auto') {
39
+ return systemIsDark;
40
+ }
41
+ return settings.themeScheme === 'dark';
42
+ }, [settings.themeScheme, systemIsDark]);
43
+
44
+ /** Grayscale mode */
45
+ const grayscaleMode = settings.grayscale;
46
+
47
+ /** Colour weakness mode */
48
+ const colourWeaknessMode = settings.colourWeakness;
49
+
50
+ /** Theme colors */
51
+ const themeColors = useMemo<ThemeColor>(() => {
52
+ const { isInfoFollowPrimary, otherColor, themeColor } = settings;
53
+ return {
54
+ primary: themeColor,
55
+ ...otherColor,
56
+ info: isInfoFollowPrimary ? themeColor : otherColor.info
57
+ };
58
+ }, [settings.themeColor, settings.otherColor, settings.isInfoFollowPrimary]);
59
+
60
+ /** Settings JSON for comparison */
61
+ const settingsJson = useMemo(() => JSON.stringify(settings), [settings]);
62
+
63
+ /** Watermark time date formatter */
64
+ const formattedWatermarkTime = useMemo(() => {
65
+ const { watermark } = settings;
66
+ return formatDateTime(watermarkTime, watermark.timeFormat);
67
+ }, [watermarkTime, settings.watermark.timeFormat]);
68
+
69
+ /** Watermark content */
70
+ const watermarkContent = useMemo(() => {
71
+ const { watermark } = settings;
72
+
73
+ if (!watermark.visible) return '';
74
+
75
+ let content = watermark.text;
76
+
77
+ if (watermark.enableUserName && userName) {
78
+ content = `${content} - ${userName}`;
79
+ }
80
+
81
+ if (watermark.enableTime) {
82
+ content = `${content} - ${formattedWatermarkTime}`;
83
+ }
84
+
85
+ return content;
86
+ }, [settings.watermark, userName, formattedWatermarkTime]);
87
+
88
+ /** Update settings with partial update */
89
+ function setSettings(update: Partial<Theme.ThemeSetting>) {
90
+ setSettingsAtom(prev => ({ ...prev, ...update }));
91
+ }
92
+
93
+ /**
94
+ * Set theme scheme
95
+ *
96
+ * @param themeScheme
97
+ */
98
+ function setThemeScheme(themeScheme: ThemeMode) {
99
+ setSettings({ themeScheme });
100
+ }
101
+
102
+ /**
103
+ * Set grayscale value
104
+ *
105
+ * @param isGrayscale
106
+ */
107
+ function setGrayscale(isGrayscale: boolean) {
108
+ setSettings({ grayscale: isGrayscale });
109
+ }
110
+
111
+ /**
112
+ * Set colourWeakness value
113
+ *
114
+ * @param isColourWeakness
115
+ */
116
+ function setColourWeakness(isColourWeakness: boolean) {
117
+ setSettings({ colourWeakness: isColourWeakness });
118
+ }
119
+
120
+ /** Toggle theme scheme */
121
+ function toggleThemeScheme() {
122
+ const themeSchemes: ThemeMode[] = ['light', 'dark', 'auto'];
123
+
124
+ const index = themeSchemes.findIndex(item => item === settings.themeScheme);
125
+
126
+ const nextIndex = index === themeSchemes.length - 1 ? 0 : index + 1;
127
+
128
+ const nextThemeScheme = themeSchemes[nextIndex];
129
+
130
+ setThemeScheme(nextThemeScheme);
131
+ }
132
+
133
+ /**
134
+ * Update theme colors
135
+ *
136
+ * @param key Theme color key
137
+ * @param color Theme color
138
+ */
139
+ function updateThemeColors(key: ThemeColorKey, color: string) {
140
+ let colorValue = color;
141
+
142
+ if (settings.recommendColor) {
143
+ // get a color palette by provided color and color name, and use the suitable color
144
+ colorValue = getPaletteColorByNumber(color, 500, 'recommended');
145
+ }
146
+
147
+ if (key === 'primary') {
148
+ setSettings({ themeColor: colorValue });
149
+ } else {
150
+ setSettings({ otherColor: { ...settings.otherColor, [key]: colorValue } });
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Set theme layout
156
+ *
157
+ * @param mode Theme layout mode
158
+ */
159
+ function setThemeLayout(mode: ThemeLayoutMode) {
160
+ setSettings({
161
+ layout: {
162
+ ...settings.layout,
163
+ mode
164
+ }
165
+ });
166
+ }
167
+
168
+ /**
169
+ * Set watermark enable user name
170
+ *
171
+ * @param enable Whether to enable user name watermark
172
+ */
173
+ function setWatermarkEnableUserName(enable: boolean) {
174
+ const update = {
175
+ watermark: {
176
+ ...settings.watermark,
177
+ enableUserName: enable
178
+ }
179
+ };
180
+
181
+ setSettings(update);
182
+ }
183
+
184
+ /**
185
+ * Set watermark enable time
186
+ *
187
+ * @param enable Whether to enable time watermark
188
+ */
189
+ function setWatermarkEnableTime(enable: boolean) {
190
+ const update = {
191
+ watermark: {
192
+ ...settings.watermark,
193
+ enableTime: enable
194
+ }
195
+ };
196
+
197
+ setSettings(update);
198
+ }
199
+
200
+ /** Only run timer when watermark is visible and time display is enabled */
201
+ function updateWatermarkTimer() {
202
+ const { watermark } = settings;
203
+
204
+ const shouldRunTimer = watermark.visible && watermark.enableTime;
205
+
206
+ if (shouldRunTimer) {
207
+ resumeWatermarkTime();
208
+ } else {
209
+ pauseWatermarkTime();
210
+ }
211
+ }
212
+
213
+ /** Reset to default settings */
214
+ function reset() {
215
+ setSettingsAtom(defaultThemeSettings);
216
+ }
217
+
218
+ return {
219
+ settings,
220
+ // Settings properties
221
+ ...settings,
222
+ // Computed values
223
+ darkMode,
224
+ themeColors,
225
+ settingsJson,
226
+ watermarkContent,
227
+ grayscaleMode,
228
+ colourWeaknessMode,
229
+ // Methods
230
+ setGrayscale,
231
+ setColourWeakness,
232
+ setThemeScheme,
233
+ toggleThemeScheme,
234
+ updateThemeColors,
235
+ updateWatermarkTimer,
236
+ setThemeLayout,
237
+ setWatermarkEnableUserName,
238
+ setWatermarkEnableTime,
239
+ setSettings,
240
+ reset
241
+ };
242
+ }
243
+
244
+ export type UseThemeReturn = ReturnType<typeof useTheme>;