Skip to content

Commit

Permalink
fix: Modify the implementation of slashes & support dropdownProps set…
Browse files Browse the repository at this point in the history
…tings
  • Loading branch information
YyumeiZhang committed Aug 26, 2024
1 parent 8af4471 commit b092971
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 24 deletions.
43 changes: 41 additions & 2 deletions content/navigation/tabs/index-en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Tabs, TabPane } from '@douyinfe/semi-ui';

### Basic Usage

Tbs supports three types of styles: `line`, `button`, and `card`. By default, the first tab is selected.
Tbs supports three types of styles: `line`, `button`, `card`, and `slash`. By default, the first tab is selected.

Tabs supports two declare ways, and the rendering process of the two is different:

Expand Down Expand Up @@ -168,6 +168,44 @@ class TabDemo extends React.Component {
}
```
```jsx live=true
import React from 'react';
import { Tabs } from '@douyinfe/semi-ui';

class TabDemo extends React.Component {
constructor() {
super();
this.state = { key: '1' };
this.onTabClick = this.onTabClick.bind(this);
}

onTabClick(key, type) {
this.setState({ [type]: key });
}

render() {
// eslint-disable-next-line react/jsx-key
const contentList = [<div>Document</div>, <div>Quick Start</div>, <div>Help</div>];
const tabList = [
{ tab: 'Document', itemKey: '1' },
{ tab: 'Quick Start', itemKey: '2' },
{ tab: 'Help', itemKey: '3' },
];
return (
<Tabs
type="slash"
tabList={tabList}
onChange={key => {
this.onTabClick(key, 'key');
}}
>
{contentList[this.state.key - 1]}
</Tabs>
);
}
}
```
### With Icon
```jsx live=true
Expand Down Expand Up @@ -274,7 +312,7 @@ function Demo() {
### Vertical mode
Support two positions: `tabPosition='left|top'`
When `type` is `line`, `card`, or `button`, horizontal and vertical modes are supported, `tabPosition='left|top'`,default is top. When `type` is `slash`, only horizontal mode is supported.
```jsx live=true
import React from 'react';
Expand Down Expand Up @@ -703,6 +741,7 @@ class App extends React.Component {
| activeKey | The itemKey value of the currently active tab page | string | None |
| className | class name | string | None |
| collapsible | collapsed Tabs, **>=1.1.0** | boolean | false |
| dropdownProps | In collapsible mode, It is used to transparently transmit parameters to the Dropdown component of the drop-down menu, support since 2.65.0 | DropDownProps | { start: DropdownProps, end: DropdownProps } |
| visibleTabsStyle | Overall scrolling area style **>=2.61.0** | style: CSSProperties | None |
| contentStyle | The outer style object of the content area | CSSProperties | None |
| defaultActiveKey | Initialize the key value of the selected tab page | string | '1' |
Expand Down
45 changes: 42 additions & 3 deletions content/navigation/tabs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { Tabs, TabPane } from '@douyinfe/semi-ui';

### 基本用法

标签栏支持三种样式的显示:线条式,按钮式,卡片式。默认选中第一项。
标签栏支持三种样式的显示:线条式,按钮式,卡片式,斜线式。默认选中第一项。
标签页支持两种传入方式,两者渲染流程上有所区别:

- 通过 `tabList` 传入标签页对象的数组,当使用 `tabList` 时每次只渲染当前传入的节点
Expand Down Expand Up @@ -153,6 +153,44 @@ class TabDemo extends React.Component {
}
```

```jsx live=true
import React from 'react';
import { Tabs } from '@douyinfe/semi-ui';

class TabDemo extends React.Component {
constructor() {
super();
this.state = { key: '1' };
this.onTabClick = this.onTabClick.bind(this);
}

onTabClick(key, type) {
this.setState({ [type]: key });
}

render() {
// eslint-disable-next-line react/jsx-key
const contentList = [<div>文档</div>, <div>快速起步</div>, <div>帮助</div>];
const tabList = [
{ tab: '文档', itemKey: '1' },
{ tab: '快速起步', itemKey: '2' },
{ tab: '帮助', itemKey: '3' },
];
return (
<Tabs
type="slash"
tabList={tabList}
onChange={key => {
this.onTabClick(key, 'key');
}}
>
{contentList[this.state.key - 1]}
</Tabs>
);
}
}
```

### 带图标的

有图标的标签栏。
Expand Down Expand Up @@ -257,7 +295,7 @@ function Demo() {

### 垂直的标签栏

支持水平和垂直两种模式, `tabPosition='left|top'`
`type``line`, `card`, `button` 支持水平和垂直两种模式,`tabPosition='left|top'`, 默认为 `top``type``slash` 仅支持水平模式,无需设置。

```jsx live=true
import React from 'react';
Expand Down Expand Up @@ -720,6 +758,7 @@ class App extends React.Component {
| arrowPosition | 折叠模式下,左右切换箭头渲染位置 **>=2.61.0** | "start" "end" "both" ||
| className | 类名 | string ||
| collapsible | 折叠的 Tabs,**>=1.1.0** | boolean | false |
| dropdownProps | 用于在折叠模式下透传参数到下拉菜单的 Dropdown 组件 | { start: DropdownProps, end: DropdownProps } ||
| visibleTabsStyle | 整体滚动区域 Style **>=2.61.0** | style: CSSProperties ||
| contentStyle | 内容区域外层样式对象 | CSSProperties ||
| defaultActiveKey | 初始化选中的 tab 页的 key 值 | string | '1' |
Expand All @@ -736,7 +775,7 @@ class App extends React.Component {
| tabList | 标签页对象组成的数组,该对象支持 itemKey(对应 activeKey,tab(标签页文字)及 icon(标签页图标) | TabPane[] ||
| tabPaneMotion | 是否使用动画切换 tabs | boolean | true |
| tabPosition | tab 的位置,支持`top`(水平), `left`(垂直) | string | `top` |
| type | 标签栏的样式,可选`line``card``button` | string | `line` |
| type | 标签栏的样式,可选`line``card``button``slash` | string | `line` |
| onChange | 切换 tab 页时的回调函数 | function(activeKey: string) ||
| onTabClick | 单击事件 | function(key: string, e: Event) ||
| onTabClose | 关闭 tab 页时的回调函数 **>=2.1.0** | function(tabKey: string) ||
Expand Down
14 changes: 11 additions & 3 deletions packages/semi-foundation/tabs/tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -608,10 +608,18 @@ $ignoreIcon: '.#{$prefix}-icon-checkbox_tick, .#{$prefix}-icon-radio, .#{$prefix
margin-right: $spacing-tabs_bar_slash-marginRight;

&:after {
content: "/";
font-weight: $font-tabs_tab_slash_line-fontWeight;
content: "";
margin-left: $spacing-tabs_bar_slash_line_marginLeft;
color: $color-tabs_tab_slash_line;
display: inline-block;
height: $height-tabs_tab_slash_line;
width: $width-tabs_tab_slash_line;
margin-top: $spacing-tabs_bar_slash_line_marginTop;
margin-bottom: $spacing-tabs_bar_slash_line_marginBottom;
vertical-align: bottom;
// Get diagonal slash
background: linear-gradient(to bottom right, transparent 0%,
transparent calc(50% - 1px), $color-tabs_tab_slash_line 50%,
transparent calc(50% + 1px), transparent 100%);
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions packages/semi-foundation/tabs/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ $color-tabs_tab-pane_arrow_disabled-bg-hover: transparent;
$color-tabs_tab-pane_arrow_disabled-text-default: var(--semi-color-disabled-text);
$color-tabs_tab-pane_arrow_disabled-text-hover: var(--semi-color-disabled-text);

$color-tabs_tab_slash_line: var(--semi-color-text-2); //斜线式页签分割线字体颜色
$font-tabs_tab_slash_line-fontWeight: $font-weight-regular; //斜线式页签分割线字重
$color-tabs_tab_slash_line: var(--semi-color-text-2); //斜线式页签分割线颜色

$font-tabs_tab-fontWeight: $font-weight-regular; // 页签文本字重 - 默认
$font-tabs_tab_active-fontWeight: $font-weight-bold; // 页签文本字重 - 选中
Expand All @@ -82,6 +81,9 @@ $width-tabs-outline-offset: -2px; // 聚焦轮廓偏移宽度
$width-tabs_bar_line-outline-offset: -1px; // 线条式页签聚焦轮廓偏移宽度
$width-tabs_tab-pane_arrow-border:0px; // 滚动折叠箭头边框宽度

$width-tabs_tab_slash_line: 8px; // 斜线式页签分割线宽度
$height-tabs_tab_slash_line: 14px; // 斜线式页签分割线高度

$height-tabs_bar_extra_large: 50px; // 大尺寸页签高度
$font-tabs_bar_extra_large-lineHeight: $height-tabs_bar_extra_large; // 大尺寸页签文字行高

Expand Down Expand Up @@ -125,6 +127,8 @@ $spacing-tabs_bar_slash_tab-paddingY: 12px; // 斜线式页签上下内边距
$spacing-tabs_bar_slash_tab-paddingX: 0px; // 斜线式页签水平内边距
$spacing-tabs_bar_slash-marginRight: 16px; // 斜线式页签右侧外边距
$spacing-tabs_bar_slash_line_marginLeft: 16px; // 斜线式页签斜线左侧外边距
$spacing-tabs_bar_slash_line_marginTop: 3px; // 斜线式页签斜线顶部外边距
$spacing-tabs_bar_slash_line_marginBottom: 3px; // 斜线式页签斜线底部外边距

$spacing-tabs_content-paddingY: 5px; // 页签内容区垂直方向内边距
$spacing-tabs_content-paddingX: 0; // 页签内容区水平方向内边距
Expand Down
5 changes: 4 additions & 1 deletion packages/semi-ui/tabs/TabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
</div>
);
}
const { dropdownClassName, dropdownStyle, showRestInDropdown } = this.props;
const { dropdownClassName, dropdownStyle, showRestInDropdown, dropdownProps } = this.props;
const { rePosKey } = this.state;
const disabled = !items.length;
const menu = (
Expand Down Expand Up @@ -197,6 +197,8 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
[`${cssClasses.TABS_BAR}-dropdown`]: true,
});

const customDropdownProps = dropdownProps?.[pos] ?? {};

return (
<>
{showRestInDropdown ? (
Expand All @@ -211,6 +213,7 @@ class TabBar extends React.Component<TabBarProps, TabBarState> {
style={dropdownStyle}
trigger={'hover'}
disableFocusListener // prevent the panel from popping up again after clicking
{...customDropdownProps}
>
{button}
</Dropdown>
Expand Down
16 changes: 7 additions & 9 deletions packages/semi-ui/tabs/_story/tabs.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ Level2Card.story = {
export const SlashTab = () => {
return (
<>
<Tabs defaultActiveKey="1" type="slash" >
<Tabs defaultActiveKey="1" type="slash">
<TabPane tab="文档" itemKey="1">文档</TabPane>
<TabPane tab="快速起步" itemKey="2" disabled>快速起步</TabPane>
<TabPane tab="帮助" itemKey="3">帮助</TabPane>
Expand All @@ -376,16 +376,14 @@ export const SlashTab = () => {
<br />
<br />
<Tabs defaultActiveKey="1" type="slash">
<TabPane tab="文档" itemKey="1">文档</TabPane>
<TabPane tab="快速起步" itemKey="2" disabled>快速起步</TabPane>
<TabPane tab="帮助" itemKey="3">帮助</TabPane>
<TabPane tab="关于" itemKey="4">关于</TabPane>
<TabPane tab="资源工具" itemKey="5">资源工具</TabPane>
<TabPane tab={<span><IconFile />文档</span>} itemKey="1">文档</TabPane>
<TabPane tab={<span><IconGlobe />快速起步</span>} itemKey="2" disabled>快速起步</TabPane>
<TabPane tab={<span><IconHelpCircle />帮助</span>} itemKey="3">帮助</TabPane>
</Tabs>
<br />
<Tabs style={{ width: '400px'}} type="slash" collapsible>
{['文档', "快速起步", "帮助", "关于", "资源工具"].map((i, index) => (
<TabPane tab={`tab-${index}`} itemKey={i} key={i} >
<Tabs style={{ width: '400px'}} type="slash" collapsible dropdownProps={{ start: { showTick: false}, end: { showTick: false}}}>
{['文档', "快速起步", "帮助", "关于", "资源工具", "主页"].map((i, index) => (
<TabPane tab={i} itemKey={i} key={i} >
Content of card tab {i}
</TabPane>
))}
Expand Down
5 changes: 4 additions & 1 deletion packages/semi-ui/tabs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
more: PropTypes.oneOfType([PropTypes.number, PropTypes.object]),
arrowPosition: PropTypes.string,
renderArrow: PropTypes.func,
dropdownProps: PropTypes.object,
};
static __SemiComponentName__ = "Tabs";
static defaultProps: TabsProps = getDefaultPropsFromGlobalConfig(Tabs.__SemiComponentName__, {
Expand Down Expand Up @@ -265,6 +266,7 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
visibleTabsStyle,
arrowPosition,
renderArrow,
dropdownProps,
...restProps
} = this.props;
const { panes, activeKey } = this.state;
Expand Down Expand Up @@ -296,7 +298,8 @@ class Tabs extends BaseComponent<TabsProps, TabsState> {
onVisibleTabsChange,
visibleTabsStyle,
arrowPosition,
renderArrow
renderArrow,
dropdownProps,
} as TabBarProps;

const tabBar = renderTabBar ? renderTabBar(tabBarProps, TabBar) : <TabBar {...tabBarProps} />;
Expand Down
11 changes: 8 additions & 3 deletions packages/semi-ui/tabs/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export interface PlainTab {
closable?: boolean
}

interface TabsDropDownProps {
start: DropdownProps;
end: DropdownProps
}

export interface TabsProps {
activeKey?: string;
Expand Down Expand Up @@ -45,7 +49,8 @@ export interface TabsProps {
onVisibleTabsChange?: TabBarProps["onVisibleTabsChange"];
visibleTabsStyle?: TabBarProps['visibleTabsStyle'];
arrowPosition?: TabBarProps['arrowPosition'];
renderArrow?: TabBarProps['renderArrow']
renderArrow?: TabBarProps['renderArrow'];
dropdownProps?: TabsDropDownProps
}

export interface TabBarProps {
Expand All @@ -69,8 +74,8 @@ export interface TabBarProps {
onVisibleTabsChange?: (visibleState: Map<string, boolean>) => void;
visibleTabsStyle?: CSSProperties;
arrowPosition?: OverflowListProps['overflowRenderDirection'];
renderArrow?: (items: OverflowItem[], pos: "start"|"end", handleArrowClick: () => void, defaultNode: ReactNode) => ReactNode

renderArrow?: (items: OverflowItem[], pos: "start"|"end", handleArrowClick: () => void, defaultNode: ReactNode) => ReactNode;
dropdownProps?: TabsDropDownProps
}

export interface TabPaneProps {
Expand Down

0 comments on commit b092971

Please sign in to comment.