diff --git a/devui/text-input/src/text-input.scss b/devui/text-input/src/text-input.scss new file mode 100644 index 0000000000000000000000000000000000000000..05d93cd73c9313d8f65d515426b1d59457e15653 --- /dev/null +++ b/devui/text-input/src/text-input.scss @@ -0,0 +1 @@ +@import '../../style/core/form' diff --git a/devui/text-input/src/text-input.tsx b/devui/text-input/src/text-input.tsx index eafc297936b12f57cfce81518201dd15d627fef2..a02f10922bcfd07184f99ff5f2d4032b3836a162 100644 --- a/devui/text-input/src/text-input.tsx +++ b/devui/text-input/src/text-input.tsx @@ -1,5 +1,6 @@ import { defineComponent, computed } from 'vue'; import { inputProps } from './use-input'; +import './text-input.scss' export default defineComponent({ name: 'DTextInput', diff --git a/sites/.vitepress/config/sidebar.ts b/sites/.vitepress/config/sidebar.ts index cc9dc4fce7d5cebbcedba076bf1a119025b91688..15c005494f64c0bb511aedeb33eb35affb411ce5 100644 --- a/sites/.vitepress/config/sidebar.ts +++ b/sites/.vitepress/config/sidebar.ts @@ -5,7 +5,35 @@ const sidebar = { text: '通用', children: [ { text: 'Button 按钮', link: '/components/button/' }, + { text: 'Panel 面板', link: '/components/panel/' }, + ] + }, + { + text: '导航', + children: [ + { text: 'Tabs 选项卡切换', link: '/components/tabs/' }, + ] + }, + { + text: '反馈', + children: [ + { text: 'Alert 警告', link: '/components/alert/' }, + ] + }, + { + text: '数据录入', + children: [ + { text: 'Checkbox 复选框', link: '/components/checkbox/' }, + { text: 'Radio 单选框', link: '/components/radio/' }, { text: 'Switch 开关', link: '/components/switch/' }, + { text: 'TagsInput 标签输入', link: '/components/tags-input/' }, + { text: 'TextInput 文本框', link: '/components/text-input/' }, + ] + }, + { + text: '数据展示', + children: [ + { text: 'Avatar 头像', link: '/components/avatar/' }, ] } ], diff --git a/sites/.vitepress/devui-theme/Layout.vue b/sites/.vitepress/devui-theme/Layout.vue new file mode 100644 index 0000000000000000000000000000000000000000..62bffadfba7183176dd6ab44ee3c009c38b47f89 --- /dev/null +++ b/sites/.vitepress/devui-theme/Layout.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/NotFound.vue b/sites/.vitepress/devui-theme/NotFound.vue new file mode 100644 index 0000000000000000000000000000000000000000..e797d7b328870278b7426e10047a2a657979520f --- /dev/null +++ b/sites/.vitepress/devui-theme/NotFound.vue @@ -0,0 +1,20 @@ + + + diff --git a/sites/.vitepress/devui-theme/components/AlgoliaSearchBox.vue b/sites/.vitepress/devui-theme/components/AlgoliaSearchBox.vue new file mode 100644 index 0000000000000000000000000000000000000000..fee1c1c2182a403afa7bedfad6a629ed464f9540 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/AlgoliaSearchBox.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/BuySellAds.vue b/sites/.vitepress/devui-theme/components/BuySellAds.vue new file mode 100644 index 0000000000000000000000000000000000000000..9a73a60ce8aef438a8bb7430d0249fa89545efb9 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/BuySellAds.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/CarbonAds.vue b/sites/.vitepress/devui-theme/components/CarbonAds.vue new file mode 100644 index 0000000000000000000000000000000000000000..ce2b977d77269993e6bc3bb1e5ea89c0b7ecba1d --- /dev/null +++ b/sites/.vitepress/devui-theme/components/CarbonAds.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/EditLink.vue b/sites/.vitepress/devui-theme/components/EditLink.vue new file mode 100644 index 0000000000000000000000000000000000000000..ffdab5ea9f5ee471008c36be198ee5909b8ac707 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/EditLink.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/Home.vue b/sites/.vitepress/devui-theme/components/Home.vue new file mode 100644 index 0000000000000000000000000000000000000000..f9ba63ddd03155e00084b0f3fed55bb34b57c170 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/Home.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/HomeFeatures.vue b/sites/.vitepress/devui-theme/components/HomeFeatures.vue new file mode 100644 index 0000000000000000000000000000000000000000..c435248ea7ee32223788aab7708cb26737ac7639 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/HomeFeatures.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/HomeFooter.vue b/sites/.vitepress/devui-theme/components/HomeFooter.vue new file mode 100644 index 0000000000000000000000000000000000000000..55f27af4c785e2ade5a9d85bef9172781937dd56 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/HomeFooter.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/HomeHero.vue b/sites/.vitepress/devui-theme/components/HomeHero.vue new file mode 100644 index 0000000000000000000000000000000000000000..9ff14a759cabfb810407358af910d756afdaabeb --- /dev/null +++ b/sites/.vitepress/devui-theme/components/HomeHero.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/LastUpdated.vue b/sites/.vitepress/devui-theme/components/LastUpdated.vue new file mode 100644 index 0000000000000000000000000000000000000000..ab888fbc222e5dba6b60fcab08972fe29c61b5fc --- /dev/null +++ b/sites/.vitepress/devui-theme/components/LastUpdated.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/NavBar.vue b/sites/.vitepress/devui-theme/components/NavBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..28b459e8b156569836cf159ba3f5f06ce1fc33bc --- /dev/null +++ b/sites/.vitepress/devui-theme/components/NavBar.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/NavBarTitle.vue b/sites/.vitepress/devui-theme/components/NavBarTitle.vue new file mode 100644 index 0000000000000000000000000000000000000000..4bfcbb1dbb0e53215ea6ac4be2cff9bd436a090f --- /dev/null +++ b/sites/.vitepress/devui-theme/components/NavBarTitle.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/NavDropdownLink.vue b/sites/.vitepress/devui-theme/components/NavDropdownLink.vue new file mode 100644 index 0000000000000000000000000000000000000000..51e9a11ae1ccceb64186ae2024ca26055580b61b --- /dev/null +++ b/sites/.vitepress/devui-theme/components/NavDropdownLink.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/NavDropdownLinkItem.vue b/sites/.vitepress/devui-theme/components/NavDropdownLinkItem.vue new file mode 100644 index 0000000000000000000000000000000000000000..e8c133ccdc2ab223d2acf755b937d79ddc931f0f --- /dev/null +++ b/sites/.vitepress/devui-theme/components/NavDropdownLinkItem.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/NavLink.vue b/sites/.vitepress/devui-theme/components/NavLink.vue new file mode 100644 index 0000000000000000000000000000000000000000..514b2282655af82360e443e1d6fee5f76dd06bbf --- /dev/null +++ b/sites/.vitepress/devui-theme/components/NavLink.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/NavLinks.vue b/sites/.vitepress/devui-theme/components/NavLinks.vue new file mode 100644 index 0000000000000000000000000000000000000000..aaa622a1079d93d5bca42fcae0ccdf9fce420210 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/NavLinks.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/NextAndPrevLinks.vue b/sites/.vitepress/devui-theme/components/NextAndPrevLinks.vue new file mode 100644 index 0000000000000000000000000000000000000000..e826aca45fad7b8730abb224dba41935cf74bd7f --- /dev/null +++ b/sites/.vitepress/devui-theme/components/NextAndPrevLinks.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/Page.vue b/sites/.vitepress/devui-theme/components/Page.vue new file mode 100644 index 0000000000000000000000000000000000000000..7a1d422bc5f308dce065b5a95b762aaf2bc57357 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/Page.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/PageFooter.vue b/sites/.vitepress/devui-theme/components/PageFooter.vue new file mode 100644 index 0000000000000000000000000000000000000000..41e1dded014f74b04e06fe2c5dc9c5675d7ca5d6 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/PageFooter.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/SearchBox.vue b/sites/.vitepress/devui-theme/components/SearchBox.vue new file mode 100644 index 0000000000000000000000000000000000000000..85f71692070d3397df7f97c4695f519cf702390a --- /dev/null +++ b/sites/.vitepress/devui-theme/components/SearchBox.vue @@ -0,0 +1,290 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/SideBar.vue b/sites/.vitepress/devui-theme/components/SideBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..13929737d12a08e7024b05f47d1005fb71fc7ad8 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/SideBar.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/SideBarLink.d.ts b/sites/.vitepress/devui-theme/components/SideBarLink.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..acc55bf916c02c06793dae303e6233d416d21245 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/SideBarLink.d.ts @@ -0,0 +1,6 @@ +import { FunctionalComponent } from 'vue'; +import { DefaultTheme } from '../config'; +export declare const SideBarLink: FunctionalComponent<{ + item: DefaultTheme.SideBarItem; + depth?: number; +}>; diff --git a/sites/.vitepress/devui-theme/components/SideBarLink.js b/sites/.vitepress/devui-theme/components/SideBarLink.js new file mode 100644 index 0000000000000000000000000000000000000000..68b31d7122382a7b8dbf6c1fb1ce340b80342613 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/SideBarLink.js @@ -0,0 +1,68 @@ +import { h } from 'vue'; +import { useRoute, useData } from 'vitepress'; +import { joinUrl, isActive } from '../utils'; +export const SideBarLink = (props) => { + const route = useRoute(); + const { site, frontmatter } = useData(); + const depth = props.depth || 1; + const maxDepth = frontmatter.value.sidebarDepth || Infinity; + const headers = route.data.headers; + const text = props.item.text; + const link = resolveLink(site.value.base, props.item.link); + const children = props.item.children; + const active = isActive(route, props.item.link); + const childItems = depth < maxDepth + ? createChildren(active, children, headers, depth + 1) + : null; + return h('li', { class: 'sidebar-link' }, [ + h(link ? 'a' : 'p', { + class: { 'sidebar-link-item': true, active }, + href: link + }, text), + childItems + ]); +}; +function resolveLink(base, path) { + if (path === undefined) { + return path; + } + // keep relative hash to the same page + if (path.startsWith('#')) { + return path; + } + return joinUrl(base, path); +} +function createChildren(active, children, headers, depth = 1) { + if (children && children.length > 0) { + return h('ul', { class: 'sidebar-links' }, children.map((c) => { + return h(SideBarLink, { item: c, depth }); + })); + } + return active && headers + ? createChildren(false, resolveHeaders(headers), undefined, depth) + : null; +} +function resolveHeaders(headers) { + return mapHeaders(groupHeaders(headers)); +} +function groupHeaders(headers) { + headers = headers.map((h) => Object.assign({}, h)); + let lastH2; + headers.forEach((h) => { + if (h.level === 2) { + lastH2 = h; + } + else if (lastH2) { + ; + (lastH2.children || (lastH2.children = [])).push(h); + } + }); + return headers.filter((h) => h.level === 2); +} +function mapHeaders(headers) { + return headers.map((header) => ({ + text: header.title, + link: `#${header.slug}`, + children: header.children ? mapHeaders(header.children) : undefined + })); +} diff --git a/sites/.vitepress/devui-theme/components/SideBarLinks.vue b/sites/.vitepress/devui-theme/components/SideBarLinks.vue new file mode 100644 index 0000000000000000000000000000000000000000..768013e3bb73fc63c588d9c5256d4ddfad8f9134 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/SideBarLinks.vue @@ -0,0 +1,12 @@ + + + diff --git a/sites/.vitepress/devui-theme/components/ToggleSideBarButton.vue b/sites/.vitepress/devui-theme/components/ToggleSideBarButton.vue new file mode 100644 index 0000000000000000000000000000000000000000..07448cc0cb6c5eda4d6d2baeb2fbb597c7c34532 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/ToggleSideBarButton.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/sites/.vitepress/devui-theme/components/icons/ArrowLeft.vue b/sites/.vitepress/devui-theme/components/icons/ArrowLeft.vue new file mode 100644 index 0000000000000000000000000000000000000000..3f65b866a9e402815809b2f92ce3cd5c97642499 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/icons/ArrowLeft.vue @@ -0,0 +1,7 @@ + diff --git a/sites/.vitepress/devui-theme/components/icons/ArrowRight.vue b/sites/.vitepress/devui-theme/components/icons/ArrowRight.vue new file mode 100644 index 0000000000000000000000000000000000000000..ed89263f76efe5edcbaad14cf28535fec2c5a32d --- /dev/null +++ b/sites/.vitepress/devui-theme/components/icons/ArrowRight.vue @@ -0,0 +1,7 @@ + diff --git a/sites/.vitepress/devui-theme/components/icons/OutboundLink.vue b/sites/.vitepress/devui-theme/components/icons/OutboundLink.vue new file mode 100644 index 0000000000000000000000000000000000000000..4d74eeeb24d0c43350b1e205938e11f9fd26d9a5 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/icons/OutboundLink.vue @@ -0,0 +1,31 @@ + + + diff --git a/sites/.vitepress/devui-theme/components/match-query.js b/sites/.vitepress/devui-theme/components/match-query.js new file mode 100644 index 0000000000000000000000000000000000000000..5678e3771edd11fd6aceda071fb041d30ee5c088 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/match-query.js @@ -0,0 +1,50 @@ +import get from 'lodash.get' + +export default (query, page, additionalStr = null) => { + let domain = get(page, 'title', '') + + if (get(page, 'frontmatter.tags')) { + domain += ` ${page.frontmatter.tags.join(' ')}` + } + + if (additionalStr) { + domain += ` ${additionalStr}` + } + + return matchTest(query, domain) +} + +const matchTest = (query, domain) => { + const escapeRegExp = (str) => str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') + + // eslint-disable-next-line no-control-regex + const nonASCIIRegExp = new RegExp('[^\x00-\x7F]') + + const words = query + .split(/\s+/g) + .map((str) => str.trim()) + .filter((str) => !!str) + + if (!nonASCIIRegExp.test(query)) { + // if the query only has ASCII chars, treat as English + const hasTrailingSpace = query.endsWith(' ') + const searchRegex = new RegExp( + words + .map((word, index) => { + if (words.length === index + 1 && !hasTrailingSpace) { + // The last word - ok with the word being "startswith"-like + return `(?=.*\\b${escapeRegExp(word)})` + } else { + // Not the last word - expect the whole word exactly + return `(?=.*\\b${escapeRegExp(word)}\\b)` + } + }) + .join('') + '.+', + 'gi' + ) + return searchRegex.test(domain) + } else { + // if the query has non-ASCII chars, treat as other languages + return words.some((word) => domain.toLowerCase().indexOf(word) > -1) + } +} diff --git a/sites/.vitepress/devui-theme/components/test.d.ts b/sites/.vitepress/devui-theme/components/test.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f14b13f995161efa6cdacd27271aa70c6f911c14 --- /dev/null +++ b/sites/.vitepress/devui-theme/components/test.d.ts @@ -0,0 +1,4 @@ +export interface Hello { + world: string; +} +export declare const O = 2; diff --git a/sites/.vitepress/devui-theme/components/test.js b/sites/.vitepress/devui-theme/components/test.js new file mode 100644 index 0000000000000000000000000000000000000000..8e5eabec73a3bfbc6e194496c446070ac9f38b7a --- /dev/null +++ b/sites/.vitepress/devui-theme/components/test.js @@ -0,0 +1 @@ +export const O = 2; diff --git a/sites/.vitepress/devui-theme/composables/activeSidebarLink.d.ts b/sites/.vitepress/devui-theme/composables/activeSidebarLink.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..68d9ecbad25cfe03cc90aa48fdd43ef4f068383e --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/activeSidebarLink.d.ts @@ -0,0 +1 @@ +export declare function useActiveSidebarLinks(): void; diff --git a/sites/.vitepress/devui-theme/composables/activeSidebarLink.js b/sites/.vitepress/devui-theme/composables/activeSidebarLink.js new file mode 100644 index 0000000000000000000000000000000000000000..05f54c9fd2b2244289d952e7295eb6b503c09012 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/activeSidebarLink.js @@ -0,0 +1,99 @@ +import { onMounted, onUnmounted, onUpdated } from 'vue'; +export function useActiveSidebarLinks() { + let rootActiveLink = null; + let activeLink = null; + const onScroll = throttleAndDebounce(setActiveLink, 300); + function setActiveLink() { + const sidebarLinks = getSidebarLinks(); + const anchors = getAnchors(sidebarLinks); + for (let i = 0; i < anchors.length; i++) { + const anchor = anchors[i]; + const nextAnchor = anchors[i + 1]; + const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor); + if (isActive) { + history.replaceState(null, document.title, hash ? hash : ' '); + activateLink(hash); + return; + } + } + } + function activateLink(hash) { + deactiveLink(activeLink); + deactiveLink(rootActiveLink); + activeLink = document.querySelector(`.sidebar a[href="${hash}"]`); + if (!activeLink) { + return; + } + activeLink.classList.add('active'); + // also add active class to parent h2 anchors + const rootLi = activeLink.closest('.sidebar-links > ul > li'); + if (rootLi && rootLi !== activeLink.parentElement) { + rootActiveLink = rootLi.querySelector('a'); + rootActiveLink && rootActiveLink.classList.add('active'); + } + else { + rootActiveLink = null; + } + } + function deactiveLink(link) { + link && link.classList.remove('active'); + } + onMounted(() => { + setActiveLink(); + window.addEventListener('scroll', onScroll); + }); + onUpdated(() => { + // sidebar update means a route change + activateLink(decodeURIComponent(location.hash)); + }); + onUnmounted(() => { + window.removeEventListener('scroll', onScroll); + }); +} +function getSidebarLinks() { + return [].slice.call(document.querySelectorAll('.sidebar a.sidebar-link-item')); +} +function getAnchors(sidebarLinks) { + return [].slice + .call(document.querySelectorAll('.header-anchor')) + .filter((anchor) => sidebarLinks.some((sidebarLink) => sidebarLink.hash === anchor.hash)); +} +function getPageOffset() { + return document.querySelector('.nav-bar').offsetHeight; +} +function getAnchorTop(anchor) { + const pageOffset = getPageOffset(); + return anchor.parentElement.offsetTop - pageOffset - 15; +} +function isAnchorActive(index, anchor, nextAnchor) { + const scrollTop = window.scrollY; + if (index === 0 && scrollTop === 0) { + return [true, null]; + } + if (scrollTop < getAnchorTop(anchor)) { + return [false, null]; + } + if (!nextAnchor || scrollTop < getAnchorTop(nextAnchor)) { + return [true, decodeURIComponent(anchor.hash)]; + } + return [false, null]; +} +function throttleAndDebounce(fn, delay) { + let timeout; + let called = false; + return () => { + if (timeout) { + clearTimeout(timeout); + } + if (!called) { + fn(); + called = true; + setTimeout(() => { + called = false; + }, delay); + } + else { + timeout = setTimeout(fn, delay); + } + }; +} diff --git a/sites/.vitepress/devui-theme/composables/editLink.d.ts b/sites/.vitepress/devui-theme/composables/editLink.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..1f7abc19802df171fafeddb0688446550b70f973 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/editLink.d.ts @@ -0,0 +1,4 @@ +export declare function useEditLink(): { + url: import("vue").ComputedRef; + text: import("vue").ComputedRef; +}; diff --git a/sites/.vitepress/devui-theme/composables/editLink.js b/sites/.vitepress/devui-theme/composables/editLink.js new file mode 100644 index 0000000000000000000000000000000000000000..9ba67c9d7ad8ae1c9772acf5a50af31485f54ce2 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/editLink.js @@ -0,0 +1,47 @@ +import { computed } from 'vue'; +import { useData } from 'vitepress'; +import { endingSlashRE, isExternal } from '../utils'; +const bitbucketRE = /bitbucket.org/; +export function useEditLink() { + const { page, theme, frontmatter } = useData(); + const url = computed(() => { + const { repo, docsDir = '', docsBranch = 'master', docsRepo = repo, editLinks } = theme.value; + const showEditLink = frontmatter.value.editLink || editLinks; + const { relativePath } = page.value; + if (!showEditLink || !relativePath || !repo) { + return null; + } + return createUrl(repo, docsRepo, docsDir, docsBranch, relativePath); + }); + const text = computed(() => { + return theme.value.editLinkText || 'Edit this page'; + }); + return { + url, + text + }; +} +function createUrl(repo, docsRepo, docsDir, docsBranch, path) { + return bitbucketRE.test(repo) + ? createBitbucketUrl(repo, docsRepo, docsDir, docsBranch, path) + : createGitHubUrl(repo, docsRepo, docsDir, docsBranch, path); +} +function createGitHubUrl(repo, docsRepo, docsDir, docsBranch, path) { + const base = isExternal(docsRepo) + ? docsRepo + : `https://github.com/${docsRepo}`; + return (base.replace(endingSlashRE, '') + + `/edit` + + `/${docsBranch}/` + + (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') + + path); +} +function createBitbucketUrl(repo, docsRepo, docsDir, docsBranch, path) { + const base = isExternal(docsRepo) ? docsRepo : repo; + return (base.replace(endingSlashRE, '') + + `/src` + + `/${docsBranch}/` + + (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') + + path + + `?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`); +} diff --git a/sites/.vitepress/devui-theme/composables/nav.d.ts b/sites/.vitepress/devui-theme/composables/nav.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..e0abff6864462de7656a82f75cc5dba52bf773a3 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/nav.d.ts @@ -0,0 +1,2 @@ +import type { DefaultTheme } from '../config'; +export declare function useLocaleLinks(): import("vue").ComputedRef; diff --git a/sites/.vitepress/devui-theme/composables/nav.js b/sites/.vitepress/devui-theme/composables/nav.js new file mode 100644 index 0000000000000000000000000000000000000000..22ac0dd12100502b1533bc2e4d7cf6ea89b05689 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/nav.js @@ -0,0 +1,45 @@ +import { computed } from 'vue'; +import { useRoute, useData, inBrowser } from 'vitepress'; +export function useLocaleLinks() { + const route = useRoute(); + const { site } = useData(); + return computed(() => { + const theme = site.value.themeConfig; + const locales = theme.locales; + if (!locales) { + return null; + } + const localeKeys = Object.keys(locales); + if (localeKeys.length <= 1) { + return null; + } + // handle site base + const siteBase = inBrowser ? site.value.base : '/'; + const siteBaseWithoutSuffix = siteBase.endsWith('/') + ? siteBase.slice(0, -1) + : siteBase; + // remove site base in browser env + const routerPath = route.path.slice(siteBaseWithoutSuffix.length); + const currentLangBase = localeKeys.find((key) => { + return key === '/' ? false : routerPath.startsWith(key); + }); + const currentContentPath = currentLangBase + ? routerPath.substring(currentLangBase.length - 1) + : routerPath; + const candidates = localeKeys.map((v) => { + const localePath = v.endsWith('/') ? v.slice(0, -1) : v; + return { + text: locales[v].label, + link: `${localePath}${currentContentPath}` + }; + }); + const currentLangKey = currentLangBase ? currentLangBase : '/'; + const selectText = locales[currentLangKey].selectText + ? locales[currentLangKey].selectText + : 'Languages'; + return { + text: selectText, + items: candidates + }; + }); +} diff --git a/sites/.vitepress/devui-theme/composables/navLink.d.ts b/sites/.vitepress/devui-theme/composables/navLink.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..881bc11494e1e449a2d84d201c6038015d589f7f --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/navLink.d.ts @@ -0,0 +1,15 @@ +import { Ref } from 'vue'; +import type { DefaultTheme } from '../config'; +export declare function useNavLink(item: Ref): { + props: import("vue").ComputedRef<{ + class: { + active: boolean; + isExternal: boolean; + }; + href: string; + target: string | null; + rel: string | null; + 'aria-label': string | undefined; + }>; + isExternal: boolean; +}; diff --git a/sites/.vitepress/devui-theme/composables/navLink.js b/sites/.vitepress/devui-theme/composables/navLink.js new file mode 100644 index 0000000000000000000000000000000000000000..9cc42c3f765ef8f4befa9a20d786dd5c06a2943f --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/navLink.js @@ -0,0 +1,42 @@ +import { computed } from 'vue'; +import { useRoute, withBase } from 'vitepress'; +import { isExternal as isExternalCheck } from '../utils'; +export function useNavLink(item) { + const route = useRoute(); + const isExternal = isExternalCheck(item.value.link); + const props = computed(() => { + const routePath = normalizePath(`/${route.data.relativePath}`); + let active = false; + if (item.value.activeMatch) { + active = new RegExp(item.value.activeMatch).test(routePath); + } + else { + const itemPath = normalizePath(withBase(item.value.link)); + active = + itemPath === '/' + ? itemPath === routePath + : routePath.startsWith(itemPath); + } + return { + class: { + active, + isExternal + }, + href: isExternal ? item.value.link : withBase(item.value.link), + target: item.value.target || isExternal ? `_blank` : null, + rel: item.value.rel || isExternal ? `noopener noreferrer` : null, + 'aria-label': item.value.ariaLabel + }; + }); + return { + props, + isExternal + }; +} +function normalizePath(path) { + return path + .replace(/#.*$/, '') + .replace(/\?.*$/, '') + .replace(/\.(html|md)$/, '') + .replace(/\/index$/, '/'); +} diff --git a/sites/.vitepress/devui-theme/composables/nextAndPrevLinks.d.ts b/sites/.vitepress/devui-theme/composables/nextAndPrevLinks.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..fe9c8407a96d1cad50fd8cca0996e4e28041d974 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/nextAndPrevLinks.d.ts @@ -0,0 +1,5 @@ +export declare function useNextAndPrevLinks(): { + next: import("vue").ComputedRef; + prev: import("vue").ComputedRef; + hasLinks: import("vue").ComputedRef; +}; diff --git a/sites/.vitepress/devui-theme/composables/nextAndPrevLinks.js b/sites/.vitepress/devui-theme/composables/nextAndPrevLinks.js new file mode 100644 index 0000000000000000000000000000000000000000..8ed32d7910b63d658ec2cf55e71c5ad2e983426d --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/nextAndPrevLinks.js @@ -0,0 +1,37 @@ +import { computed } from 'vue'; +import { useData } from 'vitepress'; +import { isArray, ensureStartingSlash, removeExtention } from '../utils'; +import { getSideBarConfig, getFlatSideBarLinks } from '../support/sideBar'; +export function useNextAndPrevLinks() { + const { page, theme } = useData(); + const path = computed(() => { + return removeExtention(ensureStartingSlash(page.value.relativePath)); + }); + const candidates = computed(() => { + const config = getSideBarConfig(theme.value.sidebar, path.value); + return isArray(config) ? getFlatSideBarLinks(config) : []; + }); + const index = computed(() => { + return candidates.value.findIndex((item) => { + return item.link === path.value; + }); + }); + const next = computed(() => { + if (theme.value.nextLinks !== false && + index.value > -1 && + index.value < candidates.value.length - 1) { + return candidates.value[index.value + 1]; + } + }); + const prev = computed(() => { + if (theme.value.prevLinks !== false && index.value > 0) { + return candidates.value[index.value - 1]; + } + }); + const hasLinks = computed(() => !!next.value || !!prev.value); + return { + next, + prev, + hasLinks + }; +} diff --git a/sites/.vitepress/devui-theme/composables/repo.d.ts b/sites/.vitepress/devui-theme/composables/repo.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..abd93bbe2c78df1446da3d57ea059df7eae19d94 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/repo.d.ts @@ -0,0 +1,5 @@ +export declare const platforms: (readonly [string, RegExp])[]; +export declare function useRepo(): import("vue").ComputedRef<{ + text: string; + link: string; +} | null>; diff --git a/sites/.vitepress/devui-theme/composables/repo.js b/sites/.vitepress/devui-theme/composables/repo.js new file mode 100644 index 0000000000000000000000000000000000000000..a3c79ee304f81172b738eeece99ee38099a658f7 --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/repo.js @@ -0,0 +1,37 @@ +import { computed } from 'vue'; +import { useData } from 'vitepress'; +export const platforms = ['GitHub', 'GitLab', 'Bitbucket'].map((platform) => { + return [platform, new RegExp(platform, 'i')]; +}); +export function useRepo() { + const { site } = useData(); + return computed(() => { + const theme = site.value.themeConfig; + const name = theme.docsRepo || theme.repo; + if (!name) { + return null; + } + const link = getRepoUrl(name); + const text = getRepoText(link, theme.repoLabel); + return { text, link }; + }); +} +function getRepoUrl(repo) { + // if the full url is not provided, default to GitHub repo + return /^https?:/.test(repo) ? repo : `https://github.com/${repo}`; +} +function getRepoText(url, text) { + if (text) { + return text; + } + // if no label is provided, deduce it from the repo url + const hosts = url.match(/^https?:\/\/[^/]+/); + if (!hosts) { + return 'Source'; + } + const platform = platforms.find(([_p, re]) => re.test(hosts[0])); + if (platform && platform[0]) { + return platform[0]; + } + return 'Source'; +} diff --git a/sites/.vitepress/devui-theme/composables/sideBar.d.ts b/sites/.vitepress/devui-theme/composables/sideBar.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..ec7544f882064084dd105591c4dbcdf76095aa4d --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/sideBar.d.ts @@ -0,0 +1,2 @@ +import { DefaultTheme } from '../config'; +export declare function useSideBar(): import("vue").ComputedRef; diff --git a/sites/.vitepress/devui-theme/composables/sideBar.js b/sites/.vitepress/devui-theme/composables/sideBar.js new file mode 100644 index 0000000000000000000000000000000000000000..3ca2b557dc1e771389dc6253dcf3957bd5fda74a --- /dev/null +++ b/sites/.vitepress/devui-theme/composables/sideBar.js @@ -0,0 +1,57 @@ +import { computed } from 'vue'; +import { useRoute, useData } from 'vitepress'; +import { useActiveSidebarLinks } from '../composables/activeSidebarLink'; +import { getSideBarConfig } from '../support/sideBar'; +export function useSideBar() { + const route = useRoute(); + const { site } = useData(); + useActiveSidebarLinks(); + return computed(() => { + // at first, we'll check if we can find the sidebar setting in frontmatter. + const headers = route.data.headers; + const frontSidebar = route.data.frontmatter.sidebar; + const sidebarDepth = route.data.frontmatter.sidebarDepth; + // if it's `false`, we'll just return an empty array here. + if (frontSidebar === false) { + return []; + } + // if it's `atuo`, render headers of the current page + if (frontSidebar === 'auto') { + return resolveAutoSidebar(headers, sidebarDepth); + } + // now, there's no sidebar setting at frontmatter; let's see the configs + const themeSidebar = getSideBarConfig(site.value.themeConfig.sidebar, route.data.relativePath); + if (themeSidebar === false) { + return []; + } + if (themeSidebar === 'auto') { + return resolveAutoSidebar(headers, sidebarDepth); + } + return themeSidebar; + }); +} +function resolveAutoSidebar(headers, depth) { + const ret = []; + if (headers === undefined) { + return []; + } + let lastH2 = undefined; + headers.forEach(({ level, title, slug }) => { + if (level - 1 > depth) { + return; + } + const item = { + text: title, + link: `#${slug}` + }; + if (level === 2) { + lastH2 = item; + ret.push(item); + } + else if (lastH2) { + ; + (lastH2.children || (lastH2.children = [])).push(item); + } + }); + return ret; +} diff --git a/sites/.vitepress/devui-theme/config.d.ts b/sites/.vitepress/devui-theme/config.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..be96e467e55075bc435a5c4d0ee4088e812d10cf --- /dev/null +++ b/sites/.vitepress/devui-theme/config.d.ts @@ -0,0 +1,112 @@ +export declare namespace DefaultTheme { + interface Config { + logo?: string; + nav?: NavItem[] | false; + sidebar?: SideBarConfig | MultiSideBarConfig; + /** + * GitHub repository following the format /. + * + * @example `"vuejs/vue-next"` + */ + repo?: string; + /** + * Customize the header label. Defaults to GitHub/Gitlab/Bitbucket + * depending on the provided repo. + * + * @example `"Contribute!"` + */ + repoLabel?: string; + /** + * If your docs are in a different repository from your main project. + * + * @example `"vuejs/docs-next"` + */ + docsRepo?: string; + /** + * If your docs are not at the root of the repo. + * + * @example `"docs"` + */ + docsDir?: string; + /** + * If your docs are in a different branch. Defaults to `master`. + * + * @example `"next"` + */ + docsBranch?: string; + /** + * Enable links to edit pages at the bottom of the page. + */ + editLinks?: boolean; + /** + * Custom text for edit link. Defaults to "Edit this page". + */ + editLinkText?: string; + /** + * Show last updated time at the bottom of the page. Defaults to `false`. + * If given a string, it will be displayed as a prefix (default value: + * "Last Updated"). + */ + lastUpdated?: string | boolean; + prevLinks?: boolean; + nextLinks?: boolean; + locales?: Record>; + algolia?: AlgoliaSearchOptions; + carbonAds?: { + carbon: string; + custom?: string; + placement: string; + }; + } + type NavItem = NavItemWithLink | NavItemWithChildren; + interface NavItemBase { + text: string; + target?: string; + rel?: string; + ariaLabel?: string; + activeMatch?: string; + } + interface NavItemWithLink extends NavItemBase { + link: string; + } + interface NavItemWithChildren extends NavItemBase { + items: NavItemWithLink[]; + } + type SideBarConfig = SideBarItem[] | 'auto' | false; + interface MultiSideBarConfig { + [path: string]: SideBarConfig; + } + type SideBarItem = SideBarLink | SideBarGroup; + interface SideBarLink { + text: string; + link: string; + } + interface SideBarGroup { + text: string; + link?: string; + /** + * @default false + */ + collapsable?: boolean; + children: SideBarItem[]; + } + interface AlgoliaSearchOptions { + appId?: string; + apiKey: string; + indexName: string; + placeholder?: string; + searchParameters?: any; + disableUserPersonalization?: boolean; + initialQuery?: string; + } + interface LocaleConfig { + /** + * Text for the language dropdown. + */ + selectText?: string; + /** + * Label for this locale in the language dropdown. + */ + label?: string; + } +} diff --git a/sites/.vitepress/devui-theme/config.js b/sites/.vitepress/devui-theme/config.js new file mode 100644 index 0000000000000000000000000000000000000000..cb0ff5c3b541f646105198ee23ac0fc3d805023e --- /dev/null +++ b/sites/.vitepress/devui-theme/config.js @@ -0,0 +1 @@ +export {}; diff --git a/sites/.vitepress/devui-theme/index.d.ts b/sites/.vitepress/devui-theme/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..fb57816d76df5c0ed4200265ebdb8676a3c9d5d3 --- /dev/null +++ b/sites/.vitepress/devui-theme/index.d.ts @@ -0,0 +1,8 @@ +import './styles/vars.css'; +import './styles/layout.css'; +import './styles/code.css'; +import './styles/custom-blocks.css'; +import './styles/sidebar-links.css'; +import { Theme } from 'vitepress'; +declare const theme: Theme; +export default theme; diff --git a/sites/.vitepress/devui-theme/index.js b/sites/.vitepress/devui-theme/index.js new file mode 100644 index 0000000000000000000000000000000000000000..156939ecd1e5006fdd66797a5f64a60aee14e97f --- /dev/null +++ b/sites/.vitepress/devui-theme/index.js @@ -0,0 +1,12 @@ +import './styles/vars.css'; +import './styles/layout.css'; +import './styles/code.css'; +import './styles/custom-blocks.css'; +import './styles/sidebar-links.css'; +import Layout from './Layout.vue'; +import NotFound from './NotFound.vue'; +const theme = { + Layout, + NotFound +}; +export default theme; diff --git a/sites/.vitepress/devui-theme/styles/code.css b/sites/.vitepress/devui-theme/styles/code.css new file mode 100644 index 0000000000000000000000000000000000000000..1e821af9adebd202749f39208b0ff1add6c5997e --- /dev/null +++ b/sites/.vitepress/devui-theme/styles/code.css @@ -0,0 +1,298 @@ +code { + margin: 0; + border-radius: 3px; + padding: 0.25rem 0.5rem; + font-family: var(--code-font-family); + font-size: 0.85em; + color: var(--c-text-light); + background-color: var(--code-inline-bg-color); +} + +code .token.deleted { + color: #ec5975; +} + +code .token.inserted { + color: var(--c-brand); +} + +div[class*='language-'] { + position: relative; + margin: 1rem -1.5rem; + background-color: var(--code-bg-color); + overflow-x: auto; +} + +li > div[class*='language-'] { + border-radius: 6px 0 0 6px; + margin: 1rem -1.5rem 1rem -1.25rem; +} + +@media (min-width: 420px) { + div[class*='language-'] { + margin: 1rem 0; + border-radius: 6px; + } + + li > div[class*='language-'] { + margin: 1rem 0 1rem 0rem; + border-radius: 6px; + } +} + +[class*='language-'] pre, +[class*='language-'] code { + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +[class*='language-'] pre { + position: relative; + z-index: 1; + margin: 0; + padding: 1.25rem 1.5rem; + background: transparent; + overflow-x: auto; +} + +[class*='language-'] code { + padding: 0; + line-height: var(--code-line-height); + font-size: var(--code-font-size); + color: #eee; +} + +/* Line highlighting */ + +.highlight-lines { + position: absolute; + top: 0; + bottom: 0; + left: 0; + padding: 1.25rem 0; + width: 100%; + line-height: var(--code-line-height); + font-family: var(--code-font-family); + font-size: var(--code-font-size); + user-select: none; + overflow: hidden; +} + +.highlight-lines .highlighted { + background-color: rgba(0, 0, 0, 0.66); +} + +/* Line numbers mode */ + +div[class*='language-'].line-numbers-mode { + padding-left: 3.5rem; +} + +.line-numbers-wrapper { + position: absolute; + top: 0; + bottom: 0; + left: 0; + z-index: 3; + border-right: 1px solid rgba(0, 0, 0, 0.5); + padding: 1.25rem 0; + width: 3.5rem; + text-align: center; + line-height: var(--code-line-height); + font-family: var(--code-font-family); + font-size: var(--code-font-size); + color: #888; +} + +/* Language marker */ + +div[class*='language-']:before { + position: absolute; + top: 0.6em; + right: 1em; + z-index: 2; + font-size: 0.8rem; + color: #888; +} + +div[class~='language-html']:before, +div[class~='language-markup']:before { + content: 'html'; +} + +div[class~='language-md']:before, +div[class~='language-markdown']:before { + content: 'md'; +} + +div[class~='language-css']:before { + content: 'css'; +} + +div[class~='language-sass']:before { + content: 'sass'; +} + +div[class~='language-scss']:before { + content: 'scss'; +} + +div[class~='language-less']:before { + content: 'less'; +} + +div[class~='language-stylus']:before { + content: 'styl'; +} + +div[class~='language-js']:before, +div[class~='language-javascript']:before { + content: 'js'; +} + +div[class~='language-ts']:before, +div[class~='language-typescript']:before { + content: 'ts'; +} + +div[class~='language-json']:before { + content: 'json'; +} + +div[class~='language-rb']:before, +div[class~='language-ruby']:before { + content: 'rb'; +} + +div[class~='language-py']:before, +div[class~='language-python']:before { + content: 'py'; +} + +div[class~='language-sh']:before, +div[class~='language-bash']:before { + content: 'sh'; +} + +div[class~='language-php']:before { + content: 'php'; +} + +div[class~='language-go']:before { + content: 'go'; +} + +div[class~='language-rust']:before { + content: 'rust'; +} + +div[class~='language-java']:before { + content: 'java'; +} + +div[class~='language-c']:before { + content: 'c'; +} + +div[class~='language-yaml']:before { + content: 'yaml'; +} + +div[class~='language-dockerfile']:before { + content: 'dockerfile'; +} + +div[class~='language-vue']:before { + content: 'vue'; +} + +/** + * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML. + * Based on https://github.com/chriskempson/tomorrow-theme + * + * @author Rose Pritchard + */ +.token.comment, +.token.block-comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #999; +} + +.token.punctuation { + color: #ccc; +} + +.token.tag, +.token.attr-name, +.token.namespace, +.token.deleted { + color: #e2777a; +} + +.token.function-name { + color: #6196cc; +} + +.token.boolean, +.token.number, +.token.function { + color: #f08d49; +} + +.token.property, +.token.class-name, +.token.constant, +.token.symbol { + color: #f8c555; +} + +.token.selector, +.token.important, +.token.atrule, +.token.keyword, +.token.builtin { + color: #cc99cd; +} + +.token.string, +.token.char, +.token.attr-value, +.token.regex, +.token.variable { + color: #7ec699; +} + +.token.operator, +.token.entity, +.token.url { + color: #67cdcc; +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +.token.inserted { + color: green; +} diff --git a/sites/.vitepress/devui-theme/styles/custom-blocks.css b/sites/.vitepress/devui-theme/styles/custom-blocks.css new file mode 100644 index 0000000000000000000000000000000000000000..ee52d4c04864ac1d53c64bd2750de3a18bc05c38 --- /dev/null +++ b/sites/.vitepress/devui-theme/styles/custom-blocks.css @@ -0,0 +1,70 @@ +.custom-block.tip, +.custom-block.warning, +.custom-block.danger { + margin: 1rem 0; + border-left: 0.5rem solid; + padding: 0.1rem 1.5rem; + overflow-x: auto; +} + +.custom-block.tip { + background-color: #f3f5f7; + border-color: var(--c-brand); +} + +.custom-block.warning { + border-color: #e7c000; + color: #6b5900; + background-color: rgba(255, 229, 100, 0.3); +} + +.custom-block.warning .custom-block-title { + color: #b29400; +} + +.custom-block.warning a { + color: var(--c-text); +} + +.custom-block.danger { + border-color: #c00; + color: #4d0000; + background-color: #ffe6e6; +} + +.custom-block.danger .custom-block-title { + color: #900; +} + +.custom-block.danger a { + color: var(--c-text); +} + +.custom-block.details { + position: relative; + display: block; + border-radius: 2px; + margin: 1.6em 0; + padding: 1.6em; + background-color: #eee; +} + +.custom-block.details h4 { + margin-top: 0; +} + +.custom-block.details figure:last-child, +.custom-block.details p:last-child { + margin-bottom: 0; + padding-bottom: 0; +} + +.custom-block.details summary { + outline: none; + cursor: pointer; +} + +.custom-block-title { + margin-bottom: -0.4rem; + font-weight: 600; +} diff --git a/sites/.vitepress/devui-theme/styles/layout.css b/sites/.vitepress/devui-theme/styles/layout.css new file mode 100644 index 0000000000000000000000000000000000000000..8d9e0a8e9acf7fbf482f76396fe8006d479bcb09 --- /dev/null +++ b/sites/.vitepress/devui-theme/styles/layout.css @@ -0,0 +1,236 @@ +*, +::before, +::after { + box-sizing: border-box; +} + +html { + line-height: 1.4; + font-size: 16px; + -webkit-text-size-adjust: 100%; +} + +body { + margin: 0; + width: 100%; + min-width: 320px; + min-height: 100vh; + line-height: 1.4; + font-family: var(--font-family-base); + font-size: 16px; + font-weight: 400; + color: var(--c-text); + background-color: var(--c-bg); + direction: ltr; + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +main { + display: block; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + line-height: 1.25; +} + +h1, +h2, +h3, +h4, +h5, +h6, +strong, +b { + font-weight: 600; +} + +h1:hover .header-anchor, +h1:focus .header-anchor, +h2:hover .header-anchor, +h2:focus .header-anchor, +h3:hover .header-anchor, +h3:focus .header-anchor, +h4:hover .header-anchor, +h4:focus .header-anchor, +h5:hover .header-anchor, +h5:focus .header-anchor, +h6:hover .header-anchor, +h6:focus .header-anchor { + opacity: 1; +} + +h1 { + margin-top: 1.5rem; + font-size: 1.9rem; +} + +@media screen and (min-width: 420px) { + h1 { + font-size: 2.2rem; + } +} + +h2 { + margin-top: 2.25rem; + margin-bottom: 1.25rem; + border-bottom: 1px solid var(--c-divider); + padding-bottom: 0.3rem; + line-height: 1.25; + font-size: 1.65rem; + /* overflow-x: auto; */ +} + +h2 + h3 { + margin-top: 1.5rem; +} + +h3 { + margin-top: 2rem; + font-size: 1.35rem; +} + +h4 { + font-size: 1.15rem; +} + +p, +ol, +ul { + margin: 1rem 0; + line-height: 1.7; +} + +a, +area, +button, +[role='button'], +input, +label, +select, +summary, +textarea { + touch-action: manipulation; +} + +a { + text-decoration: none; + color: var(--c-brand); +} + +a:hover { + text-decoration: underline; +} + +a.header-anchor { + float: left; + margin-top: 0.125em; + margin-left: -0.87em; + padding-right: 0.23em; + font-size: 0.85em; + opacity: 0; +} + +a.header-anchor:hover, +a.header-anchor:focus { + text-decoration: none; +} + +figure { + margin: 0; +} + +img { + max-width: 100%; +} + +ul, +ol { + padding-left: 1.25em; +} + +li > ul, +li > ol { + margin: 0; +} + +table { + display: block; + border-collapse: collapse; + margin: 1rem 0; + overflow-x: auto; +} + +tr { + border-top: 1px solid #dfe2e5; +} + +tr:nth-child(2n) { + background-color: #f6f8fa; +} + +th, +td { + border: 1px solid #dfe2e5; + padding: 0.6em 1em; +} + +blockquote { + margin: 1rem 0; + border-left: 0.2rem solid #dfe2e5; + padding: 0.25rem 0 0.25rem 1rem; + font-size: 1rem; + color: #999; +} + +blockquote > p { + margin: 0; +} + +form { + margin: 0; +} + +.theme.sidebar-open .sidebar-mask { + display: block; +} + +.theme.no-navbar > h1, +.theme.no-navbar > h2, +.theme.no-navbar > h3, +.theme.no-navbar > h4, +.theme.no-navbar > h5, +.theme.no-navbar > h6 { + margin-top: 1.5rem; + padding-top: 0; +} + +.theme.no-navbar aside { + top: 0; +} + +@media screen and (min-width: 720px) { + .theme.no-sidebar aside { + display: none; + } + + .theme.no-sidebar main { + margin-left: 0; + } +} + +.sidebar-mask { + position: fixed; + z-index: 2; + display: none; + width: 100vw; + height: 100vh; +} diff --git a/sites/.vitepress/devui-theme/styles/sidebar-links.css b/sites/.vitepress/devui-theme/styles/sidebar-links.css new file mode 100644 index 0000000000000000000000000000000000000000..c15f53fdb038e289040e9e458b95ddb74dcbe7df --- /dev/null +++ b/sites/.vitepress/devui-theme/styles/sidebar-links.css @@ -0,0 +1,107 @@ +.sidebar-links { + margin: 0; + padding: 0; + list-style: none; +} + +.sidebar-link-item { + display: block; + margin: 0; + border-left: 0.25rem solid transparent; + color: var(--c-text); +} + +a.sidebar-link-item:hover { + text-decoration: none; + color: var(--c-brand); +} + +a.sidebar-link-item.active { + color: var(--c-brand); +} + +.sidebar > .sidebar-links { + padding: 0.75rem 0 5rem; +} + +@media (min-width: 720px) { + .sidebar > .sidebar-links { + padding: 1.5rem 0; + } +} + +.sidebar > .sidebar-links > .sidebar-link + .sidebar-link { + padding-top: 0.5rem; +} + +@media (min-width: 720px) { + .sidebar > .sidebar-links > .sidebar-link + .sidebar-link { + padding-top: 1.25rem; + } +} + +.sidebar > .sidebar-links > .sidebar-link > .sidebar-link-item { + padding: 0.35rem 1.5rem 0.35rem 1.25rem; + font-size: 1.1rem; + font-weight: 700; +} + +.sidebar > .sidebar-links > .sidebar-link > a.sidebar-link-item.active { + border-left-color: var(--c-brand); + font-weight: 600; +} + +.sidebar + > .sidebar-links + > .sidebar-link + > .sidebar-links + > .sidebar-link + > .sidebar-link-item { + display: block; + padding: 0.35rem 1.5rem 0.35rem 2rem; + line-height: 1.4; + font-size: 1rem; + font-weight: 400; +} + +.sidebar + > .sidebar-links + > .sidebar-link + > .sidebar-links + > .sidebar-link + > a.sidebar-link-item.active { + border-left-color: var(--c-brand); + font-weight: 600; +} + +.sidebar + > .sidebar-links + > .sidebar-link + > .sidebar-links + > .sidebar-link + > .sidebar-links + > .sidebar-link + > .sidebar-link-item { + display: block; + padding: 0.3rem 1.5rem 0.3rem 3rem; + line-height: 1.4; + font-size: 0.9rem; + font-weight: 400; +} + +.sidebar + > .sidebar-links + > .sidebar-link + > .sidebar-links + > .sidebar-link + > .sidebar-links + > .sidebar-link + > .sidebar-links + > .sidebar-link + > .sidebar-link-item { + display: block; + padding: 0.3rem 1.5rem 0.3rem 4rem; + line-height: 1.4; + font-size: 0.9rem; + font-weight: 400; +} diff --git a/sites/.vitepress/devui-theme/styles/vars.css b/sites/.vitepress/devui-theme/styles/vars.css new file mode 100644 index 0000000000000000000000000000000000000000..78ec1203d9ea24c15b470a29429eb2cf2e3dd940 --- /dev/null +++ b/sites/.vitepress/devui-theme/styles/vars.css @@ -0,0 +1,74 @@ +/** Base Styles */ +:root { + /** + * Colors + * --------------------------------------------------------------------- */ + + --c-white: #ffffff; + --c-white-dark: #f8f8f8; + --c-black: #000000; + + --c-divider-light: rgba(60, 60, 67, 0.12); + --c-divider-dark: rgba(84, 84, 88, 0.48); + + --c-text-light-1: #2c3e50; + --c-text-light-2: #476582; + --c-text-light-3: #90a4b7; + + --c-brand: #3eaf7c; + --c-brand-light: #4abf8a; + + /** + * Typography + * --------------------------------------------------------------------- */ + + --font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + --font-family-mono: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; + + /** + * Z Indexes + * + * Algolia SearchBox has a z-index of 200, so make sure not to go above + * that value. + * --------------------------------------------------------------------- */ + + --z-index-navbar: 10; + --z-index-sidebar: 6; + + /** + * Shadows + * --------------------------------------------------------------------- */ + + --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06); + --shadow-2: 0 3px 12px rgba(0, 0, 0, 0.07), 0 1px 4px rgba(0, 0, 0, 0.07); + --shadow-3: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08); + --shadow-4: 0 14px 44px rgba(0, 0, 0, 0.12), 0 3px 9px rgba(0, 0, 0, 0.12); + --shadow-5: 0 18px 56px rgba(0, 0, 0, 0.16), 0 4px 12px rgba(0, 0, 0, 0.16); + + /** + * Sizes + * --------------------------------------------------------------------- */ + + --header-height: 3.6rem; +} + +/** Fallback Styles */ +:root { + --c-divider: var(--c-divider-light); + + --c-text: var(--c-text-light-1); + --c-text-light: var(--c-text-light-2); + --c-text-lighter: var(--c-text-light-3); + + --c-bg: var(--c-white); + --c-bg-accent: var(--c-white-dark); + + --code-line-height: 24px; + --code-font-family: var(--font-family-mono); + --code-font-size: 14px; + --code-inline-bg-color: rgba(27, 31, 35, 0.05); + --code-bg-color: #282c34; +} diff --git a/sites/.vitepress/devui-theme/support/sideBar.d.ts b/sites/.vitepress/devui-theme/support/sideBar.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..5d8cc85a5b688f42bbe526686ad916f800dfdb36 --- /dev/null +++ b/sites/.vitepress/devui-theme/support/sideBar.d.ts @@ -0,0 +1,18 @@ +import { DefaultTheme } from '../config'; +export declare function isSideBarConfig(sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig): sidebar is DefaultTheme.SideBarConfig; +export declare function isSideBarGroup(item: DefaultTheme.SideBarItem): item is DefaultTheme.SideBarGroup; +export declare function isSideBarEmpty(sidebar?: DefaultTheme.SideBarConfig): boolean; +/** + * Get the `SideBarConfig` from sidebar option. This method will ensure to get + * correct sidebar config from `MultiSideBarConfig` with various path + * combinations such as matching `guide/` and `/guide/`. If no matching config + * was found, it will return `auto` as a fallback. + */ +export declare function getSideBarConfig(sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig, path: string): DefaultTheme.SideBarConfig; +/** + * Get flat sidebar links from the sidebar items. This method is useful for + * creating the "next and prev link" feature. It will ignore any items that + * don't have `link` property and removes `.md` or `.html` extension if a + * link contains it. + */ +export declare function getFlatSideBarLinks(sidebar: DefaultTheme.SideBarItem[]): DefaultTheme.SideBarLink[]; diff --git a/sites/.vitepress/devui-theme/support/sideBar.js b/sites/.vitepress/devui-theme/support/sideBar.js new file mode 100644 index 0000000000000000000000000000000000000000..54c95bea18e10fd6922e8b9d7f2a9471dc512dfa --- /dev/null +++ b/sites/.vitepress/devui-theme/support/sideBar.js @@ -0,0 +1,46 @@ +import { isArray, ensureStartingSlash, removeExtention } from '../utils'; +export function isSideBarConfig(sidebar) { + return sidebar === false || sidebar === 'auto' || isArray(sidebar); +} +export function isSideBarGroup(item) { + return item.children !== undefined; +} +export function isSideBarEmpty(sidebar) { + return isArray(sidebar) ? sidebar.length === 0 : !sidebar; +} +/** + * Get the `SideBarConfig` from sidebar option. This method will ensure to get + * correct sidebar config from `MultiSideBarConfig` with various path + * combinations such as matching `guide/` and `/guide/`. If no matching config + * was found, it will return `auto` as a fallback. + */ +export function getSideBarConfig(sidebar, path) { + if (isSideBarConfig(sidebar)) { + return sidebar; + } + path = ensureStartingSlash(path); + for (const dir in sidebar) { + // make sure the multi sidebar key starts with slash too + if (path.startsWith(ensureStartingSlash(dir))) { + return sidebar[dir]; + } + } + return 'auto'; +} +/** + * Get flat sidebar links from the sidebar items. This method is useful for + * creating the "next and prev link" feature. It will ignore any items that + * don't have `link` property and removes `.md` or `.html` extension if a + * link contains it. + */ +export function getFlatSideBarLinks(sidebar) { + return sidebar.reduce((links, item) => { + if (item.link) { + links.push({ text: item.text, link: removeExtention(item.link) }); + } + if (isSideBarGroup(item)) { + links = [...links, ...getFlatSideBarLinks(item.children)]; + } + return links; + }, []); +} diff --git a/sites/.vitepress/devui-theme/utils.d.ts b/sites/.vitepress/devui-theme/utils.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..68258968c2d28456c79e43e46992781d54764b76 --- /dev/null +++ b/sites/.vitepress/devui-theme/utils.d.ts @@ -0,0 +1,25 @@ +import { Route } from 'vitepress'; +export declare const hashRE: RegExp; +export declare const extRE: RegExp; +export declare const endingSlashRE: RegExp; +export declare const outboundRE: RegExp; +export declare function isNullish(value: any): value is null | undefined; +export declare function isArray(value: any): value is any[]; +export declare function isExternal(path: string): boolean; +export declare function isActive(route: Route, path?: string): boolean; +export declare function normalize(path: string): string; +export declare function joinUrl(base: string, path: string): string; +/** + * get the path without filename (the last segment). for example, if the given + * path is `/guide/getting-started.html`, this method will return `/guide/`. + * Always with a trailing slash. + */ +export declare function getPathDirName(path: string): string; +export declare function ensureSlash(path: string): string; +export declare function ensureStartingSlash(path: string): string; +export declare function ensureEndingSlash(path: string): string; +/** + * Remove `.md` or `.html` extention from the given path. It also converts + * `index` to slush. + */ +export declare function removeExtention(path: string): string; diff --git a/sites/.vitepress/devui-theme/utils.js b/sites/.vitepress/devui-theme/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..51ad485ce435d54ccdca1d1e9a5da2da9f4235c5 --- /dev/null +++ b/sites/.vitepress/devui-theme/utils.js @@ -0,0 +1,63 @@ +export const hashRE = /#.*$/; +export const extRE = /(index)?\.(md|html)$/; +export const endingSlashRE = /\/$/; +export const outboundRE = /^[a-z]+:/i; +export function isNullish(value) { + return value === null || value === undefined; +} +export function isArray(value) { + return Array.isArray(value); +} +export function isExternal(path) { + return outboundRE.test(path); +} +export function isActive(route, path) { + if (path === undefined) { + return false; + } + const routePath = normalize(`/${route.data.relativePath}`); + const pagePath = normalize(path); + return routePath === pagePath; +} +export function normalize(path) { + return decodeURI(path).replace(hashRE, '').replace(extRE, ''); +} +export function joinUrl(base, path) { + const baseEndsWithSlash = base.endsWith('/'); + const pathStartsWithSlash = path.startsWith('/'); + if (baseEndsWithSlash && pathStartsWithSlash) { + return base.slice(0, -1) + path; + } + if (!baseEndsWithSlash && !pathStartsWithSlash) { + return `${base}/${path}`; + } + return base + path; +} +/** + * get the path without filename (the last segment). for example, if the given + * path is `/guide/getting-started.html`, this method will return `/guide/`. + * Always with a trailing slash. + */ +export function getPathDirName(path) { + const segments = path.split('/'); + if (segments[segments.length - 1]) { + segments.pop(); + } + return ensureEndingSlash(segments.join('/')); +} +export function ensureSlash(path) { + return ensureEndingSlash(ensureStartingSlash(path)); +} +export function ensureStartingSlash(path) { + return /^\//.test(path) ? path : `/${path}`; +} +export function ensureEndingSlash(path) { + return /(\.html|\/)$/.test(path) ? path : `${path}/`; +} +/** + * Remove `.md` or `.html` extention from the given path. It also converts + * `index` to slush. + */ +export function removeExtention(path) { + return path.replace(/(index)?(\.(md|html))?$/, '') || '/'; +} diff --git a/sites/.vitepress/theme/index.ts b/sites/.vitepress/theme/index.ts index 8d4209c5045bbe4847a7585f7fd153c6523c10b7..7a5ebb457d35791fb76b665cc8af53d73279dd6d 100644 --- a/sites/.vitepress/theme/index.ts +++ b/sites/.vitepress/theme/index.ts @@ -1,5 +1,5 @@ import DevUI from '../../../devui/vue-devui' -import Theme from 'vitepress/dist/client/theme-default' +import Theme from '../devui-theme' export default { ...Theme, diff --git a/sites/components/alert/index.md b/sites/components/alert/index.md new file mode 100644 index 0000000000000000000000000000000000000000..498a279314bf632ce2e6373df20ab09971a3127d --- /dev/null +++ b/sites/components/alert/index.md @@ -0,0 +1,23 @@ +# Alert 警告 + +显示警告信息,需要用户关注的信息的组件。 + +### 何时使用 + +当页面需要向用户发出警告信息时。 + +### 基本用法 + + success + danger + warning + info + simple + +```html + success + danger + warning + info + simple +``` \ No newline at end of file diff --git a/sites/components/avatar/index.md b/sites/components/avatar/index.md new file mode 100644 index 0000000000000000000000000000000000000000..51a5543836df6c26056cfa90c5342bed2d14c7a6 --- /dev/null +++ b/sites/components/avatar/index.md @@ -0,0 +1,23 @@ +# Avatar 头像 + +显示用户头像的组件。 + +### 何时使用 + +当需要显示用户头像时。 + +### 头像显示的基本规则 + +头像组件传入'name'属性时,会根据一定的规则显示头像的字段,具体规则参见API。 + + + + + + +```html + + + + +``` \ No newline at end of file diff --git a/sites/components/button/index.md b/sites/components/button/index.md index 0f6e440135bd47592ccb34c03e0570f455612ea7..82c6470e92b365bc20e4cefc8560d2b0621fbd1d 100644 --- a/sites/components/button/index.md +++ b/sites/components/button/index.md @@ -1 +1,27 @@ -# Button 按钮 \ No newline at end of file +# Button 按钮 + +按钮用于开始一个即时操作。 + +### 何时使用 + +标记了一个(或封装一组)操作命令,响应用户点击行为,触发相应的业务逻辑。 + +### 主要按钮 + +Primary +Disabled + +```html +Primary +Disabled +``` + +### 次要按钮 + +Common +Disabled + +```html +Common +Disabled +``` \ No newline at end of file diff --git a/sites/components/checkbox/index.md b/sites/components/checkbox/index.md new file mode 100644 index 0000000000000000000000000000000000000000..ee370b2b4fc7a843ca9976c6553a38f9a0b945dc --- /dev/null +++ b/sites/components/checkbox/index.md @@ -0,0 +1,34 @@ +# CheckBox 复选框 + +多选框。 + +### 何时使用 + +1. 在一组选项中进行多项选择; +2. 单独使用可以表示在两个状态之间切换,可以和提交操作结合。 + +### 基本用法 + + + + +```html + + +``` + + \ No newline at end of file diff --git a/sites/components/panel/index.md b/sites/components/panel/index.md new file mode 100644 index 0000000000000000000000000000000000000000..10c3ae76c4874da0e2e2fd1f7242e4af26af6c45 --- /dev/null +++ b/sites/components/panel/index.md @@ -0,0 +1,74 @@ +# Panel 面板 + +内容面板,用于内容分组。 + +### 何时使用 + +当页面内容需要进行分组显示时使用,一般包含头部、内容区域、底部三个部分。 + +### 基本用法 + +
+ + + Panel with foldable + + + This is body + +

+ + + Panel has no left padding + + + This is body + +

+ + Panel with header and footer + This is body + This is footer + +
+ + +```html +
+ + + Panel with foldable + + + This is body + +

+ + + Panel has no left padding + + + This is body + +

+ + Panel with header and footer + This is body + This is footer + +
+``` + + diff --git a/sites/components/radio/index.md b/sites/components/radio/index.md new file mode 100644 index 0000000000000000000000000000000000000000..99241365bf6037042b36420b97b567f9c74b9c8f --- /dev/null +++ b/sites/components/radio/index.md @@ -0,0 +1,33 @@ +# Radio 单选框 + +单选框。 + +### 何时使用 + +用户要从一个数据集中选择单个选项,且能并排查看所有可选项,选项数量在2~7之间时,建议使用单选按钮。 + +### 横向排列 + +checked +unchecked + +```html +checked +unchecked +``` + + diff --git a/sites/components/tabs/index.md b/sites/components/tabs/index.md new file mode 100644 index 0000000000000000000000000000000000000000..1fe147671caabaffff282bdff74f4af2dce92a39 --- /dev/null +++ b/sites/components/tabs/index.md @@ -0,0 +1,7 @@ +# Tabs 选项卡切换 + +选项卡切换组件。 + +### 何时使用 + +用户需要通过平级的区域将大块内容进行收纳和展现,保持界面整洁。 diff --git a/sites/components/tags-input/index.md b/sites/components/tags-input/index.md new file mode 100644 index 0000000000000000000000000000000000000000..4a962755ea5912695ec9dc8cb617ccabb9d751bb --- /dev/null +++ b/sites/components/tags-input/index.md @@ -0,0 +1,44 @@ +# TagsInput 标签输入 + +输入标签组件。 + +### 何时使用 + +当用户需要输入多个标签时。 + +### 基本用法 + + + +```html + +``` + + \ No newline at end of file diff --git a/sites/components/text-input/index.md b/sites/components/text-input/index.md new file mode 100644 index 0000000000000000000000000000000000000000..150884520b87217fb95c5e840e71bcb37d307ab5 --- /dev/null +++ b/sites/components/text-input/index.md @@ -0,0 +1,16 @@ +# Text Input 文本框 + +文本输入框。 + +### 何时使用 + +需要手动输入文字使用。 + +### 基本用法 + +

Default

+ +

Disabled

+ +

Error

+ diff --git a/sites/index.md b/sites/index.md index 6eedf66228eaed4cabe763db0b6b0c878722ab1f..3380e0697efb277f21e2ff5111bc52b5783cdc44 100644 --- a/sites/index.md +++ b/sites/index.md @@ -10,7 +10,7 @@ 推荐使用@vite/cli创建你的项目 -``` +```sh yarn create vite my-vue-app --template vue-ts ``` @@ -18,7 +18,7 @@ yarn create vite my-vue-app --template vue-ts 进入你的项目文件夹,使用yarn安装DevUI -``` +```sh yarn add vue-devui # 可选,字体图标库, 部分Demo依赖此字体库 @@ -29,7 +29,7 @@ yarn add vue-devui main.ts -``` +```js import DevUI from 'vue-devui' import 'vue-devui/style.css' @@ -38,6 +38,6 @@ createApp(App).use(DevUI).mount(#app) ### 4. 启动开发调试 -``` +```sh yarn dev ``` \ No newline at end of file