├── .all-contributorsrc
├── .browserslistrc
├── .eslintrc.js
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── question.md
│ └── suggestion.md
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── babel.config.js
├── build
├── bin
│ └── gen-cssfile.js
└── docs-deploy.sh
├── components.json
├── docs
├── .vuepress
│ ├── config.js
│ ├── enhanceApp.js
│ └── layout.vue
├── README.md
└── component
│ ├── README.md
│ ├── basic
│ ├── deepexi-card.md
│ ├── list-container.md
│ └── markdown-view.md
│ ├── guide
│ ├── guide.md
│ └── introduction.md
│ └── hoc
│ ├── loading-button.md
│ ├── loading-dialog.md
│ ├── prompt-form.md
│ ├── search-input.md
│ └── text-tooltip.md
├── package.json
├── plop-templates
├── component
│ ├── css.hbs
│ ├── export.hbs
│ ├── index.hbs
│ ├── md.hbs
│ └── prompt.js
├── utils.js
└── writeJsonAndBuildEntry.js
├── plopfile.js
├── public
├── demo.html
├── favicon.ico
├── index.html
└── test.html
├── src
├── components
│ ├── deepexi-card
│ │ ├── index.js
│ │ └── index.vue
│ ├── list-container
│ │ ├── index.js
│ │ └── index.vue
│ ├── loading-button
│ │ ├── index.js
│ │ └── index.vue
│ ├── loading-dialog
│ │ ├── index.js
│ │ ├── index.vue
│ │ └── render.js
│ ├── markdown-view
│ │ ├── index.js
│ │ ├── index.vue
│ │ └── utils.js
│ ├── prompt-form
│ │ ├── drawer.vue
│ │ ├── gene-wrapper.js
│ │ └── index.js
│ ├── search-input
│ │ ├── index.js
│ │ └── index.vue
│ └── text-tooltip
│ │ ├── index.js
│ │ └── index.vue
├── index.js
├── mixins
│ └── emitter.js
├── theme-chalk
│ ├── gulpfile.js
│ └── src
│ │ ├── common
│ │ ├── markdown-preview.less
│ │ └── var.less
│ │ ├── deepexi-card.less
│ │ ├── index.less
│ │ ├── list-container.less
│ │ ├── loading-button.less
│ │ ├── loading-dialog.less
│ │ ├── markdown-view.less
│ │ ├── search-input.less
│ │ └── text-tooltip.less
└── utils
│ └── assist.js
├── vue.config.js
└── yarn.lock
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "deep-ui",
3 | "projectOwner": "cjfff",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "README.md"
8 | ],
9 | "imageSize": 100,
10 | "commit": true,
11 | "commitConvention": "gitmoji",
12 | "contributors": [
13 | {
14 | "login": "cjfff",
15 | "name": "cjfff",
16 | "avatar_url": "https://avatars1.githubusercontent.com/u/20502762?v=4",
17 | "profile": "http://www.ccc1996.cn",
18 | "contributions": [
19 | "doc",
20 | "bug",
21 | "example",
22 | "ideas",
23 | "maintenance",
24 | "code"
25 | ]
26 | },
27 | {
28 | "login": "JE-lee",
29 | "name": "lee",
30 | "avatar_url": "https://avatars0.githubusercontent.com/u/19794813?v=4",
31 | "profile": "https://github.com/JE-lee",
32 | "contributions": [
33 | "code",
34 | "doc",
35 | "example"
36 | ]
37 | }
38 | ],
39 | "contributorsPerLine": 7
40 | }
41 |
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
7 | parserOptions: {
8 | parser: "babel-eslint"
9 | },
10 | rules: {
11 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
12 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 'Bug Report'
3 | about: '创建错误报告以帮助我们改进。'
4 | title: '[bug]'
5 | labels: 'bug'
6 | assignees: ''
7 |
8 | ---
9 |
10 |
13 |
14 | ## 问题描述
15 |
16 |
17 | ## 最小可复现仓库
18 | > 请创建最小可复现代码,并上传到你的 GitHub 仓库
19 |
20 |
21 | ## 预期的行为和实际行为
22 |
23 |
24 | ## 复现步骤,具体代码
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## 相关环境信息
32 | - **操作系统**:
33 | - **Node 版本**:
34 | - **deep-ui 版本**:
35 | - **Vue 版本**:
36 | - **引用方式**: CDN / NPM ?
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: 问我们一个关于这个项目的问题
4 | title: '[question]'
5 | labels: 'question'
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 | ## 你想知道什么?
12 |
13 |
14 | 你好,我想知道这个项目是否可以...
15 |
16 | ## 描述你考虑过的替代方案
17 |
18 |
19 | 我想...
20 |
21 | ## 其它
22 |
23 | 无
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/suggestion.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Suggestion
3 | about: 为这个项目提出一个建议
4 | title: '[suggest]'
5 | labels: 'help wanted'
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## 你建议我们做什么?
11 |
12 |
13 | 现在...
14 |
15 | 如果你能...
16 |
17 | 它将使...
18 |
19 | ## 其它
20 |
21 | 无
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
23 | lib/*
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - lts/*
4 | install:
5 | - yarn install # npm ci
6 | script: npm run docs:deploy
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018-present, Vivint, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # deep-ui
2 |
3 | [](https://travis-ci.com/cjfff/deep-ui)
4 | [](https://github.com/cjfff/deep-ui/raw/master/LICENSE)
5 | [](https://github.com/cjfff/deep-ui/pulls)
6 |
7 |
8 | ## 介绍
9 |
10 | 每家公司/每个团队,在持续协作维护项目的过程中,总会产出一些较为通用性的组件,或者 UI 会设计一些样式组件。
11 |
12 | 但是如果放在项目里的话,大家其实都不会去翻文件看,那这时候有个文档记录一下这些通用组件的话,会让大家协作的意愿更强烈。:fire:
13 |
14 | 更重要的是,可以提高代码的复用性, 打包编译发布到 `npm` 上,告别多项目的复制粘贴。 :beers:
15 |
16 | 使用及其简单的方式 (vue-cli3 以及 vuepress) 维护 团队/个人的 组件库。:tada::tada::tada:
17 |
18 | ## Features
19 |
20 | - [x] 代码打包 📦 npm lib 即可
21 | - [x] 代码即文档,代码里面加注释即可解决文档问题
22 | - [x] `yarn new` 交互式创建新组件文件,不用再繁琐的写 `template`
23 | - [x] 按需加载 css [栗子仓库](https://github.com/cjfff/deep-ui-demo)
24 | - [ ] 添加 eslint
25 | - [ ] standard-version
26 | - [ ] 自动生成 release logs
27 |
28 | ## Project setup
29 |
30 | 由于 `vuepress` 依赖的是 `core-js` 是 2.x 版本,而 `vue-cli3` 中依赖的是 3.x 版本.
31 |
32 | 所以 `vuepress` 需要进行全局安装。
33 |
34 | ```js
35 |
36 | npm i -g vuepress core-js@2.6.11
37 |
38 | ```
39 |
40 | ```
41 | git clone
42 |
43 | yarn install
44 |
45 | yarn docs:dev // 启动开发模式
46 |
47 | yarn new // 创建新组件
48 | ```
49 |
50 | ## 发布
51 |
52 | 现在还没有自动化...
53 |
54 | ```shell
55 | yarn pub
56 |
57 | # 更新 package.json 然后
58 |
59 | npm publish
60 | "pub": "yarn build:lib && yarn build:theme",
61 | ```
62 |
63 | ### 参考链接
64 | - https://github.com/vue-styleguidist/vuepress-plugin-live
65 | - https://github.com/BuptStEve/markdown-it-vuese
66 | - https://github.com/shuidi-fed/vuese
67 | - https://markdown-it.github.io/markdown-it/
68 | - https://github.com/koca/vue-prism-editor
69 | - https://juejin.im/post/5dd234635188254a1f44646a#heading-27
70 | - https://segmentfault.com/a/1190000015261753
71 |
72 |
73 |
74 | ## Contributors ✨
75 |
76 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
77 |
78 |
79 |
80 |
81 |
87 |
88 |
89 |
90 |
91 |
92 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
93 |
94 |
95 | [](#contributors-)
96 |
97 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@vue/cli-plugin-babel/preset"]
3 | };
4 |
--------------------------------------------------------------------------------
/build/bin/gen-cssfile.js:
--------------------------------------------------------------------------------
1 | var fs = require("fs");
2 | var path = require("path");
3 | var Components = require("../../components.json");
4 | var themes = ["theme-chalk"];
5 | Components = Object.keys(Components);
6 | var basepath = path.resolve(__dirname, "../../src/");
7 |
8 | function fileExists(filePath) {
9 | try {
10 | return fs.statSync(filePath).isFile();
11 | } catch (err) {
12 | return false;
13 | }
14 | }
15 |
16 | themes.forEach(theme => {
17 | var isSCSS = theme !== "theme-default";
18 | var indexContent = isSCSS
19 | ? '@import "./common/var.less";\n'
20 | : '@import "./base.css";\n';
21 | Components.forEach(function(key) {
22 | if (["icon", "option", "option-group"].indexOf(key) > -1) return;
23 | var fileName = key + (isSCSS ? ".less" : ".css");
24 | indexContent += '@import "./' + fileName + '";\n';
25 | var filePath = path.resolve(basepath, theme, "src", fileName);
26 | if (!fileExists(filePath)) {
27 | fs.writeFileSync(filePath, "", "utf8");
28 | console.log(theme, " 创建遗漏的 ", fileName, " 文件");
29 | }
30 | });
31 | fs.writeFileSync(
32 | path.resolve(basepath, theme, "src", isSCSS ? "index.less" : "index.css"),
33 | indexContent
34 | );
35 | });
36 |
--------------------------------------------------------------------------------
/build/docs-deploy.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # 确保脚本抛出遇到的错误
4 | set -e
5 |
6 | # 安装 vuepress 和 core-js 依赖
7 | npm i -g vuepress core-js@2.6.11 --registry=https://registry.npm.taobao.org
8 |
9 | # 生成静态文件
10 | npm run docs:build
11 |
12 |
13 | mkdir temp_web
14 | cd temp_web
15 |
16 |
17 | git clone --depth 1 -b gh-pages --single-branch https://${GITHUB_TOKEN}@github.com/cjfff/deep-ui.git && cd deep-ui
18 |
19 | rm -rf ./deep-ui/*
20 |
21 | cp -rf ../../dist/* .
22 |
23 | git add -A .
24 | git commit -m "deploy"
25 | git push origin gh-pages
26 |
27 | cd ../../
28 | rm -rf temp_web
29 |
30 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "text-tooltip": "./components/text-tooltip/index.js",
3 | "search-input": "./components/search-input/index.js",
4 | "list-container": "./components/list-container/index.js",
5 | "deepexi-card": "./components/deepexi-card/index.js",
6 | "loading-dialog": "./components/loading-dialog/index.js",
7 | "markdown-view": "./components/markdown-view/index.js",
8 | "loading-button": "./components/loading-button/index.js"
9 | }
--------------------------------------------------------------------------------
/docs/.vuepress/config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const glob = require('glob');
3 |
4 | const getPath = (path) => path.replace(/.*component\//, '')
5 |
6 | const getDocs = (dir = 'basic') => {
7 |
8 | const docs = glob
9 | .sync(path.resolve(__dirname, `../component/${dir}/*.md`))
10 | .map(p => getPath(p))
11 |
12 | return docs
13 | }
14 |
15 | module.exports = {
16 | title: 'DeepUi',
17 | base: `/deep-ui/`,
18 | dest: 'dist',
19 | description: 'deepexi.com 中台研发团队的组件库',
20 | port: 8083,
21 | head: [
22 | ['link', { rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/npm/vue-prism-editor@0.5.1/dist/VuePrismEditor.css' }],
23 | ['link', { rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/npm/@femessage/element-ui@2.16.0/lib/theme-chalk/index.css' }],
24 | ],
25 | plugins: [
26 | '@vuepress/last-updated',
27 | '@vuepress/back-to-top',
28 | [
29 | 'live',
30 | {
31 | // to use a custom layout for your vue components
32 | layout: path.resolve(__dirname, './layout.vue'),
33 | editorProps: {
34 | lineNumbers: true,
35 | }
36 | }
37 | ],
38 | ],
39 | configureWebpack: {
40 | resolve: {
41 | alias: {
42 | '@component': path.resolve(__dirname, '../../src'),
43 | '@': path.resolve(__dirname, '../../src'),
44 | '~': path.resolve(__dirname, '../../src')
45 | }
46 | },
47 | },
48 | themeConfig: {
49 | nav: [
50 | { text: '主页', link: '/' },
51 | { text: '组件', link: '/component/guide/introduction' },
52 | { text: 'GitHub', link: 'https://github.com/cjfff/deep-ui' },
53 | ],
54 | sidebar: {
55 | '/component/': [
56 | {
57 | title: '开发指南',
58 | collapsable: false,
59 | children: getDocs('guide')
60 | },
61 | {
62 | title: '基础组件',
63 | collapsable: false,
64 | children: getDocs('basic')
65 | },
66 | {
67 | title: '高阶组件',
68 | collapsable: false,
69 | children: getDocs('hoc')
70 | },
71 | {
72 | title: '布局组件',
73 | collapsable: false,
74 | children: getDocs('layout')
75 | },
76 | ]
77 | }
78 | },
79 | markdown: {
80 | extendMarkdown: (md) => {
81 | md.use(require('markdown-it-vuese/src/index.js'), {
82 | root: `${process.cwd()}/src/components/`,
83 | useRender: (vueseRender) => {
84 | const renderRes = vueseRender.render()
85 | // 格式转换可以去这里查看详情 https://vuese.org/zh/markdown-render/#%E5%AE%9E%E4%BE%8B%E6%96%B9%E6%B3%95-render
86 | return Object.entries(renderRes).reduce((acc, [title, value]) => acc.concat(`## ${title}\r ${value}`)
87 | , []).join('\r')
88 | },
89 | })
90 |
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/docs/.vuepress/enhanceApp.js:
--------------------------------------------------------------------------------
1 | import FormRenderer from '@femessage/el-form-renderer';
2 | import ELEMENT from '@femessage/element-ui'
3 | import DeepUi from '../../src/index.js'
4 | import '../../src/theme-chalk/src/index.less'
5 |
6 | export default ({
7 | Vue,
8 | options,
9 | router
10 | }) => {
11 | Vue.use(ELEMENT)
12 | Vue.use(DeepUi)
13 | Vue.component(FormRenderer.name, FormRenderer)
14 | }
--------------------------------------------------------------------------------
/docs/.vuepress/layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{ copyMsg }}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {{ controlText }}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
70 |
71 |
319 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroImage:
4 | actionText: 开始使用 →
5 | actionLink: /component/guide/introduction
6 | features:
7 | - title: 基于Vue2.X
8 | details: 享受 Vue + webpack 的开发体验,在 Markdown 中使用 Vue 组件,同时可以使用 Vue 来开发自定义主题。
9 | - title: 轻量级UI
10 | details: 该UI使用了非常轻量级的设计理念,视觉感官更强烈
11 | - title: 高可用性
12 | details: 良好的API接口设计,统一的使用习惯
13 | footer: MIT Licensed | Copyright © 2020-cjfff
14 | ---
--------------------------------------------------------------------------------
/docs/component/README.md:
--------------------------------------------------------------------------------
1 | ## 阅读
--------------------------------------------------------------------------------
/docs/component/basic/deepexi-card.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: deepexi-card
3 | ---
4 | # deepexi-card
5 |
6 | ## 基本使用
7 |
8 | ```vue live lineNumbers
9 |
10 |
11 |
12 | 登陆
13 |
14 | {{data}}
15 |
16 |
17 |
18 |
47 | ```
48 |
49 | <[vuese](deepexi-card/index.vue)
50 |
--------------------------------------------------------------------------------
/docs/component/basic/list-container.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: list-container
3 | ---
4 | # list-container
5 |
6 | 简单易用的形式实现 `tab` 点击切换效果,无论是配合动态组件渲染还是内容修改,都及其容易扩展!
7 |
8 | ## 基本使用
9 |
10 | ```vue live lineNumbers
11 |
12 |
13 |
14 |
15 |
16 |
17 | 绑定的数据:
18 | {{value}}
19 |
20 |
21 |
22 |
23 |
51 | ```
52 |
53 |
54 |
55 | ## slot header
56 |
57 | ```vue live
58 |
59 |
60 |
61 |
62 |
63 | this is header slot
64 |
65 |
66 |
67 |
68 | 绑定的数据:
69 | {{value}}
70 |
71 |
72 |
73 |
74 |
102 | ```
103 |
104 | <[vuese](list-container/index.vue)
105 |
--------------------------------------------------------------------------------
/docs/component/basic/markdown-view.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: markdown-view
3 | ---
4 | # markdown-view
5 |
6 | 快速渲染 markdown 内容以及 toc 标题生成
7 |
8 | ## 基本使用
9 |
10 | ```vue live
11 |
12 |
13 |
14 |
15 |
16 |
17 |
259 | ```
260 |
261 |
262 | <[vuese](markdown-view/index.vue)
--------------------------------------------------------------------------------
/docs/component/guide/guide.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 安装
3 | ---
4 | # 开发指南
5 |
6 | 输入下列命令可以安装 deep-ui
7 | ```
8 | npm install deep-ui --save
9 | ```
--------------------------------------------------------------------------------
/docs/component/guide/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 介绍
3 | ---
4 | # 介绍
5 |
6 | 由于 `vuepress` 依赖的是 `core-js` 是 2.x 版本,而 `vue-cli3` 中依赖的是 3.x 版本.
7 |
8 | 所以写文档的时候,需要你去全局安装一下 `vuepress` 以及 `core-js@2.6.11`
9 |
10 | ```js
11 | npm i -g vuepress core-js@2.6.11
12 | ```
--------------------------------------------------------------------------------
/docs/component/hoc/loading-button.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: loading-button
3 | ---
4 | # loading-button
5 |
6 | 懒人专用,小写一个 `loading` 效果,传入 `promise` 就会在 `promise pending` 期间产生 `loading` 的效果,`resolve` 或者 `rejected` 后结束。
7 |
8 | ## 基本使用
9 |
10 | ```vue live
11 |
12 | click me
13 |
14 |
15 |
27 | ```
28 |
29 | <[vuese](@/loading-button/index.vue)
--------------------------------------------------------------------------------
/docs/component/hoc/loading-dialog.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: loading-dialog
3 | ---
4 | # loading-dialog
5 |
6 | 该组件内置了 `el-footer`,以及发送请求自动对 `confirm` 按钮进行 `loading`, 从细节上减少您的工作量~
7 |
8 | ```vue live lineNumbers
9 |
10 |
11 |
16 |
17 |
18 |
19 | 打开弹窗
20 |
21 |
22 |
23 |
58 | ```
59 |
60 |
61 | <[vuese](loading-dialog/index.vue)
--------------------------------------------------------------------------------
/docs/component/hoc/prompt-form.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: prompt-form
3 | ---
4 | # prompt-form
5 | 提供Vue.prototype.$promptDialog和Vue.prototype.$prompDrawer方法,用来向用户确认信息。
6 | 类似于window.prompt方法,让用户在弹窗中填写相关信息。好处是,不需要写那么多HTML模板。
7 |
8 | ## Arguments
9 | - [Array | Object] formOpt:
10 | - [el-form-renderer](https://github.com/FEMessage/el-form-renderer)组件接受的属性content,
11 | - 或者是el-form-render 可接受属性的对象。eg: { content: [], width: '170px'}
12 | - [String] title: 默认为'提示'
13 | - [Number] width: el-form-render的宽度, 默认是600
14 |
15 | ## 基本使用
16 |
17 | ```vue live
18 |
19 |
20 | dialog
21 | drawer
22 |
23 |
24 |
25 |
53 | ```
54 |
55 | ## 提交信息到服务器
56 | 可以指定弹窗关闭前调用的函数,这个函数需要返回一个Promise. 只有当该Promise resolve之后,弹窗才会关闭。
57 | 你可以在这个函数提交信息到服务器。当然你也可以在关闭弹窗之后在后台提交到服务器,但是如果提交失败,用户就必须重新输入
58 | 之前的表单信息了。
59 |
60 | ```vue live
61 |
62 |
63 | 提交到服务器
64 |
65 |
66 |
67 |
101 | ```
102 |
--------------------------------------------------------------------------------
/docs/component/hoc/search-input.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: search-input
3 | ---
4 | # search-input
5 |
6 | 这是一个 UI 样式组件
7 |
8 | ```vue live lineNumbers
9 |
10 |
11 |
12 |
13 |
22 | ```
23 |
24 |
25 | <[vuese](search-input/index.vue)
--------------------------------------------------------------------------------
/docs/component/hoc/text-tooltip.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: text-tooltip
3 | ---
4 | # text-tooltip
5 |
6 | 当一些内容固定宽度,然后需要超出宽度部分隐藏的时候,为了防止重复书写这种 css....特产出此组件
7 |
8 | ## 基本使用
9 |
10 | ```vue live lineNumbers
11 |
12 |
13 |
14 |
15 |
16 | ```
17 |
18 | ## 多行截断
19 |
20 | ```vue live
21 |
22 |
23 |
24 |
25 |
26 | ```
27 |
28 | <[vuese](text-tooltip/index.vue)
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "deep-ui",
3 | "version": "1.0.0",
4 | "private": false,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "yarn lib",
8 | "lint": "vue-cli-service lint",
9 | "clean": "rimraf lib && rimraf src/*/lib",
10 | "build:theme": "node build/bin/gen-cssfile && gulp build --gulpfile src/theme-chalk/gulpfile.js && cp-cli src/theme-chalk/lib lib/theme-chalk",
11 | "build:lib": "vue-cli-service build --target lib --name deep-ui --dest lib src/index.js",
12 | "pub": "yarn build:lib && yarn build:theme",
13 | "docs:build": "vuepress build docs",
14 | "docs:dev": "vuepress dev docs",
15 | "docs:deploy": "bash build/docs-deploy.sh",
16 | "contributors:add": "all-contributors add",
17 | "contributors:generate": "all-contributors generate",
18 | "new": "plop"
19 | },
20 | "description": "A Component Library for Vue.js.",
21 | "author": "cjfff ",
22 | "contributors": [
23 | "https://github.com/cjfff"
24 | ],
25 | "repository": {
26 | "type": "git",
27 | "url": "https://github.com/cjfff/deep-ui.git"
28 | },
29 | "homepage": "https://github.com/deep-ui/README.md",
30 | "files": [
31 | "lib",
32 | "src"
33 | ],
34 | "keywords": [
35 | "deep-ui",
36 | "vue",
37 | "components"
38 | ],
39 | "license": "MIT",
40 | "main": "lib/deep-ui.umd.min.js",
41 | "unpkg": "src/index.js",
42 | "style": "lib/theme-chalk/index.css",
43 | "devDependencies": {
44 | "@femessage/el-form-renderer": "^1.14.6",
45 | "@femessage/element-ui": "^2.16.0",
46 | "@vue/babel-preset-app": "^4.1.0",
47 | "@vue/cli-plugin-babel": "~4.2.0",
48 | "@vue/cli-plugin-eslint": "~4.2.0",
49 | "@vue/cli-plugin-router": "~4.2.0",
50 | "@vue/cli-service": "^4.2.3",
51 | "@vue/eslint-config-prettier": "^6.0.0",
52 | "all-contributors-cli": "^6.14.0",
53 | "babel-eslint": "^10.0.3",
54 | "cp-cli": "^2.0.0",
55 | "eslint": "^6.7.2",
56 | "eslint-plugin-prettier": "^3.1.1",
57 | "eslint-plugin-vue": "^6.1.2",
58 | "glob": "^7.1.6",
59 | "gulp": "^4.0.2",
60 | "gulp-autoprefixer": "^7.0.1",
61 | "gulp-cssmin": "^0.2.0",
62 | "gulp-less": "^4.0.1",
63 | "json-templater": "^1.2.0",
64 | "less": "^3.11.1",
65 | "less-loader": "^5.0.0",
66 | "markdown-it-vuese": "^0.4.0",
67 | "plop": "^2.6.0",
68 | "prettier": "^1.19.1",
69 | "vue": "^2.6.11",
70 | "vue-template-compiler": "^2.6.11",
71 | "vuepress-plugin-live": "^1.5.1"
72 | },
73 | "dependencies": {
74 | "core-js": "3.x"
75 | }
76 | }
--------------------------------------------------------------------------------
/plop-templates/component/css.hbs:
--------------------------------------------------------------------------------
1 | @import './common/var.less'
--------------------------------------------------------------------------------
/plop-templates/component/export.hbs:
--------------------------------------------------------------------------------
1 | import {{ componentName }} from "./index.vue";
2 |
3 | {{ componentName }}.install = function(Vue) {
4 | Vue.component({{ componentName }}.name, {{ componentName }});
5 | };
6 |
7 | export default {{ componentName }};
--------------------------------------------------------------------------------
/plop-templates/component/index.hbs:
--------------------------------------------------------------------------------
1 | {{#if template}}
2 |
3 | {{ name }}
4 |
5 | {{/if}}
6 |
7 | {{#if script}}
8 |
18 | {{/if}}
19 |
--------------------------------------------------------------------------------
/plop-templates/component/md.hbs:
--------------------------------------------------------------------------------
1 | ---
2 | title: {{ name }}
3 | ---
4 | # {{ name }}
5 |
6 | ## 基本使用
7 |
8 | ```vue live
9 |
10 | <{{name}}>{{name}}>
11 |
12 | ```
13 |
14 | <[vuese]({{name}}/index.vue)
--------------------------------------------------------------------------------
/plop-templates/component/prompt.js:
--------------------------------------------------------------------------------
1 | const { notEmpty, kebabCase, camelCase } = require("../utils.js");
2 |
3 | module.exports = {
4 | description: "generate a component",
5 | prompts: [
6 | {
7 | type: "input",
8 | name: "name",
9 | message: "请输入组件名字(请以驼峰命名)",
10 | validate: notEmpty("组件名字")
11 | },
12 | {
13 | type: "list",
14 | name: "type",
15 | message: "请选择组件类型",
16 | choices: [
17 | {
18 | name: "基础组件",
19 | value: "basic"
20 | },
21 | {
22 | name: "高阶组件",
23 | value: "hoc"
24 | },
25 | {
26 | name: "布局组件",
27 | value: "layout"
28 | }
29 | ]
30 | }
31 | ],
32 | actions: data => {
33 | const kebabName = kebabCase(data.name);
34 | const componentName = camelCase(data.name);
35 |
36 | const actions = [
37 | {
38 | type: "add",
39 | path: `src/components/${kebabName}/index.vue`,
40 | templateFile: "plop-templates/component/index.hbs",
41 | data: {
42 | componentName,
43 | name: kebabName,
44 | template: true,
45 | script: true,
46 | style: true
47 | }
48 | },
49 | {
50 | type: "add",
51 | path: `src/components/${kebabName}/index.js`,
52 | templateFile: "plop-templates/component/export.hbs",
53 | data: {
54 | componentName
55 | }
56 | },
57 | {
58 | type: "add",
59 | path: `docs/component/${data.type}/${kebabName}.md`,
60 | templateFile: "plop-templates/component/md.hbs",
61 | data: {
62 | name: kebabName
63 | }
64 | },
65 | {
66 | type: "add",
67 | path: `src/theme-chalk/src/${kebabName}.less`,
68 | templateFile: "plop-templates/component/css.hbs"
69 | },
70 | {
71 | type: "writeJsonAndBuildEntry",
72 | data: {
73 | name: data.name
74 | }
75 | }
76 | ];
77 |
78 | return actions;
79 | }
80 | };
81 |
--------------------------------------------------------------------------------
/plop-templates/utils.js:
--------------------------------------------------------------------------------
1 | exports.notEmpty = name => {
2 | return v => {
3 | if (!v || v.trim === "") {
4 | return `${name} 必须填写`;
5 | }
6 | return true;
7 | };
8 | };
9 |
10 | // 下划线转换驼峰
11 | function camelCase(name) {
12 | return name
13 | .replace(/[\_|-](\w)/g, function(all, letter) {
14 | return letter.toUpperCase();
15 | })
16 | .replace(/./, _ => _.toUpperCase());
17 | }
18 | // 驼峰转换中划线
19 | function kebabCase(name) {
20 | return name.replace(/([A-Z])/g, "-$1").toLowerCase();
21 | }
22 |
23 | exports.camelCase = camelCase;
24 | exports.kebabCase = kebabCase;
25 |
--------------------------------------------------------------------------------
/plop-templates/writeJsonAndBuildEntry.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const path = require("path");
3 | const render = require("json-templater/string");
4 | const { kebabCase, camelCase } = require("./utils.js");
5 |
6 | const componentsFileName = "components.json";
7 | const fcomponentsFileNameFilePath = path.resolve(
8 | __dirname,
9 | `../${componentsFileName}`
10 | );
11 |
12 | const INDEX_OUTPUT_PATH = path.resolve(__dirname, "../src/index.js");
13 |
14 | const endOfLine = require("os").EOL;
15 |
16 | const IMPORT_TEMPLATE = `import {{name}} from "{{path}}";`;
17 | const INSTALL_COMPONENT_TEMPLATE = " {{name}}";
18 | const MAIN_TEMPLATE = `/* Automatically generated by plop buildEntryData action */
19 |
20 | {{componentsImport}}
21 |
22 | // 存储组件列表
23 | const components = [
24 | {{componentNames}}
25 | ];
26 |
27 | // 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
28 | const install = function(Vue) {
29 | // 判断是否安装
30 | if (install.installed) return;
31 | // 遍历注册全局组件
32 | components.forEach(component => Vue.component(component.name, component));
33 | };
34 |
35 | // 判断是否是直接引入文件
36 | if (typeof window !== "undefined" && window.Vue) {
37 | install(window.Vue);
38 | }
39 |
40 | export default {
41 | // 导出的对象必须具有 install,才能被 Vue.use() 方法安装
42 | install,
43 | // 以下是具体的组件列表
44 | {{componentNames}}
45 | };
46 | `;
47 | module.exports = function({ name }) {
48 | const componentJson = require(fcomponentsFileNameFilePath);
49 |
50 | const kebName = kebabCase(name);
51 |
52 | componentJson[kebName] = `./components/${kebName}/index.js`;
53 |
54 | const componetsEntries = Object.entries(componentJson);
55 |
56 | const componentsImport = componetsEntries
57 | .map(([name, path]) =>
58 | render(IMPORT_TEMPLATE, {
59 | name: camelCase(name),
60 | path
61 | })
62 | )
63 | .join(endOfLine);
64 |
65 | const componentNames = componetsEntries
66 | .map(([name]) =>
67 | render(INSTALL_COMPONENT_TEMPLATE, { name: camelCase(name) })
68 | )
69 | .join(`,${endOfLine}`);
70 |
71 | fs.writeFileSync(
72 | fcomponentsFileNameFilePath,
73 | JSON.stringify(componentJson, null, " "),
74 | "utf-8"
75 | );
76 |
77 | fs.writeFileSync(
78 | INDEX_OUTPUT_PATH,
79 | render(MAIN_TEMPLATE, {
80 | componentNames,
81 | componentsImport
82 | }),
83 | "utf-8"
84 | );
85 |
86 | return "write component.json and index.js is ok";
87 | };
88 |
--------------------------------------------------------------------------------
/plopfile.js:
--------------------------------------------------------------------------------
1 | const componentGenerator = require("./plop-templates/component/prompt");
2 | const writeJsonAndBuildEntry = require("./plop-templates/writeJsonAndBuildEntry");
3 |
4 | module.exports = plop => {
5 | // 增加一种 action
6 | plop.setActionType("writeJsonAndBuildEntry", writeJsonAndBuildEntry);
7 |
8 | plop.setGenerator("component", componentGenerator);
9 | };
10 |
--------------------------------------------------------------------------------
/public/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | <%= htmlWebpackPlugin.options.title %>
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjfff/deep-ui/5efa3ef655d6d26bc298acc40d07da715d21c909/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/public/test.html:
--------------------------------------------------------------------------------
1 |
2 | deepexi demo
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{msg}}
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/components/deepexi-card/index.js:
--------------------------------------------------------------------------------
1 | import DeepexiCard from "./index.vue";
2 |
3 | DeepexiCard.install = function(Vue) {
4 | Vue.component(DeepexiCard.name, DeepexiCard);
5 | };
6 |
7 | export default DeepexiCard;
8 |
--------------------------------------------------------------------------------
/src/components/deepexi-card/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ title }}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
--------------------------------------------------------------------------------
/src/components/list-container/index.js:
--------------------------------------------------------------------------------
1 | import ListContainer from "./index.vue";
2 |
3 | ListContainer.install = function(Vue) {
4 | Vue.component(ListContainer.name, ListContainer);
5 | };
6 |
7 | export default ListContainer;
8 |
--------------------------------------------------------------------------------
/src/components/list-container/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
24 |
25 |
26 |
115 |
--------------------------------------------------------------------------------
/src/components/loading-button/index.js:
--------------------------------------------------------------------------------
1 | import LoadingButton from "./index.vue";
2 |
3 | LoadingButton.install = function(Vue) {
4 | Vue.component(LoadingButton.name, LoadingButton);
5 | };
6 |
7 | export default LoadingButton;
8 |
--------------------------------------------------------------------------------
/src/components/loading-button/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
39 |
--------------------------------------------------------------------------------
/src/components/loading-dialog/index.js:
--------------------------------------------------------------------------------
1 | import LoadingDialog from "./index.vue";
2 |
3 | LoadingDialog.install = function(Vue) {
4 | Vue.component(LoadingDialog.name, LoadingDialog);
5 | };
6 |
7 | export default LoadingDialog;
8 |
--------------------------------------------------------------------------------
/src/components/loading-dialog/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
30 |
31 |
32 |
33 |
34 |
136 |
--------------------------------------------------------------------------------
/src/components/loading-dialog/render.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: "render",
3 | functional: true,
4 | props: {
5 | render: Function,
6 | data: Object,
7 | node: Array
8 | },
9 | render: (h, ctx) => {
10 | const params = {
11 | data: ctx.props.data
12 | };
13 | const { render } = ctx.props;
14 |
15 | return typeof render === "object" ? render : render(h, params);
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/src/components/markdown-view/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./index.vue";
2 |
--------------------------------------------------------------------------------
/src/components/markdown-view/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
36 |
37 |
38 |
326 |
--------------------------------------------------------------------------------
/src/components/markdown-view/utils.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | /**
3 | * 生成带有 id 的标题 DOM
4 | * @param {*} param0
5 | */
6 | export const renderTitle = ({level, id, content}) => `${content}`;
7 |
8 | /**
9 | * 生成带有 height & width 的 img DOM
10 | * @param {*} param0
11 | */
12 | export const renderImage = ({src, height, width}) =>
13 | `
`;
14 |
15 | /**
16 | * 生成随机值的 id
17 | * @param {*} name
18 | */
19 | export const ganerateId = name =>
20 | name + (Math.random().toString(16) + Date.now()).toString(16).slice(2);
21 |
22 | // 进行
23 | export const handleMenuReplace = (html, menuList) =>
24 | menuList.reduce((content, {origin, htmlContent}) => content.replace(origin, htmlContent), html);
25 |
26 | // 批量对图片节点进行替换
27 | export const handleImageList = async (content, maxImageWidth) => {
28 | let imageList = [];
29 |
30 | try {
31 | imageList = await handleContentImage(content, maxImageWidth); // 批量获取图片宽高
32 | } catch (error) {
33 | console.error(error);
34 | return imageList;
35 | }
36 |
37 | return imageList.reduce(
38 | (html, {origin, src, height, width}) => html.replace(origin, renderImage({src, height, width})),
39 | content,
40 | );
41 | };
42 |
43 | /**
44 | * 获取图片高度宽度
45 | * @param {*} param0
46 | * @param {*} maxImageWidth
47 | */
48 | export const getImageWidthAndHeight = ({src, dom}, maxImageWidth = 746) => {
49 | return new Promise(resolve => {
50 | const image = new Image();
51 | image.referrerPolicy = 'no-referrer';
52 | image.src = src;
53 | image.onload = () => {
54 | const {width, height} = image;
55 | const rate = width > maxImageWidth ? parseFloat((image.width / maxImageWidth).toFixed(2)) : 1;
56 | const isOrigin = rate === 1;
57 | resolve({
58 | src,
59 | origin: dom,
60 | width: isOrigin ? width : maxImageWidth,
61 | height: isOrigin ? height : ~~(height / rate),
62 | });
63 | };
64 | });
65 | };
66 |
67 | export const handleContentImage = async (content, maxImageWidth = 746) => {
68 | const imgRegExp = //i;
69 | // 取得内容中所有的 img 标签字符
70 |
71 | const imgListReg = RegExp(imgRegExp.source, 'ig');
72 | const imgList = content.match(imgListReg);
73 |
74 | if (!imgList) return [];
75 |
76 | // 这个正则是用来取得 src="" 里面的链接的
77 | const srcRegexp = RegExp(imgRegExp.source, 'i');
78 |
79 | return Promise.all(
80 | imgList.map(imgItem => {
81 | const [dom, src] = srcRegexp.exec(imgItem);
82 | return getImageWidthAndHeight(
83 | {
84 | dom,
85 | src,
86 | },
87 | maxImageWidth,
88 | );
89 | }),
90 | );
91 | };
92 |
93 | export const handleMenuList = html => {
94 | const TITLE_REGEXP = /(.*)<\/h\1>/;
95 |
96 | // 匹配到所有的 title
97 | const titleListRegexep = RegExp(TITLE_REGEXP.source, 'g');
98 |
99 | const titleList = html.match(titleListRegexep);
100 |
101 | const titleRegExp = RegExp(TITLE_REGEXP.source, 'i');
102 |
103 | const menuList = (titleList || []).reduce((acc, item) => {
104 | const id = ganerateId('menu_');
105 |
106 | const [str, level, _content] = titleRegExp.exec(item);
107 |
108 | // 只提取标签内的内容
109 | const content = _content.replace(/<[^>]+>/gi, '').replace(/ /g, ' ');
110 |
111 | if (level && content) {
112 | const htmlContent = renderTitle({level, content, id});
113 | acc.push({
114 | origin: str,
115 | htmlContent,
116 | level,
117 | content,
118 | id,
119 | });
120 | }
121 | return acc;
122 | }, []);
123 | return menuList;
124 | };
125 |
126 | /**
127 | * 节流,一段时间只运行一次
128 | * @param {*} fn 回调函数
129 | * @param {*} wait
130 | */
131 | export const throttle = (fn, wait) => {
132 | let inThrottle, lastFn, lastTime;
133 | return function() {
134 | const context = this,
135 | args = arguments;
136 | if (!inThrottle) {
137 | fn.apply(context, args);
138 | lastTime = Date.now();
139 | inThrottle = true;
140 | } else {
141 | clearTimeout(lastFn);
142 | lastFn = setTimeout(function() {
143 | if (Date.now() - lastTime >= wait) {
144 | fn.apply(context, args);
145 | lastTime = Date.now();
146 | }
147 | }, Math.max(wait - (Date.now() - lastTime), 0));
148 | }
149 | };
150 | };
151 |
152 | /**
153 | * 获取element元素对于target元素的相对高度
154 | * @param {*} element
155 | */
156 | export function getElementViewTop(element, isRelative = false) {
157 | let actualTop = element.offsetTop;
158 | let current = element.offsetParent;
159 | if (!isRelative) {
160 | while (current !== null && current !== parent) {
161 | actualTop += current.offsetTop;
162 | current = current.offsetParent;
163 | }
164 | }
165 | let elementScrollTop = 0;
166 | if (document.compatMode == 'BackCompat') {
167 | elementScrollTop = document.body.scrollTop;
168 | } else {
169 | elementScrollTop = document.documentElement.scrollTop;
170 | }
171 | return actualTop - elementScrollTop;
172 | }
173 |
--------------------------------------------------------------------------------
/src/components/prompt-form/drawer.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
19 |
20 |
21 |
22 |
35 |
57 |
--------------------------------------------------------------------------------
/src/components/prompt-form/gene-wrapper.js:
--------------------------------------------------------------------------------
1 | import Drawer from "./drawer"; // hack: 因为 el-drawer对超过屏幕的内容不会应用滚动条
2 |
3 | export function geneDialogWrapper(width = 600) {
4 | return {
5 | props: {
6 | visible: Boolean,
7 | title: String,
8 | sureLoading: Boolean
9 | },
10 | methods: {
11 | proxyEvent(eventType, ...rest) {
12 | return () => this.$emit(eventType, rest);
13 | }
14 | },
15 | render() {
16 | const footerStyle = {
17 | textAlign: "right"
18 | };
19 | const handleUpdateVisible = val => {
20 | this.proxyEvent("update:visible", val)();
21 | };
22 | const visiListener = {
23 | on: {
24 | "update:visible": handleUpdateVisible
25 | }
26 | };
27 | return (
28 |
35 |
36 | {this.$slots.default}
37 |
38 |
39 | 取 消
40 |
45 | 确 定
46 |
47 |
48 |
49 | );
50 | }
51 | };
52 | }
53 |
54 | export function geneDrawerWrapper(width = 600) {
55 | return {
56 | props: {
57 | visible: Boolean,
58 | title: String
59 | },
60 | components: {
61 | Drawer
62 | },
63 | methods: {
64 | proxyEvent(eventType, ...rest) {
65 | return () => this.$emit(eventType, rest);
66 | },
67 | sureHandler() {
68 | this.proxyEvent("sure")();
69 | return Promise.resolve();
70 | }
71 | },
72 | render() {
73 | const _this = this;
74 | const spread = {
75 | on: {
76 | "update:visible"(val) {
77 | _this.proxyEvent("update:visible", val)();
78 | }
79 | }
80 | };
81 | return (
82 |
90 |
91 | {this.$slots.default}
92 |
93 |
94 | );
95 | }
96 | };
97 | }
98 |
--------------------------------------------------------------------------------
/src/components/prompt-form/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import { geneDialogWrapper, geneDrawerWrapper } from "./gene-wrapper";
3 | let boxId = 0;
4 |
5 | // eslint-disable-next-line no-unused-vars
6 | function createPrompt(PromptWrapper, title, formOpt) {
7 | // formOpt的处理
8 | const formOpts = [];
9 | if (Array.isArray(formOpt.content)) {
10 | formOpts.push(formOpt);
11 | }
12 | const geneRef = i => `form${i}`;
13 | const geneVueOpt = (resolve, reject) => {
14 | return {
15 | data() {
16 | return {
17 | visible: false,
18 | id: `prompt-${boxId++}`,
19 | defaultLoading: false,
20 | sureLoading: false
21 | };
22 | },
23 | destroyed() {
24 | const child = document.getElementById(this.id);
25 | child && document.body.removeChild(child);
26 | },
27 | methods: {
28 | prompt() {
29 | this.visible = true;
30 | },
31 | shutdown() {
32 | this.visible = false;
33 | },
34 | handleClosed() {
35 | this.$destroy();
36 | // dialog 或者 drawer关闭的时候一律reject
37 | // 根据Promise的状态不可逆,这不会影响到已经resolve状态的Promise
38 | reject(new Error("cancel"));
39 | },
40 | async handleSure() {
41 | let forms = [];
42 |
43 | try {
44 | if (formOpts.length <= 1) {
45 | const ref = this.$refs[geneRef(0)];
46 | forms = ref.getFormValue();
47 | await ref.validate();
48 | }
49 | } catch {
50 | return;
51 | }
52 |
53 | if (typeof formOpt.beforeClose === "function") {
54 | this.sureLoading = true;
55 | await formOpt.beforeClose(forms).finally(() => {
56 | this.sureLoading = false;
57 | });
58 | }
59 | resolve(forms);
60 | this.shutdown();
61 | }
62 | },
63 | mounted() {
64 | // TODO: 将rule validator函数绑定this到当前form
65 | /* formOpts.forEach((opt) => {
66 | (opt.content || []).forEach(item => {
67 | (item.rules || []).forEach(rule => {
68 | if (typeof rule.validator === 'function') {
69 | const validator = rule.validator
70 | rule.validator = (...rest) => {
71 | validator.call({}, ...rest);
72 | };
73 | }
74 | });
75 | });
76 | }); */
77 | },
78 | components: { PromptWrapper },
79 | render() {
80 | const _this = this;
81 | const visiListener = {
82 | on: {
83 | "update:visible"() {
84 | _this.shutdown();
85 | }
86 | }
87 | };
88 | const renderForm = (opt, ref) => {
89 | const { labelWidth = "120px", content, ...rest } = opt;
90 | return (
91 |
99 | );
100 | };
101 |
102 | let body = null;
103 | // 单个表单
104 | if (formOpts.length <= 1) {
105 | body = renderForm(formOpts[0], geneRef(0));
106 | }
107 | return (
108 |
118 | {body}
119 |
120 | );
121 | }
122 | };
123 | };
124 | return new Promise((resolve, reject) => {
125 | const box = document.createElement("div");
126 | document.body.appendChild(box);
127 | // 实例化并且挂载
128 | const comp = (window.comp = new Vue(geneVueOpt(resolve, reject)));
129 | comp.$mount(box);
130 |
131 | comp.prompt();
132 | // nextTick 确保el-form-render已经渲染
133 | Vue.nextTick(() => {
134 | const initDefaultValue = (opt, index) => {
135 | const ref = comp.$refs[geneRef(index)];
136 | const defaultValue = opt.defaultValue;
137 | if (typeof defaultValue === "function") {
138 | comp.defaultLoading = true;
139 | defaultValue()
140 | .then(res => ref.updateForm(res))
141 | .finally(() => (comp.defaultLoading = false));
142 | } else {
143 | ref.updateForm(defaultValue || {});
144 | }
145 | };
146 | // 设置每个表单的初始值
147 | formOpts.forEach((form, index) => initDefaultValue(form, index));
148 | });
149 | });
150 | }
151 |
152 | /**
153 | *
154 | * @param {*} formOpt | el-form-render 配置对象 或者是
155 | * {
156 | * beforeClose: fn, //点击确定之后调用的函数,必须得返回一个promise, promise resolve 后将会关闭对话框
157 | * content: el-form-render 配置对象,
158 | * defaultValue: 表单的初始值
159 | * }
160 | * @param {*} title
161 | */
162 | export function promptDialog(formOpt, title, width) {
163 | const opt = Array.isArray(formOpt) ? { content: formOpt } : formOpt;
164 | return createPrompt(geneDialogWrapper(width), formOpt.title || title, opt);
165 | }
166 |
167 | /**
168 | * @param {*} formOpt | el-form-render 配置对象 或者是
169 | * {
170 | * beforeClose: fn, //点击确定之后调用的函数,必须得返回一个promise, promise resolve 后将会关闭对话框
171 | * content: el-form-render 配置对象,
172 | * defaultValue: 表单的初始值
173 | * }
174 | * @param {*} title
175 | */
176 | export function promptDrawer(formOpt, title, width) {
177 | const opt = Array.isArray(formOpt) ? { content: formOpt } : formOpt;
178 | return createPrompt(geneDrawerWrapper(width), formOpt.title || title, opt);
179 | }
180 |
--------------------------------------------------------------------------------
/src/components/search-input/index.js:
--------------------------------------------------------------------------------
1 | import SearchInput from "./index.vue";
2 |
3 | SearchInput.install = function(Vue) {
4 | Vue.component(SearchInput.name, SearchInput);
5 | };
6 |
7 | export default SearchInput;
8 |
--------------------------------------------------------------------------------
/src/components/search-input/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
50 |
--------------------------------------------------------------------------------
/src/components/text-tooltip/index.js:
--------------------------------------------------------------------------------
1 | import textTooltip from "./index.vue";
2 |
3 | textTooltip.install = function(Vue) {
4 | Vue.component(textTooltip.name, textTooltip);
5 | };
6 |
7 | export default textTooltip;
8 |
--------------------------------------------------------------------------------
/src/components/text-tooltip/index.vue:
--------------------------------------------------------------------------------
1 |
97 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /* Automatically generated by plop buildEntryData action */
2 |
3 | import TextTooltip from "./components/text-tooltip/index.js";
4 | import SearchInput from "./components/search-input/index.js";
5 | import ListContainer from "./components/list-container/index.js";
6 | import DeepexiCard from "./components/deepexi-card/index.js";
7 | import LoadingDialog from "./components/loading-dialog/index.js";
8 | import MarkdownView from "./components/markdown-view/index.js";
9 | import LoadingButton from "./components/loading-button/index.js";
10 | import { promptDialog, promptDrawer } from "./components/prompt-form";
11 |
12 | // 存储组件列表
13 | const components = [
14 | TextTooltip,
15 | SearchInput,
16 | ListContainer,
17 | DeepexiCard,
18 | LoadingDialog,
19 | MarkdownView,
20 | LoadingButton
21 | ];
22 |
23 | // 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
24 | const install = function(Vue) {
25 | // 判断是否安装
26 | if (install.installed) return;
27 | // 遍历注册全局组件
28 | components.forEach(component => Vue.component(component.name, component));
29 | // prompt-form 方法
30 | Vue.prototype.$promptDialog = promptDialog;
31 | Vue.prototype.$promptDrawer = promptDrawer;
32 | };
33 |
34 | // 判断是否是直接引入文件
35 | if (typeof window !== "undefined" && window.Vue) {
36 | install(window.Vue);
37 | }
38 |
39 | export default {
40 | // 导出的对象必须具有 install,才能被 Vue.use() 方法安装
41 | install,
42 | // 以下是具体的组件列表
43 | TextTooltip,
44 | SearchInput,
45 | ListContainer,
46 | DeepexiCard,
47 | LoadingDialog,
48 | MarkdownView,
49 | LoadingButton
50 | };
51 |
--------------------------------------------------------------------------------
/src/mixins/emitter.js:
--------------------------------------------------------------------------------
1 | function broadcast(componentName, eventName, params) {
2 | this.$children.forEach(child => {
3 | const name = child.$options.name;
4 |
5 | if (name === componentName) {
6 | child.$emit.apply(child, [eventName].concat(params));
7 | } else {
8 | broadcast.apply(child, [componentName, eventName].concat([params]));
9 | }
10 | });
11 | }
12 | export default {
13 | methods: {
14 | dispatch(componentName, eventName, params) {
15 | let parent = this.$parent || this.$root;
16 | let name = parent.$options.name;
17 |
18 | while (parent && (!name || name !== componentName)) {
19 | parent = parent.$parent;
20 |
21 | if (parent) {
22 | name = parent.$options.name;
23 | }
24 | }
25 | if (parent) {
26 | parent.$emit.apply(parent, [eventName].concat(params));
27 | }
28 | },
29 | broadcast(componentName, eventName, params) {
30 | broadcast.call(this, componentName, eventName, params);
31 | }
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/src/theme-chalk/gulpfile.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const { series, src, dest } = require("gulp");
4 | const less = require("gulp-less");
5 | const autoprefixer = require("gulp-autoprefixer");
6 | const cssmin = require("gulp-cssmin");
7 |
8 | function compile() {
9 | return src("./src/*.less")
10 | .pipe(
11 | less({
12 | plugins: [
13 | autoprefixer({
14 | browsers: ["ie > 9", "last 2 versions"],
15 | cascade: false
16 | })
17 | ]
18 | })
19 | )
20 | .pipe(cssmin())
21 | .pipe(dest("./lib"));
22 | }
23 |
24 | // function copyfont() {
25 | // return src("./src/fonts/**")
26 | // .pipe(cssmin())
27 | // .pipe(dest("./lib/fonts"));
28 | // }
29 |
30 | exports.build = series(compile);
31 |
--------------------------------------------------------------------------------
/src/theme-chalk/src/common/markdown-preview.less:
--------------------------------------------------------------------------------
1 | @margin: 8px 0;
2 | //主体颜色
3 | @primary: #292d35;
4 | @light-primary: #323741;
5 | @dark-primary: #1c1e24;
6 | //
7 | @info: #007acc;
8 | @success: #19be6b;
9 | @warning: #ff9900;
10 | @error: #ed3f14;
11 | //
12 | @title: #252525;
13 | @content: #555;
14 | @sub-color: #80848f;
15 | @disabled: #bbbec4;
16 | @border: #dddee1;
17 | @divider: #e9eaec;
18 | @background: #f7f7f7;
19 | @tip: #c1c1c1;
20 | @primary-rgba: rgba(49, 204, 102, 0.2);
21 | @mask: rgba(0, 0, 0, 0.3);
22 | @blue-rgba: rgba(0, 122, 204, 0.2);
23 | @dark-info: #0169af;
24 | @line-height: 1.8rem;
25 |
26 |
27 | pre {
28 | padding: 20px 20px 30px !important;
29 | display: block;
30 | color: #abb2bf;
31 | font-family: Menlo, Consolas, "Courier New", Courier, FreeMono, monospace;
32 | background: #292c34;
33 | border-radius: 4px;
34 | overflow-y: hidden !important;
35 | overflow-x: auto !important;
36 | margin: 20px 0 !important;
37 |
38 | * {
39 | line-height: 1.6 !important;
40 | font-size: 14px;
41 | font-family: Menlo, Consolas, "Courier New", Courier, FreeMono,
42 | monospace;
43 | }
44 | }
45 |
46 | .hljs-comment,
47 | .hljs-quote {
48 | color: #5c6370;
49 | font-style: italic;
50 | }
51 |
52 | .hljs-doctag,
53 | .hljs-formula,
54 | .hljs-keyword {
55 | color: #c678dd;
56 | }
57 |
58 | .hljs-deletion,
59 | .hljs-name,
60 | .hljs-section,
61 | .hljs-selector-tag,
62 | .hljs-subst {
63 | color: #e06c75;
64 | }
65 |
66 | .hljs-literal {
67 | color: #56b6c2;
68 | }
69 |
70 | .hljs-addition,
71 | .hljs-attribute,
72 | .hljs-meta-string,
73 | .hljs-regexp,
74 | .hljs-string {
75 | color: #98c379;
76 | }
77 |
78 | .hljs-built_in,
79 | .hljs-class .hljs-title {
80 | color: #e6c07b;
81 | }
82 |
83 | .hljs-attr,
84 | .hljs-number,
85 | .hljs-selector-attr,
86 | .hljs-selector-class,
87 | .hljs-selector-pseudo,
88 | .hljs-template-variable,
89 | .hljs-type,
90 | .hljs-variable {
91 | color: #d19a66;
92 | }
93 |
94 | .hljs-bullet,
95 | .hljs-link,
96 | .hljs-meta,
97 | .hljs-selector-id,
98 | .hljs-symbol,
99 | .hljs-title {
100 | color: #61aeee;
101 | }
102 |
103 | .hljs-emphasis {
104 | font-style: italic;
105 | }
106 |
107 | .hljs-strong {
108 | font-weight: bold;
109 | }
110 |
111 | .hljs-link {
112 | text-decoration: underline;
113 | }
114 |
115 | .markdown-preview {
116 | flex: 1;
117 | overflow: hidden;
118 | background: #fff;
119 | // padding: 20px 12px !important;
120 | font-family: "Open Sans",
121 | "Helvetica Neue",
122 | Helvetica,
123 | Arial,
124 | sans-serif;
125 |
126 |
127 | >div {
128 | padding: 10px 12px !important;
129 | background: #fff;
130 |
131 | &::-webkit-scrollbar {
132 | display: none;
133 | }
134 | }
135 |
136 | &::-webkit-scrollbar {
137 | display: none;
138 | }
139 |
140 | ul {
141 | list-style: none;
142 | padding: 0 20px;
143 |
144 | li {
145 | position: relative;
146 |
147 | &:after {
148 | display: block;
149 | content: "";
150 | width: 8px;
151 | height: 8px;
152 | border-radius: 50%;
153 | position: absolute;
154 | z-index: 99;
155 | top: 7px;
156 | left: -20px;
157 | background: @content;
158 | }
159 | }
160 | }
161 |
162 | ol,
163 | ul {
164 | margin: 20px 0;
165 | padding: 0 40px;
166 |
167 | li {
168 | font-size: 14px !important;
169 | color: @content;
170 | margin-bottom: 10px;
171 | line-height: 24px;
172 | padding-left: 12px;
173 |
174 | input[type="checkbox"] {
175 | position: relative;
176 | cursor: pointer;
177 | overflow: visible;
178 | position: absolute;
179 | left: 0;
180 | top: 0;
181 |
182 | &:after {
183 | display: block;
184 | content: "";
185 | width: 16px;
186 | height: 16px;
187 | position: absolute;
188 | z-index: 99999;
189 | background: #fff;
190 | top: 0;
191 | right: 0;
192 | }
193 |
194 | &:before {
195 | display: block;
196 | width: 18px;
197 | height: 18px;
198 | position: absolute;
199 | content: "";
200 | top: 2px;
201 | left: -25px;
202 | z-index: 999999;
203 | background-position: center;
204 | background: url("data:image/jpeg;base64,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AAAATmd0dmJvb2wAAAAAAEVtbERib29sAAAAAABJbnRyYm9vbAAAAAAAQmNrZ09iamMAAAABAAAAAAAAUkdCQwAAAAMAAAAAUmQgIGRvdWJAb+AAAAAAAAAAAABHcm4gZG91YkBv4AAAAAAAAAAAAEJsICBkb3ViQG/gAAAAAAAAAAAAQnJkVFVudEYjUmx0AAAAAAAAAAAAAAAAQmxkIFVudEYjUmx0AAAAAAAAAAAAAAAAUnNsdFVudEYjUHhsQFIAAAAAAAAAAAAKdmVjdG9yRGF0YWJvb2wBAAAAAFBnUHNlbnVtAAAAAFBnUHMAAAAAUGdQQwAAAABMZWZ0VW50RiNSbHQAAAAAAAAAAAAAAABUb3AgVW50RiNSbHQAAAAAAAAAAAAAAABTY2wgVW50RiNQcmNAWQAAAAAAAAAAABBjcm9wV2hlblByaW50aW5nYm9vbAAAAAAOY3JvcFJlY3RCb3R0b21sb25nAAAAAAAAAAxjcm9wUmVjdExlZnRsb25nAAAAAAAAAA1jcm9wUmVjdFJpZ2h0bG9uZwAAAAAAAAALY3JvcFJlY3RUb3Bsb25nAAAAAAA4QklNA+0AAAAAABAASAAAAAEAAgBIAAAAAQACOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD+AAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0EAAAAAAAAAgAAOEJJTQQCAAAAAAACAAA4QklNBDAAAAAAAAEBADhCSU0ELQAAAAAABgABAAAAAjhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAANDAAAA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OjM4KzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOC0wOS0xM1QxNjo1NjozOCswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOC0wOS0xM1QxNjo1NjozOCswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9qcGVnIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6YmFlYmVlNTQtODI3My00MTJhLTk0NDgtZTdhYzU1MjFjMWZkIiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6NjBlZDg0MmItNjZjMy1hNDRlLTgxNGItYWVjM2JiMjg1Mjg3IiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MTQyYTk3NzMtZjA2NC00N2Q3LTllMDMtOWI5YzhhYzc0YWI5Ij4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxNDJhOTc3My1mMDY0LTQ3ZDctOWUwMy05YjljOGFjNzRhYjkiIHN0RXZ0OndoZW49IjIwMTgtMDktMDVUMTg6MjE6MzgrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKSIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY29udmVydGVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJmcm9tIGltYWdlL3BuZyB0byBpbWFnZS9qcGVnIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpiYWViZWU1NC04MjczLTQxMmEtOTQ0OC1lN2FjNTUyMWMxZmQiIHN0RXZ0OndoZW49IjIwMTgtMDktMTNUMTY6NTY6MzgrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/Pv/iDFhJQ0NfUFJPRklMRQABAQAADEhMaW5vAhAAAG1udHJSR0IgWFlaIAfOAAIACQAGADEAAGFjc3BNU0ZUAAAAAElFQyBzUkdCAAAAAAAAAAAAAAAAAAD21gABAAAAANMtSFAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWNwcnQAAAFQAAAAM2Rlc2MAAAGEAAAAbHd0cHQAAAHwAAAAFGJrcHQAAAIEAAAAFHJYWVoAAAIYAAAAFGdYWVoAAAIsAAAAFGJYWVoAAAJAAAAAFGRtbmQAAAJUAAAAcGRtZGQAAALEAAAAiHZ1ZWQAAANMAAAAhnZpZXcAAAPUAAAAJGx1bWkAAAP4AAAAFG1lYXMAAAQMAAAAJHRlY2gAAAQwAAAADHJUUkMAAAQ8AAAIDGdUUkMAAAQ8AAAIDGJUUkMAAAQ8AAAIDHRleHQAAAAAQ29weXJpZ2h0IChjKSAxOTk4IEhld2xldHQtUGFja2FyZCBDb21wYW55AABkZXNjAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAAAAAAAAAAAAAAAAWFla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") no-repeat;
205 | background-size: contain;
206 | }
207 | }
208 |
209 | input[type="checkbox"]:checked {
210 | &:before {
211 | background: url("data:image/jpeg;base64,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WQAAAAAAAAAAABBjcm9wV2hlblByaW50aW5nYm9vbAAAAAAOY3JvcFJlY3RCb3R0b21sb25nAAAAAAAAAAxjcm9wUmVjdExlZnRsb25nAAAAAAAAAA1jcm9wUmVjdFJpZ2h0bG9uZwAAAAAAAAALY3JvcFJlY3RUb3Bsb25nAAAAAAA4QklNA+0AAAAAABAASAAAAAEAAgBIAAAAAQACOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD+AAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0EAAAAAAAAAgAAOEJJTQQCAAAAAAACAAA4QklNBDAAAAAAAAEBADhCSU0ELQAAAAAABgABAAAAAjhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAANDAAAABgAAAAAAAAAAAAAAgAAAAIAAAAAHAGMAaABlAGMAawBlAGQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAIAAAACAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAACAAAAAAFJnaHRsb25nAAAAgAAAAAZzbGljZXNWbExzAAAAAU9iamMAAAABAAAAAAAFc2xpY2UAAAASAAAAB3NsaWNlSURsb25nAAAAAAAAAAdncm91cElEbG9uZwAAAAAAAAAGb3Jp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dHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKE1hY2ludG9zaCkiIHhtcDpDcmVhdGVEYXRlPSIyMDE4LTA5LTA1VDE4OjIxOjM4KzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOC0wOS0xM1QxNjo1NTo0OSswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOC0wOS0xM1QxNjo1NTo0OSswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9qcGVnIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTMwY2QwMDgtODA3Zi00NDk4LTlkYjctMjZjYWI2ZWI1ODM3IiB4bXBNTTpEb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6MWNkYzYwM2UtNmVhNy0wYjQ0LThhMTEtZDk4YTFlODhkMTVlIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6M2EwNjc1YjItZTY3MC00NWU0LThhZmUtN2UzYzU1ZTRjNTEyIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozYTA2NzViMi1lNjcwLTQ1ZTQtOGFmZS03ZTNjNTVlNGM1MTIiIHN0RXZ0OndoZW49IjIwMTgtMDktMDVUMTg6MjE6MzgrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKSIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY29udmVydGVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJmcm9tIGltYWdlL3BuZyB0byBpbWFnZS9qcGVnIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxMzBjZDAwOC04MDdmLTQ0OTgtOWRiNy0yNmNhYjZlYjU4MzciIHN0RXZ0OndoZW49IjIwMTgtMDktMTNUMTY6NTU6NDkrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoTWFjaW50b3NoKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/Pv/iDFhJQ0NfUFJPRklMRQABAQAADEhMaW5vAhAAAG1udHJSR0IgWFlaIAfOAAIACQAGADEAAGFjc3BNU0ZUAAAAAElFQyBzUkdCAAAAAAAAAAAAAAAAAAD21gABAAAAANMtSFAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWNwcnQAAAFQAAAAM2Rlc2MAAAGEAAAAbHd0cHQAAAHwAAAAFGJrcHQAAAIEAAAAFHJYWVoAAAIYAAAAFGdYWVoAAAIsAAAAFGJYWVoAAAJAAAAAFGRtbmQAAAJUAAAAcGRtZGQAAALEAAAAiHZ1ZWQAAANMAAAAhnZpZXcAAAPUAAAA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") no-repeat;
212 | background-size: contain;
213 | }
214 | }
215 | }
216 | }
217 |
218 | ol {
219 | list-style-type: decimal;
220 | }
221 |
222 | hr {
223 | color: @border;
224 | height: 1px;
225 | border: 0;
226 | border-top: 1px solid @border;
227 | margin: 20px 0;
228 | padding: 0;
229 | }
230 |
231 | del,
232 | em,
233 | strong {
234 | display: inline-block;
235 | margin: @margin;
236 | }
237 |
238 | blockquote {
239 | position: relative;
240 | background: @background;
241 | padding: 6px 12px;
242 | border-left: 5px solid @divider;
243 | border-radius: 2px;
244 | margin: @margin;
245 | }
246 |
247 | /*基本样式*/
248 |
249 | h1,
250 | h2,
251 | h3,
252 | h4,
253 | h5,
254 | h6 {
255 | color: @title;
256 | }
257 |
258 | h1 {
259 | font-size: 28px;
260 | border-bottom: 1px solid @border;
261 | //text-align: center;
262 | }
263 |
264 | h2 {
265 | font-size: 24px;
266 | }
267 |
268 | h3 {
269 | font-size: 18px;
270 | }
271 |
272 | h4 {
273 | font-size: 16px;
274 | }
275 |
276 | h5 {
277 | font-size: 14px;
278 | }
279 |
280 | h6 {
281 | font-size: 12px;
282 | }
283 |
284 | h1,
285 | h2,
286 | h3,
287 | h4,
288 | h5,
289 | h6 {
290 | /* border-bottom: 1px solid @border; */
291 | padding: 20px 0;
292 | font-weight: 600;
293 | }
294 |
295 | p {
296 | font-size: 14px !important;
297 | color: @content;
298 | margin: @margin;
299 | line-height: @line-height;
300 | }
301 |
302 | img {
303 | display: block;
304 | width: 90%;
305 | cursor: pointer;
306 | }
307 |
308 | table {
309 | width: 100%;
310 | border: 1px solid @border;
311 | border-bottom: 0;
312 | background: #fff;
313 | border-spacing: 0;
314 | border-collapse: collapse;
315 | margin: 20px 0;
316 |
317 | tr {
318 | -webkit-transition: background 0.1s;
319 | transition: background 0.1s;
320 | text-align: nav;
321 | }
322 |
323 | tr td,
324 | tr th {
325 | padding: 0 8px;
326 | font-size: 14px;
327 | line-height: 39px;
328 | color: #333;
329 | border-bottom: 1px solid @border;
330 | cursor: pointer;
331 | }
332 |
333 | th {
334 | background: #f8f8f9;
335 | text-align: left;
336 | font-weight: bold;
337 | }
338 |
339 | tr:nth-of-type(even) {
340 | td {
341 | background: #f8f8f9;
342 | }
343 | }
344 |
345 | tr {
346 | &:hover {
347 | td {
348 | background: #eaf5f6;
349 | }
350 | }
351 | }
352 |
353 | td,
354 | th {
355 | border: 1px solid @border;
356 | }
357 | }
358 |
359 | input[type="checkbox"] {
360 | display: inline-block;
361 | border-radius: 0;
362 | margin-right: 8px;
363 | }
364 |
365 | a {
366 | text-decoration: none;
367 | color: @info;
368 | font-size: 14px;
369 | line-height: @line-height;
370 | }
371 | }
372 |
--------------------------------------------------------------------------------
/src/theme-chalk/src/common/var.less:
--------------------------------------------------------------------------------
1 | /*
2 | 支持自动引入less变量表,使用时无需手动引入
3 | */
4 |
5 | @primary-color: #5D81F9;
6 | // base color
7 | /// color|1|BrandColor|0
8 | @--color-primary: #5D81F9; //
9 | /// color|1|SecondaryColor|1
10 | @--color-success: #02C5E2;
11 | /// color|1|SecondaryColor|1
12 | @--color-warning: #F5A623;
13 | /// color|1|SecondaryColor|1
14 | @--color-danger: #E24156;
15 | /// color|1|SecondaryColor|1
16 | @--color-info: #6A6E7B;
17 |
18 | /// color|1|FontColor|2
19 | @--color-text-primary: #2D303B;
20 | /// color|1|FontColor|2
21 | @--color-text-regular: #2D303B;
22 | /// color|1|FontColor|2
23 | @--color-text-secondary: #93959b;
24 | /// color|1|FontColor|2
25 | @--color-text-placeholder: #9CA6C7;
26 | /// color|1|BorderColor|3
27 | @--border-color-base: #CAD1E8;
28 | /// color|1|BorderColor|3
29 | @--border-color-light: #CAD1E8;
30 | /// color|1|BorderColor|3
31 | @--border-color-lighter: #EBEEF5;
32 | /// color|1|BorderColor|3
33 | @--border-color-extra-light: #F2F6FC;
34 |
35 | @--font-color-disabled-base: #bbb;
36 |
37 | // Background
38 | /// color|1|BackgroundColor|4
39 | @--background-color-base: #f5f7fa;
40 |
41 | //sidebar
42 | @menuText: rgba(255, 255, 255, 1);
43 | @menuFontColor: rgba(255, 255, 255, 0.7);
44 | @menuActiveText: #fff;
45 | @subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
46 |
47 | @menuBg: rgba(51, 54, 67, 1);
48 |
49 | @subMenuBg:#1f2d3d;
50 | @subMenuHover:#001528;
51 |
52 | @sideBarMaxWidth: 200px; // 侧边栏的最大宽度
53 | @sideBarMinWidth: 64px; // 侧边栏的最小宽度
54 |
55 | @padding-size: 24px;
56 | @margin-size: 16px;
57 |
58 | @cyan: #02C5E2;
59 | @black: #2D303B;
60 | @white: #fff;
61 | @gray: #9CA6C7;
62 | @error: #E24156;
63 |
64 | @font-l: 16px;
65 | @font-m: 14px;
66 | @font-s: 12px;
67 |
68 | @border-color: #CAD1E8;
69 | @bg-color: #F0F2F5;
70 | @bg-code: #f6f8fa;
71 |
72 | @basic-font-family: PingFangSC-Regular;
73 | @font-weight: 400;
74 | .setFontHidden {
75 | // 字体超出显示省略号
76 | white-space: nowrap;
77 | overflow: hidden;
78 | text-overflow: ellipsis;
79 | }
80 |
--------------------------------------------------------------------------------
/src/theme-chalk/src/deepexi-card.less:
--------------------------------------------------------------------------------
1 | @import './common/var';
2 |
3 | .deepexi-card {
4 | background: #fff;
5 | border-radius: 4px;
6 | & + .deepexi-card {
7 | margin-top: @margin-size;
8 | }
9 | &-title {
10 | height: 48px;
11 | line-height: 48px;
12 | border-bottom: 1px solid #e4e8f3;
13 | padding: 0 @padding-size;
14 | font-size: 14px;
15 | font-weight: 500;
16 | color: rgba(106, 108, 115, 1);
17 | }
18 | &-content {
19 | padding: @padding-size;
20 | }
21 | }
--------------------------------------------------------------------------------
/src/theme-chalk/src/index.less:
--------------------------------------------------------------------------------
1 | @import "./common/var.less";
2 | @import "./text-tooltip.less";
3 | @import "./search-input.less";
4 | @import "./list-container.less";
5 | @import "./deepexi-card.less";
6 | @import "./loading-dialog.less";
7 | @import "./markdown-view.less";
8 | @import "./loading-button.less";
9 |
--------------------------------------------------------------------------------
/src/theme-chalk/src/list-container.less:
--------------------------------------------------------------------------------
1 | @import './common/var';
2 |
3 | .list-container {
4 | @lineHeight: 60px;
5 |
6 | &-header {
7 | position: relative;
8 | display: flex;
9 | border-bottom: 1px solid #eee;
10 | background: #fff;
11 | overflow-x: auto;
12 |
13 | .tab-active-bar {
14 | position: absolute;
15 | bottom: 0;
16 | left: 0;
17 | z-index: 1;
18 | width: 80px;
19 | height: 2px;
20 | background: @primary-color;
21 |
22 | &.animation {
23 | transition: 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); // element.ui tabbar 的动画
24 | }
25 | }
26 |
27 | .tab-like-box {
28 | list-style: none;
29 | padding: 0;
30 | font-weight: 400;
31 | display: inherit;
32 | width: auto;
33 | white-space: nowrap;
34 |
35 | .tab {
36 | padding: 0 16px;
37 | line-height: @lineHeight;
38 | display: inline-block;
39 | cursor: pointer;
40 | color: #000;
41 |
42 | &.is-active {
43 | color: @primary-color;
44 | }
45 | }
46 | }
47 |
48 | .right-part {
49 | line-height: @lineHeight;
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/theme-chalk/src/loading-button.less:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjfff/deep-ui/5efa3ef655d6d26bc298acc40d07da715d21c909/src/theme-chalk/src/loading-button.less
--------------------------------------------------------------------------------
/src/theme-chalk/src/loading-dialog.less:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjfff/deep-ui/5efa3ef655d6d26bc298acc40d07da715d21c909/src/theme-chalk/src/loading-dialog.less
--------------------------------------------------------------------------------
/src/theme-chalk/src/markdown-view.less:
--------------------------------------------------------------------------------
1 | @import './common/var';
2 | @import "./common/markdown-preview.less";
3 |
4 | .mardkdown-view {
5 | position: relative;
6 | background: #fff;
7 | display: flex;
8 |
9 | .left-content {
10 | width: 100%;
11 | min-width: 300px;
12 | margin-right: 80px;
13 |
14 | .markdown-preview {
15 | h1 {
16 | border-bottom: none;
17 | }
18 | }
19 | }
20 |
21 | .right-content {
22 | width: 230px;
23 | }
24 |
25 | .deepexi-scrollbar-wrap {
26 | position: relative;
27 | transform: translateX(-20px);
28 |
29 | &.fixed {
30 | top: 0;
31 | right: 0;
32 | position: fixed;
33 | }
34 | }
35 |
36 | .deepexi-scrollbar {
37 | overflow-y: auto;
38 | width: 200px;
39 |
40 | &::-webkit-scrollbar {
41 | width: 4px;
42 | height: 20px;
43 | }
44 |
45 | &::-webkit-scrollbar-track {
46 | box-shadow: inset 0 0 6px #e5e5e5;
47 | border-radius: 5px;
48 | }
49 |
50 | &::-webkit-scrollbar-thumb {
51 | border-radius: 5px;
52 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.2);
53 | }
54 | }
55 |
56 | .fe-menu {
57 | list-style: none;
58 | position: relative;
59 | padding: 0;
60 |
61 | &-item {
62 | cursor: pointer;
63 | position: relative;
64 | line-height: 2;
65 | font-size: 12px;
66 | width: 100%;
67 | overflow: hidden; /* 超出部分隐藏 */
68 | white-space: nowrap;
69 | text-overflow: ellipsis; /* 适用IE */
70 | padding: 0 10px;
71 | transition: color 0.5s;
72 | border-left: 2px solid #e8e8e8;
73 |
74 | &:hover {
75 | opacity: 0.8;
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/theme-chalk/src/search-input.less:
--------------------------------------------------------------------------------
1 | .search-input {
2 | width : 240px;
3 | z-index: 10;
4 |
5 | .search-icon /deep/ {
6 | display : inline-block;
7 | width : 14px;
8 | margin-left: 5px;
9 | background : url("https://deepexi.oss-cn-shenzhen.aliyuncs.com/deepexi-services-dashboard/common/search.svg") center / contain no-repeat;
10 | }
11 |
12 | .el-icon-search:before {
13 | font-size: 20px;
14 | color : #eee;
15 | }
16 |
17 | .el-input__inner {
18 | padding-left: 34px;
19 | border : none;
20 | border : 1px solid #eee;
21 |
22 | &:focus {
23 | border: 1px solid #bcc3d9;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/theme-chalk/src/text-tooltip.less:
--------------------------------------------------------------------------------
1 | .text-tooltip {
2 | display : inline-block;
3 | overflow: hidden;
4 | width : 100%;
5 |
6 | &.ellipsis {
7 | text-overflow: ellipsis;
8 | white-space : nowrap;
9 | }
10 | }
--------------------------------------------------------------------------------
/src/utils/assist.js:
--------------------------------------------------------------------------------
1 | export function oneOf(value, validList) {
2 | for (let i = 0; i < validList.length; i++) {
3 | if (value === validList[i]) {
4 | return true;
5 | }
6 | }
7 | return false;
8 | }
9 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | const buildMode = process.env.BUILD_MODE;
4 |
5 | console.log(buildMode);
6 |
7 | module.exports = {
8 | productionSourceMap: false,
9 | pages: {
10 | index: {
11 | entry: "src/index.js",
12 | template: "public/index.html",
13 | filename: "index.html"
14 | }
15 | },
16 | configureWebpack: {
17 | externals: {
18 | "@femessage/element-ui": "Element",
19 | vue: {
20 | root: "Vue",
21 | commonjs: "vue",
22 | commonjs2: "vue",
23 | amd: "vue"
24 | }
25 | }
26 | },
27 | chainWebpack: config => {
28 | if (process.env.NODE_ENV === "development") {
29 | config.devtool = "source-map";
30 | }
31 | }
32 | };
33 |
--------------------------------------------------------------------------------