@smartos-lib/components 1.7.0-beta.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/.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
|
+
}
|