mirror of
https://github.com/element-plus/element-plus.git
synced 2025-01-30 11:16:12 +08:00
feat(breadcrumb): add breadcrumb component
This commit is contained in:
parent
2760994026
commit
79e9bdfb38
@ -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": {
|
||||
|
60
packages/breadcrumb/__tests__/breadcrumb.spec.ts
Normal file
60
packages/breadcrumb/__tests__/breadcrumb.spec.ts
Normal 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('')
|
||||
})
|
||||
})
|
16
packages/breadcrumb/doc/basic.vue
Normal file
16
packages/breadcrumb/doc/basic.vue
Normal 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>
|
5
packages/breadcrumb/doc/index.stories.ts
Normal file
5
packages/breadcrumb/doc/index.stories.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export { default as BasicUsage } from './basic.vue'
|
||||
|
||||
export default {
|
||||
title: 'Breadcrumb',
|
||||
}
|
7
packages/breadcrumb/index.ts
Normal file
7
packages/breadcrumb/index.ts
Normal 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)
|
||||
}
|
13
packages/breadcrumb/package.json
Normal file
13
packages/breadcrumb/package.json
Normal 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"
|
||||
}
|
||||
}
|
49
packages/breadcrumb/src/index.vue
Normal file
49
packages/breadcrumb/src/index.vue
Normal 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>
|
62
packages/breadcrumb/src/item.vue
Normal file
62
packages/breadcrumb/src/item.vue
Normal 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>
|
@ -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)
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user