fix: Card tabList API to align with Tabs (#42413)

* chore: pass to tabs

* test: update snapshot
This commit is contained in:
二货爱吃白萝卜 2023-05-16 22:24:41 +08:00 committed by GitHub
parent 890a65f1bd
commit a3fb7834a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 314 additions and 26 deletions

View File

@ -1,4 +1,5 @@
import classNames from 'classnames';
import type { Tab } from 'rc-tabs/lib/interface';
import omit from 'rc-util/lib/omit';
import * as React from 'react';
import { ConfigContext } from '../config-provider';
@ -12,10 +13,11 @@ import useStyle from './style';
export type CardType = 'inner';
export type CardSize = 'default' | 'small';
export interface CardTabListType {
export interface CardTabListType extends Omit<Tab, 'label'> {
key: string;
tab: React.ReactNode;
disabled?: boolean;
/** @deprecated Please use `label` instead */
tab?: React.ReactNode;
label?: React.ReactNode;
}
export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
@ -123,10 +125,9 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>((props, ref) => {
{...extraProps}
className={`${prefixCls}-head-tabs`}
onChange={onTabChange}
items={tabList.map((item) => ({
label: item.tab,
key: item.key,
disabled: item.disabled ?? false,
items={tabList.map(({ tab, ...item }) => ({
label: tab,
...item,
}))}
/>
) : null;

View File

@ -771,7 +771,6 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-tab1"
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-tab1"
@ -787,7 +786,6 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-tab2"
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-tab2"
@ -913,7 +911,6 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-article"
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-article"
@ -929,7 +926,6 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-app"
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-app"
@ -945,7 +941,6 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-project"
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-project"

View File

@ -770,7 +770,6 @@ Array [
data-node-key="tab1"
>
<div
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
@ -784,7 +783,6 @@ Array [
data-node-key="tab2"
>
<div
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
@ -889,7 +887,6 @@ Array [
data-node-key="article"
>
<div
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
@ -903,7 +900,6 @@ Array [
data-node-key="app"
>
<div
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
@ -917,7 +913,6 @@ Array [
data-node-key="project"
>
<div
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"

View File

@ -1,5 +1,268 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Card correct pass tabList props 1`] = `
<div
class="ant-card ant-card-bordered ant-card-contain-tabs"
>
<div
class="ant-card-head"
>
<div
class="ant-card-head-wrapper"
/>
<div
class="ant-tabs ant-tabs-top ant-tabs-editable ant-tabs-large ant-tabs-card ant-tabs-editable-card ant-card-head-tabs"
>
<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-with-remove ant-tabs-tab-active"
data-node-key="basic"
>
<div
aria-controls="rc-tabs-test-panel-basic"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-basic"
role="tab"
tabindex="0"
>
Basic
</div>
<button
aria-label="remove"
class="ant-tabs-tab-remove"
tabindex="0"
type="button"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</span>
</button>
</div>
<div
class="ant-tabs-tab ant-tabs-tab-with-remove"
data-node-key="deprecated"
>
<div
aria-controls="rc-tabs-test-panel-deprecated"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-deprecated"
role="tab"
tabindex="0"
>
Deprecated
</div>
<button
aria-label="remove"
class="ant-tabs-tab-remove"
tabindex="0"
type="button"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</span>
</button>
</div>
<div
class="ant-tabs-tab ant-tabs-tab-disabled"
data-node-key="disabled"
>
<div
aria-controls="rc-tabs-test-panel-disabled"
aria-disabled="true"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-disabled"
role="tab"
>
Disabled
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="notClosable"
>
<div
aria-controls="rc-tabs-test-panel-notClosable"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-notClosable"
role="tab"
tabindex="0"
>
NotClosable
</div>
</div>
<button
aria-label="Add tab"
class="ant-tabs-nav-add"
type="button"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
>
<svg
aria-hidden="true"
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
</button>
<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>
<button
aria-label="Add tab"
class="ant-tabs-nav-add"
type="button"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
>
<svg
aria-hidden="true"
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
</button>
</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-basic"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
id="rc-tabs-test-panel-basic"
role="tabpanel"
tabindex="0"
/>
</div>
</div>
</div>
</div>
<div
class="ant-card-body"
/>
</div>
`;
exports[`Card rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-card ant-card-bordered ant-card-rtl"

View File

@ -1,11 +1,11 @@
import React from 'react';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import React from 'react';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { screen, render } from '../../../tests/utils';
import { render, screen } from '../../../tests/utils';
import Button from '../../button/index';
import Card from '../index';
import '@testing-library/jest-dom';
describe('Card', () => {
mountTest(Card);
@ -112,7 +112,7 @@ describe('Card', () => {
tab: 'tab',
},
]}
size='small'
size="small"
>
<p>Card content</p>
</Card>,
@ -131,4 +131,36 @@ describe('Card', () => {
expect(cardRef.current).toHaveClass('ant-card');
});
it('correct pass tabList props', () => {
const { container } = render(
<Card
tabList={[
{
label: 'Basic',
key: 'basic',
},
{
tab: 'Deprecated',
key: 'deprecated',
},
{
tab: 'Disabled',
key: 'disabled',
disabled: true,
},
{
tab: 'NotClosable',
key: 'notClosable',
closable: false,
},
]}
tabProps={{
type: 'editable-card',
}}
/>,
);
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -20,15 +20,15 @@ const contentList: Record<string, React.ReactNode> = {
const tabListNoTitle = [
{
key: 'article',
tab: 'article',
label: 'article',
},
{
key: 'app',
tab: 'app',
label: 'app',
},
{
key: 'project',
tab: 'project',
label: 'project',
},
];

View File

@ -48,7 +48,7 @@ A card can be used to display content related to a single subject. The content c
| loading | Shows a loading indicator while the contents of the card are being fetched | boolean | false | |
| size | Size of card | `default` \| `small` | `default` | |
| tabBarExtraContent | Extra content in tab bar | ReactNode | - | |
| tabList | List of TabPane's head | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabList | List of TabPane's head | [TabItemType](/components/tabs#tabitemtype)[] | - | |
| tabProps | [Tabs](/components/tabs/#tabs) | - | - | |
| title | Card title | ReactNode | - | |
| type | Card style type, can be set to `inner` or not set | string | - | |

View File

@ -49,7 +49,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*a-8zR6rrupgAAA
| loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean | false | |
| size | card 的尺寸 | `default` \| `small` | `default` | |
| tabBarExtraContent | tab bar 上额外的元素 | ReactNode | - | |
| tabList | 页签标题列表 | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabList | 页签标题列表 | [TabItemType](/components/tabs#tabitemtype)[] | - | |
| tabProps | [Tabs](/components/tabs-cn#tabs) | - | - | |
| title | 卡片标题 | ReactNode | - | |
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - | |

View File

@ -71,6 +71,7 @@ More option at [rc-tabs tabs](https://github.com/react-component/tabs#tabs)
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| closable | Set tab closable. Only works while `type="editable-card"` | boolean | true |
| closeIcon | Customize close icon in TabPane's head. Only works while `type="editable-card"` | ReactNode | - |
| disabled | Set TabPane disabled | boolean | false |
| forceRender | Forced render of content in tabs, not lazy render after clicking on tabs | boolean | false |

View File

@ -73,6 +73,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
| 参数 | 说明 | 类型 | 默认值 |
| ----------- | ----------------------------------------------- | --------- | ------ |
| closable | 是否可关闭,`在 type="editable-card"`时有效 | boolean | true |
| closeIcon | 自定义关闭图标,`在 type="editable-card"`时有效 | ReactNode | - |
| disabled | 禁用某一项 | boolean | false |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |