feat(site): added component version prompting (#977)
This commit is contained in:
parent
162a267728
commit
cd9304bcdb
|
@ -0,0 +1,192 @@
|
|||
<template>
|
||||
<span v-if="currentStageComputed" class="version-tip">
|
||||
<div v-if="renderType === 'alert'">
|
||||
<tiny-alert :type="alertTypeComputed" :closable="false">
|
||||
<template #description>
|
||||
<span>{{ tipComputed }}</span>
|
||||
</template>
|
||||
</tiny-alert>
|
||||
</div>
|
||||
<span v-if="renderType === 'tag'">
|
||||
<tiny-tooltip
|
||||
effect="light"
|
||||
placement="top-start"
|
||||
:open-delay="500"
|
||||
:content="tipComputed"
|
||||
:disabled="!tipComputed"
|
||||
>
|
||||
<tiny-tag size="mini" effect="dark" :type="tagTypeComputed">{{ currentStageComputed }}</tiny-tag>
|
||||
</tiny-tooltip>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { PropType } from 'vue'
|
||||
import { defineComponent, computed } from 'vue'
|
||||
import { Tag as TinyTag, Alert as TinyAlert, Tooltip as TinyTooltip } from '@opentiny/vue'
|
||||
import { $t2 } from '../../i18n/index'
|
||||
|
||||
enum STAGE {
|
||||
experimental = 'experimental',
|
||||
stable = 'stable',
|
||||
deprecated = 'deprecated',
|
||||
removed = 'removed'
|
||||
}
|
||||
|
||||
interface IStageVersionMetaData {
|
||||
version: string
|
||||
}
|
||||
|
||||
interface IVersionMetaData {
|
||||
[STAGE.experimental]?: IStageVersionMetaData | string
|
||||
[STAGE.stable]?: IStageVersionMetaData | string
|
||||
[STAGE.deprecated]?: IStageVersionMetaData | string
|
||||
[STAGE.removed]?: IStageVersionMetaData | string
|
||||
}
|
||||
|
||||
interface Ii18nString {
|
||||
'zh-CN': string
|
||||
'en-US': string
|
||||
}
|
||||
|
||||
const alertTypeMap = {
|
||||
[STAGE.removed]: 'error',
|
||||
[STAGE.deprecated]: 'error',
|
||||
[STAGE.experimental]: 'warning',
|
||||
[STAGE.stable]: 'info'
|
||||
}
|
||||
|
||||
const tagTypeMap = {
|
||||
[STAGE.removed]: 'danger',
|
||||
[STAGE.deprecated]: 'danger',
|
||||
[STAGE.experimental]: 'warning',
|
||||
[STAGE.stable]: 'info'
|
||||
}
|
||||
|
||||
const cnDesMap = {
|
||||
[STAGE.experimental]: '处于测试阶段',
|
||||
[STAGE.stable]: '自 v{version} 起稳定提供',
|
||||
[STAGE.deprecated]: '从 v{version} 开始被废弃',
|
||||
[STAGE.removed]: '于 v{version} 移除'
|
||||
}
|
||||
|
||||
const enDesMap = {
|
||||
[STAGE.experimental]: 'in beta',
|
||||
[STAGE.stable]: 'stable since v{version}',
|
||||
[STAGE.deprecated]: 'deprecated since v{version}',
|
||||
[STAGE.removed]: 'removed in v{version}'
|
||||
}
|
||||
|
||||
// 默认的,只需要显示deprecated,experimental状态时的提示,除非声明了briefStage
|
||||
export default defineComponent({
|
||||
components: {
|
||||
TinyTag,
|
||||
TinyAlert,
|
||||
TinyTooltip
|
||||
},
|
||||
props: {
|
||||
metaData: {
|
||||
type: Object as PropType<IVersionMetaData>,
|
||||
default: () => ({})
|
||||
},
|
||||
renderType: {
|
||||
type: String as PropType<'tag' | 'alert'>,
|
||||
default: 'alert'
|
||||
},
|
||||
tipSubject: {
|
||||
type: String as PropType<'component' | 'api'>,
|
||||
default: 'component'
|
||||
},
|
||||
stages: {
|
||||
type: Array as PropType<STAGE[]>,
|
||||
default: () => [STAGE.experimental, STAGE.deprecated, STAGE.removed]
|
||||
},
|
||||
alertType: {
|
||||
type: String
|
||||
},
|
||||
tagType: {
|
||||
type: String
|
||||
},
|
||||
briefStage: {
|
||||
type: Object as PropType<STAGE>
|
||||
},
|
||||
tip: {
|
||||
type: Object as PropType<Ii18nString>
|
||||
},
|
||||
extendTip: {
|
||||
type: Object as PropType<Ii18nString>
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const isInStage = (stage: STAGE) => Boolean(props.metaData[stage]) && props.stages.includes(stage)
|
||||
|
||||
const getVersion = (stage: STAGE) => {
|
||||
if (!props.metaData[stage]) return ''
|
||||
|
||||
if (typeof props.metaData[stage] === 'string') {
|
||||
return props.metaData[stage] as string
|
||||
} else {
|
||||
return (props.metaData[stage] as IStageVersionMetaData).version
|
||||
}
|
||||
}
|
||||
|
||||
const currentStageComputed = computed(() => {
|
||||
if (props.briefStage) {
|
||||
return props.briefStage
|
||||
}
|
||||
|
||||
return [STAGE.deprecated, STAGE.experimental].find(isInStage)
|
||||
})
|
||||
|
||||
const generateDes = (desMap: typeof cnDesMap) => {
|
||||
const isFilterExperimental = isInStage(STAGE.deprecated) || isInStage(STAGE.stable)
|
||||
|
||||
const goingStages = Object.entries(desMap).filter(([stage]) => {
|
||||
let isPicked = isInStage(stage as STAGE)
|
||||
|
||||
if (stage === STAGE.experimental) {
|
||||
isPicked = isPicked && !isFilterExperimental
|
||||
}
|
||||
|
||||
return isPicked
|
||||
})
|
||||
|
||||
return goingStages.map(([stage, des]) => des.replace('{version}', getVersion(stage as STAGE))).join(',')
|
||||
}
|
||||
|
||||
const tipComputed = computed(() => {
|
||||
if (props.tip) return $t2(props.tip['zh-CN'], props.tip['en-US']) as string
|
||||
|
||||
if (!props.metaData) return ''
|
||||
|
||||
const vertionDesZnCn = generateDes(cnDesMap)
|
||||
const znChTip = `该${props.tipSubject === 'component' ? '组件' : '特性'}${vertionDesZnCn}。${props.extendTip?.['zh-CN'] || ''}`
|
||||
|
||||
const vertionDesEnUs = generateDes(enDesMap)
|
||||
const enUsTip = `This ${props.tipSubject === 'component' ? 'component' : 'feature'} is ${vertionDesEnUs}. ${props.extendTip?.['en-US'] || ''}`
|
||||
|
||||
return $t2(znChTip, enUsTip) as string
|
||||
})
|
||||
|
||||
const alertTypeComputed = computed(() => {
|
||||
if (props.alertType) return props.alertType
|
||||
|
||||
return currentStageComputed.value ? alertTypeMap[currentStageComputed.value] : 'error'
|
||||
})
|
||||
|
||||
const tagTypeComputed = computed(() => {
|
||||
if (props.tagType) return props.tagType
|
||||
|
||||
return currentStageComputed.value ? tagTypeMap[currentStageComputed.value] : 'error'
|
||||
})
|
||||
|
||||
return {
|
||||
tipComputed,
|
||||
currentStageComputed,
|
||||
alertTypeComputed,
|
||||
tagTypeComputed
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -8,6 +8,11 @@
|
|||
<div class="ti-fi-1 ti-w0 ti-rel cmp-container">
|
||||
<!-- 一个组件的文档: 描述md + demos + apis -->
|
||||
<div class="markdown-body markdown-top-body" size="medium" v-html="cmpTopMd"></div>
|
||||
<version-tip
|
||||
v-if="currJson.metaData || currJson.versionTipOption"
|
||||
:metaData="currJson.metaData"
|
||||
v-bind="currJson.versionTipOption">
|
||||
</version-tip>
|
||||
<template v-if="currJson?.demos?.length > 0">
|
||||
<div class="all-demos-container">
|
||||
<h2 class="ti-f30 ti-fw-normal !ti-mb20">{{ $t('yan-shi') }}</h2>
|
||||
|
@ -66,6 +71,13 @@
|
|||
<td>
|
||||
<a v-if="row.demoId" @click="jumpToDemo(row.demoId)">{{ row.name }}</a>
|
||||
<span v-else>{{ row.name }}</span>
|
||||
<version-tip
|
||||
v-if="row.metaData || row.versionTipOption"
|
||||
:metaData="row.metaData"
|
||||
v-bind="row.versionTipOption"
|
||||
renderType="tag"
|
||||
tipSubject="api">
|
||||
</version-tip>
|
||||
</td>
|
||||
<td v-if="!key.includes('slots')">
|
||||
<a
|
||||
|
@ -134,6 +146,7 @@ import { router } from '@/router.js'
|
|||
import { Collapse, CollapseItem } from '@opentiny/vue'
|
||||
import { faqMdConfig, staticDemoPath, getWebdocPath } from './cmpConfig'
|
||||
import AsyncHighlight from './async-highlight.vue'
|
||||
import VersionTip from './VersionTip.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CmpPageVue',
|
||||
|
@ -143,7 +156,8 @@ export default defineComponent({
|
|||
TinyButtonGroup: ButtonGroup,
|
||||
TinyCollapse: Collapse,
|
||||
TinyCollapseItem: CollapseItem,
|
||||
AsyncHighlight
|
||||
AsyncHighlight,
|
||||
VersionTip
|
||||
},
|
||||
directives: {
|
||||
loading: Loading.directive
|
||||
|
@ -436,6 +450,9 @@ table.api-table {
|
|||
border-bottom: 1px solid rgb(239, 239, 245);
|
||||
padding: 12px;
|
||||
line-height: 1.5;
|
||||
.version-tip {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,8 +80,17 @@
|
|||
@collapse-change="collapseChange"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<tiny-tag v-if="data?.mode?.includes('mobile-first')" effect="plain" class="ti-mr6">多端</tiny-tag>
|
||||
<span>{{ data.label }}</span>
|
||||
<div class="node-name-container">
|
||||
<tiny-tag v-if="data?.mode?.includes('mobile-first')" effect="plain">多端</tiny-tag>
|
||||
<span class="node-name-label">{{ data.label }}</span>
|
||||
<tiny-tag
|
||||
v-if="data.mark?.text"
|
||||
class="node-float-tip"
|
||||
effect="dark"
|
||||
:type="data.mark?.type">
|
||||
{{ data.mark.text}}
|
||||
</tiny-tag>
|
||||
</div>
|
||||
</template>
|
||||
</tiny-tree-menu>
|
||||
</div>
|
||||
|
@ -282,6 +291,10 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
.main-menu.tiny-tree-menu {
|
||||
.tiny-tree-node__content-box {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
height: calc(100% - var(--layout-api-mode-height));
|
||||
.tiny-tree {
|
||||
height: calc(100% - var(--layout-tree-menu-input-height));
|
||||
|
@ -289,6 +302,21 @@ export default defineComponent({
|
|||
}
|
||||
.tree-node-name {
|
||||
line-height: 1.5;
|
||||
|
||||
.node-name-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
gap: 6px;
|
||||
|
||||
.node-name-label {
|
||||
flex-grow: 0;
|
||||
min-width: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
& > .tiny-input .tiny-input__inner {
|
||||
height: var(--layout-tree-menu-input-height);
|
||||
|
|
Loading…
Reference in New Issue