feat: Tabs add slot to support extra position (#25138)

* Update package.json

* update API

* update Demo

* update test

* Update components/tabs/index.zh-CN.md

Co-authored-by: xrkffgg <xrkffgg@vip.qq.com>

* Update components/tabs/demo/extra.md

Co-authored-by: xrkffgg <xrkffgg@vip.qq.com>

* update index.en-US

Co-authored-by: xrkffgg <xrkffgg@vip.qq.com>
This commit is contained in:
jesse 2020-08-07 09:53:45 +08:00 committed by GitHub
parent f928baf52a
commit 7121760f52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 379 additions and 123 deletions

View File

@ -1316,141 +1316,347 @@ exports[`renders ./components/tabs/demo/editable-card.md correctly 1`] = `
`; `;
exports[`renders ./components/tabs/demo/extra.md correctly 1`] = ` exports[`renders ./components/tabs/demo/extra.md correctly 1`] = `
<div Array [
class="ant-tabs ant-tabs-top"
>
<div <div
class="ant-tabs-nav" class="ant-tabs ant-tabs-top"
role="tablist"
> >
<div <div
class="ant-tabs-nav-wrap" class="ant-tabs-nav"
role="tablist"
> >
<div <div
class="ant-tabs-nav-list" class="ant-tabs-nav-wrap"
style="transform:translate(0px, 0px)"
> >
<div <div
class="ant-tabs-tab ant-tabs-tab-active" class="ant-tabs-nav-list"
style="transform:translate(0px, 0px)"
> >
<div <div
aria-selected="true" class="ant-tabs-tab ant-tabs-tab-active"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
> >
Tab 1 <div
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 1
</div>
</div> </div>
</div>
<div
class="ant-tabs-tab"
>
<div <div
aria-selected="false" class="ant-tabs-tab"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
> >
Tab 2 <div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 2
</div>
</div> </div>
</div>
<div
class="ant-tabs-tab"
>
<div <div
aria-selected="false" class="ant-tabs-tab"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
> >
Tab 3 <div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 3
</div>
</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"
class=""
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
class="ant-tabs-extra-content"
>
<button
class="ant-btn"
type="button"
>
<span>
Extra Action
</span>
</button>
</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 1
</div> </div>
<div <div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated" aria-hidden="true"
class="ant-tabs-tabpane"
role="tabpanel"
style="display:none"
tabindex="-1"
/>
<div
aria-hidden="true"
class="ant-tabs-tabpane"
role="tabpanel"
style="display:none"
tabindex="-1"
/> />
</div> </div>
</div> </div>
<div </div>,
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden" <br />,
> <br />,
<button <br />,
aria-controls="null-more-popup" <div>
aria-expanded="false" You can also specify its direction or both side
aria-haspopup="listbox" </div>,
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"
class=""
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
class="ant-tabs-extra-content"
>
<button
class="ant-btn"
type="button"
>
<span>
Extra Action
</span>
</button>
</div>
</div>
<div <div
class="ant-tabs-content-holder" class="ant-divider ant-divider-horizontal"
role="separator"
/>,
<div
class="ant-checkbox-group"
>
<label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked"
>
<span
class="ant-checkbox ant-checkbox-checked"
>
<input
checked=""
class="ant-checkbox-input"
type="checkbox"
value="left"
/>
<span
class="ant-checkbox-inner"
/>
</span>
<span>
left
</span>
</label>
<label
class="ant-checkbox-group-item ant-checkbox-wrapper ant-checkbox-wrapper-checked"
>
<span
class="ant-checkbox ant-checkbox-checked"
>
<input
checked=""
class="ant-checkbox-input"
type="checkbox"
value="right"
/>
<span
class="ant-checkbox-inner"
/>
</span>
<span>
right
</span>
</label>
</div>,
<br />,
<br />,
<div
class="ant-tabs ant-tabs-top"
> >
<div <div
class="ant-tabs-content ant-tabs-content-top" class="ant-tabs-nav"
role="tablist"
> >
<div <div
aria-hidden="false" class="ant-tabs-extra-content"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
role="tabpanel"
tabindex="0"
> >
Content of tab 1 <button
class="ant-btn"
style="margin-right:15px"
type="button"
>
<span>
Left Extra Action
</span>
</button>
</div> </div>
<div <div
aria-hidden="true" class="ant-tabs-nav-wrap"
class="ant-tabs-tabpane" >
role="tabpanel" <div
style="display:none" class="ant-tabs-nav-list"
tabindex="-1" style="transform:translate(0px, 0px)"
/> >
<div
class="ant-tabs-tab ant-tabs-tab-active"
>
<div
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 1
</div>
</div>
<div
class="ant-tabs-tab"
>
<div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
Tab 2
</div>
</div>
<div
class="ant-tabs-tab"
>
<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 <div
aria-hidden="true" class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
class="ant-tabs-tabpane" >
role="tabpanel" <button
style="display:none" aria-controls="null-more-popup"
tabindex="-1" 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"
class=""
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
class="ant-tabs-extra-content"
>
<button
class="ant-btn"
type="button"
>
<span>
Right Extra Action
</span>
</button>
</div>
</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 1
</div>
<div
aria-hidden="true"
class="ant-tabs-tabpane"
role="tabpanel"
style="display:none"
tabindex="-1"
/>
<div
aria-hidden="true"
class="ant-tabs-tabpane"
role="tabpanel"
style="display:none"
tabindex="-1"
/>
</div>
</div>
</div>,
]
`; `;
exports[`renders ./components/tabs/demo/icon.md correctly 1`] = ` exports[`renders ./components/tabs/demo/icon.md correctly 1`] = `

View File

@ -7,31 +7,81 @@ title:
## zh-CN ## zh-CN
可以在页签边添加附加操作。 可以在页签边添加附加操作。
## en-US ## en-US
You can add extra actions to the right of Tabs. You can add extra actions to the right or left or even both side of Tabs.
```jsx ```jsx
import { Tabs, Button } from 'antd'; import { Tabs, Button, Divider, Checkbox } from 'antd';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const CheckboxGroup = Checkbox.Group;
const operations = <Button>Extra Action</Button>; const operations = <Button>Extra Action</Button>;
ReactDOM.render( const OperationsSlot = {
<Tabs tabBarExtraContent={operations}> left: <Button style={{ marginRight: 15 }}>Left Extra Action</Button>,
<TabPane tab="Tab 1" key="1"> right: <Button>Right Extra Action</Button>,
Content of tab 1 };
</TabPane>
<TabPane tab="Tab 2" key="2"> const options = ['left', 'right'];
Content of tab 2
</TabPane> const Demo = () => {
<TabPane tab="Tab 3" key="3"> const [positon, setPosition] = React.useState(['left', 'right']);
Content of tab 3
</TabPane> const slot = React.useMemo(() => {
</Tabs>, if (positon.length === 0) return null;
mountNode,
); return positon.reduce(
(acc, direaction) => ({ ...acc, [direaction]: OperationsSlot[direaction] }),
{},
);
}, [positon]);
return (
<>
<Tabs tabBarExtraContent={operations}>
<TabPane tab="Tab 1" key="1">
Content of tab 1
</TabPane>
<TabPane tab="Tab 2" key="2">
Content of tab 2
</TabPane>
<TabPane tab="Tab 3" key="3">
Content of tab 3
</TabPane>
</Tabs>
<br />
<br />
<br />
<div>You can also specify its direction or both side</div>
<Divider />
<CheckboxGroup
options={options}
value={positon}
onChange={value => {
setPosition(value);
}}
/>
<br />
<br />
<Tabs tabBarExtraContent={slot}>
<TabPane tab="Tab 1" key="1">
Content of tab 1
</TabPane>
<TabPane tab="Tab 2" key="2">
Content of tab 2
</TabPane>
<TabPane tab="Tab 3" key="3">
Content of tab 3
</TabPane>
</Tabs>
</>
);
};
ReactDOM.render(<Demo />, mountNode);
``` ```

View File

@ -30,7 +30,7 @@ Ant Design has 3 types of Tabs for different situations.
| hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | false | | | hideAdd | Hide plus icon or not. Only works while `type="editable-card"` | boolean | false | |
| size | Preset tab bar size | `large` \| `default` \| `small` | `default` | | | size | Preset tab bar size | `large` \| `default` \| `small` | `default` | |
| centered | Centers tabs | boolean | false | 4.4.0 | | centered | Centers tabs | boolean | false | 4.4.0 |
| tabBarExtraContent | Extra content in tab bar | ReactNode | - | | | tabBarExtraContent | Extra content in tab bar | ReactNode \| {left?: ReactNode, right?: ReactNode} | - | |
| tabBarGutter | The gap between tabs | number | - | | | tabBarGutter | The gap between tabs | number | - | |
| tabBarStyle | Tab bar style object | object | - | | | tabBarStyle | Tab bar style object | object | - | |
| tabPosition | Position of tabs | `top` \| `right` \| `bottom` \| `left` | `top` | | | tabPosition | Position of tabs | `top` \| `right` \| `bottom` \| `left` | `top` | |

View File

@ -33,7 +33,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | | | hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | |
| size | 大小,提供 `large` `default``small` 三种大小 | string | `default` | | | size | 大小,提供 `large` `default``small` 三种大小 | string | `default` | |
| centered | 标签居中展示 | boolean | false | 4.4.0 | | centered | 标签居中展示 | boolean | false | 4.4.0 |
| tabBarExtraContent | tab bar 上额外的元素 | ReactNode | - | | | tabBarExtraContent | tab bar 上额外的元素 | ReactNode \| {left?: ReactNode, right?: ReactNode} | - | |
| tabBarGutter | tabs 之间的间隙 | number | - | | | tabBarGutter | tabs 之间的间隙 | number | - | |
| tabBarStyle | tab bar 的样式对象 | object | - | | | tabBarStyle | tab bar 的样式对象 | object | - | |
| tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | `top` | | | tabPosition | 页签位置,可选值有 `top` `right` `bottom` `left` | string | `top` | |

View File

@ -139,7 +139,7 @@
"rc-steps": "~4.1.0", "rc-steps": "~4.1.0",
"rc-switch": "~3.2.0", "rc-switch": "~3.2.0",
"rc-table": "~7.8.0", "rc-table": "~7.8.0",
"rc-tabs": "~11.5.0", "rc-tabs": "~11.6.0",
"rc-textarea": "~0.3.0", "rc-textarea": "~0.3.0",
"rc-tooltip": "~4.2.0", "rc-tooltip": "~4.2.0",
"rc-tree": "~3.8.5", "rc-tree": "~3.8.5",