mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
fix: Card tabList
API to align with Tabs (#42413)
* chore: pass to tabs * test: update snapshot
This commit is contained in:
parent
890a65f1bd
commit
a3fb7834a7
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
@ -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',
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -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<{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 | - | |
|
||||
|
@ -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<{key: string, tab: ReactNode}> | - | |
|
||||
| tabList | 页签标题列表 | [TabItemType](/components/tabs#tabitemtype)[] | - | |
|
||||
| tabProps | [Tabs](/components/tabs-cn#tabs) | - | - | |
|
||||
| title | 卡片标题 | ReactNode | - | |
|
||||
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - | |
|
||||
|
@ -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 |
|
||||
|
@ -73,6 +73,7 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ----------- | ----------------------------------------------- | --------- | ------ |
|
||||
| closable | 是否可关闭,`在 type="editable-card"`时有效 | boolean | true |
|
||||
| closeIcon | 自定义关闭图标,`在 type="editable-card"`时有效 | ReactNode | - |
|
||||
| disabled | 禁用某一项 | boolean | false |
|
||||
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false |
|
||||
|
Loading…
Reference in New Issue
Block a user