diff --git a/.gitignore b/.gitignore index 37861b36819a137886ee87d1b0c8331eac6349b0..399d9de0dc493a8789286352bf31e082f755f4f6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ yarn-error.log packages/devui-vue/devui/vue-devui.ts packages/devui-vue/devui/theme/theme.scss packages/devui-vue/docs/.vitepress/config/sidebar.ts +packages/devui-vue/docs/.vitepress/config/enSidebar.ts + diff --git a/packages/devui-vue/devui-cli/commands/create.js b/packages/devui-vue/devui-cli/commands/create.js index 91433ada765ab462e4ed653fca4eecaf3aa28150..15b2e4f50129b51b271212a87113d314b1fe730a 100644 --- a/packages/devui-vue/devui-cli/commands/create.js +++ b/packages/devui-vue/devui-cli/commands/create.js @@ -8,10 +8,8 @@ const { const fs = require('fs-extra') const { resolve } = require('path') const { - DEVUI_NAMESPACE, DEVUI_DIR, TESTS_DIR_NAME, - COMPONENT_PARTS_MAP, INDEX_FILE_NAME, DOCS_FILE_NAME, VUE_DEVUI_FILE, @@ -22,7 +20,9 @@ const { CREATE_SUPPORT_TYPE_MAP, SITES_COMPONENTS_DIR, VITEPRESS_SIDEBAR_FILE, - VITEPRESS_SIDEBAR_FILE_NAME + VITEPRESS_SIDEBAR_FILE_NAME, + VITEPRESS_SIDEBAR_FILE_EN, + VITEPRESS_SIDEBAR_FILE_NAME_EN } = require('../shared/constant') const { isEmpty, kebabCase } = require('lodash') const inquirer = require('inquirer') @@ -40,7 +40,7 @@ const { } = require('../templates/component') const { createVueDevuiTemplate } = require('../templates/vue-devui') const ora = require('ora') -const { createVitepressSidebarTemplate } = require('../templates/vitepress-sidebar') +const { createVitepressSidebarTemplates } = require('../templates/vitepress-sidebar') exports.validateCreateType = (type) => { const re = new RegExp('^(' + CREATE_SUPPORT_TYPES.map((t) => `(${t})`).join('|') + ')$') @@ -80,7 +80,7 @@ exports.create = async (cwd) => { case CREATE_SUPPORT_TYPE_MAP['vue-devui']: // 创建 devui/vue-devui.ts await createVueDevui(params, cwd) - // 创建 docs/.vitepress/config/sidebar.ts + // 创建 docs/.vitepress/config/sidebar.ts enSidebar.ts await createVitepressSidebar() break default: @@ -140,14 +140,16 @@ async function createComponent(params = {}) { const writeFiles = [ fs.writeFile(resolve(componentDir, INDEX_FILE_NAME), indexTemplate), - fs.writeFile(resolve(testsDir, `${testName}.ts`), testsTemplate), + fs.writeFile(resolve(testsDir, `${testName}.ts`), testsTemplate) ] if (!fs.existsSync(docsDir)) { fs.mkdirSync(docsDir) writeFiles.push(fs.writeFile(resolve(docsDir, DOCS_FILE_NAME), docTemplate)) } else { - logger.warning(`\n${bigCamelCase(componentName)} 组件文档已存在:${resolve(docsDir, DOCS_FILE_NAME)}`) + logger.warning( + `\n${bigCamelCase(componentName)} 组件文档已存在:${resolve(docsDir, DOCS_FILE_NAME)}` + ) } if (hasComponent || hasService) { @@ -207,9 +209,18 @@ async function createVueDevui(params, { ignoreParseError }) { } async function createVitepressSidebar() { + const generateFileConfig = { + zh: { + fileName: VITEPRESS_SIDEBAR_FILE_NAME, + location: VITEPRESS_SIDEBAR_FILE + }, + en: { + fileName: VITEPRESS_SIDEBAR_FILE_NAME_EN, + location: VITEPRESS_SIDEBAR_FILE_EN + } + } const fileInfo = resolveDirFilesInfo(DEVUI_DIR, VUE_DEVUI_IGNORE_DIRS) const componentsInfo = [] - fileInfo.forEach((f) => { const info = parseComponentInfo(f.dirname) @@ -218,17 +229,19 @@ async function createVitepressSidebar() { componentsInfo.push(info) }) - const template = createVitepressSidebarTemplate(componentsInfo) - - let spinner = ora(`创建 ${VITEPRESS_SIDEBAR_FILE_NAME} 文件开始...`).start() + const templates = createVitepressSidebarTemplates(componentsInfo) + templates.forEach((template) => { + const { fileName, location } = generateFileConfig[template.lang] + const spinner = ora(`创建 ${fileName} 文件开始...`).start() - try { - await fs.writeFile(VITEPRESS_SIDEBAR_FILE, template, { encoding: 'utf-8' }) + try { + fs.writeFile(location, template.content, { encoding: 'utf-8' }) - spinner.succeed(`创建 ${VITEPRESS_SIDEBAR_FILE_NAME} 文件成功!`) - logger.info(`文件地址:${VITEPRESS_SIDEBAR_FILE}`) - } catch (e) { - spinner.fail(e.toString()) - process.exit(1) - } + spinner.succeed(`创建 ${fileName} 文件成功!`) + logger.info(`文件地址:${location}`) + } catch (e) { + spinner.fail(e.toString()) + process.exit(1) + } + }) } diff --git a/packages/devui-vue/devui-cli/shared/constant.js b/packages/devui-vue/devui-cli/shared/constant.js index 6288409782d590df0d3e450b4f279a854a627793..9a27665b7c1382b69066408711e009623cc59a9a 100644 --- a/packages/devui-vue/devui-cli/shared/constant.js +++ b/packages/devui-vue/devui-cli/shared/constant.js @@ -14,14 +14,37 @@ exports.VUE_DEVUI_FILE_NAME = 'vue-devui.ts' exports.VUE_DEVUI_FILE = resolve(this.DEVUI_DIR, this.VUE_DEVUI_FILE_NAME) exports.SITES_DIR = resolve(this.CWD, 'docs') exports.SITES_COMPONENTS_DIR_NAME = 'components' +exports.SITES_COMPONENTS_DIR_NAME_EN = 'en-US/components' exports.SITES_COMPONENTS_DIR = resolve(this.SITES_DIR, this.SITES_COMPONENTS_DIR_NAME) exports.VITEPRESS_DIR = resolve(this.SITES_DIR, '.vitepress') exports.VITEPRESS_SIDEBAR_FILE_NAME = 'sidebar.ts' -exports.VITEPRESS_SIDEBAR_FILE = resolve(this.VITEPRESS_DIR, `config/${this.VITEPRESS_SIDEBAR_FILE_NAME}`) - +exports.VITEPRESS_SIDEBAR_FILE = resolve( + this.VITEPRESS_DIR, + `config/${this.VITEPRESS_SIDEBAR_FILE_NAME}` +) +exports.VITEPRESS_SIDEBAR_FILE_NAME_EN = 'enSidebar.ts' +exports.VITEPRESS_SIDEBAR_FILE_EN = resolve( + this.VITEPRESS_DIR, + `config/${this.VITEPRESS_SIDEBAR_FILE_NAME_EN}` +) // 这里的分类顺序将会影响最终生成的页面侧边栏顺序 exports.VITEPRESS_SIDEBAR_CATEGORY = ['通用', '导航', '反馈', '数据录入', '数据展示', '布局'] - +exports.VITEPRESS_SIDEBAR_CATEGORY_EN = [ + 'General', + 'Navigation', + 'Feedback', + 'Data Entry', + 'Data Display', + 'Layout' +] +exports.VITEPRESS_SIDEBAR_CATEGORY_ZH_TO_EN = { + 通用: 'General', + 导航: 'Navigation', + 反馈: 'Feedback', + 数据录入: 'Data Entry', + 数据展示: 'Data Display', + 布局: 'Layout' +} exports.COMPONENT_PARTS_MAP = [ { name: 'component(组件)', @@ -40,7 +63,7 @@ exports.COMPONENT_PARTS_MAP = [ exports.CREATE_SUPPORT_TYPE_MAP = Object.freeze({ component: 'component', 'vue-devui': 'vue-devui', - 'theme-variable': 'theme-variable', + 'theme-variable': 'theme-variable' }) exports.CREATE_SUPPORT_TYPES = Object.keys(this.CREATE_SUPPORT_TYPE_MAP) exports.CREATE_UNFINISHED_TYPES = [] diff --git a/packages/devui-vue/devui-cli/templates/vitepress-sidebar.js b/packages/devui-vue/devui-cli/templates/vitepress-sidebar.js index ee079340e486e227daea5c8190784cbeea83c7ad..1bba664fb2dddf2a574f33670c8d644c1945260c 100644 --- a/packages/devui-vue/devui-cli/templates/vitepress-sidebar.js +++ b/packages/devui-vue/devui-cli/templates/vitepress-sidebar.js @@ -1,35 +1,80 @@ const { kebabCase } = require('lodash') -const { SITES_COMPONENTS_DIR_NAME, VITEPRESS_SIDEBAR_CATEGORY } = require('../shared/constant') +const { + SITES_COMPONENTS_DIR_NAME, + VITEPRESS_SIDEBAR_CATEGORY, + VITEPRESS_SIDEBAR_CATEGORY_EN, + VITEPRESS_SIDEBAR_CATEGORY_ZH_TO_EN, + SITES_COMPONENTS_DIR_NAME_EN +} = require('../shared/constant') const logger = require('../shared/logger') -function buildComponentOptions(text, name, status) { - return { text, link: `/${SITES_COMPONENTS_DIR_NAME}/${kebabCase(name)}/`, status } -} +// function buildComponentOptions(text, name, status) { +// return { text, link: `/${SITES_COMPONENTS_DIR_NAME}/${kebabCase(name)}/`, status } +// } function buildCategoryOptions(text, children = []) { return { text, children } } -exports.createVitepressSidebarTemplate = (componentsInfo = []) => { - const rootNav = { text: '快速开始', link: '/' } +function generateZhMenus(componentsInfo) { const categoryMap = VITEPRESS_SIDEBAR_CATEGORY.reduce((map, cate) => map.set(cate, []), new Map()) - componentsInfo.forEach((info) => { if (categoryMap.has(info.category)) { - categoryMap.get(info.category).push(buildComponentOptions(info.title, info.name, info.status)) + categoryMap.get(info.category).push({ + text: info.title, + link: `/${SITES_COMPONENTS_DIR_NAME}/${kebabCase(info.name)}/`, + status: info.status + }) } else { logger.warning(`组件 ${info.name} 的分类 ${info.category} 不存在!`) } }) + return Array.from(categoryMap).map(([k, v]) => buildCategoryOptions(k, v)) +} - const sidebar = [].concat( - rootNav, - Array.from(categoryMap).map(([k, v]) => buildCategoryOptions(k, v)) +function generateEnMenus(componentsInfo) { + const categoryMapEn = VITEPRESS_SIDEBAR_CATEGORY_EN.reduce( + (map, cate) => map.set(cate, []), + new Map() ) - - return `\ -export default { - '/': ${JSON.stringify(sidebar, null, 2).replace(/\n/g, '\n\t')} + componentsInfo.forEach((info) => { + if (categoryMapEn.has(VITEPRESS_SIDEBAR_CATEGORY_ZH_TO_EN[info.category])) { + categoryMapEn.get(VITEPRESS_SIDEBAR_CATEGORY_ZH_TO_EN[info.category]).push({ + text: info.name, + link: `/${SITES_COMPONENTS_DIR_NAME_EN}/${kebabCase(info.name)}/`, + status: info.status + }) + } + }) + return Array.from(categoryMapEn).map(([k, v]) => buildCategoryOptions(k, v)) } -` + +exports.createVitepressSidebarTemplates = (componentsInfo = []) => { + const rootNavs = [ + { + text: '快速开始', + link: '/', + handler: generateZhMenus, + lang: 'zh' + }, + { text: 'Quick Start', link: '/en-US/', handler: generateEnMenus, lang: 'en' } + ] + + const templates = rootNavs.map((nav) => { + const rootItem = { + text: nav.text, + link: nav.link + } + const sidebar = [].concat(rootItem, nav.handler(componentsInfo)) + return { + lang: nav.lang, + content: `\ + export default { + '/': ${JSON.stringify(sidebar, null, 2).replace(/\n/g, '\n\t')} + } + ` + } + }) + + return templates } diff --git a/packages/devui-vue/docs/.vitepress/config/enSidebar.ts b/packages/devui-vue/docs/.vitepress/config/enSidebar.ts deleted file mode 100644 index 4f814fef10adede3ade044596c936706d44a719c..0000000000000000000000000000000000000000 --- a/packages/devui-vue/docs/.vitepress/config/enSidebar.ts +++ /dev/null @@ -1,101 +0,0 @@ -const enSidebar = { - '/en-US/': [ - { text: 'Quick Start', link: '/en-US/' }, - { - text: 'General', - children: [ - { text: 'Button', link: '/en-US/components/button/', status: 'completed' }, - { text: 'Icon', link: '/en-US/components/icon/', status: 'completed' }, - { text: 'DragDrop', link: '/en-US/components/dragdrop/' }, - { text: 'Fullscreen', link: '/en-US/components/fullscreen/' }, - { text: 'Panel', link: '/en-US/components/panel/', status: 'completed' }, - { text: 'Search', link: '/en-US/components/search/', status: 'completed' }, - { text: 'Status', link: '/en-US/components/status/', status: 'completed' }, - { text: 'Sticky', link: '/en-US/components/sticky/' }, - { text: 'Overlay', link: '/en-US/components/overlay/'} - ] - }, - { - text: 'Navigation', - children: [ - { text: 'Accordion', link: '/en-US/components/accordion/' }, - { text: 'Anchor', link: '/en-US/components/anchor/' }, - { text: 'BackTop', link: '/en-US/components/back-top/' }, - { text: 'Breadcrumb', link: '/en-US/components/breadcrumb/' }, - { text: 'Dropdown', link: '/en-US/components/dropdown/' }, - { text: 'NavSprite', link: '/en-US/components/nav-sprite/' }, - { text: 'Pagination', link: '/en-US/components/pagination/', status: 'progress' }, - { text: 'StepsGuide', link: '/en-US/components/steps-guide/' }, - { text: 'Tabs', link: '/en-US/components/tabs/', status: 'completed' }, - { text: 'Anchor', link: '/en-US/components/Anchor/' }, - ] - }, - { - text: 'Feedback', - children: [ - { text: 'Alert', link: '/en-US/components/alert/', status: 'completed' }, - { text: 'Drawer', link: '/en-US/components/drawer/' }, - { text: 'Loading', link: '/en-US/components/loading/', status: 'completed' }, - { text: 'Mention', link: '/en-US/components/mention/' }, - { text: 'Modal', link: '/en-US/components/modal/' }, - { text: 'Popover', link: '/en-US/components/popover/', status: "progress" }, - { text: 'ReadTip', link: '/en-US/components/read-tip/' }, - { text: 'Toast', link: '/en-US/components/toast/', status: 'completed' }, - { text: 'Tooltip', link: '/en-US/components/tooltip/', status: 'completed' }, - ] - }, - { - text: 'Data Entry', - children: [ - { text: 'AutoComplete', link: '/en-US/components/auto-complete/' }, - { text: 'Cascader', link: '/en-US/components/cascader/' }, - { text: 'CategorySearch', link: '/en-US/components/category-search/' }, - { text: 'Checkbox', link: '/en-US/components/checkbox/', status: 'completed' }, - { text: 'DatePicker', link: '/en-US/components/date-picker/', status: 'progress' }, - { text: 'DatePickerPro', link: '/en-US/components/date-picker-pro/' }, - { text: 'EditableSelect', link: '/en-US/components/editable-select/' }, - { text: 'Form', link: '/en-US/components/form/' }, - { text: 'Input', link: '/en-US/components/input/', status: 'completed' }, - { text: 'InputNumber', link: '/en-US/components/input-number/' }, - { text: 'MultiAutoComplete', link: '/en-US/components/multi-auto-complete/' }, - { text: 'Radio', link: '/en-US/components/radio/', status: 'completed' }, - { text: 'Select', link: '/en-US/components/select/', status: 'progress' }, - { text: 'Slider', link: '/en-US/components/slider/' }, - { text: 'Switch', link: '/en-US/components/switch/', status: 'completed' }, - { text: 'TagInput', link: '/en-US/components/tag-input/', status: 'completed' }, - { text: 'Textarea', link: '/en-US/components/textarea/' }, - { text: 'TimePicker', link: '/en-US/components/time-picker/' }, - { text: 'Transfer', link: '/en-US/components/transfer/' }, - { text: 'TreeSelect', link: '/en-US/components/tree-select/' }, - { text: 'Upload', link: '/en-US/components/upload/', status: 'progress' }, - ] - }, - { - text: 'Data Display', - children: [ - { text: 'Avatar', link: '/en-US/components/avatar/', status: 'completed' }, - { text: 'Badge', link: '/en-US/components/badge/', status: 'completed' }, - { text: 'Card', link: '/en-US/components/card/', status: 'completed' }, - { text: 'Carousel', link: '/en-US/components/carousel/', status: 'completed' }, - { text: 'DataTable', link: '/en-US/components/data-table/' }, - { text: 'Gantt', link: '/en-US/components/gantt/' }, - { text: 'ImagePreview', link: '/en-US/components/image-preview/' }, - { text: 'Progress', link: '/en-US/components/progress/', status: 'completed' }, - { text: 'QuadrantDiagram', link: '/en-US/components/quadrant-diagram/' }, - { text: 'Rate', link: '/en-US/components/rate/', status: 'completed' }, - { text: 'Tag', link: '/en-US/components/tag/' }, - { text: 'Tree', link: '/en-US/components/tree/' }, - ] - }, - { - text: 'Layout', - children: [ - { text: 'Layout', link: '/en-US/components/layout/' }, - { text: 'Splitter', link: '/en-US/components/splitter/' } - ] - }, - ] -} - -export default enSidebar - \ No newline at end of file