@smartos-lib/components 1.7.0-beta.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintrc +12 -0
- package/.eslintrc-auto-import.json +332 -0
- package/Components.code-workspace +143 -0
- package/LICENSE +21 -0
- package/dist/smart-docx-editor/index.d.ts +2 -0
- package/dist/smart-docx-editor/index.js +68 -0
- package/dist/smart-file-preview/index.d.ts +18 -0
- package/dist/smart-file-preview/index.js +37 -0
- package/dist/smart-upload/index.d.ts +2 -0
- package/dist/smart-upload/index.js +800 -0
- package/index.html +16 -0
- package/package.json +23 -0
- package/public/favicon.svg +6 -0
- package/scripts/components.vite.config.ts +96 -0
- package/scripts/shared.ts +9 -0
- package/src/App.vue +28 -0
- package/src/components/Logo/index.vue +15 -0
- package/src/components-private/.gitkeep +0 -0
- package/src/composables/useElementStyle.ts +23 -0
- package/src/composables/useNaiveStyle.ts +43 -0
- package/src/composables/useNaiveTheme.ts +71 -0
- package/src/composables/useSmart.ts +36 -0
- package/src/layouts/default.vue +3 -0
- package/src/main.ts +33 -0
- package/src/modules/pinia/index.ts +8 -0
- package/src/modules/progress/index.ts +12 -0
- package/src/modules/router/install.ts +9 -0
- package/src/modules/router/routes.ts +40 -0
- package/src/pages/[...all].vue +21 -0
- package/src/pages/frame/component/[name].vue +14 -0
- package/src/pages/frame/index.vue +81 -0
- package/src/pages/index/composables/useTabsManage.ts +46 -0
- package/src/pages/index/index.vue +111 -0
- package/src/pages/index/type.ts +13 -0
- package/src/pages/index/utils/index.ts +41 -0
- package/src/settings.ts +9 -0
- package/src/shared/components.ts +52 -0
- package/src/shared/env.ts +11 -0
- package/src/shared/unocss.theme.ts +1600 -0
- package/src/stores/theme.ts +29 -0
- package/src/styles/element.scss +3 -0
- package/src/styles/styles.scss +21 -0
- package/src/types.ts +20 -0
- package/src/utils/callCustomElementExposed.ts +6 -0
- package/src/utils/deepCloneESModule.ts +10 -0
- package/src/utils/defineCustomElements.ts +18 -0
- package/src/utils/formatComponentsGlob.ts +16 -0
- package/src/utils/getFileMD5.ts +31 -0
- package/src/utils/getFileNameAndExt.ts +11 -0
- package/src/utils/isFileEqual.ts +13 -0
- package/src/utils/jsonToFormData.ts +8 -0
- package/src/web-components/smart-docx-drive-page/App.vue +37 -0
- package/src/web-components/smart-docx-drive-page/apis/doc.ts +85 -0
- package/src/web-components/smart-docx-drive-page/apis/file.ts +278 -0
- package/src/web-components/smart-docx-drive-page/apis/folder.ts +72 -0
- package/src/web-components/smart-docx-drive-page/children/Home.vue +8 -0
- package/src/web-components/smart-docx-drive-page/children/Me.vue +47 -0
- package/src/web-components/smart-docx-drive-page/components/CustomImage.vue +26 -0
- package/src/web-components/smart-docx-drive-page/components/CustomPopover.vue +62 -0
- package/src/web-components/smart-docx-drive-page/components/DocxDir.vue +99 -0
- package/src/web-components/smart-docx-drive-page/components/DocxDoc.vue +132 -0
- package/src/web-components/smart-docx-drive-page/components/DocxDownloadPopoverItem.vue +41 -0
- package/src/web-components/smart-docx-drive-page/components/DocxFileList.vue +156 -0
- package/src/web-components/smart-docx-drive-page/components/DocxPreview.vue +33 -0
- package/src/web-components/smart-docx-drive-page/components/DocxUpload.vue +164 -0
- package/src/web-components/smart-docx-drive-page/components/FileIcon.vue +62 -0
- package/src/web-components/smart-docx-drive-page/components-private/Header.vue +65 -0
- package/src/web-components/smart-docx-drive-page/components-private/Logo.vue +15 -0
- package/src/web-components/smart-docx-drive-page/components-private/Menu.vue +34 -0
- package/src/web-components/smart-docx-drive-page/components-private/Navbar.vue +36 -0
- package/src/web-components/smart-docx-drive-page/composables/useFullscreenElDialog.ts +41 -0
- package/src/web-components/smart-docx-drive-page/composables/usePrompt.ts +73 -0
- package/src/web-components/smart-docx-drive-page/data.ts +10 -0
- package/src/web-components/smart-docx-drive-page/external-style/custom-popover.sass +8 -0
- package/src/web-components/smart-docx-drive-page/external-style/index.sass +1 -0
- package/src/web-components/smart-docx-drive-page/index.ts +20 -0
- package/src/web-components/smart-docx-drive-page/index.vue +39 -0
- package/src/web-components/smart-docx-drive-page/info.ts +2 -0
- package/src/web-components/smart-docx-drive-page/stores/menu.ts +60 -0
- package/src/web-components/smart-docx-drive-page/types.ts +51 -0
- package/src/web-components/smart-docx-drive-page/utils/file-actions.ts +63 -0
- package/src/web-components/smart-docx-drive-page/utils/file.ts +31 -0
- package/src/web-components/smart-docx-editor/App.vue +32 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components/Markdown.vue +202 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components/Menu.vue +100 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components/types.ts +6 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/Markdown.tsx +71 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/MarkdownElement.tsx +81 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/elements/Blockquote/index.sass +6 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/elements/Blockquote/index.tsx +12 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/elements/Heading/index.sass +14 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/elements/Heading/index.tsx +17 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/elements/List/index.scss +16 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/elements/List/index.tsx +39 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/components-react/types/custom-types.d.ts +69 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/composables/useTextSelection.ts +50 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/index.sass +19 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/index.vue +21 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/shared/const.ts +23 -0
- package/src/web-components/smart-docx-editor/MarkdownShortcuts/utils/slateHelpers.ts +23 -0
- package/src/web-components/smart-docx-editor/data.ts +38 -0
- package/src/web-components/smart-docx-editor/demo.vue +11 -0
- package/src/web-components/smart-docx-editor/index.md +3 -0
- package/src/web-components/smart-docx-editor/index.ts +5 -0
- package/src/web-components/smart-docx-editor/index.vue +12 -0
- package/src/web-components/smart-docx-editor/info.ts +2 -0
- package/src/web-components/smart-file-preview/category/Code.vue +171 -0
- package/src/web-components/smart-file-preview/category/Image.vue +49 -0
- package/src/web-components/smart-file-preview/category/Pdf.vue +14 -0
- package/src/web-components/smart-file-preview/category/Video.vue +27 -0
- package/src/web-components/smart-file-preview/demo.vue +34 -0
- package/src/web-components/smart-file-preview/index.md +5 -0
- package/src/web-components/smart-file-preview/index.ts +29 -0
- package/src/web-components/smart-file-preview/index.vue +56 -0
- package/src/web-components/smart-file-preview/info.ts +2 -0
- package/src/web-components/smart-file-preview/shared/const.ts +4 -0
- package/src/web-components/smart-file-preview/types.ts +38 -0
- package/src/web-components/smart-upload/index.ts +5 -0
- package/src/web-components/smart-upload/index.vue +101 -0
- package/src/web-components/smart-upload/info.ts +2 -0
- package/src/web-components/smart-upload/types.ts +28 -0
- package/tsconfig.json +15 -0
- package/types/auto-imports.d.ts +975 -0
- package/types/components.d.ts +14 -0
- package/types/env.d.ts +8 -0
- package/types/shims.d.ts +6 -0
- package/unocss.config.ts +23 -0
- package/vite.config.ts +60 -0
package/index.html
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="zh-CN">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
|
+
<meta http-equiv="Expires" content="0">
|
7
|
+
<meta http-equiv="Pragma" content="no-cache">
|
8
|
+
<meta http-equiv="Cache-control" content="no-cache">
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
10
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<div id="app"></div>
|
14
|
+
<script type="module" src="/src/main.ts"></script>
|
15
|
+
</body>
|
16
|
+
</html>
|
package/package.json
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"name": "@smartos-lib/components",
|
3
|
+
"type": "module",
|
4
|
+
"version": "1.7.0-beta.0",
|
5
|
+
"packageManager": "pnpm@8.14.3",
|
6
|
+
"author": "Wei Zhang <https://github.com/Zhang-Wei-666>",
|
7
|
+
"devDependencies": {
|
8
|
+
"@rollup/pluginutils": "^5.1.0",
|
9
|
+
"@types/prompts": "^2.4.9",
|
10
|
+
"pinia": "^2.1.7",
|
11
|
+
"prompts": "^2.4.2",
|
12
|
+
"vite-plugin-inspect": "^0.8.2",
|
13
|
+
"vite-plugin-pages": "^0.32.0",
|
14
|
+
"vite-plugin-vue-layouts": "^0.11.0",
|
15
|
+
"vue-router": "^4.2.5"
|
16
|
+
},
|
17
|
+
"scripts": {
|
18
|
+
"dev": "pnpm install && vite --host",
|
19
|
+
"build": "cd ../../ && pnpm build:components-prompts",
|
20
|
+
"build:editor": "pnpm install && vite build:components-prompts",
|
21
|
+
"preview": "pnpm install && vite build && vite preview --host"
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<svg width="234" height="234" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path d="M187.197 10h46.797L117.001 224.805.008 10h89.5L117 59.81 143.91 10h43.287Z" fill="#41B883"/>
|
3
|
+
<path d="M.008 10 117 224.805 233.994 10h-46.797l-70.196 128.883L46.221 10H.007Z" fill="#41B883"/>
|
4
|
+
<path d="M46.219 10 117 139.506 187.196 10h-43.288L117 59.81 89.506 10H46.22Z" fill="#35495E"/>
|
5
|
+
<path d="M210.562 138.833v14.557h-78.124v-14.557h78.124Zm0-7.278h-78.124c-2.073 0-4.06.767-5.525 2.131-1.465 1.365-2.288 3.217-2.288 5.147v14.557c0 1.93.823 3.781 2.288 5.146 1.465 1.365 3.452 2.132 5.525 2.132h78.124c2.073 0 4.06-.767 5.525-2.132 1.465-1.365 2.288-3.216 2.288-5.146v-14.557c0-1.93-.823-3.782-2.288-5.147-1.465-1.364-3.452-2.131-5.525-2.131Zm-62.5 43.67v36.391h-15.624v-36.391h15.624Zm0-7.279h-15.624c-2.073 0-4.06.767-5.525 2.132-1.465 1.365-2.288 3.216-2.288 5.147v36.391c0 1.93.823 3.782 2.288 5.147 1.465 1.365 3.452 2.131 5.525 2.131h15.624c2.073 0 4.06-.766 5.525-2.131 1.465-1.365 2.288-3.217 2.288-5.147v-36.391c0-1.931-.823-3.782-2.288-5.147-1.465-1.365-3.452-2.132-5.525-2.132Zm62.5 7.279v36.391H171.5v-36.391h39.062Zm0-7.279H171.5c-2.072 0-4.059.767-5.524 2.132-1.465 1.365-2.288 3.216-2.288 5.147v36.391c0 1.93.823 3.782 2.288 5.147 1.465 1.365 3.452 2.131 5.524 2.131h39.062c2.073 0 4.06-.766 5.525-2.131 1.465-1.365 2.288-3.217 2.288-5.147v-36.391c0-1.931-.823-3.782-2.288-5.147-1.465-1.365-3.452-2.132-5.525-2.132Z" fill="#000"/>
|
6
|
+
</svg>
|
@@ -0,0 +1,96 @@
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
2
|
+
import { fileURLToPath } from 'node:url';
|
3
|
+
import type { UserConfig } from 'vite';
|
4
|
+
import { defineConfig } from 'vite';
|
5
|
+
import Vue from '@vitejs/plugin-vue';
|
6
|
+
import VueJsx from '@vitejs/plugin-vue-jsx';
|
7
|
+
import React from '@vitejs/plugin-react';
|
8
|
+
import Unocss from 'unocss/vite';
|
9
|
+
import Components from 'unplugin-vue-components/vite';
|
10
|
+
import IconsResolver from 'unplugin-icons/resolver';
|
11
|
+
import { ElementPlusResolver, NaiveUiResolver } from 'unplugin-vue-components/resolvers';
|
12
|
+
import { viteVueCESubStyle } from '@unplugin-vue-ce/sub-style';
|
13
|
+
import ViteCommonPlugins from '../../.vitepress/vite.common.plugins';
|
14
|
+
import { isCustomElementRE, viteCssConfig } from './shared';
|
15
|
+
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
17
|
+
|
18
|
+
export default (options: CreateViteBaseConfigOptions = {}) => {
|
19
|
+
const plugins = options.plugins || [];
|
20
|
+
|
21
|
+
return defineConfig({
|
22
|
+
plugins: [
|
23
|
+
...plugins,
|
24
|
+
|
25
|
+
// Vue 3 支持
|
26
|
+
Vue({
|
27
|
+
customElement: [isCustomElementRE],
|
28
|
+
script: {
|
29
|
+
defineModel: true,
|
30
|
+
},
|
31
|
+
template: {
|
32
|
+
compilerOptions: {
|
33
|
+
isCustomElement: tag => tag.startsWith('smart-'),
|
34
|
+
},
|
35
|
+
},
|
36
|
+
}),
|
37
|
+
// Vue JSX 支持
|
38
|
+
{
|
39
|
+
...VueJsx({
|
40
|
+
exclude: [/[/\\]components-react[\\/$]+/],
|
41
|
+
}),
|
42
|
+
enforce: 'pre',
|
43
|
+
},
|
44
|
+
{
|
45
|
+
config: () => ({
|
46
|
+
esbuild: {
|
47
|
+
include: /\.[jt]sx*$/,
|
48
|
+
},
|
49
|
+
}),
|
50
|
+
},
|
51
|
+
// React 支持
|
52
|
+
React(),
|
53
|
+
// 子组件样式支持
|
54
|
+
viteVueCESubStyle(),
|
55
|
+
// 原子化 CSS 引擎 ( 供 Web Components 使用 )
|
56
|
+
Unocss({
|
57
|
+
configFile: resolve(__dirname, '../unocss.config.ts'),
|
58
|
+
mode: 'vue-scoped',
|
59
|
+
content: {
|
60
|
+
pipeline: {
|
61
|
+
include: [isCustomElementRE],
|
62
|
+
},
|
63
|
+
},
|
64
|
+
}),
|
65
|
+
// 自动导入使用到的组件
|
66
|
+
Components({
|
67
|
+
dts: resolve(__dirname, '../types/components.d.ts'),
|
68
|
+
dirs: [
|
69
|
+
resolve(__dirname, '../src/components'),
|
70
|
+
resolve(__dirname, '../src/components-private'),
|
71
|
+
],
|
72
|
+
resolvers: [
|
73
|
+
// 自动导入图标组件
|
74
|
+
IconsResolver({ prefix: 'i' }),
|
75
|
+
// 自动导入 Naive UI 组件
|
76
|
+
NaiveUiResolver(),
|
77
|
+
// 自动导入 Element Plus 组件
|
78
|
+
ElementPlusResolver({ importStyle: false }),
|
79
|
+
],
|
80
|
+
}),
|
81
|
+
|
82
|
+
...ViteCommonPlugins({
|
83
|
+
autoImportDirs: [
|
84
|
+
resolve(__dirname, '../src/composables'),
|
85
|
+
resolve(__dirname, '../src/stores'),
|
86
|
+
],
|
87
|
+
}),
|
88
|
+
],
|
89
|
+
css: viteCssConfig,
|
90
|
+
});
|
91
|
+
};
|
92
|
+
|
93
|
+
interface CreateViteBaseConfigOptions {
|
94
|
+
/** 需要额外插入的 vite 插件 */
|
95
|
+
plugins?: UserConfig['plugins']
|
96
|
+
}
|
package/src/App.vue
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
<template>
|
2
|
+
<!-- 全局化配置 ( 主题 ) -->
|
3
|
+
<NConfigProvider :theme="theme" :theme-overrides="themeOverrides" :locale="zhCN" :date-locale="dateZhCN" abstract>
|
4
|
+
<!-- 加载条 ( 页面加载进度 ) -->
|
5
|
+
<NLoadingBarProvider>
|
6
|
+
<router-view />
|
7
|
+
<GetAppEnv />
|
8
|
+
</NLoadingBarProvider>
|
9
|
+
<!-- 全局样式 ( 写入一些样式至 body 层 ) -->
|
10
|
+
<NGlobalStyle />
|
11
|
+
</NConfigProvider>
|
12
|
+
</template>
|
13
|
+
|
14
|
+
<script lang="ts" setup>
|
15
|
+
import { useLoadingBar } from 'naive-ui';
|
16
|
+
import { app } from '@/shared/env';
|
17
|
+
import { settings } from '@/settings';
|
18
|
+
|
19
|
+
/** 主题相关 */
|
20
|
+
const { theme, themeOverrides, zhCN, dateZhCN } = useNaiveTheme();
|
21
|
+
|
22
|
+
/** 获取当前应用的一些环境变量 */
|
23
|
+
function GetAppEnv() {
|
24
|
+
app.loadingBar = useLoadingBar();
|
25
|
+
}
|
26
|
+
|
27
|
+
useTitle(settings.name);
|
28
|
+
</script>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="relative" :class="props.size">
|
3
|
+
<i-logos-vue class="size-full" />
|
4
|
+
<i-carbon-template class="size-1/2 absolute right-0 bottom-0" />
|
5
|
+
</div>
|
6
|
+
</template>
|
7
|
+
|
8
|
+
<script lang="ts" setup>
|
9
|
+
const props = defineProps({
|
10
|
+
size: {
|
11
|
+
type: String,
|
12
|
+
default: 'size-12',
|
13
|
+
},
|
14
|
+
});
|
15
|
+
</script>
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/indent */
|
2
|
+
|
3
|
+
import elementPlusStyle from 'element-plus/theme-chalk/src/index.scss?inline';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* 挂载 Element Plus UI 的样式到 web components 组件中
|
7
|
+
*/
|
8
|
+
export function useElementStyle() {
|
9
|
+
const el = useCurrentElement();
|
10
|
+
|
11
|
+
onMounted(() => {
|
12
|
+
const shadowRoot = el.value!.parentNode!;
|
13
|
+
const style = document.createElement('style');
|
14
|
+
style.setAttribute('namespace', 'smart');
|
15
|
+
|
16
|
+
// 添加 element-plus 的样式到组件中
|
17
|
+
shadowRoot.appendChild(style).textContent = elementPlusStyle;
|
18
|
+
|
19
|
+
// 添加 element-plus 的样式到 document.head 中
|
20
|
+
// 因为 MessageBox、Notification 等组件是挂载在 document.body 上的, 否则样式不生效
|
21
|
+
document.querySelector('style[namespace="smart"]') || (document.head.appendChild(style.cloneNode()).textContent = elementPlusStyle);
|
22
|
+
});
|
23
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { uniqueKeyCustomizer } from 'mixte';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* 挂载 Naive UI 的样式到 web components 组件中
|
5
|
+
* @param classPrefix 自定义组件的类的前缀, 默认为随机字符串
|
6
|
+
* @example
|
7
|
+
*
|
8
|
+
* // js
|
9
|
+
* const classPrefix = useNaiveStyle();
|
10
|
+
*
|
11
|
+
* // template
|
12
|
+
* <n-config-provider :cls-prefix="classPrefix">
|
13
|
+
* <n-select />
|
14
|
+
* </n-config-provider>
|
15
|
+
*/
|
16
|
+
export function useNaiveStyle(classPrefix = uniqueKeyCustomizer()) {
|
17
|
+
const el = useCurrentElement();
|
18
|
+
const selectors = `style[cssr-id^="${classPrefix}-"]`;
|
19
|
+
|
20
|
+
onMounted(() => {
|
21
|
+
// Naive UI 的样式是动态插入到 document.head 中的
|
22
|
+
// 所以监听 document.head 中样式的变化, 并将同样前缀的样式其插入到组件中
|
23
|
+
function insertStyle() {
|
24
|
+
const shadowRoot = el.value!.parentNode!;
|
25
|
+
|
26
|
+
shadowRoot.querySelectorAll(selectors).forEach((style) => {
|
27
|
+
shadowRoot.removeChild(style);
|
28
|
+
});
|
29
|
+
|
30
|
+
Array.from(document.querySelectorAll(selectors)).forEach((style) => {
|
31
|
+
shadowRoot.appendChild(style.cloneNode()).textContent = style.textContent;
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
useMutationObserver(document.head, insertStyle, {
|
36
|
+
childList: true,
|
37
|
+
});
|
38
|
+
|
39
|
+
insertStyle();
|
40
|
+
});
|
41
|
+
|
42
|
+
return classPrefix;
|
43
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import type { GlobalThemeOverrides } from 'naive-ui';
|
2
|
+
import { darkTheme, dateZhCN, zhCN } from 'naive-ui';
|
3
|
+
import { deepMerge } from 'mixte';
|
4
|
+
import { colors, fontFamily } from '@/shared/unocss.theme';
|
5
|
+
|
6
|
+
/** 通用主题变量覆盖 */
|
7
|
+
export const commonOverrides: GlobalThemeOverrides = {
|
8
|
+
common: {
|
9
|
+
// 默认字体
|
10
|
+
fontFamily: fontFamily.sans,
|
11
|
+
// 等宽字体
|
12
|
+
fontFamilyMono: fontFamily.mono,
|
13
|
+
|
14
|
+
// Primary 颜色
|
15
|
+
primaryColor: colors.primary,
|
16
|
+
primaryColorHover: colors['primary-hover'],
|
17
|
+
primaryColorPressed: colors['primary-active'],
|
18
|
+
primaryColorSuppl: colors.primary,
|
19
|
+
// Info 颜色
|
20
|
+
infoColor: colors.info,
|
21
|
+
infoColorHover: colors['info-hover'],
|
22
|
+
infoColorPressed: colors['info-active'],
|
23
|
+
infoColorSuppl: colors.info,
|
24
|
+
// Success 颜色
|
25
|
+
successColor: colors.success,
|
26
|
+
successColorHover: colors['success-hover'],
|
27
|
+
successColorPressed: colors['success-active'],
|
28
|
+
successColorSuppl: colors.success,
|
29
|
+
// Warning 颜色
|
30
|
+
warningColor: colors.warning,
|
31
|
+
warningColorHover: colors['warning-hover'],
|
32
|
+
warningColorPressed: colors['warning-active'],
|
33
|
+
warningColorSuppl: colors.warning,
|
34
|
+
// Error 颜色
|
35
|
+
errorColor: colors.error,
|
36
|
+
errorColorHover: colors['error-hover'],
|
37
|
+
errorColorPressed: colors['error-active'],
|
38
|
+
errorColorSuppl: colors.error,
|
39
|
+
},
|
40
|
+
};
|
41
|
+
|
42
|
+
/** 亮色主题变量覆盖 */
|
43
|
+
export const lightThemeOverrides: GlobalThemeOverrides = deepMerge({}, commonOverrides, {
|
44
|
+
|
45
|
+
});
|
46
|
+
/** 深色主题变量覆盖 */
|
47
|
+
export const darkThemeOverrides: GlobalThemeOverrides = deepMerge({}, commonOverrides, {
|
48
|
+
Button: {
|
49
|
+
textColorPrimary: '#FFF',
|
50
|
+
textColorHoverPrimary: '#FFF',
|
51
|
+
textColorPressedPrimary: '#FFF',
|
52
|
+
textColorFocusPrimary: '#FFF',
|
53
|
+
textColorDisabledPrimary: '#FFF',
|
54
|
+
},
|
55
|
+
});
|
56
|
+
|
57
|
+
export const useNaiveTheme = createSharedComposable(() => {
|
58
|
+
const themeStore = useThemeStore();
|
59
|
+
|
60
|
+
/** 当前 Naive UI 主题 */
|
61
|
+
const theme = computed(() => themeStore.dark ? darkTheme : null);
|
62
|
+
/** 对当前 NaiveUI 主题的变量覆盖 */
|
63
|
+
const themeOverrides = computed(() => themeStore.dark ? darkThemeOverrides : lightThemeOverrides);
|
64
|
+
|
65
|
+
return {
|
66
|
+
theme,
|
67
|
+
themeOverrides,
|
68
|
+
zhCN,
|
69
|
+
dateZhCN,
|
70
|
+
};
|
71
|
+
});
|
@@ -0,0 +1,36 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/indent */
|
2
|
+
|
3
|
+
import { version } from '@@/package.json';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* SmartOS 相关组件的公用处理逻辑
|
7
|
+
*/
|
8
|
+
export function useSmart() {
|
9
|
+
const el = useCurrentElement();
|
10
|
+
|
11
|
+
onMounted(() => {
|
12
|
+
const shadowRoot = el.value!.parentNode!; // @ts-expect-error
|
13
|
+
const { tailwindResetStyle, elementPlusStyle } = globalThis.SmartCore?.[version] ?? {};
|
14
|
+
|
15
|
+
// 挂载 Tailwind Reset 的样式
|
16
|
+
if (tailwindResetStyle)
|
17
|
+
shadowRoot.appendChild(document.createElement('style')).textContent = tailwindResetStyle;
|
18
|
+
|
19
|
+
// 挂载 Element Plus UI 的样式
|
20
|
+
if (elementPlusStyle) {
|
21
|
+
const style = document.createElement('style');
|
22
|
+
style.setAttribute('namespace', 'smart');
|
23
|
+
|
24
|
+
// 添加 element-plus 的样式到组件中
|
25
|
+
shadowRoot.appendChild(style).textContent = elementPlusStyle;
|
26
|
+
|
27
|
+
// 添加 element-plus 的样式到 document.head 中
|
28
|
+
// 因为 MessageBox、Notification 等组件是挂载在 document.body 上的, 否则样式不生效
|
29
|
+
document.querySelector('style[namespace="smart"]') || (document.head.appendChild(style.cloneNode()).textContent = elementPlusStyle);
|
30
|
+
}
|
31
|
+
});
|
32
|
+
|
33
|
+
return {
|
34
|
+
classPrefix: useNaiveStyle(),
|
35
|
+
};
|
36
|
+
}
|
package/src/main.ts
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
import { isString } from 'mixte';
|
2
|
+
import App from './App.vue';
|
3
|
+
import type { UserModule } from './types';
|
4
|
+
import router from '@/modules/router/install';
|
5
|
+
|
6
|
+
import '@unocss/reset/tailwind.css';
|
7
|
+
import 'uno.css';
|
8
|
+
import '@/styles/styles.scss';
|
9
|
+
|
10
|
+
// 修复 Naive UI 和 Tailwind Reset 的样式冲突
|
11
|
+
document.head.insertAdjacentHTML('beforeend', '<meta name="naive-ui-style" />');
|
12
|
+
|
13
|
+
const app = createApp(App);
|
14
|
+
|
15
|
+
app.use(router);
|
16
|
+
|
17
|
+
Object.values(import.meta.glob<{ install: UserModule }>('./modules/**/index.ts', { eager: true })).forEach(m => m.install?.({ app, router }));
|
18
|
+
|
19
|
+
router.isReady().then(() => {
|
20
|
+
app.mount('#app');
|
21
|
+
});
|
22
|
+
|
23
|
+
const { warn, info } = console;
|
24
|
+
|
25
|
+
console.warn = (message?: any, ...optionalParams: any[]) => {
|
26
|
+
if (isString(message) && message.startsWith('[Vue warn]: Extraneous non-props attributes (data')) return;
|
27
|
+
warn.call(console, message, ...optionalParams);
|
28
|
+
};
|
29
|
+
|
30
|
+
console.info = (message?: any, ...optionalParams: any[]) => { // eslint-disable-line no-console
|
31
|
+
if (isString(message) && message.includes('Download the React DevTools')) return;
|
32
|
+
info.call(console, message, ...optionalParams);
|
33
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import type { UserModule } from '@/types';
|
2
|
+
import { app } from '@/shared/env';
|
3
|
+
|
4
|
+
export const install: UserModule = ({ router }) => {
|
5
|
+
router.beforeEach(() => {
|
6
|
+
app.loadingBar?.start();
|
7
|
+
});
|
8
|
+
|
9
|
+
router.afterEach(() => {
|
10
|
+
app.loadingBar?.finish();
|
11
|
+
});
|
12
|
+
};
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import type { RouteComponent, RouteRecordRaw } from 'vue-router';
|
2
|
+
import { isESModule, isFunction, isPlainObject, leastRun } from 'mixte';
|
3
|
+
import { camelCase, upperFirst } from 'lodash-es';
|
4
|
+
import { setupLayouts } from 'virtual:generated-layouts';
|
5
|
+
import generatedRoutes from 'virtual:generated-pages';
|
6
|
+
|
7
|
+
/** 定义页面组件名称为路由名称 */
|
8
|
+
function defineComponentName(route: RouteRecordRaw, component: RouteComponent) {
|
9
|
+
if (component.name) return component;
|
10
|
+
return Object.assign({}, component, {
|
11
|
+
name: upperFirst(camelCase(route.name as string)),
|
12
|
+
});
|
13
|
+
}
|
14
|
+
|
15
|
+
/** 遍历路由 */
|
16
|
+
function eachRoutes(routes: RouteRecordRaw[]) {
|
17
|
+
routes.forEach((route) => {
|
18
|
+
const component = route.component;
|
19
|
+
|
20
|
+
// 对象形式的页面组件
|
21
|
+
if (isPlainObject(component)) {
|
22
|
+
route.component = defineComponentName(route, component);
|
23
|
+
}
|
24
|
+
// 页面组件是一个方法
|
25
|
+
else if (isFunction(component)) {
|
26
|
+
// @ts-expect-error
|
27
|
+
route.component = () => leastRun(0, component).then((m) => {
|
28
|
+
return defineComponentName(route, isESModule(m) ? m.default : m);
|
29
|
+
});
|
30
|
+
}
|
31
|
+
|
32
|
+
// 存在子路由
|
33
|
+
if (route.children)
|
34
|
+
eachRoutes(route.children);
|
35
|
+
});
|
36
|
+
}
|
37
|
+
|
38
|
+
eachRoutes(generatedRoutes);
|
39
|
+
|
40
|
+
export default setupLayouts(generatedRoutes);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="px-4 py-10 text-center">
|
3
|
+
<div class="text-5xl">
|
4
|
+
<i-bx-message-alt-x class="inline-block" />
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<div class="mt-1">
|
8
|
+
未找到页面
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="mt-6">
|
12
|
+
<NButton type="primary" @click="router.back()">
|
13
|
+
返回
|
14
|
+
</NButton>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
</template>
|
18
|
+
|
19
|
+
<script lang="ts" setup>
|
20
|
+
const router = useRouter();
|
21
|
+
</script>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<template>
|
2
|
+
<Index :component="name" />
|
3
|
+
</template>
|
4
|
+
|
5
|
+
<script lang="ts" setup>
|
6
|
+
import Index from '../index.vue';
|
7
|
+
|
8
|
+
const route = useRoute();
|
9
|
+
const name = computed(() => route.params.name as string);
|
10
|
+
</script>
|
11
|
+
|
12
|
+
<route lang="yaml">
|
13
|
+
name: Frame/Component
|
14
|
+
</route>
|
@@ -0,0 +1,81 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="min-h-screen flex">
|
3
|
+
<div class="w-full flex-grow">
|
4
|
+
<template v-if="tab && isReady">
|
5
|
+
<component :is="tab.component" v-bind="finalData" />
|
6
|
+
</template>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
</template>
|
10
|
+
|
11
|
+
<script lang="ts" setup>
|
12
|
+
import { isFunction } from 'mixte';
|
13
|
+
import { setConfigProvider } from '@smartos-lib/core';
|
14
|
+
import type { Tab } from '../index/type';
|
15
|
+
import { LOGIN_AJAX_CONFIG, createAxiosInstance } from '../../../../apis/test-utils/env';
|
16
|
+
import { components } from '@/shared/components';
|
17
|
+
|
18
|
+
interface Props {
|
19
|
+
/** 指定渲染的组件名称 */
|
20
|
+
component?: string
|
21
|
+
}
|
22
|
+
|
23
|
+
const props = defineProps<Props>();
|
24
|
+
|
25
|
+
/** 组件是否加载完成 */
|
26
|
+
const isReady = ref(false);
|
27
|
+
|
28
|
+
/** 所有的选项卡信息 */
|
29
|
+
const tabs = useLocalStorage<Tab[]>('st-tabs', []);
|
30
|
+
/** 当前选项卡信息 */
|
31
|
+
const tab = computed(() => props.component ? ({ component: props.component } as Tab) : tabs.value.find(tab => tab.id === window.name));
|
32
|
+
/** 当前选项卡测试数据 */
|
33
|
+
const data = computed(() => components[tab.value?.component as string]?.data?.[tab.value?.data as string] || {});
|
34
|
+
/** 最终使用的选项卡数据 - 支持使用函数返回测试数据 */
|
35
|
+
const finalData = computed(() => {
|
36
|
+
return isFunction(data.value) ? data.value({ reloadCount: tab.value?.dataReloadCount ?? 0 }) : data.value;
|
37
|
+
});
|
38
|
+
|
39
|
+
/** Token */
|
40
|
+
const token = ref('');
|
41
|
+
/** 创建一个新的 axios 实例 */
|
42
|
+
const request = createAxiosInstance('/', token);
|
43
|
+
|
44
|
+
/** 发起登录请求 */
|
45
|
+
const login = useRequest(() => {
|
46
|
+
return request(LOGIN_AJAX_CONFIG);
|
47
|
+
});
|
48
|
+
|
49
|
+
login.onSuccess(() => {
|
50
|
+
token.value = login.data.value?.access_token;
|
51
|
+
});
|
52
|
+
|
53
|
+
// 加载组件
|
54
|
+
watchEffect(async () => {
|
55
|
+
const name = tab.value?.component;
|
56
|
+
const component = components[name as string];
|
57
|
+
|
58
|
+
if (component) {
|
59
|
+
// SmartOS 组件库, 需要先加载 '@smartos-lib/core/componentsProvider' 依赖
|
60
|
+
if (name!.startsWith('smart-')) {
|
61
|
+
setConfigProvider({ request });
|
62
|
+
login.execute();
|
63
|
+
await import('@smartos-lib/core/componentsProvider');
|
64
|
+
}
|
65
|
+
|
66
|
+
component?.index().then(() => {
|
67
|
+
isReady.value = true;
|
68
|
+
|
69
|
+
// 云文档云服务页, 依赖这几个组件, 所以也需要加载过来
|
70
|
+
if (name === 'smart-docx-drive-page') {
|
71
|
+
components['smart-file-preview']?.index();
|
72
|
+
components['smart-docx-editor']?.index();
|
73
|
+
}
|
74
|
+
});
|
75
|
+
}
|
76
|
+
});
|
77
|
+
</script>
|
78
|
+
|
79
|
+
<route lang="yaml">
|
80
|
+
name: Frame
|
81
|
+
</route>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { uniqueKey } from 'mixte';
|
2
|
+
import type { Tab } from '../type';
|
3
|
+
import { components } from '@/shared/components';
|
4
|
+
|
5
|
+
/** 选项卡管理 */
|
6
|
+
export function useTabsManage() {
|
7
|
+
/** 所有的选项卡信息 */
|
8
|
+
const tabs = useLocalStorage<Tab[]>('st-tabs', []);
|
9
|
+
/** 当前激活的选项卡 ID */
|
10
|
+
const activeTabId = useLocalStorage<string>('st-active-tab-id', '');
|
11
|
+
/** 当前激活的选项卡 */
|
12
|
+
const activeTab = computed(() => tabs.value.find(tab => tab.id === activeTabId.value));
|
13
|
+
/** 当前激活的选项卡的测试数据 */
|
14
|
+
const activeTabData = computed(() => components[activeTab.value?.component as string]?.data);
|
15
|
+
|
16
|
+
/** 创建一个新选项卡 */
|
17
|
+
function createTab(component: string) {
|
18
|
+
const id = uniqueKey(tabs.value);
|
19
|
+
|
20
|
+
tabs.value.push({
|
21
|
+
id,
|
22
|
+
component,
|
23
|
+
});
|
24
|
+
|
25
|
+
activeTabId.value = id;
|
26
|
+
}
|
27
|
+
|
28
|
+
/** 关闭一个选项卡 */
|
29
|
+
function closeTab(id: string) {
|
30
|
+
const index = tabs.value.findIndex(tab => tab.id === id);
|
31
|
+
|
32
|
+
if (index > -1) {
|
33
|
+
tabs.value.splice(index, 1);
|
34
|
+
activeTabId.value === id && (activeTabId.value = tabs.value[Math.min(index, tabs.value.length - 1)]?.id);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
return {
|
39
|
+
activeTab,
|
40
|
+
activeTabId,
|
41
|
+
activeTabData,
|
42
|
+
tabs,
|
43
|
+
createTab,
|
44
|
+
closeTab,
|
45
|
+
};
|
46
|
+
}
|