完成tabs组件
parent
bfeb588858
commit
707dd7d8cc
|
@ -13,6 +13,7 @@ import {
|
||||||
styleMap,
|
styleMap,
|
||||||
classMap
|
classMap
|
||||||
} from '@bd/core'
|
} from '@bd/core'
|
||||||
|
import '../icon/index.js'
|
||||||
|
|
||||||
class Tabs extends Component {
|
class Tabs extends Component {
|
||||||
static props = {
|
static props = {
|
||||||
|
@ -54,7 +55,12 @@ class Tabs extends Component {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navs {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
flex: 1;
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +68,7 @@ class Tabs extends Component {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
max-width: 120px;
|
max-width: 120px;
|
||||||
margin: 0 16px;
|
margin: 0 16px;
|
||||||
--size: 16px;
|
--size: 16px;
|
||||||
|
@ -79,10 +86,38 @@ class Tabs extends Component {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover:not([disabled]),
|
||||||
&.active {
|
&.active {
|
||||||
color: var(--color-teal-1);
|
color: var(--color-teal-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
display: none;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
margin-left: 4px;
|
||||||
|
padding: 3px;
|
||||||
|
border-radius: 50px;
|
||||||
|
color: var(--color-dark-1);
|
||||||
|
transition: background 0.2s ease-in, color 0.2s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[closable='true'] {
|
||||||
|
.close:hover {
|
||||||
|
background: var(--color-red-1);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .close {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|
||||||
|
@ -124,6 +159,9 @@ class Tabs extends Component {
|
||||||
max-width: 120px;
|
max-width: 120px;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
|
.navs {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
.content {
|
.content {
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
@ -179,11 +217,13 @@ class Tabs extends Component {
|
||||||
background: var(--color-plain-1);
|
background: var(--color-plain-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
// type folder
|
||||||
|
css`
|
||||||
:host([type='folder']) {
|
:host([type='folder']) {
|
||||||
.header {
|
.header {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-left: 6px;
|
padding: 0 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
@ -232,8 +272,48 @@ class Tabs extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
&:host([tab-position='left']),
|
||||||
|
&:host([tab-position='right']) {
|
||||||
|
.header {
|
||||||
|
flex-direction: column;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
.navs {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
height: 38px;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:host([tab-position='left']) {
|
||||||
|
.label {
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
border-radius: 6px 0 0 6px;
|
||||||
|
transform: perspective(120px) rotateY(-20deg) translateX(-6px);
|
||||||
|
box-shadow: -1px 0 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:host([tab-position='right']) {
|
||||||
|
.label {
|
||||||
|
&::before {
|
||||||
|
border-radius: 0 6px 6px 0;
|
||||||
|
transform: perspective(120px) rotateY(20deg) translateX(6px);
|
||||||
|
box-shadow: -1px 0 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
// type card
|
||||||
|
css`
|
||||||
:host([type='card']) {
|
:host([type='card']) {
|
||||||
border: 1px solid var(--color-plain-3);
|
border: 1px solid var(--color-plain-3);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
@ -251,6 +331,63 @@ class Tabs extends Component {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:host([tab-position='bottom']) {
|
||||||
|
.header {
|
||||||
|
box-shadow: inset 0 1px 0 0px var(--color-plain-3);
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
border-top: 1px solid var(--color-plain-3);
|
||||||
|
border-bottom: 0;
|
||||||
|
&.active {
|
||||||
|
border-top-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:host([tab-position='left']),
|
||||||
|
&:host([tab-position='right']) {
|
||||||
|
.header {
|
||||||
|
flex-direction: column;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.navs {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
height: 38px;
|
||||||
|
padding-top: 0;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:host([tab-position='left']) {
|
||||||
|
.label {
|
||||||
|
&.active {
|
||||||
|
border-bottom-color: var(--color-plain-3);
|
||||||
|
border-right-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:host([tab-position='right']) {
|
||||||
|
.label {
|
||||||
|
border-left: 1px solid var(--color-plain-3);
|
||||||
|
border-right: 0;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-bottom-color: var(--color-plain-3);
|
||||||
|
border-left-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
]
|
]
|
||||||
|
@ -307,6 +444,10 @@ class Tabs extends Component {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.labels[+elem.dataset.i].disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 非默认类型, 不显示active-bar
|
// 非默认类型, 不显示active-bar
|
||||||
if (gaps) {
|
if (gaps) {
|
||||||
this.#tabWidth = elem.clientWidth
|
this.#tabWidth = elem.clientWidth
|
||||||
|
@ -328,6 +469,15 @@ class Tabs extends Component {
|
||||||
.then(_ => this.#cache[key].panel.$animate())
|
.then(_ => this.#cache[key].panel.$animate())
|
||||||
|
|
||||||
this.tab = key
|
this.tab = key
|
||||||
|
|
||||||
|
this.$emit('tab-change', {
|
||||||
|
data: { name: key, label: this.#cache[key].label }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
removeTab(ev) {
|
||||||
|
let tab = this.labels[+ev.target.dataset.i]
|
||||||
|
this.$emit('tab-close', { data: { name: tab.name, label: tab.label } })
|
||||||
}
|
}
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
|
@ -378,20 +528,30 @@ class Tabs extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<header class="header" ref="navs" @click=${this.selectTab}>
|
<header class="header">
|
||||||
${this.labels.map(
|
<section class="navs" ref="navs" @click=${this.selectTab}>
|
||||||
(it, i) =>
|
${this.labels.map(
|
||||||
html`<label
|
(it, i) =>
|
||||||
class=${classMap({
|
html`<label
|
||||||
label: true,
|
class=${classMap({
|
||||||
active: it.name === this.tab
|
label: true,
|
||||||
})}
|
active: it.name === this.tab
|
||||||
title=${it.label}
|
})}
|
||||||
data-i=${i}
|
disabled=${it.disabled}
|
||||||
>
|
closable=${it.closable}
|
||||||
<span class="ell">${it.label}</span>
|
title=${it.label}
|
||||||
</label>`
|
data-i=${i}
|
||||||
)}
|
>
|
||||||
|
<span class="ell">${it.label}</span>
|
||||||
|
<wc-icon
|
||||||
|
class="close"
|
||||||
|
name="close"
|
||||||
|
data-i=${i}
|
||||||
|
@click.stop=${this.removeTab}
|
||||||
|
></wc-icon>
|
||||||
|
</label>`
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
<span class="active-bar" style=${styleMap(tabStyle)}></span>
|
<span class="active-bar" style=${styleMap(tabStyle)}></span>
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|
Loading…
Reference in New Issue