mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-30 02:58:05 +08:00
Tabs 宽度问题修改,与样式优化 (#3654)
* fix: tabs 宽度 sensor 问题 和 样式修复 * feat: tabs 新增 editor 样式风格 * feat: tabs 新增 editor 样式风格 * feat: tabs schema fix * feat: tabs toobar style fix * feat: tabs md 修改 * feat: tabs md 修改 * feat: tabs snapshots Co-authored-by: liuzedong02 <liuzedong02@baidu.com>
This commit is contained in:
parent
7f29c70a5a
commit
608dd5c3fe
@ -37,6 +37,7 @@ exports[`Renderer:tabs 1`] = `
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer-wrapper"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer"
|
||||
@ -65,6 +66,45 @@ exports[`Renderer:tabs 1`] = `
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="cxd-Tabs-content"
|
||||
|
@ -74,7 +74,8 @@ exports[`Renderer:tabs-transfer 1`] = `
|
||||
class="cxd-Tabs cxd-Tabs--card cxd-TabsTransfer-tabs"
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer-wrapper"
|
||||
class="cxd-Tabs-linksContainer-wrapper cxd-Tabs-linksContainer-wrapper--toolbar"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer"
|
||||
@ -123,6 +124,45 @@ exports[`Renderer:tabs-transfer 1`] = `
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="cxd-Tabs-content"
|
||||
|
@ -9,7 +9,8 @@ exports[`Renderer:portlet 1`] = `
|
||||
class="cxd-Tabs cxd-Tabs--line cxd-Portlet-tab"
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer-wrapper"
|
||||
class="cxd-Tabs-linksContainer-wrapper cxd-Tabs-linksContainer-wrapper--toolbar"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer"
|
||||
@ -77,6 +78,45 @@ exports[`Renderer:portlet 1`] = `
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="cxd-Tabs-content"
|
||||
|
@ -7,6 +7,7 @@ exports[`Renderer:tabs 1`] = `
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer-wrapper"
|
||||
style="position: relative;"
|
||||
>
|
||||
<div
|
||||
class="cxd-Tabs-linksContainer"
|
||||
@ -35,6 +36,45 @@ exports[`Renderer:tabs 1`] = `
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="cxd-Tabs-content"
|
||||
|
@ -90,13 +90,14 @@ order: 68
|
||||
|
||||
## 可增加、删除
|
||||
|
||||
`tab` 设置的 `closable` 优先级高于整体
|
||||
`tab` 设置的 `closable` 优先级高于整体。使用 `addBtnText` 设置新增按钮文案
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"closable": true,
|
||||
"addable": true,
|
||||
"addBtnText": "新增Tab",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "Tab 1",
|
||||
@ -181,7 +182,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "simple",
|
||||
"tabsMode": "simple",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "简约(10)",
|
||||
@ -205,7 +206,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "strong",
|
||||
"tabsMode": "strong",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
@ -228,7 +229,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "line",
|
||||
"tabsMode": "line",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
@ -251,7 +252,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "card",
|
||||
"tabsMode": "card",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
@ -276,7 +277,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "chrome",
|
||||
"tabsMode": "chrome",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
@ -299,7 +300,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "tiled",
|
||||
"tabsMode": "tiled",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
@ -326,7 +327,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "radio",
|
||||
"tabsMode": "radio",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
@ -349,7 +350,7 @@ order: 68
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"mode": "vertical",
|
||||
"tabsMode": "vertical",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "选项卡1",
|
||||
@ -367,6 +368,30 @@ order: 68
|
||||
}
|
||||
```
|
||||
|
||||
### 侧边栏模式
|
||||
|
||||
使用 `sidePosition` 设置标签栏位置。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "tabs",
|
||||
"tabsMode": "sidebar",
|
||||
"sidePosition": "right",
|
||||
"tabs": [
|
||||
{
|
||||
"title": "按钮",
|
||||
"body": "选项卡内容1",
|
||||
"icon": "fa fa-square"
|
||||
},
|
||||
{
|
||||
"title": "动作",
|
||||
"body": "选项卡内容2",
|
||||
"icon": "fa fa-gavel"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 配置顶部工具栏
|
||||
|
||||
@ -379,6 +404,7 @@ order: 68
|
||||
{
|
||||
"type": "button",
|
||||
"label": "按钮",
|
||||
"size": "sm",
|
||||
"actionType": "dialog",
|
||||
"dialog": {
|
||||
"title": "弹窗标题",
|
||||
@ -391,7 +417,6 @@ order: 68
|
||||
"title": "Tab 1",
|
||||
"tab": "Content 1"
|
||||
},
|
||||
|
||||
{
|
||||
"title": "Tab 2",
|
||||
"tab": "Content 2"
|
||||
@ -533,7 +558,7 @@ order: 68
|
||||
| --------------------- | --------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| type | `string` | `"tabs"` | 指定为 Tabs 渲染器 |
|
||||
| className | `string` | | 外层 Dom 的类名 |
|
||||
| mode | `string` | | 展示模式,取值可以是 `line`、`card`、`radio`、`vertical`、`chrome`、`simple`、`strong` |
|
||||
| tabsMode | `string` | | 展示模式,取值可以是 `line`、`card`、`radio`、`vertical`、`chrome`、`simple`、`strong`、`tiled`、`sidebar` |
|
||||
| tabsClassName | `string` | | Tabs Dom 的类名 |
|
||||
| tabs | `Array` | | tabs 内容 |
|
||||
| source | `string` | | tabs 关联数据,关联后可以重复生成选项卡 |
|
||||
@ -541,18 +566,22 @@ order: 68
|
||||
| toolbarClassName | `string` | | tabs 中工具栏的类名 |
|
||||
| tabs[x].title | `string` | | Tab 标题 |
|
||||
| tabs[x].icon | `icon` | | Tab 的图标 |
|
||||
| tabs[x].iconPosition | `left` / `right` | `left` | Tab 的图标位置 |
|
||||
| tabs[x].tab | [SchemaNode](../types/schemanode) | | 内容区 |
|
||||
| tabs[x].hash | `string` | | 设置以后将跟 url 的 hash 对应 |
|
||||
| tabs[x].reload | `boolean` | | 设置以后内容每次都会重新渲染,对于 crud 的重新拉取很有用 |
|
||||
| tabs[x].unmountOnExit | `boolean` | | 每次退出都会销毁当前 tab 栏内容 |
|
||||
| tabs[x].className | `string` | `"bg-white b-l b-r b-b wrapper-md"` | Tab 区域样式 |
|
||||
| tabs[x].closable | `boolean` | false | 是否支持删除,优先级高于组件的 `closable` |
|
||||
| tabs[x].disabled | `boolean` | false | 是否禁用 |
|
||||
| mountOnEnter | `boolean` | false | 只有在点中 tab 的时候才渲染 |
|
||||
| unmountOnExit | `boolean` | false | 切换 tab 的时候销毁 |
|
||||
| addable | `boolean` | false | 是否支持新增 |
|
||||
| addable | `boolean` | false | 是否支持新增 |
|
||||
| addBtnText | `string` | 增加 | 新增按钮文案 |
|
||||
| closable | `boolean` | false | 是否支持删除 |
|
||||
| draggable | `boolean` | false | 是否支持拖拽 |
|
||||
| showTip | `boolean` | false | 是否支持提示 |
|
||||
| showTipClassName | `string` | `'' ` | 提示的类 |
|
||||
| editable | `boolean` | false | 收否可编辑标签名 |
|
||||
| scrollable | `boolean` | true | 是否导航支持内容溢出滚动。(属性废弃) |
|
||||
| sidePosition | `left` / `right` | `left` | `sidebar` 模式下,标签栏位置
|
||||
|
@ -1314,6 +1314,7 @@
|
||||
--Tabs--line-content-padding: var(--gap-base) 0;
|
||||
--Tabs--line-linkMargin: 0 32px 0 0;
|
||||
--Tabs--line-linkPadding: 0 0 8px;
|
||||
--Tabs--line-addPadding: 0 0 10px;
|
||||
--Tabs--line-padding: var(--gap-md);
|
||||
--Tabs--line-onHover-borderColor: var(--primary);
|
||||
--Tabs--line-onHover-color: var(--primary);
|
||||
@ -1337,14 +1338,22 @@
|
||||
--Tabs-onActive-color: #{$gray700};
|
||||
--Tabs-onDisabled-color: #{$gray600};
|
||||
--Tabs-onHover-borderColor: #{$gray200};
|
||||
--Tabs-add-icon-size: #{px2rem(16px)};
|
||||
--Tabs-add-icon-size: #{px2rem(15px)};
|
||||
--Tabs-add-icon-padding: #{px2rem(1px)};
|
||||
--Tabs-add-icon-margin: var(--gap-xs);
|
||||
--Tabs-add-margin: var(--gap-lg);
|
||||
--Tabs-gray-color: #83868c;
|
||||
--Tabs-close-margin: #{var(--gap-xs)};
|
||||
--Tabs-close-marginTop: #{px2rem(1px)};
|
||||
--Tabs-close-size: #{px2rem(12px)};
|
||||
--Tabs-link-maxWidth: #{px2rem(160px)};
|
||||
|
||||
--Tabs--sidebar-sideWidth: #{px2rem(62px)};
|
||||
--Tabs--sidebar-sidePadding: #{px2rem(27px)};
|
||||
--Tabs--sidebar-sideMargin: 0 0 #{px2rem(22px)} 0;
|
||||
--Tabs--sidebar-iconSize: #{px2rem(24px)};
|
||||
--Tabs--sidebar-iconMargin: #{px2rem(5px)};
|
||||
|
||||
--Tabs--vertical-bg: var(--Table-thead-bg);
|
||||
--Tabs--vertical-width: #{px2rem(140px)};
|
||||
--Tabs--vertical-onActive-color: var(--primary);
|
||||
|
@ -21,7 +21,7 @@
|
||||
margin-left: var(--Tabs-add-margin);
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: var(--Tabs--line-linkPadding);
|
||||
padding: var(--Tabs--line-addPadding);
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
|
||||
@ -36,9 +36,16 @@
|
||||
margin-left: 4px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--primary);
|
||||
fill: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.#{$ns}Tabs-linksContainer {
|
||||
flex-grow: 1;
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -53,7 +60,7 @@
|
||||
// }
|
||||
|
||||
&-arrow {
|
||||
margin-bottom: 7px;
|
||||
margin: var(--Tabs--line-addPadding);
|
||||
width: 16px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
@ -89,6 +96,8 @@
|
||||
}
|
||||
|
||||
&-main {
|
||||
position: relative;
|
||||
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
width: 100%;
|
||||
@ -97,8 +106,11 @@
|
||||
}
|
||||
|
||||
.#{$ns}Tabs-links {
|
||||
position: relative;
|
||||
// position: relative;
|
||||
min-width: 100%;
|
||||
max-width: 0;
|
||||
height: 100%;
|
||||
overflow-x: hidden;
|
||||
|
||||
.#{$ns}Tabs-links-drag {
|
||||
position: absolute;
|
||||
@ -133,7 +145,9 @@
|
||||
}
|
||||
|
||||
.#{$ns}Tabs-link-close {
|
||||
margin-left: var( --Tabs-close-margin);
|
||||
margin: var(--Tabs-close-marginTop) 0 0 var(--Tabs-close-margin);
|
||||
fill: var(--Tabs-gray-color);
|
||||
cursor: pointer;
|
||||
|
||||
.#{$ns}Tabs-link-close-icon {
|
||||
width: var(--Tabs-close-size);
|
||||
@ -223,6 +237,20 @@
|
||||
&--line {
|
||||
> .#{$ns}Tabs-linksContainer-wrapper {
|
||||
border-bottom: var(--Tabs-borderWidth) solid var(--Tabs--simple-split-color);
|
||||
|
||||
&--toolbar {
|
||||
.#{$ns}Tabs-link {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.#{$ns}Tabs-addable {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.#{$ns}Tabs-linksContainer-arrow {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-linksContainer > .#{$ns}Tabs-linksContainer-arrow {
|
||||
@ -248,15 +276,22 @@
|
||||
> a:first-child {
|
||||
border-width: 0 0 var(--Tabs--line-borderWidth) 0;
|
||||
padding: var(--Tabs--line-linkPadding);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
&:hover {
|
||||
a:first-child {
|
||||
color: var(--primary);
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.#{$ns}Tabs-link-close {
|
||||
fill: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&:last-child {
|
||||
> a {
|
||||
margin: 0;
|
||||
@ -298,6 +333,10 @@
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-linksContainer {
|
||||
.#{$ns}Tabs-addable {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-linksContainer-arrow {
|
||||
padding: var(--Tabs--card-arrow-gap) var(--Tabs--card-add-gap) 0;
|
||||
margin-bottom: 0;
|
||||
@ -335,6 +374,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-toolbar {
|
||||
padding: var(--Tabs--card-padding);
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-content {
|
||||
@ -346,7 +390,7 @@
|
||||
> .#{$ns}Tabs-linksContainer-wrapper {
|
||||
margin-bottom: px2rem(10px);
|
||||
|
||||
> .#{$ns}Tabs-addable {
|
||||
.#{$ns}Tabs-addable {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@ -446,7 +490,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-addable {
|
||||
.#{$ns}Tabs-addable {
|
||||
padding: 0 var(--Tabs--tiled-add-gap);
|
||||
margin-left: 0;
|
||||
white-space: nowrap;
|
||||
@ -558,6 +602,82 @@
|
||||
}
|
||||
}
|
||||
|
||||
&--sidebar {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
&.sidebar--left {
|
||||
flex-direction: row;
|
||||
|
||||
> .#{$ns}Tabs-content {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
&.sidebar--right {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
> .#{$ns}Tabs-content {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-linksWrapper {
|
||||
flex: 0 0 var(--Tabs--sidebar-sideWidth);
|
||||
align-items: flex-start;
|
||||
border: none;
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-linksWrapper > .#{$ns}Tabs-links {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding-top: var(--Tabs--sidebar-sidePadding);
|
||||
flex-grow: 1;
|
||||
border: none;
|
||||
flex-direction: column;
|
||||
border: 0;
|
||||
|
||||
> li {
|
||||
display: flex;
|
||||
margin: var(--Tabs--sidebar-sideMargin);
|
||||
padding: 0;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
border: 0;
|
||||
|
||||
> a:first-child {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: var(--Tabs-gray-color);
|
||||
|
||||
.#{$ns}Icon {
|
||||
font-size: var(--Tabs--sidebar-iconSize);
|
||||
height: var(--Tabs--sidebar-iconSize);
|
||||
margin-bottom: var(--Tabs--sidebar-iconMargin);
|
||||
}
|
||||
}
|
||||
&.is-active > a:first-child,
|
||||
> a:first-child:hover,
|
||||
> a:first-child:focus {
|
||||
color: var(--Tabs--sidebar-iconColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .#{$ns}Tabs-content {
|
||||
flex-grow: 1;
|
||||
border-bottom: none;
|
||||
|
||||
> .#{$ns}Tabs-pane {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--chrome {
|
||||
> .#{$ns}Tabs-linksWrapper {
|
||||
background: var(--Tabs--chrome-bg);
|
||||
@ -672,7 +792,7 @@
|
||||
& > .#{$ns}Tabs-linksContainer-wrapper {
|
||||
border-bottom: none;
|
||||
|
||||
& > .#{$ns}Tabs-addable {
|
||||
.#{$ns}Tabs-addable {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@ -718,6 +838,10 @@
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .#{$ns}Tabs-link-close {
|
||||
fill: var(--primary);
|
||||
}
|
||||
|
||||
& > a:first-child {
|
||||
padding: 0;
|
||||
@ -743,7 +867,7 @@
|
||||
align-items: stretch;
|
||||
border-bottom: var(--Tabs-borderWidth) solid var(--Tabs--simple-split-color);
|
||||
|
||||
& > .#{$ns}Tabs-addable {
|
||||
.#{$ns}Tabs-addable {
|
||||
width: var(--Tabs--strong-add-size);
|
||||
margin-left: var(--Tabs--card-arrow-gap);
|
||||
padding: 0;
|
||||
@ -824,6 +948,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .#{$ns}Tabs-link-close {
|
||||
fill: var(--primary);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
@ -839,8 +967,12 @@
|
||||
}
|
||||
|
||||
&-toolbar {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
padding-top: var(--gap-xs);
|
||||
// display: inline-block;
|
||||
// float: right;
|
||||
// padding-top: var(--gap-xs);
|
||||
margin-left: var(--gap-base);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
@ -504,6 +504,7 @@ $L1: 0px 4px 6px 0px rgba(8, 14, 26, 0.06),
|
||||
|
||||
// Tabs
|
||||
--Tabs-linkFontSize: #{px2rem(14px)};
|
||||
--Tabs-link-disabled-color: #{$G6};
|
||||
--Tabs--card-onActive-borderColor: var(--white);
|
||||
--Tabs--card-bg: var(--Table-thead-bg);
|
||||
--Tabs--radio-bg: var(--white);
|
||||
@ -511,7 +512,7 @@ $L1: 0px 4px 6px 0px rgba(8, 14, 26, 0.06),
|
||||
--Tabs--chrome-bg: #f5f5f5;
|
||||
--Tabs--simple-split-color: #{$G9};
|
||||
--Tabs--simple-split-size: var(--gap-xs) var(--gap-md);
|
||||
--Tabs-link-disabled-color: #{$G6};
|
||||
--Tabs--sidebar-iconColor: #{$B6};
|
||||
|
||||
// Pagination
|
||||
--Pagination-fontSize: #{px2rem(12px)};
|
||||
|
@ -16,6 +16,7 @@ import {Icon} from './icons';
|
||||
import debounce from 'lodash/debounce';
|
||||
import {findDOMNode} from 'react-dom';
|
||||
import TooltipWrapper, {TooltipObject, Trigger} from './TooltipWrapper';
|
||||
import {resizeSensor} from '../utils/resize-sensor';
|
||||
|
||||
import Sortable from 'sortablejs';
|
||||
|
||||
@ -26,7 +27,7 @@ const transitionStyles: {
|
||||
[ENTERED]: 'in'
|
||||
};
|
||||
|
||||
export type TabsMode = '' | 'line' | 'card' | 'radio' | 'vertical' | 'chrome' | 'simple' | 'strong';
|
||||
export type TabsMode = '' | 'line' | 'card' | 'radio' | 'vertical' | 'chrome' | 'simple' | 'strong' | 'tiled' |'sidebar';
|
||||
|
||||
export interface TabProps extends ThemeProps {
|
||||
title?: string | React.ReactNode; // 标题
|
||||
@ -114,6 +115,8 @@ export interface TabsProps extends ThemeProps {
|
||||
scrollable?: boolean; // 属性废弃,为了兼容暂且保留
|
||||
editable?: boolean;
|
||||
onEdit?: (index: number, text: string) => void;
|
||||
sidePosition?: 'left' | 'right';
|
||||
addBtnText?: string;
|
||||
}
|
||||
|
||||
export interface IDragInfo {
|
||||
@ -122,21 +125,25 @@ export interface IDragInfo {
|
||||
|
||||
export class Tabs extends React.Component<TabsProps, any> {
|
||||
static defaultProps: Pick<TabsProps,
|
||||
'mode' | 'contentClassName' | 'showTip' | 'showTipClassName'
|
||||
'mode' | 'contentClassName' | 'showTip' | 'showTipClassName' | 'sidePosition' | 'addBtnText'
|
||||
> = {
|
||||
mode: '',
|
||||
contentClassName: '',
|
||||
showTip: false,
|
||||
showTipClassName: ''
|
||||
showTipClassName: '',
|
||||
sidePosition: 'left',
|
||||
addBtnText: '增加'
|
||||
};
|
||||
|
||||
static Tab = Tab;
|
||||
navMain = React.createRef<HTMLDivElement>();
|
||||
navMain = React.createRef<HTMLUListElement>(); // HTMLDivElement
|
||||
scroll: boolean = false;
|
||||
sortable?: Sortable;
|
||||
dragTip?: HTMLElement;
|
||||
id: string = guid();
|
||||
draging: boolean = false;
|
||||
toDispose: Array<() => void> = [];
|
||||
resizeDom = React.createRef<HTMLDivElement>();
|
||||
|
||||
checkArrowStatus = debounce(
|
||||
() => {
|
||||
@ -200,6 +207,12 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
});
|
||||
this.checkArrowStatus();
|
||||
}
|
||||
|
||||
this.resizeDom?.current && this.toDispose.push(
|
||||
resizeSensor(this.resizeDom.current as HTMLElement, () =>
|
||||
this.computedWidth()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
@ -212,6 +225,8 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
|
||||
componentWillUnmount() {
|
||||
this.checkArrowStatus.cancel();
|
||||
this.toDispose.forEach(fn => fn());
|
||||
this.toDispose = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,7 +235,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
computedWidth() {
|
||||
const {mode: dMode, tabsMode} = this.props;
|
||||
const mode = tabsMode || dMode;
|
||||
if (mode === 'vertical') {
|
||||
if (['vertical', 'sidebar'].includes(mode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -246,7 +261,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
const {mode: dMode, tabsMode} = this.props;
|
||||
const {isOverflow} = this.state;
|
||||
const mode = tabsMode || dMode;
|
||||
if (mode === 'vertical' || !isOverflow) {
|
||||
if (['vertical', 'sidebar'].includes(mode) || !isOverflow) {
|
||||
return;
|
||||
}
|
||||
const {activeKey, children} = this.props;
|
||||
@ -254,7 +269,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
const currentIndex = (children as any[])?.findIndex(
|
||||
(item: any) => item.props.eventKey === currentKey
|
||||
);
|
||||
const li = this.navMain.current?.children[0]?.children || [];
|
||||
const li = this.navMain.current?.children || [];
|
||||
const currentLi = li[currentIndex] as HTMLElement;
|
||||
const liOffsetLeft = currentLi?.offsetLeft;
|
||||
const liClientWidth = currentLi?.clientWidth;
|
||||
@ -569,7 +584,7 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
renderArrow(type: 'left' | 'right') {
|
||||
const {mode: dMode, tabsMode} = this.props;
|
||||
const mode = tabsMode || dMode;
|
||||
if (mode === 'vertical') {
|
||||
if (['vertical', 'sidebar'].includes(mode)) {
|
||||
return;
|
||||
}
|
||||
const {classnames: cx} = this.props;
|
||||
@ -607,7 +622,9 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
toolbar,
|
||||
linksClassName,
|
||||
addable,
|
||||
draggable
|
||||
draggable,
|
||||
sidePosition,
|
||||
addBtnText
|
||||
} = this.props;
|
||||
|
||||
const {isOverflow} = this.state;
|
||||
@ -617,19 +634,35 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
|
||||
const mode = tabsMode || dMode;
|
||||
|
||||
const toolButtons = (
|
||||
<>
|
||||
{addable && (
|
||||
<div className={cx('Tabs-addable')} onClick={() => this.handleAddBtn()}>
|
||||
<Icon icon="plus" className={cx('Tabs-addable-icon')} />
|
||||
{addBtnText}
|
||||
</div>
|
||||
)}
|
||||
{toolbar}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
`Tabs`,
|
||||
{
|
||||
[`Tabs--${mode}`]: mode
|
||||
[`Tabs--${mode}`]: mode,
|
||||
[`sidebar--${sidePosition}`]: mode === 'sidebar'
|
||||
},
|
||||
className
|
||||
)}
|
||||
>
|
||||
{
|
||||
!['vertical', 'chrome'].includes(mode) ? (
|
||||
<div className={cx('Tabs-linksContainer-wrapper')}>
|
||||
!['vertical', 'sidebar', 'chrome'].includes(mode) ? (
|
||||
<div
|
||||
className={cx('Tabs-linksContainer-wrapper', toolbar && 'Tabs-linksContainer-wrapper--toolbar')}
|
||||
ref={this.resizeDom}
|
||||
>
|
||||
<div
|
||||
className={cx(
|
||||
'Tabs-linksContainer',
|
||||
@ -637,22 +670,19 @@ export class Tabs extends React.Component<TabsProps, any> {
|
||||
)}
|
||||
>
|
||||
{this.renderArrow('left')}
|
||||
<div className={cx('Tabs-linksContainer-main')} ref={this.navMain}>
|
||||
<ul className={cx('Tabs-links', linksClassName)} role="tablist">
|
||||
<div className={cx('Tabs-linksContainer-main')}>
|
||||
<ul className={cx('Tabs-links', linksClassName)} role="tablist" ref={this.navMain}>
|
||||
{children.map((tab, index) => this.renderNav(tab, index))}
|
||||
{additionBtns}
|
||||
{toolbar}
|
||||
{
|
||||
!isOverflow && toolButtons
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
{this.renderArrow('right')}
|
||||
</div>
|
||||
{
|
||||
addable && (
|
||||
<div className={cx('Tabs-addable')} onClick={() => this.handleAddBtn()}>
|
||||
<Icon icon="plus" className={cx('Tabs-addable-icon')} />
|
||||
增加
|
||||
</div>
|
||||
)
|
||||
isOverflow && toolButtons
|
||||
}
|
||||
</div>
|
||||
) : (
|
||||
|
@ -89,9 +89,9 @@ export interface TabSchema extends Omit<BaseSchema, 'type'> {
|
||||
*/
|
||||
horizontal?: FormSchemaHorizontal;
|
||||
/**
|
||||
* 是否可关闭,优先级高于 tabs 的 closeable
|
||||
* 是否可关闭,优先级高于 tabs 的 closable
|
||||
*/
|
||||
closeable?: boolean;
|
||||
closable?: boolean;
|
||||
/**
|
||||
* 是否禁用
|
||||
*/
|
||||
@ -186,6 +186,14 @@ export interface TabsSchema extends BaseSchema {
|
||||
* 是否导航支持内容溢出滚动。属性废弃,为了兼容暂且保留
|
||||
*/
|
||||
scrollable?: boolean;
|
||||
/**
|
||||
* 编辑器模式,侧边的位置
|
||||
*/
|
||||
sidePosition?: 'left' | 'right';
|
||||
/**
|
||||
* 自定义增加按钮文案
|
||||
*/
|
||||
addBtnText?: string;
|
||||
}
|
||||
|
||||
export interface TabsProps
|
||||
@ -643,7 +651,9 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
||||
draggable,
|
||||
showTip,
|
||||
showTipClassName,
|
||||
editable
|
||||
editable,
|
||||
sidePosition,
|
||||
addBtnText
|
||||
} = this.props;
|
||||
|
||||
const mode = tabsMode || dMode;
|
||||
@ -747,6 +757,8 @@ export default class Tabs extends React.Component<TabsProps, TabsState> {
|
||||
showTipClassName={showTipClassName}
|
||||
editable={editable}
|
||||
onEdit={this.handleEdit}
|
||||
sidePosition={sidePosition}
|
||||
addBtnText={addBtnText}
|
||||
>
|
||||
{children}
|
||||
</CTabs>
|
||||
|
Loading…
Reference in New Issue
Block a user