mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
feat: ConfigProvider support Tabs indicatorSize
(#44517)
* feat: ConfigProvider support tabs.indicatorLength
* feat: ConfigProvider support card.tabProps
* Revert "feat: ConfigProvider support card.tabProps"
This reverts commit 817af9a6bb
.
* chore: rename
* docs: add demo
This commit is contained in:
parent
659054ee49
commit
b0dd138fba
@ -39,7 +39,6 @@ import Select from '../../select';
|
||||
import Skeleton from '../../skeleton';
|
||||
import type { SliderTooltipProps } from '../../slider';
|
||||
import Slider from '../../slider';
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import { render } from '../../../tests/utils';
|
||||
import Spin from '../../spin';
|
||||
import Statistic from '../../statistic';
|
||||
|
@ -11,6 +11,7 @@ import type { AliasToken, MappingAlgorithm, OverrideToken } from '../theme/inter
|
||||
import type { SizeType } from './SizeContext';
|
||||
import type { RenderEmptyHandler } from './defaultRenderEmpty';
|
||||
import type { ShowWaveEffect } from '../_util/wave/interface';
|
||||
import type { TabsProps } from '../tabs';
|
||||
|
||||
export const defaultIconPrefixCls = 'anticon';
|
||||
|
||||
@ -143,7 +144,7 @@ export interface ConfigConsumerProps {
|
||||
tag?: ComponentStyleConfig;
|
||||
table?: ComponentStyleConfig;
|
||||
card?: ComponentStyleConfig;
|
||||
tabs?: ComponentStyleConfig;
|
||||
tabs?: ComponentStyleConfig & Pick<TabsProps, 'indicatorSize'>;
|
||||
timeline?: ComponentStyleConfig;
|
||||
timePicker?: ComponentStyleConfig;
|
||||
upload?: ComponentStyleConfig;
|
||||
|
@ -43,6 +43,7 @@ import type { SizeType } from './SizeContext';
|
||||
import SizeContext, { SizeContextProvider } from './SizeContext';
|
||||
import useStyle from './style';
|
||||
import { defaultTheme } from '../theme/context';
|
||||
import type { TabsProps } from '../tabs';
|
||||
|
||||
/**
|
||||
* Since too many feedback using static method like `Modal.confirm` not getting theme, we record the
|
||||
@ -180,7 +181,7 @@ export interface ConfigProviderProps {
|
||||
tag?: ComponentStyleConfig;
|
||||
table?: ComponentStyleConfig;
|
||||
card?: ComponentStyleConfig;
|
||||
tabs?: ComponentStyleConfig;
|
||||
tabs?: ComponentStyleConfig & Pick<TabsProps, 'indicatorSize'>;
|
||||
timeline?: ComponentStyleConfig;
|
||||
timePicker?: ComponentStyleConfig;
|
||||
upload?: ComponentStyleConfig;
|
||||
|
@ -1992,6 +1992,147 @@ 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"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-wrap"
|
||||
>
|
||||
<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"
|
||||
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
|
||||
class="ant-tabs-content-holder"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-content ant-tabs-content-top"
|
||||
>
|
||||
<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>
|
||||
`;
|
||||
|
||||
exports[`renders components/tabs/demo/custom-indicator.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/tabs/demo/custom-tab-bar.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top"
|
||||
|
@ -1661,6 +1661,120 @@ exports[`renders components/tabs/demo/custom-add-trigger.tsx correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/tabs/demo/custom-indicator.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
class="ant-tabs-nav-wrap"
|
||||
>
|
||||
<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
|
||||
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`] = `
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top"
|
||||
|
@ -4,6 +4,7 @@ import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { fireEvent, render } from '../../../tests/utils';
|
||||
import { resetWarned } from '../../_util/warning';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
@ -125,4 +126,18 @@ describe('Tabs', () => {
|
||||
);
|
||||
errorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('indicator in ConfigProvider should work', () => {
|
||||
const { container } = render(
|
||||
<ConfigProvider tabs={{ indicatorSize: 12 }}>
|
||||
<Tabs items={[{ key: '1', label: 'foo' }]} className="Tabs_1" />
|
||||
<Tabs items={[{ key: '2', label: 'bar' }]} className="Tabs_2" />
|
||||
<Tabs items={[{ key: '3', label: 'too' }]} indicatorSize={4} className="Tabs_3" />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
|
||||
expect(container.querySelector('.Tabs_1 .ant-tabs-ink-bar')).toHaveStyle({ width: 12 });
|
||||
expect(container.querySelector('.Tabs_2 .ant-tabs-ink-bar')).toHaveStyle({ width: 12 });
|
||||
expect(container.querySelector('.Tabs_3 .ant-tabs-ink-bar')).toHaveStyle({ width: 4 });
|
||||
});
|
||||
});
|
||||
|
7
components/tabs/demo/custom-indicator.md
Normal file
7
components/tabs/demo/custom-indicator.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
自定义指示器宽度
|
||||
|
||||
## en-US
|
||||
|
||||
Custom indicator size
|
36
components/tabs/demo/custom-indicator.tsx
Normal file
36
components/tabs/demo/custom-indicator.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import { Tabs } from 'antd';
|
||||
import type { TabsProps } from 'antd';
|
||||
|
||||
const onChange = (key: string) => {
|
||||
console.log(key);
|
||||
};
|
||||
|
||||
const items: TabsProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: 'Tab 1',
|
||||
children: 'Content of Tab Pane 1',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: 'Tab 2',
|
||||
children: 'Content of Tab Pane 2',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: 'Tab 3',
|
||||
children: 'Content of Tab Pane 3',
|
||||
},
|
||||
];
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Tabs
|
||||
defaultActiveKey="1"
|
||||
items={items}
|
||||
onChange={onChange}
|
||||
indicatorSize={(origin) => origin - 16}
|
||||
/>
|
||||
);
|
||||
|
||||
export default App;
|
@ -23,6 +23,7 @@ Ant Design has 3 types of Tabs for different situations.
|
||||
<code src="./demo/disabled.tsx">Disabled</code>
|
||||
<code src="./demo/centered.tsx">Centered</code>
|
||||
<code src="./demo/icon.tsx">Icon</code>
|
||||
<code src="./demo/custom-indicator.tsx">Indicator</code>
|
||||
<code src="./demo/slide.tsx">Slide</code>
|
||||
<code src="./demo/extra.tsx">Extra content</code>
|
||||
<code src="./demo/size.tsx">Size</code>
|
||||
@ -52,7 +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 | |
|
||||
| indicatorLength | Customize length of indicator, which is the same as tab by default | number \| (origin: number) => number | - | 5.9.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 | <EllipsisOutlined /> | 4.14.0 |
|
||||
| popupClassName | `className` for more dropdown. | string | - | 4.21.0 |
|
||||
|
@ -48,6 +48,7 @@ const Tabs: React.FC<TabsProps> & { TabPane: typeof TabPane } = (props) => {
|
||||
items,
|
||||
animated,
|
||||
style,
|
||||
indicatorSize,
|
||||
...otherProps
|
||||
} = props;
|
||||
const { prefixCls: customizePrefixCls, moreIcon = <EllipsisOutlined /> } = otherProps;
|
||||
@ -107,6 +108,7 @@ const Tabs: React.FC<TabsProps> & { TabPane: typeof TabPane } = (props) => {
|
||||
moreIcon={moreIcon}
|
||||
prefixCls={prefixCls}
|
||||
animated={mergedAnimated}
|
||||
indicatorSize={indicatorSize ?? tabs?.indicatorSize}
|
||||
/>,
|
||||
);
|
||||
};
|
||||
|
@ -26,6 +26,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
|
||||
<code src="./demo/disabled.tsx">禁用</code>
|
||||
<code src="./demo/centered.tsx">居中</code>
|
||||
<code src="./demo/icon.tsx">图标</code>
|
||||
<code src="./demo/custom-indicator.tsx">指示条</code>
|
||||
<code src="./demo/slide.tsx">滑动</code>
|
||||
<code src="./demo/extra.tsx">附加内容</code>
|
||||
<code src="./demo/size.tsx">大小</code>
|
||||
@ -54,7 +55,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
|
||||
| centered | 标签居中展示 | boolean | false | 4.4.0 |
|
||||
| defaultActiveKey | 初始化选中面板的 key,如果没有设置 activeKey | string | `第一个面板` | |
|
||||
| hideAdd | 是否隐藏加号图标,在 `type="editable-card"` 时有效 | boolean | false | |
|
||||
| indicatorLength | 自定义指示条长度,默认与 tab 等宽 | number \| (origin: number) => number | - | 5.9.0 |
|
||||
| indicatorSize | 自定义指示条长度,默认与 tab 等宽 | number \| (origin: number) => number | - | 5.9.0 |
|
||||
| items | 配置选项卡内容 | [TabItemType](#tabitemtype) | [] | 4.23.0 |
|
||||
| moreIcon | 自定义折叠 icon | ReactNode | <EllipsisOutlined /> | 4.14.0 |
|
||||
| popupClassName | 更多菜单的 `className` | string | - | 4.21.0 |
|
||||
|
@ -148,7 +148,7 @@
|
||||
"rc-steps": "~6.0.1",
|
||||
"rc-switch": "~4.1.0",
|
||||
"rc-table": "~7.33.1",
|
||||
"rc-tabs": "~12.11.0",
|
||||
"rc-tabs": "~12.11.1",
|
||||
"rc-textarea": "~1.3.3",
|
||||
"rc-tooltip": "~6.0.0",
|
||||
"rc-tree": "~5.7.6",
|
||||
|
Loading…
Reference in New Issue
Block a user