feat: Tabs support indicatorAlign prop (#46308)

* feat: Tabs support indicatorPosition prop

* update demo

* Update components/tabs/demo/custom-indicator.tsx

Co-authored-by: 红 <wxh1220@gmail.com>
Signed-off-by: lijianan <574980606@qq.com>

* update demo

---------

Signed-off-by: lijianan <574980606@qq.com>
Co-authored-by: 红 <wxh1220@gmail.com>
This commit is contained in:
lijianan 2023-12-08 20:14:39 +08:00 committed by GitHub
parent 1aa5bc1d68
commit 7b771c5db2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 344 additions and 222 deletions

View File

@ -1992,142 +1992,196 @@ exports[`renders components/tabs/demo/custom-add-trigger.tsx extend context corr
exports[`renders components/tabs/demo/custom-add-trigger.tsx extend context correctly 2`] = `[]`;
exports[`renders components/tabs/demo/custom-indicator.tsx extend context correctly 1`] = `
<div
class="ant-tabs ant-tabs-top"
>
Array [
<div
class="ant-tabs-nav"
role="tablist"
class="ant-segmented"
style="margin-bottom: 8px;"
>
<div
class="ant-tabs-nav-wrap"
class="ant-segmented-group"
>
<div
class="ant-tabs-nav-list"
style="transform: translate(0px, 0px);"
<label
class="ant-segmented-item"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="1"
>
<div
aria-controls="rc-tabs-test-panel-1"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-1"
role="tab"
tabindex="0"
>
Tab 1
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="2"
>
<div
aria-controls="rc-tabs-test-panel-2"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-2"
role="tab"
tabindex="0"
>
Tab 2
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="3"
>
<div
aria-controls="rc-tabs-test-panel-3"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-3"
role="tab"
tabindex="0"
>
Tab 3
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
<input
class="ant-segmented-item-input"
type="radio"
/>
</div>
<div
class="ant-segmented-item-label"
title="start"
>
start
</div>
</label>
<label
class="ant-segmented-item ant-segmented-item-selected"
>
<input
checked=""
class="ant-segmented-item-input"
type="radio"
/>
<div
class="ant-segmented-item-label"
title="center"
>
center
</div>
</label>
<label
class="ant-segmented-item"
>
<input
class="ant-segmented-item-input"
type="radio"
/>
<div
class="ant-segmented-item-label"
title="end"
>
end
</div>
</label>
</div>
</div>,
<div
class="ant-tabs ant-tabs-top"
>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
class="ant-tabs-nav"
role="tablist"
>
<button
aria-controls="rc-tabs-test-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="rc-tabs-test-more"
style="visibility: hidden; order: 1;"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
<div
class="ant-tabs-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-tabs-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
class="ant-tabs-nav-wrap"
>
<ul
aria-label="expanded dropdown"
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
data-menu-list="true"
id="rc-tabs-test-more-popup"
role="listbox"
tabindex="-1"
/>
<div
class="ant-tabs-nav-list"
style="transform: translate(0px, 0px);"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="1"
>
<div
aria-controls="rc-tabs-test-panel-1"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-1"
role="tab"
tabindex="0"
>
Tab 1
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="2"
>
<div
aria-controls="rc-tabs-test-panel-2"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-2"
role="tab"
tabindex="0"
>
Tab 2
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="3"
>
<div
aria-controls="rc-tabs-test-panel-3"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-3"
role="tab"
tabindex="0"
>
Tab 3
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="rc-tabs-test-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
style="display: none;"
/>
class="ant-tabs-nav-more"
id="rc-tabs-test-more"
style="visibility: hidden; order: 1;"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
<div
class="ant-tabs-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-tabs-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
aria-label="expanded dropdown"
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
data-menu-list="true"
id="rc-tabs-test-more-popup"
role="listbox"
tabindex="-1"
/>
<div
aria-hidden="true"
style="display: none;"
/>
</div>
</div>
</div>
</div>
<div
class="ant-tabs-content-holder"
>
<div
class="ant-tabs-content ant-tabs-content-top"
class="ant-tabs-content-holder"
>
<div
aria-hidden="false"
aria-labelledby="rc-tabs-test-tab-1"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
id="rc-tabs-test-panel-1"
role="tabpanel"
tabindex="0"
class="ant-tabs-content ant-tabs-content-top"
>
Content of Tab Pane 1
<div
aria-hidden="false"
aria-labelledby="rc-tabs-test-tab-1"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
id="rc-tabs-test-panel-1"
role="tabpanel"
tabindex="0"
>
Content of Tab Pane 1
</div>
</div>
</div>
</div>
</div>
</div>,
]
`;
exports[`renders components/tabs/demo/custom-indicator.tsx extend context correctly 2`] = `[]`;

View File

@ -1661,117 +1661,171 @@ exports[`renders components/tabs/demo/custom-add-trigger.tsx correctly 1`] = `
`;
exports[`renders components/tabs/demo/custom-indicator.tsx correctly 1`] = `
<div
class="ant-tabs ant-tabs-top"
>
Array [
<div
class="ant-tabs-nav"
role="tablist"
class="ant-segmented"
style="margin-bottom:8px"
>
<div
class="ant-tabs-nav-wrap"
class="ant-segmented-group"
>
<div
class="ant-tabs-nav-list"
style="transform:translate(0px, 0px)"
<label
class="ant-segmented-item"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="1"
>
<div
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 1
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="2"
>
<div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 2
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="3"
>
<div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 3
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
<input
class="ant-segmented-item-input"
type="radio"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="null-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="null-more"
style="visibility:hidden;order:1"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
<div
class="ant-segmented-item-label"
title="start"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
start
</div>
</label>
<label
class="ant-segmented-item ant-segmented-item-selected"
>
<input
checked=""
class="ant-segmented-item-input"
type="radio"
/>
<div
class="ant-segmented-item-label"
title="center"
>
center
</div>
</label>
<label
class="ant-segmented-item"
>
<input
class="ant-segmented-item-input"
type="radio"
/>
<div
class="ant-segmented-item-label"
title="end"
>
end
</div>
</label>
</div>
</div>
</div>,
<div
class="ant-tabs-content-holder"
class="ant-tabs ant-tabs-top"
>
<div
class="ant-tabs-content ant-tabs-content-top"
class="ant-tabs-nav"
role="tablist"
>
<div
aria-hidden="false"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
role="tabpanel"
tabindex="0"
class="ant-tabs-nav-wrap"
>
Content of Tab Pane 1
<div
class="ant-tabs-nav-list"
style="transform:translate(0px, 0px)"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="1"
>
<div
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 1
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="2"
>
<div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 2
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="3"
>
<div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 3
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="null-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="null-more"
style="visibility:hidden;order:1"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
</div>
</div>
</div>
</div>
<div
class="ant-tabs-content-holder"
>
<div
class="ant-tabs-content ant-tabs-content-top"
>
<div
aria-hidden="false"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
role="tabpanel"
tabindex="0"
>
Content of Tab Pane 1
</div>
</div>
</div>
</div>,
]
`;
exports[`renders components/tabs/demo/custom-tab-bar.tsx correctly 1`] = `

View File

@ -1,7 +1,7 @@
## zh-CN
自定义指示器宽度
自定义指示器宽度和对齐方式。
## en-US
Custom indicator size
Custom indicator size and align.

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Tabs } from 'antd';
import { Segmented, Tabs } from 'antd';
import type { TabsProps } from 'antd';
const onChange = (key: string) => {
@ -24,13 +24,25 @@ const items: TabsProps['items'] = [
},
];
const App: React.FC = () => (
<Tabs
defaultActiveKey="1"
items={items}
onChange={onChange}
indicatorSize={(origin) => origin - 16}
/>
);
const App: React.FC = () => {
const [align, setAlign] = React.useState<TabsProps['indicatorAlign']>('center');
return (
<>
<Segmented
defaultValue="center"
style={{ marginBottom: 8 }}
onChange={(value) => setAlign(value as TabsProps['indicatorAlign'])}
options={['start', 'center', 'end']}
/>
<Tabs
defaultActiveKey="1"
items={items}
onChange={onChange}
indicatorSize={(origin) => origin - 20}
indicatorAlign={align}
/>
</>
);
};
export default App;

View File

@ -53,6 +53,7 @@ Common props ref[Common props](/docs/react/common-props)
| centered | Centers tabs | boolean | false | 4.4.0 |
| defaultActiveKey | Initial active TabPane's key, if `activeKey` is not set | string | - | |
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | false | |
| indicatorAlign | Customize align of indicator | `start` \| `center` \| `end` | `center` | 5.13.0 |
| indicatorSize | Customize length of indicator, which is the same as tab by default | number \| (origin: number) => number | - | 5.9.0 |
| items | Configure tab content | [TabItemType](#tabitemtype) | [] | 4.23.0 |
| moreIcon | The custom icon of ellipsis | ReactNode | &lt;EllipsisOutlined /> | 4.14.0 |

View File

@ -55,6 +55,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| centered | 标签居中展示 | boolean | false | 4.4.0 |
| defaultActiveKey | 初始化选中面板的 key如果没有设置 activeKey | string | `第一个面板` | |
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | |
| indicatorAlign | 自定义指示条对齐方式 | `start` \| `center` \| `end` | `center` | 5.13.0 |
| indicatorSize | 自定义指示条长度,默认与 tab 等宽 | number \| (origin: number) => number | - | 5.9.0 |
| items | 配置选项卡内容 | [TabItemType](#tabitemtype) | [] | 4.23.0 |
| moreIcon | 自定义折叠 icon | ReactNode | &lt;EllipsisOutlined /> | 4.14.0 |

View File

@ -151,7 +151,7 @@
"rc-steps": "~6.0.1",
"rc-switch": "~4.1.0",
"rc-table": "~7.36.0",
"rc-tabs": "~12.14.1",
"rc-tabs": "~12.15.0",
"rc-textarea": "~1.5.3",
"rc-tooltip": "~6.1.2",
"rc-tree": "~5.8.2",