@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.
- package/LICENSE +21 -0
- package/README.md +508 -0
- package/dist/cli.mjs +78 -0
- package/dist/config-BKkdncJS.mjs +987 -0
- package/dist/index.mjs +14 -0
- package/package.json +83 -0
- package/templates/admin/.env +62 -0
- package/templates/admin/.env.prod +7 -0
- package/templates/admin/.env.test +7 -0
- package/templates/admin/.oxlintrc.json +6 -0
- package/templates/admin/README.md +508 -0
- package/templates/admin/index.html +14 -0
- package/templates/admin/package.json +105 -0
- package/templates/admin/public/favicon.svg +3 -0
- package/templates/admin/src/App.tsx +71 -0
- package/templates/admin/src/assets/audio/wechat-style-notification.wav +0 -0
- package/templates/admin/src/assets/imgs/skyroc.jpg +0 -0
- package/templates/admin/src/assets/svg-icon/activity.svg +1 -0
- package/templates/admin/src/assets/svg-icon/at-sign.svg +1 -0
- package/templates/admin/src/assets/svg-icon/avatar.svg +1 -0
- package/templates/admin/src/assets/svg-icon/banner.svg +1 -0
- package/templates/admin/src/assets/svg-icon/cast.svg +1 -0
- package/templates/admin/src/assets/svg-icon/chrome.svg +1 -0
- package/templates/admin/src/assets/svg-icon/copy.svg +1 -0
- package/templates/admin/src/assets/svg-icon/custom-icon.svg +1 -0
- package/templates/admin/src/assets/svg-icon/empty-data.svg +1 -0
- package/templates/admin/src/assets/svg-icon/error.svg +1 -0
- package/templates/admin/src/assets/svg-icon/expectation.svg +1 -0
- package/templates/admin/src/assets/svg-icon/heart.svg +1 -0
- package/templates/admin/src/assets/svg-icon/logo.svg +15 -0
- package/templates/admin/src/assets/svg-icon/network-error.svg +1 -0
- package/templates/admin/src/assets/svg-icon/no-icon.svg +1 -0
- package/templates/admin/src/assets/svg-icon/no-permission.svg +1 -0
- package/templates/admin/src/assets/svg-icon/not-found.svg +1 -0
- package/templates/admin/src/assets/svg-icon/service-error.svg +1 -0
- package/templates/admin/src/bootstrap.tsx +60 -0
- package/templates/admin/src/components/SkyrocAvatar.tsx +13 -0
- package/templates/admin/src/components/SystemLogo.tsx +7 -0
- package/templates/admin/src/config.ts +125 -0
- package/templates/admin/src/features/antd/AntdProvider.tsx +21 -0
- package/templates/admin/src/features/auth/components/UserAvatar.tsx +76 -0
- package/templates/admin/src/features/auth/use-auth-form-rules.ts +83 -0
- package/templates/admin/src/features/auth/use-auth.ts +96 -0
- package/templates/admin/src/features/auth/use-login.ts +72 -0
- package/templates/admin/src/features/effects/GlobalEffect.tsx +15 -0
- package/templates/admin/src/features/menus/dynamic-routes.ts +10 -0
- package/templates/admin/src/features/menus/extras.ts +3 -0
- package/templates/admin/src/features/menus/menu-category.ts +14 -0
- package/templates/admin/src/features/menus/menu-config.ts +5 -0
- package/templates/admin/src/features/router/RouterProvider.tsx +18 -0
- package/templates/admin/src/features/router/guard.ts +97 -0
- package/templates/admin/src/features/router/index.ts +52 -0
- package/templates/admin/src/features/router/routeTree.gen.ts +237 -0
- package/templates/admin/src/features/router/router-ref.ts +24 -0
- package/templates/admin/src/locales/antd.ts +8 -0
- package/templates/admin/src/locales/index.ts +22 -0
- package/templates/admin/src/locales/sync.ts +14 -0
- package/templates/admin/src/main.tsx +9 -0
- package/templates/admin/src/pages/(admin)/home/index.tsx +46 -0
- package/templates/admin/src/pages/(admin)/layout.tsx +44 -0
- package/templates/admin/src/pages/(auth)/login/index.tsx +102 -0
- package/templates/admin/src/pages/(auth)/login/layout.tsx +71 -0
- package/templates/admin/src/pages/(auth)/login-out.tsx +27 -0
- package/templates/admin/src/pages/(errors)/403.tsx +16 -0
- package/templates/admin/src/pages/(errors)/404.tsx +16 -0
- package/templates/admin/src/pages/(errors)/500.tsx +16 -0
- package/templates/admin/src/pages/__root.tsx +54 -0
- package/templates/admin/src/pages/error.tsx +19 -0
- package/templates/admin/src/pages/index.tsx +14 -0
- package/templates/admin/src/pages/loading.tsx +45 -0
- package/templates/admin/src/pages/not-found.tsx +9 -0
- package/templates/admin/src/plugins/app.tsx +47 -0
- package/templates/admin/src/plugins/assets.ts +4 -0
- package/templates/admin/src/plugins/index.ts +32 -0
- package/templates/admin/src/service/adapter.ts +63 -0
- package/templates/admin/src/service/api/auth/api.ts +31 -0
- package/templates/admin/src/service/api/auth/hooks.ts +28 -0
- package/templates/admin/src/service/api/auth/index.ts +10 -0
- package/templates/admin/src/service/api/auth/keys.ts +7 -0
- package/templates/admin/src/service/api/auth/urls.ts +7 -0
- package/templates/admin/src/service/api/index.ts +2 -0
- package/templates/admin/src/service/api/route/api.ts +7 -0
- package/templates/admin/src/service/api/route/hooks.ts +21 -0
- package/templates/admin/src/service/api/route/index.ts +10 -0
- package/templates/admin/src/service/api/route/keys.ts +3 -0
- package/templates/admin/src/service/api/route/urls.ts +5 -0
- package/templates/admin/src/service/queryClient.ts +13 -0
- package/templates/admin/src/service/request/index.ts +62 -0
- package/templates/admin/src/styles/scss/global.scss +1 -0
- package/templates/admin/src/styles/scss/scrollbar.scss +28 -0
- package/templates/admin/src/types/auto-imports.d.ts +186 -0
- package/templates/admin/src/types/global.d.ts +16 -0
- package/templates/admin/src/types/router.d.ts +14 -0
- package/templates/admin/src/types/storage.d.ts +17 -0
- package/templates/admin/src/types/vite-env.d.ts +117 -0
- package/templates/admin/src/utils/common.tsx +38 -0
- package/templates/admin/src/utils/icon.ts +9 -0
- package/templates/admin/src/utils/service.ts +75 -0
- package/templates/admin/src/utils/storage.ts +7 -0
- package/templates/admin/tsconfig.json +22 -0
- package/templates/admin/uno.config.ts +18 -0
- package/templates/admin/vite.config.ts +13 -0
- package/templates/admin-shell/i18n/atoms/lang.ts +20 -0
- package/templates/admin-shell/i18n/config/default.ts +11 -0
- package/templates/admin-shell/i18n/features/lang/LangEffect.tsx +25 -0
- package/templates/admin-shell/i18n/features/lang/LangSwitch.tsx +49 -0
- package/templates/admin-shell/i18n/hooks/use-lang.ts +47 -0
- package/templates/admin-shell/i18n/i18n.ts +116 -0
- package/templates/admin-shell/i18n/index.ts +23 -0
- package/templates/admin-shell/i18n/langs/en-us/common.json +49 -0
- package/templates/admin-shell/i18n/langs/en-us/datatable.json +8 -0
- package/templates/admin-shell/i18n/langs/en-us/dropdown.json +9 -0
- package/templates/admin-shell/i18n/langs/en-us/form.json +27 -0
- package/templates/admin-shell/i18n/langs/en-us/icon.json +13 -0
- package/templates/admin-shell/i18n/langs/en-us/notification.json +20 -0
- package/templates/admin-shell/i18n/langs/en-us/page.json +442 -0
- package/templates/admin-shell/i18n/langs/en-us/request.json +8 -0
- package/templates/admin-shell/i18n/langs/en-us/route.json +84 -0
- package/templates/admin-shell/i18n/langs/en-us/system.json +9 -0
- package/templates/admin-shell/i18n/langs/en-us/theme.json +173 -0
- package/templates/admin-shell/i18n/langs/index.ts +63 -0
- package/templates/admin-shell/i18n/langs/zh-cn/common.json +49 -0
- package/templates/admin-shell/i18n/langs/zh-cn/datatable.json +8 -0
- package/templates/admin-shell/i18n/langs/zh-cn/dropdown.json +9 -0
- package/templates/admin-shell/i18n/langs/zh-cn/form.json +27 -0
- package/templates/admin-shell/i18n/langs/zh-cn/icon.json +13 -0
- package/templates/admin-shell/i18n/langs/zh-cn/notification.json +20 -0
- package/templates/admin-shell/i18n/langs/zh-cn/page.json +442 -0
- package/templates/admin-shell/i18n/langs/zh-cn/request.json +8 -0
- package/templates/admin-shell/i18n/langs/zh-cn/route.json +84 -0
- package/templates/admin-shell/i18n/langs/zh-cn/system.json +9 -0
- package/templates/admin-shell/i18n/langs/zh-cn/theme.json +173 -0
- package/templates/admin-shell/i18n/types/i18n.ts +29 -0
- package/templates/admin-shell/i18n/types.ts +53 -0
- package/templates/admin-shell/i18n/utils/helpers.ts +18 -0
- package/templates/admin-shell/layouts/AdminLayout.tsx +161 -0
- package/templates/admin-shell/layouts/constant.ts +56 -0
- package/templates/admin-shell/layouts/context.tsx +101 -0
- package/templates/admin-shell/layouts/features/menus/MenuBadge.tsx +76 -0
- package/templates/admin-shell/layouts/features/menus/dynamic-routes.ts +146 -0
- package/templates/admin-shell/layouts/features/menus/menu-generator.tsx +444 -0
- package/templates/admin-shell/layouts/features/menus/menu-renderer.tsx +149 -0
- package/templates/admin-shell/layouts/features/menus/permissions.ts +28 -0
- package/templates/admin-shell/layouts/features/menus/use-menus.ts +98 -0
- package/templates/admin-shell/layouts/features/use-route.ts +30 -0
- package/templates/admin-shell/layouts/index.ts +44 -0
- package/templates/admin-shell/layouts/materials/index.ts +6 -0
- package/templates/admin-shell/layouts/materials/libs/admin-layout/index.module.css +63 -0
- package/templates/admin-shell/layouts/materials/libs/admin-layout/index.module.css.d.ts +18 -0
- package/templates/admin-shell/layouts/materials/libs/admin-layout/index.tsx +238 -0
- package/templates/admin-shell/layouts/materials/libs/admin-layout/shared.ts +67 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/ButtonTab.tsx +44 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/ChromeTab.tsx +54 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/ChromeTabBg.tsx +30 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/SliderTab.tsx +44 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/SvgClose.tsx +51 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/hook.ts +34 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/index.module.css +120 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/index.module.css.d.ts +18 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/index.tsx +76 -0
- package/templates/admin-shell/layouts/materials/libs/page-tab/shared.ts +32 -0
- package/templates/admin-shell/layouts/materials/types/index.ts +322 -0
- package/templates/admin-shell/layouts/modules/AdminContent.tsx +285 -0
- package/templates/admin-shell/layouts/modules/AdminFooter.tsx +13 -0
- package/templates/admin-shell/layouts/modules/AdminLogo.tsx +28 -0
- package/templates/admin-shell/layouts/modules/AdminSider.tsx +50 -0
- package/templates/admin-shell/layouts/modules/admin-header/AdminHeader.tsx +132 -0
- package/templates/admin-shell/layouts/modules/admin-header/components/Breadcrumb.tsx +62 -0
- package/templates/admin-shell/layouts/modules/admin-header/components/ThemeButton.tsx +24 -0
- package/templates/admin-shell/layouts/modules/admin-menu/AdminMenu.tsx +37 -0
- package/templates/admin-shell/layouts/modules/admin-menu/components/FirstLevelMenu.tsx +156 -0
- package/templates/admin-shell/layouts/modules/admin-menu/components/HorizontalMenu.tsx +88 -0
- package/templates/admin-shell/layouts/modules/admin-menu/components/MenuPortal.tsx +28 -0
- package/templates/admin-shell/layouts/modules/admin-menu/components/VerticalMenu.tsx +123 -0
- package/templates/admin-shell/layouts/modules/admin-menu/enum.ts +47 -0
- package/templates/admin-shell/layouts/modules/admin-menu/modules/Horizontal.tsx +22 -0
- package/templates/admin-shell/layouts/modules/admin-menu/modules/TopHybridHeaderFirst.tsx +15 -0
- package/templates/admin-shell/layouts/modules/admin-menu/modules/TopHybridSidebarFirst.tsx +18 -0
- package/templates/admin-shell/layouts/modules/admin-menu/modules/Vertical.tsx +14 -0
- package/templates/admin-shell/layouts/modules/admin-menu/modules/VerticalHybridHeaderFirst.tsx +18 -0
- package/templates/admin-shell/layouts/modules/admin-menu/modules/VerticalMix.tsx +132 -0
- package/templates/admin-shell/layouts/modules/admin-search/AdminSearch.tsx +36 -0
- package/templates/admin-shell/layouts/modules/admin-search/components/SearchFooter.tsx +38 -0
- package/templates/admin-shell/layouts/modules/admin-search/components/SearchModal.tsx +171 -0
- package/templates/admin-shell/layouts/modules/admin-search/components/SearchResult.tsx +43 -0
- package/templates/admin-shell/layouts/modules/admin-tab/AdminTab.tsx +125 -0
- package/templates/admin-shell/layouts/modules/admin-tab/components/TabContextMenu.tsx +107 -0
- package/templates/admin-shell/layouts/modules/admin-tab/hooks/useTabScroll.ts +86 -0
- package/templates/admin-shell/layouts/modules/shared/logo.ts +42 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/ThemeDrawer.tsx +68 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/components/AnimatedCollapse.tsx +36 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/components/AnimatedItem.tsx +35 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/components/LayoutModeCard.tsx +110 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/components/SettingItem.tsx +31 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/ConfigOperation.tsx +53 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/CustomPicker.tsx +105 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/ThemeColor.tsx +58 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/ThemeSchema.tsx +42 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/ThemeToken.tsx +44 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/appearance/index.tsx +23 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/general/GlobalSettings.tsx +57 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/general/ThemeGeneral.tsx +20 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/general/WatermarkSettings.tsx +103 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/ContentSettings.tsx +100 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/FooterSettings.tsx +71 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/HeaderSettings.tsx +63 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/LayoutMode.tsx +73 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/SiderSettings.tsx +124 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/TabSettings.tsx +95 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/layout/ThemeLayout.tsx +32 -0
- package/templates/admin-shell/layouts/modules/theme-drawer/modules/preset/ThemePreset.tsx +132 -0
- package/templates/admin-shell/layouts/options.tsx +79 -0
- package/templates/admin-shell/layouts/setup.ts +102 -0
- package/templates/admin-shell/layouts/state/AdminEffect.tsx +56 -0
- package/templates/admin-shell/layouts/state/AdminTabEffect.tsx +28 -0
- package/templates/admin-shell/layouts/state/index.ts +3 -0
- package/templates/admin-shell/layouts/state/menus/MenuToggler.tsx +53 -0
- package/templates/admin-shell/layouts/state/menus/use-admin-menu-badges.ts +46 -0
- package/templates/admin-shell/layouts/state/menus/use-admin-menus.tsx +164 -0
- package/templates/admin-shell/layouts/state/tabs/index.ts +1 -0
- package/templates/admin-shell/layouts/state/tabs/shared.tsx +148 -0
- package/templates/admin-shell/layouts/state/tabs/use-admin-tab.ts +377 -0
- package/templates/admin-shell/layouts/state/use-admin-state.ts +118 -0
- package/templates/admin-shell/layouts/types/router.d.ts +10 -0
- package/templates/admin-shell/layouts/types/storage.ts +18 -0
- package/templates/admin-shell/notification/NotificationButton.tsx +91 -0
- package/templates/admin-shell/notification/NotificationContext.ts +8 -0
- package/templates/admin-shell/notification/NotificationPanel.tsx +194 -0
- package/templates/admin-shell/notification/NotificationProvider.tsx +59 -0
- package/templates/admin-shell/notification/index.ts +12 -0
- package/templates/admin-shell/notification/mock.ts +59 -0
- package/templates/admin-shell/notification/notification-store.ts +438 -0
- package/templates/admin-shell/notification/notification.css +60 -0
- package/templates/admin-shell/notification/types.ts +104 -0
- package/templates/admin-shell/notification/use-notification.ts +51 -0
- package/templates/admin-shell/notification/useNotificationContext.ts +14 -0
- package/templates/admin-shell/runtime/app-update.ts +156 -0
- package/templates/admin-shell/runtime/dayjs.ts +20 -0
- package/templates/admin-shell/runtime/iconify.ts +17 -0
- package/templates/admin-shell/runtime/index.ts +10 -0
- package/templates/admin-shell/runtime/nprogress.ts +25 -0
- package/templates/admin-shell/runtime/plugins.ts +62 -0
- package/templates/admin-shell/styles/global.css +54 -0
- package/templates/admin-shell/styles/nprogress.css +85 -0
- package/templates/admin-shell/styles/reset.css +378 -0
- package/templates/admin-shell/theme/antd/AntdProvider.tsx +106 -0
- package/templates/admin-shell/theme/antd/index.ts +23 -0
- package/templates/admin-shell/theme/antd/shared.ts +80 -0
- package/templates/admin-shell/theme/antd/ui.ts +250 -0
- package/templates/admin-shell/theme/antd-algorithm/algorithm/dark/colors.ts +99 -0
- package/templates/admin-shell/theme/antd-algorithm/algorithm/dark/index.ts +87 -0
- package/templates/admin-shell/theme/antd-algorithm/algorithm/default/colors.ts +91 -0
- package/templates/admin-shell/theme/antd-algorithm/algorithm/default/index.ts +77 -0
- package/templates/admin-shell/theme/antd-algorithm/index.ts +80 -0
- package/templates/admin-shell/theme/antd-algorithm/seed/index.ts +41 -0
- package/templates/admin-shell/theme/antd-algorithm/shared/colorAlgorithm.ts +10 -0
- package/templates/admin-shell/theme/antd-algorithm/shared/genColorMapToken.ts +165 -0
- package/templates/admin-shell/theme/antd-algorithm/shared/genCommonMapToken.ts +23 -0
- package/templates/admin-shell/theme/antd-algorithm/shared/genControlHeight.ts +14 -0
- package/templates/admin-shell/theme/antd-algorithm/shared/genFontMapToken.ts +274 -0
- package/templates/admin-shell/theme/antd-algorithm/shared/genRadiusMapToken.ts +139 -0
- package/templates/admin-shell/theme/antd-algorithm/shared/genSizeMapToken.ts +114 -0
- package/templates/admin-shell/theme/antd-algorithm/types/index.ts +20 -0
- package/templates/admin-shell/theme/components/ThemeEffect.tsx +55 -0
- package/templates/admin-shell/theme/components/ThemeSchemaSegmented.tsx +27 -0
- package/templates/admin-shell/theme/components/ThemeSchemaSwitch.tsx +77 -0
- package/templates/admin-shell/theme/components/shared.ts +5 -0
- package/templates/admin-shell/theme/config/default.ts +108 -0
- package/templates/admin-shell/theme/config/index.ts +1 -0
- package/templates/admin-shell/theme/hooks/index.ts +2 -0
- package/templates/admin-shell/theme/hooks/use-theme.ts +244 -0
- package/templates/admin-shell/theme/index.ts +78 -0
- package/templates/admin-shell/theme/presets/azir.json +39 -0
- package/templates/admin-shell/theme/presets/compact.json +38 -0
- package/templates/admin-shell/theme/presets/dark.json +93 -0
- package/templates/admin-shell/theme/presets/default.json +95 -0
- package/templates/admin-shell/theme/presets/index.ts +29 -0
- package/templates/admin-shell/theme/presets/shadcn.json +99 -0
- package/templates/admin-shell/theme/setup.ts +115 -0
- package/templates/admin-shell/theme/types/index.ts +27 -0
- package/templates/admin-shell/theme/types/theme.d.ts +316 -0
- package/templates/admin-shell/theme/utils/dark-mode.ts +46 -0
- package/templates/admin-shell/theme/utils/filters.ts +20 -0
- package/templates/admin-shell/theme/utils/index.ts +3 -0
- package/templates/admin-shell/theme/utils/settings.ts +43 -0
- package/templates/admin-shell/types/api/auth.d.ts +148 -0
- package/templates/admin-shell/types/api/common.d.ts +54 -0
- package/templates/admin-shell/types/api/route.d.ts +104 -0
- package/templates/admin-shell/types/api/service.d.ts +51 -0
- package/templates/admin-shell/types/api/system-manage.d.ts +160 -0
- package/templates/admin-shell/types/app/common.d.ts +31 -0
- package/templates/admin-shell/types/app/global.d.ts +71 -0
- package/templates/admin-shell/types/app/menu.d.ts +57 -0
- package/templates/admin-shell/types/app/router.d.ts +201 -0
- package/templates/admin-shell/types/app/storage.d.ts +10 -0
- package/templates/admin-shell/types/app/union-key.d.ts +156 -0
- package/templates/admin-shell/types/locales/i18n.d.ts +135 -0
- package/templates/admin-shell/ui/antd/components/AppTree.tsx +62 -0
- package/templates/admin-shell/ui/antd/components/BeyondHiding.tsx +42 -0
- package/templates/admin-shell/ui/antd/components/ButtonIcon.tsx +123 -0
- package/templates/admin-shell/ui/antd/components/ButtonLink.tsx +30 -0
- package/templates/admin-shell/ui/antd/components/ErrorBoundary.tsx +45 -0
- package/templates/admin-shell/ui/antd/components/ExceptionBase.tsx +69 -0
- package/templates/admin-shell/ui/antd/components/FullScreen.tsx +33 -0
- package/templates/admin-shell/ui/antd/components/PinToggler.tsx +35 -0
- package/templates/admin-shell/ui/antd/components/ReloadButton.tsx +20 -0
- package/templates/admin-shell/ui/antd/components/index.ts +12 -0
- package/templates/admin-shell/ui/antd/components/styles/button-icon-animations.css +246 -0
- package/templates/admin-shell/ui/antd/index.ts +1 -0
- package/templates/admin-shell/ui/antd/styles.d.ts +1 -0
- package/templates/admin-shell/ui/compose/animate-feature.ts +5 -0
- package/templates/admin-shell/ui/compose/components/BetterScroll.tsx +51 -0
- package/templates/admin-shell/ui/compose/components/DarkModeContainer.tsx +22 -0
- package/templates/admin-shell/ui/compose/components/FlipText.tsx +41 -0
- package/templates/admin-shell/ui/compose/components/I18nLabel.tsx +18 -0
- package/templates/admin-shell/ui/compose/components/LazyAnimate.tsx +10 -0
- package/templates/admin-shell/ui/compose/components/LookForward.tsx +24 -0
- package/templates/admin-shell/ui/compose/components/NumberTicker.tsx +105 -0
- package/templates/admin-shell/ui/compose/components/Portal.tsx +74 -0
- package/templates/admin-shell/ui/compose/components/SvgIcon.tsx +39 -0
- package/templates/admin-shell/ui/compose/components/TypingAnimation.tsx +83 -0
- package/templates/admin-shell/ui/compose/components/WaveBg.tsx +56 -0
- package/templates/admin-shell/ui/compose/components/index.ts +11 -0
- package/templates/admin-shell/ui/compose/index.ts +2 -0
- package/templates/admin-shell/ui/compose/table/DragContent.tsx +239 -0
- package/templates/admin-shell/ui/compose/table/TableHeaderOperation.tsx +210 -0
- package/templates/admin-shell/ui/compose/table/hooks.ts +196 -0
- package/templates/admin-shell/ui/compose/table/index.ts +16 -0
- package/templates/admin-shell/ui/compose/table/types.ts +244 -0
- package/templates/admin-shell/ui/compose/table/use-table-operate.ts +136 -0
- package/templates/admin-shell/ui/compose/table/use-table-scroll.ts +49 -0
- package/templates/admin-shell/ui/compose/table/use-table.ts +303 -0
- package/templates/admin.meta.json +756 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
/** Header config */
|
|
4
|
+
interface AdminLayoutHeaderConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Header class
|
|
7
|
+
*
|
|
8
|
+
* @default ''
|
|
9
|
+
*/
|
|
10
|
+
headerClass?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Header height
|
|
13
|
+
*
|
|
14
|
+
* @default 56px
|
|
15
|
+
*/
|
|
16
|
+
headerHeight?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Whether header is visible
|
|
19
|
+
*
|
|
20
|
+
* @default true
|
|
21
|
+
*/
|
|
22
|
+
headerVisible?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Tab config */
|
|
26
|
+
interface AdminLayoutTabConfig {
|
|
27
|
+
/**
|
|
28
|
+
* Tab class
|
|
29
|
+
*
|
|
30
|
+
* @default ''
|
|
31
|
+
*/
|
|
32
|
+
tabClass?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Tab height
|
|
35
|
+
*
|
|
36
|
+
* @default 48px
|
|
37
|
+
*/
|
|
38
|
+
tabHeight?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Whether tab is visible
|
|
41
|
+
*
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
tabVisible?: boolean;
|
|
45
|
+
/** Update siderCollapse */
|
|
46
|
+
updateSiderCollapse: () => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Sider config */
|
|
50
|
+
interface AdminLayoutSiderConfig {
|
|
51
|
+
/**
|
|
52
|
+
* Mobile sider class
|
|
53
|
+
*
|
|
54
|
+
* @default ''
|
|
55
|
+
*/
|
|
56
|
+
mobileSiderClass?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Sider class
|
|
59
|
+
*
|
|
60
|
+
* @default ''
|
|
61
|
+
*/
|
|
62
|
+
siderClass?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Sider collapse status
|
|
65
|
+
*
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
siderCollapse?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Sider width when collapse is true
|
|
71
|
+
*
|
|
72
|
+
* @default '64px'
|
|
73
|
+
*/
|
|
74
|
+
siderCollapsedWidth?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Whether sider is visible
|
|
77
|
+
*
|
|
78
|
+
* @default true
|
|
79
|
+
*/
|
|
80
|
+
siderVisible?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Sider width when collapse is false
|
|
83
|
+
*
|
|
84
|
+
* @default '220px'
|
|
85
|
+
*/
|
|
86
|
+
siderWidth?: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Content config */
|
|
90
|
+
export interface AdminLayoutContentConfig {
|
|
91
|
+
/**
|
|
92
|
+
* Content class
|
|
93
|
+
*
|
|
94
|
+
* @default ''
|
|
95
|
+
*/
|
|
96
|
+
contentClass?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Whether content is full the page
|
|
99
|
+
*
|
|
100
|
+
* If true, other elements will be hidden by `display: none`
|
|
101
|
+
*/
|
|
102
|
+
fullContent?: boolean;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Footer config */
|
|
106
|
+
export interface AdminLayoutFooterConfig {
|
|
107
|
+
/**
|
|
108
|
+
* Whether footer is fixed
|
|
109
|
+
*
|
|
110
|
+
* @default true
|
|
111
|
+
*/
|
|
112
|
+
fixedFooter?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Footer class
|
|
115
|
+
*
|
|
116
|
+
* @default ''
|
|
117
|
+
*/
|
|
118
|
+
footerClass?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Footer height
|
|
121
|
+
*
|
|
122
|
+
* @default 48px
|
|
123
|
+
*/
|
|
124
|
+
footerHeight?: number;
|
|
125
|
+
/**
|
|
126
|
+
* Whether footer is visible
|
|
127
|
+
*
|
|
128
|
+
* @default true
|
|
129
|
+
*/
|
|
130
|
+
footerVisible?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Whether footer is on the right side
|
|
133
|
+
*
|
|
134
|
+
* When the layout is vertical, the footer is on the right side
|
|
135
|
+
*/
|
|
136
|
+
rightFooter?: boolean;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Layout mode
|
|
141
|
+
*
|
|
142
|
+
* - Horizontal
|
|
143
|
+
* - Vertical
|
|
144
|
+
*/
|
|
145
|
+
export type LayoutMode = 'horizontal' | 'vertical';
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The scroll mode when content overflow
|
|
149
|
+
*
|
|
150
|
+
* - Wrapper: the layout component's wrapper element has a scrollbar
|
|
151
|
+
* - Content: the layout component's content element has a scrollbar
|
|
152
|
+
*
|
|
153
|
+
* @default 'wrapper'
|
|
154
|
+
*/
|
|
155
|
+
export type LayoutScrollMode = 'content' | 'wrapper';
|
|
156
|
+
export type Slots = {
|
|
157
|
+
/** Main */
|
|
158
|
+
children?: React.ReactNode;
|
|
159
|
+
/** Footer */
|
|
160
|
+
Footer?: React.ReactNode;
|
|
161
|
+
/** Header */
|
|
162
|
+
Header?: React.ReactNode;
|
|
163
|
+
/** Sider */
|
|
164
|
+
Sider?: React.ReactNode;
|
|
165
|
+
/** Tab */
|
|
166
|
+
Tab?: React.ReactNode;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/** Admin layout props */
|
|
170
|
+
export interface AdminLayoutProps
|
|
171
|
+
extends
|
|
172
|
+
AdminLayoutHeaderConfig,
|
|
173
|
+
AdminLayoutTabConfig,
|
|
174
|
+
AdminLayoutSiderConfig,
|
|
175
|
+
AdminLayoutContentConfig,
|
|
176
|
+
AdminLayoutFooterConfig,
|
|
177
|
+
Slots {
|
|
178
|
+
/**
|
|
179
|
+
* The common class of the layout
|
|
180
|
+
*
|
|
181
|
+
* Is can be used to configure the transition animation
|
|
182
|
+
*
|
|
183
|
+
* @default 'transition-all-300'
|
|
184
|
+
*/
|
|
185
|
+
commonClass?: string;
|
|
186
|
+
/**
|
|
187
|
+
* Whether fix the header and tab
|
|
188
|
+
*
|
|
189
|
+
* @default true
|
|
190
|
+
*/
|
|
191
|
+
fixedTop?: boolean;
|
|
192
|
+
/** Is mobile layout */
|
|
193
|
+
isMobile?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* The max z-index of the layout
|
|
196
|
+
*
|
|
197
|
+
* The z-index of Header,Tab,Sider and Footer will not exceed this value
|
|
198
|
+
*/
|
|
199
|
+
maxZIndex?: number;
|
|
200
|
+
/**
|
|
201
|
+
* Layout mode
|
|
202
|
+
*
|
|
203
|
+
* - {@link LayoutMode}
|
|
204
|
+
*/
|
|
205
|
+
mode?: LayoutMode;
|
|
206
|
+
/** The class of the scroll element */
|
|
207
|
+
scrollElClass?: string;
|
|
208
|
+
/**
|
|
209
|
+
* The id of the scroll element of the layout
|
|
210
|
+
*
|
|
211
|
+
* It can be used to get the corresponding Dom and scroll it
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* use the default id by import
|
|
215
|
+
* ```ts
|
|
216
|
+
* import { adminLayoutScrollElId } from '@sa/vue-materials';
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* @default
|
|
220
|
+
* ```ts
|
|
221
|
+
* const adminLayoutScrollElId = '__ADMIN_LAYOUT_SCROLL_EL_ID__'
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
scrollElId?: string;
|
|
225
|
+
/**
|
|
226
|
+
* Scroll mode
|
|
227
|
+
*
|
|
228
|
+
* - {@link ScrollMode}
|
|
229
|
+
*/
|
|
230
|
+
scrollMode?: LayoutScrollMode;
|
|
231
|
+
/** The class of the scroll wrapper element */
|
|
232
|
+
scrollWrapperClass?: string;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
type Kebab<S extends string> = S extends Uncapitalize<S> ? S : `-${Uncapitalize<S>}`;
|
|
236
|
+
|
|
237
|
+
type KebabCase<S extends string> = S extends `${infer Start}${infer End}`
|
|
238
|
+
? `${Uncapitalize<Start>}${KebabCase<Kebab<End>>}`
|
|
239
|
+
: S;
|
|
240
|
+
|
|
241
|
+
type Prefix = '--soy-';
|
|
242
|
+
|
|
243
|
+
export type LayoutCssVarsProps = Pick<
|
|
244
|
+
AdminLayoutProps,
|
|
245
|
+
'footerHeight' | 'headerHeight' | 'siderCollapsedWidth' | 'siderWidth' | 'tabHeight'
|
|
246
|
+
> & {
|
|
247
|
+
footerZIndex?: number;
|
|
248
|
+
headerZIndex?: number;
|
|
249
|
+
mobileSiderZIndex?: number;
|
|
250
|
+
siderZIndex?: number;
|
|
251
|
+
tabZIndex?: number;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
export type LayoutCssVars = {
|
|
255
|
+
[K in keyof LayoutCssVarsProps as `${Prefix}${KebabCase<K>}`]: string | number;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* The mode of the tab
|
|
260
|
+
*
|
|
261
|
+
* - Button: button style
|
|
262
|
+
* - Chrome: chrome style
|
|
263
|
+
*
|
|
264
|
+
* @default chrome
|
|
265
|
+
*/
|
|
266
|
+
export type PageTabMode = 'button' | 'chrome' | 'slider';
|
|
267
|
+
export type ButtonTabProps = PageTabProps &
|
|
268
|
+
Omit<React.ComponentProps<'div'>, 'className' | 'onClick' | 'prefix' | 'style'>;
|
|
269
|
+
export interface PageTabProps {
|
|
270
|
+
/** Whether the tab is active */
|
|
271
|
+
active?: boolean;
|
|
272
|
+
|
|
273
|
+
/** The color of the active tab */
|
|
274
|
+
activeColor?: string;
|
|
275
|
+
/** The class of the button tab */
|
|
276
|
+
buttonClass?: string;
|
|
277
|
+
/** The class of the chrome tab */
|
|
278
|
+
chromeClass?: string;
|
|
279
|
+
className?: string;
|
|
280
|
+
/**
|
|
281
|
+
* Whether the tab is closable
|
|
282
|
+
*
|
|
283
|
+
* Show the close icon when true
|
|
284
|
+
*/
|
|
285
|
+
closable?: boolean;
|
|
286
|
+
/**
|
|
287
|
+
* The common class of the layout
|
|
288
|
+
*
|
|
289
|
+
* Is can be used to configure the transition animation
|
|
290
|
+
*
|
|
291
|
+
* @default 'transition-all-300'
|
|
292
|
+
*/
|
|
293
|
+
commonClass?: string;
|
|
294
|
+
/** Whether is dark mode */
|
|
295
|
+
darkMode?: boolean;
|
|
296
|
+
handleClose?: () => void;
|
|
297
|
+
/**
|
|
298
|
+
* The mode of the tab
|
|
299
|
+
*
|
|
300
|
+
* - {@link TabMode}
|
|
301
|
+
*/
|
|
302
|
+
mode?: PageTabMode;
|
|
303
|
+
onClick: () => void;
|
|
304
|
+
prefix: React.ReactNode;
|
|
305
|
+
/** The class of the slider tab */
|
|
306
|
+
sliderClass?: string;
|
|
307
|
+
style?: React.CSSProperties;
|
|
308
|
+
suffix?: React.ReactNode;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export type PageTabCssVarsProps = {
|
|
312
|
+
primaryColor: string;
|
|
313
|
+
primaryColor1: string;
|
|
314
|
+
primaryColor2: string;
|
|
315
|
+
primaryColorOpacity1: string;
|
|
316
|
+
primaryColorOpacity2: string;
|
|
317
|
+
primaryColorOpacity3: string;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
export type PageTabCssVars = {
|
|
321
|
+
[K in keyof PageTabCssVarsProps as `${Prefix}${KebabCase<K>}`]: string | number;
|
|
322
|
+
};
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { useSettingsTheme } from '@shell/theme';
|
|
2
|
+
import { Outlet, RouterContextProvider, useRouter } from '@tanstack/react-router';
|
|
3
|
+
import type { AnyRouter, RouterState } from '@tanstack/react-router';
|
|
4
|
+
import type { Transition, Variants } from 'motion/react';
|
|
5
|
+
import { motion } from 'motion/react';
|
|
6
|
+
import { useRef } from 'react';
|
|
7
|
+
import type { ReactNode } from 'react';
|
|
8
|
+
|
|
9
|
+
import { useAdminLayoutContext } from '../context';
|
|
10
|
+
import { useRoute } from '../features/use-route';
|
|
11
|
+
import { getTabIdByRoute } from '../state/tabs/shared';
|
|
12
|
+
import { useAdminTab } from '../state/tabs/use-admin-tab';
|
|
13
|
+
import { useAdminState } from '../state/use-admin-state';
|
|
14
|
+
|
|
15
|
+
const pageAnimationVariants: Record<Theme.ThemePageAnimateMode, Variants> = {
|
|
16
|
+
fade: {
|
|
17
|
+
initial: { opacity: 0 },
|
|
18
|
+
animate: { opacity: 1 }
|
|
19
|
+
},
|
|
20
|
+
'fade-slide': {
|
|
21
|
+
initial: { opacity: 0, x: -30 },
|
|
22
|
+
animate: { opacity: 1, x: 0 }
|
|
23
|
+
},
|
|
24
|
+
'fade-bottom': {
|
|
25
|
+
initial: { opacity: 0, y: '-10%' },
|
|
26
|
+
animate: { opacity: 1, y: 0 }
|
|
27
|
+
},
|
|
28
|
+
'fade-scale': {
|
|
29
|
+
initial: { opacity: 0, scale: 1.2 },
|
|
30
|
+
animate: { opacity: 1, scale: 1 }
|
|
31
|
+
},
|
|
32
|
+
'zoom-fade': {
|
|
33
|
+
initial: { opacity: 0, scale: 0.92 },
|
|
34
|
+
animate: { opacity: 1, scale: 1 }
|
|
35
|
+
},
|
|
36
|
+
'zoom-out': {
|
|
37
|
+
initial: { opacity: 0, scale: 0 },
|
|
38
|
+
animate: { opacity: 1, scale: 1 }
|
|
39
|
+
},
|
|
40
|
+
none: {
|
|
41
|
+
initial: {},
|
|
42
|
+
animate: {}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const pageAnimationTransitions: Record<Theme.ThemePageAnimateMode, Transition> = {
|
|
47
|
+
fade: { duration: 0.3, ease: 'easeInOut' },
|
|
48
|
+
'fade-slide': { duration: 0.3, ease: 'easeInOut' },
|
|
49
|
+
'fade-bottom': { duration: 0.3, ease: 'easeInOut' },
|
|
50
|
+
'fade-scale': { duration: 0.28, ease: 'easeInOut' },
|
|
51
|
+
'zoom-fade': { duration: 0.3, ease: 'easeOut' },
|
|
52
|
+
'zoom-out': { duration: 0.15, ease: 'easeOut' },
|
|
53
|
+
none: { duration: 0 }
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
interface KeepAliveKeysOptions {
|
|
57
|
+
activeCacheKey: string;
|
|
58
|
+
routeKeepAlive?: boolean | null;
|
|
59
|
+
tabs: App.Global.Tab[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
type RouterStateSnapshot = RouterState<AnyRouter['routeTree']>;
|
|
63
|
+
|
|
64
|
+
interface KeepAliveEntry {
|
|
65
|
+
/** 当前缓存项最近一次激活时的内容 key。 */
|
|
66
|
+
contentKey: string;
|
|
67
|
+
/** 当前缓存项对应的路由缓存 key。 */
|
|
68
|
+
key: string;
|
|
69
|
+
/** 当前缓存项最近一次激活时的 TanStack Router 状态快照。 */
|
|
70
|
+
routeState: RouterStateSnapshot;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface StaticRouterStore {
|
|
74
|
+
/** 兼容 @tanstack/react-store 的快照读取方法。 */
|
|
75
|
+
get: () => RouterStateSnapshot;
|
|
76
|
+
/** 静态路由状态,供 TanStack 的 useRouterState 读取。 */
|
|
77
|
+
readonly state: RouterStateSnapshot;
|
|
78
|
+
/** 静态快照不会主动发布更新,但需要提供订阅接口。 */
|
|
79
|
+
subscribe: () => { unsubscribe: () => void };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface KeepAliveEntriesOptions {
|
|
83
|
+
activeCacheKey: string;
|
|
84
|
+
contentKey: string;
|
|
85
|
+
entries: KeepAliveEntry[];
|
|
86
|
+
keepAliveKeys: string[];
|
|
87
|
+
routeState: RouterStateSnapshot;
|
|
88
|
+
shouldRenderContent: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface CachedRoutePaneProps {
|
|
92
|
+
/** 当前缓存项是否是正在展示的页面。 */
|
|
93
|
+
active: boolean;
|
|
94
|
+
/** 当前页面动画模式。 */
|
|
95
|
+
animationMode: Theme.ThemePageAnimateMode;
|
|
96
|
+
/** 当前缓存项的路由缓存 key。 */
|
|
97
|
+
cacheKey: string;
|
|
98
|
+
/** 自定义内容插槽,未提供时渲染 TanStack Router Outlet。 */
|
|
99
|
+
content?: ReactNode;
|
|
100
|
+
/** 缓存项记录的内容 key,用于路由刷新时重新挂载内容。 */
|
|
101
|
+
contentKey: string;
|
|
102
|
+
/** 当前缓存项使用的路由状态快照。 */
|
|
103
|
+
routeState: RouterStateSnapshot;
|
|
104
|
+
/** 应用于页面动画的 transition 配置。 */
|
|
105
|
+
transition: Transition;
|
|
106
|
+
/** 应用于页面动画的 variants 配置。 */
|
|
107
|
+
variants: Variants;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getPageAnimationMode(page?: Theme.ThemeSetting['page']) {
|
|
111
|
+
if (!page?.animate) {
|
|
112
|
+
return 'none';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return page.animateMode;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function getKeepAliveKeys(options: KeepAliveKeysOptions) {
|
|
119
|
+
const { activeCacheKey, routeKeepAlive, tabs } = options;
|
|
120
|
+
|
|
121
|
+
const keepAliveKeys = tabs.filter(tab => tab.keepAlive).map(tab => tab.id);
|
|
122
|
+
|
|
123
|
+
if (routeKeepAlive && activeCacheKey && !keepAliveKeys.includes(activeCacheKey)) {
|
|
124
|
+
keepAliveKeys.push(activeCacheKey);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return keepAliveKeys;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getRouteCacheKey(route: ReturnType<typeof useRoute>) {
|
|
131
|
+
return getTabIdByRoute(route.originPath, route.staticData?.tab?.multi ?? false, route.fullPath);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function getRouteContentKey(route: ReturnType<typeof useRoute>) {
|
|
135
|
+
if (route.staticData?.tab?.multi) {
|
|
136
|
+
return route.fullPath || route.pathname;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return route.pathname || route.originPath;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function createStaticRouterStore(routeState: RouterStateSnapshot): StaticRouterStore {
|
|
143
|
+
return {
|
|
144
|
+
get state() {
|
|
145
|
+
return routeState;
|
|
146
|
+
},
|
|
147
|
+
get() {
|
|
148
|
+
return routeState;
|
|
149
|
+
},
|
|
150
|
+
subscribe() {
|
|
151
|
+
return {
|
|
152
|
+
unsubscribe() {}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function createSnapshotRouter(router: AnyRouter, routeState: RouterStateSnapshot) {
|
|
159
|
+
const snapshotRouter = Object.assign(Object.create(Object.getPrototypeOf(router)), router) as AnyRouter;
|
|
160
|
+
|
|
161
|
+
snapshotRouter.__store = createStaticRouterStore(routeState) as unknown as AnyRouter['__store'];
|
|
162
|
+
snapshotRouter.latestLocation = routeState.location;
|
|
163
|
+
|
|
164
|
+
return snapshotRouter;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function getKeepAliveEntries(options: KeepAliveEntriesOptions) {
|
|
168
|
+
const { activeCacheKey, contentKey, entries, keepAliveKeys, routeState, shouldRenderContent } = options;
|
|
169
|
+
|
|
170
|
+
const keepAliveKeySet = new Set(keepAliveKeys);
|
|
171
|
+
const nextEntries = entries.filter(entry => keepAliveKeySet.has(entry.key));
|
|
172
|
+
|
|
173
|
+
if (!shouldRenderContent) {
|
|
174
|
+
return nextEntries.filter(entry => entry.key !== activeCacheKey);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!keepAliveKeySet.has(activeCacheKey)) {
|
|
178
|
+
return nextEntries;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const activeEntry: KeepAliveEntry = {
|
|
182
|
+
key: activeCacheKey,
|
|
183
|
+
contentKey,
|
|
184
|
+
routeState
|
|
185
|
+
};
|
|
186
|
+
const activeEntryIndex = nextEntries.findIndex(entry => entry.key === activeCacheKey);
|
|
187
|
+
|
|
188
|
+
if (activeEntryIndex === -1) {
|
|
189
|
+
return [...nextEntries, activeEntry];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return nextEntries.map(entry => (entry.key === activeCacheKey ? activeEntry : entry));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const CachedRoutePane = (props: CachedRoutePaneProps) => {
|
|
196
|
+
const { active, animationMode, cacheKey, content, contentKey, routeState, transition, variants } = props;
|
|
197
|
+
|
|
198
|
+
const router = useRouter();
|
|
199
|
+
const snapshotRouter = createSnapshotRouter(router, routeState);
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<div
|
|
203
|
+
aria-hidden={!active}
|
|
204
|
+
className="h-full"
|
|
205
|
+
data-keep-alive-key={cacheKey}
|
|
206
|
+
style={{ display: active ? undefined : 'none' }}
|
|
207
|
+
>
|
|
208
|
+
<RouterContextProvider router={snapshotRouter}>
|
|
209
|
+
<motion.div
|
|
210
|
+
animate="animate"
|
|
211
|
+
className="h-full"
|
|
212
|
+
data-page-animation={animationMode}
|
|
213
|
+
initial={false}
|
|
214
|
+
key={contentKey}
|
|
215
|
+
transition={transition}
|
|
216
|
+
variants={variants}
|
|
217
|
+
>
|
|
218
|
+
{content ?? <Outlet />}
|
|
219
|
+
</motion.div>
|
|
220
|
+
</RouterContextProvider>
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const GlobalContent = () => {
|
|
226
|
+
const { content } = useAdminLayoutContext();
|
|
227
|
+
const route = useRoute();
|
|
228
|
+
const router = useRouter();
|
|
229
|
+
const { tabs } = useAdminTab();
|
|
230
|
+
const { reloadFlag } = useAdminState();
|
|
231
|
+
const { page } = useSettingsTheme();
|
|
232
|
+
const keepAliveEntriesRef = useRef<KeepAliveEntry[]>([]);
|
|
233
|
+
|
|
234
|
+
const animationMode = getPageAnimationMode(page);
|
|
235
|
+
const contentKey = getRouteContentKey(route);
|
|
236
|
+
const activeCacheKey = getRouteCacheKey(route) || contentKey;
|
|
237
|
+
const routeKeepAlive = route.staticData?.keepAlive;
|
|
238
|
+
const keepAliveKeys = getKeepAliveKeys({ activeCacheKey, routeKeepAlive, tabs });
|
|
239
|
+
const shouldRenderContent = reloadFlag !== false;
|
|
240
|
+
const keepAliveEntries = getKeepAliveEntries({
|
|
241
|
+
activeCacheKey,
|
|
242
|
+
contentKey,
|
|
243
|
+
entries: keepAliveEntriesRef.current,
|
|
244
|
+
keepAliveKeys,
|
|
245
|
+
routeState: router.state,
|
|
246
|
+
shouldRenderContent
|
|
247
|
+
});
|
|
248
|
+
const isActiveRouteCached = keepAliveEntries.some(entry => entry.key === activeCacheKey);
|
|
249
|
+
|
|
250
|
+
keepAliveEntriesRef.current = keepAliveEntries;
|
|
251
|
+
|
|
252
|
+
return (
|
|
253
|
+
<div className="h-full grow overflow-x-hidden bg-layout p-16px">
|
|
254
|
+
{keepAliveEntries.map(entry => (
|
|
255
|
+
<CachedRoutePane
|
|
256
|
+
active={entry.key === activeCacheKey}
|
|
257
|
+
animationMode={animationMode}
|
|
258
|
+
cacheKey={entry.key}
|
|
259
|
+
content={content}
|
|
260
|
+
contentKey={entry.contentKey}
|
|
261
|
+
key={entry.key}
|
|
262
|
+
routeState={entry.routeState}
|
|
263
|
+
transition={pageAnimationTransitions[animationMode]}
|
|
264
|
+
variants={pageAnimationVariants[animationMode]}
|
|
265
|
+
/>
|
|
266
|
+
))}
|
|
267
|
+
|
|
268
|
+
{shouldRenderContent && !isActiveRouteCached && (
|
|
269
|
+
<motion.div
|
|
270
|
+
animate="animate"
|
|
271
|
+
className="h-full"
|
|
272
|
+
data-page-animation={animationMode}
|
|
273
|
+
initial="initial"
|
|
274
|
+
key={contentKey}
|
|
275
|
+
transition={pageAnimationTransitions[animationMode]}
|
|
276
|
+
variants={pageAnimationVariants[animationMode]}
|
|
277
|
+
>
|
|
278
|
+
{content ?? <Outlet />}
|
|
279
|
+
</motion.div>
|
|
280
|
+
)}
|
|
281
|
+
</div>
|
|
282
|
+
);
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
export default GlobalContent;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DarkModeContainer } from '@shell/ui/compose';
|
|
2
|
+
|
|
3
|
+
const GlobalFooter = () => {
|
|
4
|
+
return (
|
|
5
|
+
<DarkModeContainer className="h-full flex-center">
|
|
6
|
+
<a href="https://github.com/Ohh-889/skyroc-admin/blob/master/LICENSE" rel="noopener noreferrer" target="_blank">
|
|
7
|
+
Copyright MIT © 2021 Skyroc
|
|
8
|
+
</a>
|
|
9
|
+
</DarkModeContainer>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default GlobalFooter;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Link } from '@tanstack/react-router';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
|
|
4
|
+
import type { AdminLayoutLogoProps } from '../context';
|
|
5
|
+
import { getAdminLayoutsOptions } from '../setup';
|
|
6
|
+
|
|
7
|
+
const AdminLogo = (props: AdminLayoutLogoProps) => {
|
|
8
|
+
const { className, logo, showTitle = true, style, title, to } = props;
|
|
9
|
+
|
|
10
|
+
const targetPath = to ?? getAdminLayoutsOptions().defaultHome;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Link className={clsx('w-full flex-center nowrap-hidden', className)} style={style} to={targetPath}>
|
|
14
|
+
{logo}
|
|
15
|
+
|
|
16
|
+
{title ? (
|
|
17
|
+
<h2
|
|
18
|
+
className="pl-8px text-md text-primary font-bold transition duration-300 ease-in-out"
|
|
19
|
+
style={{ display: showTitle ? 'block' : 'none' }}
|
|
20
|
+
>
|
|
21
|
+
{title}
|
|
22
|
+
</h2>
|
|
23
|
+
) : null}
|
|
24
|
+
</Link>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default AdminLogo;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useSettingsTheme } from '@shell/theme';
|
|
2
|
+
import { DarkModeContainer } from '@shell/ui/compose';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
GLOBAL_SIDER_MENU_ID,
|
|
7
|
+
LAYOUT_MODE_TOP_HYBRID_HEADER_FIRST,
|
|
8
|
+
LAYOUT_MODE_TOP_HYBRID_SIDEBAR_FIRST,
|
|
9
|
+
LAYOUT_MODE_VERTICAL
|
|
10
|
+
} from '../constant';
|
|
11
|
+
import { useAdminLayoutContext } from '../context';
|
|
12
|
+
import { useAdminState } from '../state/use-admin-state';
|
|
13
|
+
import LayoutLogo from './shared/logo';
|
|
14
|
+
|
|
15
|
+
const GlobalSider = memo(() => {
|
|
16
|
+
const { logo, logoComponent, logoTitle, logoTo } = useAdminLayoutContext();
|
|
17
|
+
const { darkMode, header, layout, sider } = useSettingsTheme();
|
|
18
|
+
const { siderCollapse } = useAdminState();
|
|
19
|
+
|
|
20
|
+
const isTopHybridSidebarFirst = layout.mode === LAYOUT_MODE_TOP_HYBRID_SIDEBAR_FIRST;
|
|
21
|
+
const isTopHybridHeaderFirst = layout.mode === LAYOUT_MODE_TOP_HYBRID_HEADER_FIRST;
|
|
22
|
+
|
|
23
|
+
const darkMenu = !darkMode && !isTopHybridSidebarFirst && !isTopHybridHeaderFirst && sider.inverted;
|
|
24
|
+
|
|
25
|
+
const showLogo = layout.mode === LAYOUT_MODE_VERTICAL;
|
|
26
|
+
|
|
27
|
+
const headerHeight = header.height;
|
|
28
|
+
|
|
29
|
+
const menuWrapperClass = showLogo ? 'flex-1-hidden' : 'h-full';
|
|
30
|
+
|
|
31
|
+
const hasLogo = Boolean(logo || logoComponent || logoTitle);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<DarkModeContainer className="size-full flex-col-stretch shadow-sider" inverted={darkMenu}>
|
|
35
|
+
{showLogo && hasLogo ? (
|
|
36
|
+
<LayoutLogo
|
|
37
|
+
logo={logo}
|
|
38
|
+
logoComponent={logoComponent}
|
|
39
|
+
showTitle={!siderCollapse}
|
|
40
|
+
style={{ height: `${headerHeight}px` }}
|
|
41
|
+
title={logoTitle}
|
|
42
|
+
to={logoTo}
|
|
43
|
+
/>
|
|
44
|
+
) : null}
|
|
45
|
+
<div className={menuWrapperClass} id={GLOBAL_SIDER_MENU_ID} />
|
|
46
|
+
</DarkModeContainer>
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export default GlobalSider;
|