完成tabs组件

master
yutent 2023-04-17 18:40:45 +08:00
parent bfeb588858
commit 707dd7d8cc
1 changed files with 178 additions and 18 deletions

View File

@ -13,6 +13,7 @@ import {
styleMap,
classMap
} from '@bd/core'
import '../icon/index.js'
class Tabs extends Component {
static props = {
@ -54,7 +55,12 @@ class Tabs extends Component {
user-select: none;
}
.navs {
display: flex;
}
.content {
flex: 1;
padding: 16px 0;
}
@ -62,6 +68,7 @@ class Tabs extends Component {
position: relative;
display: inline-flex;
align-items: center;
justify-content: space-between;
max-width: 120px;
margin: 0 16px;
--size: 16px;
@ -79,10 +86,38 @@ class Tabs extends Component {
margin-right: 0;
}
&:hover,
&:hover:not([disabled]),
&.active {
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;
border-bottom: 0;
}
.navs {
flex-direction: column;
}
.content {
padding: 0 16px;
}
@ -179,11 +217,13 @@ class Tabs extends Component {
background: var(--color-plain-1);
}
}
`,
// type folder
css`
:host([type='folder']) {
.header {
overflow: hidden;
padding-left: 6px;
padding: 0 6px;
}
.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']) {
border: 1px solid var(--color-plain-3);
background: #fff;
@ -251,6 +331,63 @@ class Tabs extends Component {
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
}
if (this.labels[+elem.dataset.i].disabled) {
return
}
// 非默认类型, 不显示active-bar
if (gaps) {
this.#tabWidth = elem.clientWidth
@ -328,6 +469,15 @@ class Tabs extends Component {
.then(_ => this.#cache[key].panel.$animate())
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() {
@ -378,20 +528,30 @@ class Tabs extends Component {
}
return html`
<header class="header" ref="navs" @click=${this.selectTab}>
${this.labels.map(
(it, i) =>
html`<label
class=${classMap({
label: true,
active: it.name === this.tab
})}
title=${it.label}
data-i=${i}
>
<span class="ell">${it.label}</span>
</label>`
)}
<header class="header">
<section class="navs" ref="navs" @click=${this.selectTab}>
${this.labels.map(
(it, i) =>
html`<label
class=${classMap({
label: true,
active: it.name === this.tab
})}
disabled=${it.disabled}
closable=${it.closable}
title=${it.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>
</header>
<div class="content">