From 707dd7d8cc819d8739a68b6ea817998897b95516 Mon Sep 17 00:00:00 2001 From: yutent Date: Mon, 17 Apr 2023 18:40:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90tabs=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tabs/index.js | 196 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 178 insertions(+), 18 deletions(-) diff --git a/src/tabs/index.js b/src/tabs/index.js index f442425..cf9c1f5 100644 --- a/src/tabs/index.js +++ b/src/tabs/index.js @@ -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` -
- ${this.labels.map( - (it, i) => - html`` - )} +
+