feat(breadcrumb): add breadcrumb component

This commit is contained in:
Caaalabash 2020-08-01 22:03:08 +08:00 committed by zazzaz
parent 2760994026
commit 79e9bdfb38
11 changed files with 224 additions and 2 deletions

View File

@ -39,7 +39,8 @@
"typescript": "^3.9.7",
"vite": "^1.0.0-rc.1",
"vue-jest": "5.0.0-alpha.1",
"vue-loader": "^v16.0.0-beta.4"
"vue-loader": "^v16.0.0-beta.4",
"vue-router": "^4.0.0-beta.4"
},
"config": {
"commitizen": {

View File

@ -0,0 +1,60 @@
import { mount } from '@vue/test-utils'
import Breadcrumb from '../src/index.vue'
import BreadcrumbItem from '../src/item.vue'
const config = {
components: {
'el-breadcrumb': Breadcrumb,
'el-breadcrumb-item': BreadcrumbItem,
},
}
describe('Breadcrumb.vue', () => {
test('separator', () => {
const wrapper = mount({
...config,
template: `
<el-breadcrumb separator="?">
<el-breadcrumb-item>A</el-breadcrumb-item>
</el-breadcrumb>
`,
})
expect(wrapper.find('.el-breadcrumb__separator').text()).toBe('?')
})
test('separatorClass', () => {
const wrapper = mount({
...config,
template: `
<el-breadcrumb separator="?" separatorClass="test">
<el-breadcrumb-item>A</el-breadcrumb-item>
</el-breadcrumb>
`,
})
expect(wrapper.find('.el-breadcrumb__separator').text()).toBe('')
expect(wrapper.find('.el-breadcrumb__separator').classes()).toContain('test')
})
test('to', () => {
const wrapper = mount({
...config,
template: `
<el-breadcrumb separator="?" separatorClass="test">
<el-breadcrumb-item to="/index">A</el-breadcrumb-item>
</el-breadcrumb>
`,
})
expect(wrapper.find('.el-breadcrumb__inner').classes()).toContain('is-link')
})
test('single', () => {
const wrapper = mount({
...config,
template: `
<el-breadcrumb-item>A</el-breadcrumb-item>
`,
})
expect(wrapper.find('.el-breadcrumb__inner').text()).toBe('A')
expect(wrapper.find('.el-breadcrumb__separator').text()).toBe('')
})
})

View File

@ -0,0 +1,16 @@
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item to="/">First</el-breadcrumb-item>
<el-breadcrumb-item><a href="/">Second</a></el-breadcrumb-item>
<el-breadcrumb-item>Third</el-breadcrumb-item>
<el-breadcrumb-item>Forth</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
name: 'Basic',
})
</script>

View File

@ -0,0 +1,5 @@
export { default as BasicUsage } from './basic.vue'
export default {
title: 'Breadcrumb',
}

View File

@ -0,0 +1,7 @@
import { App } from 'vue'
import Breadcrumb from './src/index.vue'
import BreadcrumbItem from './src/item.vue'
export default (app: App): void => {
app.component(Breadcrumb.name, Breadcrumb)
app.component(BreadcrumbItem.name, BreadcrumbItem)
}

View File

@ -0,0 +1,13 @@
{
"name": "@element-plus/breadcrumb",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "^3.0.0-rc.1",
"vue-router": "^4.0.0-beta.4"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.0"
}
}

View File

@ -0,0 +1,49 @@
<template>
<div
ref="breadcrumb"
class="el-breadcrumb"
aria-label="Breadcrumb"
role="navigation"
>
<slot></slot>
</div>
</template>
<script lang="ts">
import { defineComponent, provide, ref, onMounted } from 'vue'
interface IBreadcrumbProps {
separator: string;
separatorClass: string;
}
export default defineComponent({
name: 'ElBreadcrumb',
props: {
separator: {
type: String,
default: '/',
},
separatorClass: {
type: String,
default: '',
},
},
setup(props: IBreadcrumbProps) {
const breadcrumb = ref(null)
provide('breadcrumb', props)
onMounted(() => {
const items = breadcrumb.value.querySelectorAll('.el-breadcrumb__item')
if (items.length) {
items[items.length - 1].setAttribute('aria-current', 'page')
}
})
return {
breadcrumb,
}
},
})
</script>

View File

@ -0,0 +1,62 @@
<template>
<span class="el-breadcrumb__item">
<span
ref="link"
:class="['el-breadcrumb__inner', to ? 'is-link' : '']"
role="link"
>
<slot></slot>
</span>
<i v-if="separatorClass" class="el-breadcrumb__separator" :class="separatorClass"></i>
<span v-else class="el-breadcrumb__separator" role="presentation">{{ separator }}</span>
</span>
</template>
<script lang="ts">
import { defineComponent, inject, ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
interface IBreadcrumbInject {
separator: string;
separatorClass: string;
}
interface IBreadcrumbItemProps {
to: string | Record<string, unknown>;
replace: boolean;
}
export default defineComponent({
name: 'ElBreadcrumbItem',
props: {
to: {
type: [String, Object],
default: '',
},
replace: {
type: Boolean,
default: false,
},
},
setup(props: IBreadcrumbItemProps) {
const link = ref(null)
const parent: IBreadcrumbInject = inject('breadcrumb')
onMounted(() => {
link.value.setAttribute('role', 'link')
link.value.addEventListener('click', () => {
if (!props.to) return
const router = useRouter()
if (!router) return
props.replace ? router.replace(props.to) : router.push(props.to)
})
})
return {
link,
separator: parent?.separator,
separatorClass: parent?.separatorClass,
}
},
})
</script>

View File

@ -8,6 +8,7 @@ import ElLayout from '@element-plus/layout'
import ElDivider from '@element-plus/divider'
import ElTimeLine from '@element-plus/time-line'
import ElProgress from '@element-plus/progress'
import ElBreadcrumb from '@element-plus/breadcrumb'
export {
ElAvatar,
@ -19,6 +20,7 @@ export {
ElTag,
ElTimeLine,
ElProgress,
ElBreadcrumb,
}
export default function install(app: App): void {
@ -31,4 +33,5 @@ export default function install(app: App): void {
ElDivider(app)
ElTimeLine(app)
ElProgress(app)
ElBreadcrumb(app)
}

View File

@ -22,6 +22,7 @@
"@element-plus/tag": "^0.0.0",
"@element-plus/time-line": "^0.0.0",
"@element-plus/divider": "^0.0.0",
"@element-plus/progress": "^0.0.0"
"@element-plus/progress": "^0.0.0",
"@element-plus/breadcrumb": "^0.0.0"
}
}

View File

@ -13656,6 +13656,11 @@ vue-loader@^v16.0.0-beta.4:
merge-source-map "^1.1.0"
source-map "^0.6.1"
vue-router@^4.0.0-beta.4:
version "4.0.0-beta.4"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.0-beta.4.tgz#0945886e8e35bed368ab57e50a6b004cff1459e0"
integrity sha512-Cp8CkTcQuWL3neBLZnd+zg7cH0aA/kX1AwNLmdrChz5z6JI9hNu2qImAXNvhobDddLtNbyjdYSedCB9RYt6aig==
vue@^3.0.0-rc.1:
version "3.0.0-rc.2"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.2.tgz#7eb0858e575051ac612bee6547bdd21b0f63d717"