mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 14:13:37 +08:00
docs: remove v3 to v4 migration docs (#39290)
* docs: remove v3 to v4 migration docs * update Co-authored-by: huangkairan <wb-hkr877030@alibaba-inc.com>
This commit is contained in:
parent
a59058f0b2
commit
8cb46243fd
@ -78,29 +78,3 @@ The differences with Select are:
|
||||
Please use `onChange` to manage control state. `onSearch` is used for searching input which is not the same as `onChange`. Besides, clicking on the option will not trigger the `onSearch` event.
|
||||
|
||||
Related issue: [#18230](https://github.com/ant-design/ant-design/issues/18230) [#17916](https://github.com/ant-design/ant-design/issues/17916)
|
||||
|
||||
### Part of the api in v3 are not available in v4?
|
||||
|
||||
AutoComplete is an Input component that supports auto complete tips. As such, it should not support props like `labelInValue` that affect value display. In v3, the AutoComplete implementation can not handle the case where the `value` and `label` are identical. v4 not longer support `label` as the value input.
|
||||
|
||||
Besides, to unify the API, `dataSource` is replaced with `options`. You can migrate with the following change:
|
||||
|
||||
#### v3
|
||||
|
||||
```tsx
|
||||
dataSource = ['light', 'bamboo'];
|
||||
// or
|
||||
dataSource = [
|
||||
{ value: 'light', text: 'Light' },
|
||||
{ value: 'bamboo', text: 'Bamboo' },
|
||||
];
|
||||
```
|
||||
|
||||
#### v4
|
||||
|
||||
```tsx
|
||||
options = [
|
||||
{ value: 'light', label: 'Light' },
|
||||
{ value: 'bamboo', label: 'Bamboo' },
|
||||
];
|
||||
```
|
||||
|
@ -80,29 +80,3 @@ demo:
|
||||
请使用 `onChange` 进行受控管理。`onSearch` 触发于搜索输入,与 `onChange` 时机不同。此外,点选选项时也不会触发 `onSearch` 事件。
|
||||
|
||||
相关 issue:[#18230](https://github.com/ant-design/ant-design/issues/18230) [#17916](https://github.com/ant-design/ant-design/issues/17916)
|
||||
|
||||
### v3 的部分属性为何在 v4 中没有了?
|
||||
|
||||
AutoComplete 组件是一个支持自动提示的 Input 组件,因而其不具有 `labelInValue` 等影响 value 展示的属性。在 v3 版本,AutoComplete 实现存在输入值如果遇到 `value` 与 `label` 相同时无法映射的问题。 v4 中不再支持 `label` 为值的输入形态。
|
||||
|
||||
此外为了统一 API,`dataSource` 改为 `options` 你可以如下转换:
|
||||
|
||||
#### v3
|
||||
|
||||
```tsx
|
||||
dataSource = ['light', 'bamboo'];
|
||||
// or
|
||||
dataSource = [
|
||||
{ value: 'light', text: 'Light' },
|
||||
{ value: 'bamboo', text: 'Bamboo' },
|
||||
];
|
||||
```
|
||||
|
||||
#### v4
|
||||
|
||||
```tsx
|
||||
options = [
|
||||
{ value: 'light', label: 'Light' },
|
||||
{ value: 'bamboo', label: 'Bamboo' },
|
||||
];
|
||||
```
|
||||
|
@ -15,36 +15,6 @@ A breadcrumb displays the current location within a hierarchy. It allows going b
|
||||
- When you need to inform the user of where they are.
|
||||
- When the user may need to navigate back to a higher level.
|
||||
|
||||
### Usage upgrade after 4.24.0
|
||||
|
||||
<Alert message="After version 4.24.0, we provide a simpler usage <Breadcrumb.Item menu={{ items: [...] }}> with better performance and potential of writing simpler code style in your applications. Meanwhile, we deprecated the old usage in browser console, we will remove it in antd 5.0."></Alert>
|
||||
|
||||
```jsx
|
||||
// works when >=4.24.0, recommended ✅
|
||||
const items = [
|
||||
{ label: 'item 1', key: 'item-1' }, // remember to pass the key prop
|
||||
{ label: 'item 2', key: 'item-2' },
|
||||
];
|
||||
return (
|
||||
<Breadcrumb>
|
||||
<Breadcrumb.Item menu={{ items }}>Ant Design</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
|
||||
// works when <4.24.0, deprecated when >=4.24.0 🙅🏻♀️
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item>item 1</Menu.Item>
|
||||
<Menu.Item>item 2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<Breadcrumb>
|
||||
<Breadcrumb.Item overlay={menu}>Ant Design</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
|
@ -16,36 +16,6 @@ demo:
|
||||
- 当需要告知用户『你在哪里』时;
|
||||
- 当需要向上导航的功能时。
|
||||
|
||||
### 4.24.0 用法升级
|
||||
|
||||
<Alert message="在 4.24.0 版本后,我们提供了 <Breadcrumb.Item menu={{ items: [...] }}> 的简写方式,有更好的性能和更方便的数据组织方式,开发者不再需要自行拼接 JSX。同时我们废弃了原先的写法,你还是可以在 4.x 继续使用,但会在控制台看到警告,并会在 5.0 后移除。"></Alert>
|
||||
|
||||
```jsx
|
||||
// >=4.24.0 可用,推荐的写法 ✅
|
||||
const items = [
|
||||
{ label: '菜单项一', key: 'item-1' }, // 菜单项务必填写 key
|
||||
{ label: '菜单项二', key: 'item-2' },
|
||||
];
|
||||
return (
|
||||
<Breadcrumb>
|
||||
<Breadcrumb.Item menu={{ items }}>Ant Design</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
|
||||
// <4.24.0 可用,>=4.24.0 时不推荐 🙅🏻♀️
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item>菜单项一</Menu.Item>
|
||||
<Menu.Item>菜单项二</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<Breadcrumb>
|
||||
<Breadcrumb.Item overlay={menu}>Ant Design</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
|
@ -3351,324 +3351,6 @@ Array [
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders ./components/dropdown/demo/deprecated.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<a
|
||||
class="ant-dropdown-trigger"
|
||||
>
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
Hover me
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>,
|
||||
<div>
|
||||
<div
|
||||
class="ant-dropdown"
|
||||
style="opacity:0"
|
||||
>
|
||||
<ul
|
||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||
data-menu-list="true"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<a
|
||||
href="https://www.antgroup.com"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
1st menu item
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-disabled"
|
||||
role="menuitem"
|
||||
>
|
||||
<span
|
||||
aria-label="smile"
|
||||
class="anticon anticon-smile ant-dropdown-menu-item-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="smile"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<a
|
||||
href="https://www.aliyun.com"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
2nd menu item (disabled)
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-disabled ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
>
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
<a
|
||||
href="https://www.luohanacademy.com"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
3rd menu item (disabled)
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<li
|
||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-danger ant-dropdown-menu-item-only-child"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
class="ant-dropdown-menu-title-content"
|
||||
>
|
||||
a danger item
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display:none"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-dropdown-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders ./components/dropdown/demo/dropdown-button.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
|
@ -197,46 +197,6 @@ exports[`renders ./components/dropdown/demo/custom-dropdown.tsx correctly 1`] =
|
||||
</a>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/dropdown/demo/deprecated.tsx correctly 1`] = `
|
||||
<a
|
||||
class="ant-dropdown-trigger"
|
||||
>
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
Hover me
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<span
|
||||
aria-label="down"
|
||||
class="anticon anticon-down"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="down"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/dropdown/demo/dropdown-button.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
|
@ -1,7 +0,0 @@
|
||||
## zh-CN
|
||||
|
||||
最简单的下拉菜单。
|
||||
|
||||
## en-US
|
||||
|
||||
The most basic dropdown menu.
|
@ -1,55 +0,0 @@
|
||||
import React from 'react';
|
||||
import { DownOutlined, SmileOutlined } from '@ant-design/icons';
|
||||
import { Dropdown, Menu, Space } from 'antd';
|
||||
|
||||
const menu = (
|
||||
<Menu
|
||||
items={[
|
||||
{
|
||||
key: '1',
|
||||
label: (
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://www.antgroup.com">
|
||||
1st menu item
|
||||
</a>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: (
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://www.aliyun.com">
|
||||
2nd menu item (disabled)
|
||||
</a>
|
||||
),
|
||||
icon: <SmileOutlined />,
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: (
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://www.luohanacademy.com">
|
||||
3rd menu item (disabled)
|
||||
</a>
|
||||
),
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
danger: true,
|
||||
label: 'a danger item',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Dropdown overlay={menu}>
|
||||
<a onClick={(e) => e.preventDefault()}>
|
||||
<Space>
|
||||
Hover me
|
||||
<DownOutlined />
|
||||
</Space>
|
||||
</a>
|
||||
</Dropdown>
|
||||
);
|
||||
|
||||
export default App;
|
@ -13,40 +13,9 @@ A dropdown list.
|
||||
|
||||
When there are more than a few options to choose from, you can wrap them in a `Dropdown`. By hovering or clicking on the trigger, a dropdown menu will appear, which allows you to choose an option and execute the relevant action.
|
||||
|
||||
### Usage upgrade after 4.24.0
|
||||
|
||||
<Alert message="After version 4.24.0, we provide a simpler usage <Dropdown menu={{ items: [...] }} /> with better performance and potential of writing simpler code style in your applications. Meanwhile, we deprecated the old usage in browser console, we will remove it in antd 5.0."></Alert>
|
||||
|
||||
```jsx
|
||||
// works when >=4.24.0, recommended ✅
|
||||
const items = [
|
||||
{ label: 'item 1', key: 'item-1' }, // remember to pass the key prop
|
||||
{ label: 'item 2', key: 'item-2' },
|
||||
];
|
||||
return (
|
||||
<Dropdown menu={{ items }}>
|
||||
<a>Hover me</a>
|
||||
</Dropdown>
|
||||
);
|
||||
|
||||
// works when <4.24.0, deprecated when >=4.24.0 🙅🏻♀️
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item>item 1</Menu.Item>
|
||||
<Menu.Item>item 2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<Dropdown overlay={menu}>
|
||||
<a>Hover me</a>
|
||||
</Dropdown>
|
||||
);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">Basic usage (deprecated syntactic sugar)</code>
|
||||
<code src="./demo/basic.tsx">Basic</code>
|
||||
<code src="./demo/placement.tsx">Placement</code>
|
||||
<code src="./demo/arrow.tsx">Arrow</code>
|
||||
|
@ -17,40 +17,9 @@ demo:
|
||||
- 用于收罗一组命令操作。
|
||||
- Select 用于选择,而 Dropdown 是命令集合。
|
||||
|
||||
### 4.24.0 用法升级
|
||||
|
||||
<Alert message="在 4.24.0 版本后,我们提供了 <Dropdown menu={{ items: [...] }} /> 的简写方式,有更好的性能和更方便的数据组织方式,开发者不再需要自行拼接 JSX。同时我们废弃了原先的写法,你还是可以在 4.x 继续使用,但会在控制台看到警告,并会在 5.0 后移除。"></Alert>
|
||||
|
||||
```jsx
|
||||
// >=4.24.0 可用,推荐的写法 ✅
|
||||
const items = [
|
||||
{ label: '菜单项一', key: 'item-1' }, // 菜单项务必填写 key
|
||||
{ label: '菜单项二', key: 'item-2' },
|
||||
];
|
||||
return (
|
||||
<Dropdown menu={{ items }}>
|
||||
<a>Hover me</a>
|
||||
</Dropdown>
|
||||
);
|
||||
|
||||
// <4.24.0 可用,>=4.24.0 时不推荐 🙅🏻♀️
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item>菜单项一</Menu.Item>
|
||||
<Menu.Item>菜单项二</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<Dropdown overlay={menu}>
|
||||
<a>Hover me</a>
|
||||
</Dropdown>
|
||||
);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">基础用法(废弃的语法糖)</code>
|
||||
<code src="./demo/basic.tsx">基本</code>
|
||||
<code src="./demo/placement.tsx">弹出位置</code>
|
||||
<code src="./demo/arrow.tsx">箭头</code>
|
||||
|
@ -440,10 +440,6 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
|
||||
| warningOnly | Warning only. Not block form submit | boolean | 4.17.0 |
|
||||
| whitespace | Failed if only has whitespace, only work with `type: 'string'` rule | boolean | |
|
||||
|
||||
## Migrate to v4
|
||||
|
||||
If you are a user of v3, you can ref [migrate doc](/components/form/v3)。
|
||||
|
||||
<style>
|
||||
.code-box-demo .ant-form:not(.ant-form-inline):not(.ant-form-vertical) {
|
||||
max-width: 600px;
|
||||
|
@ -439,10 +439,6 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
|
||||
| warningOnly | 仅警告,不阻塞表单提交 | boolean | 4.17.0 |
|
||||
| whitespace | 如果字段仅包含空格则校验不通过,只在 `type: 'string'` 时生效 | boolean | |
|
||||
|
||||
## 从 v3 升级到 v4
|
||||
|
||||
如果你是 antd v3 的用户,你可以参考[迁移示例](/components/form/v3)。
|
||||
|
||||
<style>
|
||||
.code-box-demo .ant-form:not(.ant-form-inline):not(.ant-form-vertical) {
|
||||
max-width: 600px;
|
||||
|
@ -1,326 +0,0 @@
|
||||
---
|
||||
title: Migrate Form to v4
|
||||
skip: true
|
||||
---
|
||||
|
||||
### Remove Form.create
|
||||
|
||||
Form of v4 does not need to create context by calling `Form.create()`. Form now has it's own data scope and you don't need `getFieldDecorator` anymore. Just use Form.Item directly:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator } }) => (
|
||||
<Form>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => (
|
||||
<Form>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
```
|
||||
|
||||
Since `Form.create()` is removed, methods like `onFieldsChange` have moved to `Form` and form state is controlled by a `fields` prop. ref [example](/components/form/#components-form-demo-global-state)。
|
||||
|
||||
### Form control
|
||||
|
||||
If you want to control form, you can use `Form.useForm()` to create Form instance for operation:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { setFieldsValue } }) => {
|
||||
React.useEffect(() => {
|
||||
setFieldsValue({
|
||||
username: 'Bamboo',
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
React.useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
username: 'Bamboo',
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Form form={form}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
For class component, you can use `ref` to access instance:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
class Demo extends React.Component {
|
||||
formRef = React.createRef();
|
||||
|
||||
componentDidMount() {
|
||||
this.formRef.current.setFieldsValue({
|
||||
username: 'Bamboo',
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Form ref={this.formRef}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you don't want to use the Item style, you can use `noStyle` prop to remove it:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator } }) => {
|
||||
return <Form>{getFieldDecorator('username')(<Input />)}</Form>;
|
||||
};
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => {
|
||||
return (
|
||||
<Form>
|
||||
<Form.Item name="username" noStyle>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### Linkage with field
|
||||
|
||||
New Form uses incremental update which only updates related field. So if there is some linkage between fields or updates with the whole form, you can use [`dependencies`](/components/form/#dependencies) or [`shouldUpdate`](/components/form/#shouldUpdate) to handle that.
|
||||
|
||||
### replace onSubmit with onFinish
|
||||
|
||||
You need to listen to `onSubmit` and call `validateFields` to handle validation in old Form. New Form provides `onFinish` which will only trigger when validation has passed:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator, validateFields } }) => {
|
||||
const onSubmit = e => {
|
||||
e.preventDefault();
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
console.log('Received values of form: ', values);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={onSubmit}>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => {
|
||||
const onFinish = values => {
|
||||
console.log('Received values of form: ', values);
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onFinish={onFinish}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Replace validateFieldsAndScroll with scrollToField
|
||||
|
||||
New version recommend use `onFinish` for submit after validation. Thus `validateFieldsAndScroll` is changed to more flexible method `scrollToField`:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
onSubmit = () => {
|
||||
form.validateFieldsAndScroll((error, values) => {
|
||||
// Your logic
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
onFinishFailed = ({ errorFields }) => {
|
||||
form.scrollToField(errorFields[0].name);
|
||||
};
|
||||
```
|
||||
|
||||
### Initialization
|
||||
|
||||
Besides, we move `initialValue` into Form to avoid field with same name both using `initialValue` to cause conflict:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator } }) => (
|
||||
<Form>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
initialValue: 'Bamboo',
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => (
|
||||
<Form initialValues={{ username: 'Bamboo' }}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
```
|
||||
|
||||
In v3, modifying the `initialValue` of un-operated field will update the field value synchronously, which is a bug. However, since it has been used as a feature for a long time, we have not fixed it. In v4, the bug has been fixed. `initialValues` only takes effect when initializing and resetting the form.
|
||||
|
||||
### Nested field paths using arrays
|
||||
|
||||
In the past versions we used `.` to represent nested paths (such as `user.name` to represent `{ user: { name: '' } }`). However, in some backend systems, `.` is also included in the variable name. This causes the user to need additional code to convert, so in the new version, nested paths are represented by arrays to avoid unexpected behavior (eg `['user', 'name']`).
|
||||
|
||||
Therefore, paths returned by methods such as `getFieldsError` are always in an array form for the user to handle:
|
||||
|
||||
```jsx
|
||||
form.getFieldsError();
|
||||
|
||||
/*
|
||||
[
|
||||
{ name: ['user', 'name'], errors: [] },
|
||||
{ name: ['user', 'age'], errors: ['Some error message'] },
|
||||
]
|
||||
*/
|
||||
```
|
||||
|
||||
Nested field definition has changed from:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
<Form.Item label="Firstname">{getFieldDecorator('user.0.firstname', {})(<Input />)}</Form.Item>
|
||||
```
|
||||
|
||||
To
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
<Form.Item name={['user', 0, 'firstname']} label="Firstname">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
```
|
||||
|
||||
Similarly using `setFieldsValue` has changed from:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
this.formRef.current.setFieldsValue({
|
||||
'user.0.firstname': 'John',
|
||||
});
|
||||
```
|
||||
|
||||
To
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
this.formRef.current.setFieldsValue({
|
||||
user: [
|
||||
{
|
||||
firstname: 'John',
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
### Remove callback in validateFields
|
||||
|
||||
`validateFields` will return a Promise, so you can handle the error with `async/await` or `then/catch`. It is no longer necessary to determine if `errors` is empty:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
validateFields((err, value) => {
|
||||
if (!err) {
|
||||
// Do something with value
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
To
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
validateFields().then(values => {
|
||||
// Do something with value
|
||||
});
|
||||
```
|
@ -1,328 +0,0 @@
|
||||
---
|
||||
title: Form 从 v3 到 v4
|
||||
skip: true
|
||||
---
|
||||
|
||||
新版本 Form 对使用方式进行了简化,因而如果你是从 v3 迁移上来。你可以参考本文做迁移工作。
|
||||
|
||||
## 去除 Form.create
|
||||
|
||||
v4 的 Form 不再需要通过 `Form.create()` 创建上下文。Form 组件现在自带数据域,因而 `getFieldDecorator` 也不再需要,直接写入 Form.Item 即可:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator } }) => (
|
||||
<Form>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => (
|
||||
<Form>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
```
|
||||
|
||||
由于移除了 `Form.create()`,原本的 `onFieldsChange` 等方法移入 Form 中,通过 `fields` 对 Form 进行控制。参考[示例](/components/form/#components-form-demo-global-state)。
|
||||
|
||||
## 表单控制调整
|
||||
|
||||
Form 自带表单控制实体,如需要调用 form 方法,可以通过 `Form.useForm()` 创建 Form 实体进行操作:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { setFieldsValue } }) => {
|
||||
React.useEffect(() => {
|
||||
setFieldsValue({
|
||||
username: 'Bamboo',
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
React.useEffect(() => {
|
||||
form.setFieldsValue({
|
||||
username: 'Bamboo',
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Form form={form}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
对于 class component,也可以通过 `ref` 获得实体:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
class Demo extends React.Component {
|
||||
formRef = React.createRef();
|
||||
|
||||
componentDidMount() {
|
||||
this.formRef.current.setFieldsValue({
|
||||
username: 'Bamboo',
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Form ref={this.formRef}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
由于 Form.Item 内置字段绑定,如果需要不带样式的表单绑定,可以使用 `noStyle` 属性移除额外样式:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator } }) => {
|
||||
return <Form>{getFieldDecorator('username')(<Input />)}</Form>;
|
||||
};
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => {
|
||||
return (
|
||||
<Form>
|
||||
<Form.Item name="username" noStyle>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## 字段联动调整
|
||||
|
||||
新版 Form 采用增量更新方式,仅会更新需要更新的字段。因而如果有字段关联更新,或者跟随整个表单更新而更新。可以使用 [`dependencies`](/components/form/#dependencies) 或 [`shouldUpdate`](/components/form/#shouldUpdate)。
|
||||
|
||||
## onFinish 替代 onSubmit
|
||||
|
||||
对于表单校验,过去版本需要通过监听 `onSubmit` 事件手工触发 `validateFields`。新版直接使用 `onFinish` 事件,该事件仅当校验通过后才会执行:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator, validateFields } }) => {
|
||||
const onSubmit = e => {
|
||||
e.preventDefault();
|
||||
validateFields((err, values) => {
|
||||
if (!err) {
|
||||
console.log('Received values of form: ', values);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={onSubmit}>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => {
|
||||
const onFinish = values => {
|
||||
console.log('Received values of form: ', values);
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onFinish={onFinish}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## scrollToField 替代 validateFieldsAndScroll
|
||||
|
||||
新版推荐使用 `onFinish` 进行校验后提交操作,因而 `validateFieldsAndScroll` 拆成更独立的 `scrollToField` 方法:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
onSubmit = () => {
|
||||
form.validateFieldsAndScroll((error, values) => {
|
||||
// Your logic
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
onFinishFailed = ({ errorFields }) => {
|
||||
form.scrollToField(errorFields[0].name);
|
||||
};
|
||||
```
|
||||
|
||||
## 初始化调整
|
||||
|
||||
此外,我们将 `initialValue` 从字段中移到 Form 中。以避免同名字段设置 `initialValue` 的冲突问题:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
const Demo = ({ form: { getFieldDecorator } }) => (
|
||||
<Form>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('username', {
|
||||
rules: [{ required: true }],
|
||||
initialValue: 'Bamboo',
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
|
||||
const WrappedDemo = Form.create()(Demo);
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
const Demo = () => (
|
||||
<Form initialValues={{ username: 'Bamboo' }}>
|
||||
<Form.Item name="username" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
```
|
||||
|
||||
在 v3 版本中,修改未操作的字段 `initialValue` 会同步更新字段值,这是一个 BUG。但是由于被长期作为一个 feature 使用,因而我们一直没有修复。在 v4 中,该 BUG 已被修复。`initialValue` 只有在初始化以及重置表单时生效。
|
||||
|
||||
## 嵌套字段路径使用数组
|
||||
|
||||
过去版本我们通过 `.` 代表嵌套路径(诸如 `user.name` 来代表 `{ user: { name: '' } }`)。然而在一些后台系统中,变量名中也会带上 `.`。这造成用户需要额外的代码进行转化,因而新版中,嵌套路径通过数组来表示以避免错误的处理行为(如 `['user', 'name']`)。
|
||||
|
||||
也因此,诸如 `getFieldsError` 等方法返回的路径总是数组形式以便于用户处理:
|
||||
|
||||
```jsx
|
||||
form.getFieldsError();
|
||||
|
||||
/*
|
||||
[
|
||||
{ name: ['user', 'name'], errors: [] },
|
||||
{ name: ['user', 'age'], errors: ['Some error message'] },
|
||||
]
|
||||
*/
|
||||
```
|
||||
|
||||
嵌套字段定义由:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
<Form.Item label="Firstname">{getFieldDecorator('user.0.firstname', {})(<Input />)}</Form.Item>
|
||||
```
|
||||
|
||||
改至:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
<Form.Item name={['user', 0, 'firstname']} label="Firstname">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
```
|
||||
|
||||
相似的,`setFieldsValue` 由:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
this.formRef.current.setFieldsValue({
|
||||
'user.0.firstname': 'John',
|
||||
});
|
||||
```
|
||||
|
||||
改至:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
this.formRef.current.setFieldsValue({
|
||||
user: [
|
||||
{
|
||||
firstname: 'John',
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
## validateFields 不再支持 callback
|
||||
|
||||
`validateFields` 会返回 Promise 对象,因而你可以通过 `async/await` 或者 `then/catch` 来执行对应的错误处理。不再需要判断 `errors` 是否为空:
|
||||
|
||||
```jsx
|
||||
// antd v3
|
||||
validateFields((err, value) => {
|
||||
if (!err) {
|
||||
// Do something with value
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
改成:
|
||||
|
||||
```jsx
|
||||
// antd v4
|
||||
validateFields().then(values => {
|
||||
// Do something with value
|
||||
});
|
||||
```
|
@ -1,274 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/menu/demo/deprecated.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<ul
|
||||
class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light"
|
||||
data-menu-list="true"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-overflow-item ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="opacity:1;order:0"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
aria-label="mail"
|
||||
class="anticon anticon-mail ant-menu-item-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="mail"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="ant-menu-title-content"
|
||||
>
|
||||
Navigation One
|
||||
</span>
|
||||
</li>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<li
|
||||
class="ant-menu-overflow-item ant-menu-submenu ant-menu-submenu-horizontal"
|
||||
role="none"
|
||||
style="opacity:1;order:1"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-menu-submenu-title"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
aria-label="setting"
|
||||
class="anticon anticon-setting ant-menu-item-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="setting"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="ant-menu-title-content"
|
||||
>
|
||||
Navigation Two - Submenu
|
||||
</span>
|
||||
<i
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-hidden="true"
|
||||
class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal"
|
||||
role="none"
|
||||
style="opacity:0;height:0;overflow-y:hidden;order:9007199254740991;pointer-events:none;position:absolute"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-menu-submenu-title"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<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>
|
||||
<i
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-menu-submenu ant-menu-submenu-popup ant-menu-light"
|
||||
style="opacity:0"
|
||||
>
|
||||
<ul
|
||||
class="ant-menu ant-menu-sub ant-menu-vertical"
|
||||
data-menu-list="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>,
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display:none"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-menu-inline-collapsed-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders ./components/menu/demo/horizontal.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<ul
|
||||
|
@ -1,130 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/menu/demo/deprecated.tsx correctly 1`] = `
|
||||
Array [
|
||||
<ul
|
||||
class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light"
|
||||
data-menu-list="true"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-overflow-item ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="opacity:1;order:0"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
aria-label="mail"
|
||||
class="anticon anticon-mail ant-menu-item-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="mail"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="ant-menu-title-content"
|
||||
>
|
||||
Navigation One
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-overflow-item ant-menu-submenu ant-menu-submenu-horizontal"
|
||||
role="none"
|
||||
style="opacity:1;order:1"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-menu-submenu-title"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span
|
||||
aria-label="setting"
|
||||
class="anticon anticon-setting ant-menu-item-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="setting"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="ant-menu-title-content"
|
||||
>
|
||||
Navigation Two - Submenu
|
||||
</span>
|
||||
<i
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
aria-hidden="true"
|
||||
class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal"
|
||||
role="none"
|
||||
style="opacity:0;height:0;overflow-y:hidden;order:9007199254740991;pointer-events:none;position:absolute"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="ant-menu-submenu-title"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<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>
|
||||
<i
|
||||
class="ant-menu-submenu-arrow"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>,
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style="display:none"
|
||||
/>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders ./components/menu/demo/horizontal.tsx correctly 1`] = `
|
||||
Array [
|
||||
<ul
|
||||
|
@ -1,7 +0,0 @@
|
||||
## zh-CN
|
||||
|
||||
通过语法糖的方式组织菜单目录树,在 `4.20.0` 之后推荐通过 `items` 属性实现。在下个大版本中语法糖用法将被移除从而让 Menu 可以获得更好的性能优化。
|
||||
|
||||
## en-US
|
||||
|
||||
Use the syntax sugar to organize the menu directory tree. We recommend to use `items` after `4.20.0`. In the next major version, the syntax sugar will be removed to make performance improvement be possible.
|
@ -1,29 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Menu } from 'antd';
|
||||
import { MailOutlined, AppstoreOutlined, SettingOutlined } from '@ant-design/icons';
|
||||
|
||||
const App = () => (
|
||||
<Menu mode="horizontal" defaultSelectedKeys={['mail']}>
|
||||
<Menu.Item key="mail" icon={<MailOutlined />}>
|
||||
Navigation One
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu key="SubMenu" title="Navigation Two - Submenu" icon={<SettingOutlined />}>
|
||||
<Menu.Item key="two" icon={<AppstoreOutlined />}>
|
||||
Navigation Two
|
||||
</Menu.Item>
|
||||
<Menu.Item key="three" icon={<AppstoreOutlined />}>
|
||||
Navigation Three
|
||||
</Menu.Item>
|
||||
<Menu.ItemGroup title="Item Group">
|
||||
<Menu.Item key="four" icon={<AppstoreOutlined />}>
|
||||
Navigation Four
|
||||
</Menu.Item>
|
||||
<Menu.Item key="five" icon={<AppstoreOutlined />}>
|
||||
Navigation Five
|
||||
</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
export default App;
|
@ -18,39 +18,9 @@ More layouts with navigation: [Layout](/components/layout).
|
||||
- Menu is rendered as a `ul` element, so it only supports [`li` and `script-supporting` elements](https://html.spec.whatwg.org/multipage/grouping-content.html#the-ul-element) as children nodes。Your customized node should be wrapped by `Menu.Item`.
|
||||
- Menu needs to collect its node structure, so its children should be `Menu.*` or encapsulated HOCs.
|
||||
|
||||
### Usage upgrade after 4.20.0
|
||||
|
||||
<Alert message="After version 4.20.0, we provide a simpler usage <Menu items={[...]} /> with better performance and potential of writing simpler code style in your applications. Meanwhile, we deprecated the old usage in browser console, we will remove it in antd 5.0."></Alert>
|
||||
|
||||
```jsx
|
||||
// works when >=4.20.0, recommended ✅
|
||||
const items = [
|
||||
{ label: 'item 1', key: 'item-1' }, // remember to pass the key prop
|
||||
{ label: 'item 2', key: 'item-2' }, // which is required
|
||||
{
|
||||
label: 'sub menu',
|
||||
key: 'submenu',
|
||||
children: [{ label: 'item 3', key: 'submenu-item-1' }],
|
||||
},
|
||||
];
|
||||
return <Menu items={items} />;
|
||||
|
||||
// works when <4.20.0, deprecated when >=4.20.0 🙅🏻♀️
|
||||
<Menu>
|
||||
<Menu.Item>item 1</Menu.Item>
|
||||
<Menu.Item>item 2</Menu.Item>
|
||||
<Menu.SubMenu title="sub menu">
|
||||
<Menu.Item>item 3</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>;
|
||||
```
|
||||
|
||||
The legacy demo code for version `<4.20.0` could be found at [https://github.com/ant-design/ant-design/tree/4.19.5/components/menu/demo](https://github.com/ant-design/ant-design/tree/4.19.5/components/menu/demo).
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">Basic usage (deprecated syntactic sugar)</code>
|
||||
<code src="./demo/horizontal.tsx">Top Navigation</code>
|
||||
<code src="./demo/inline.tsx">Inline menu</code>
|
||||
<code src="./demo/inline-collapsed.tsx">Collapsed inline menu</code>
|
||||
@ -108,25 +78,6 @@ The legacy demo code for version `<4.20.0` could be found at [https://github.com
|
||||
| label | Menu label | ReactNode | - | |
|
||||
| title | Set display title for collapsed item | string | - | |
|
||||
|
||||
> Note: `icon` is a newly added prop in `4.2.0`. For previous versions, please use the following method to define the icon.
|
||||
>
|
||||
> ```jsx
|
||||
> <Menu.Item>
|
||||
> <PieChartOutlined />
|
||||
> <span>Option 1</span>
|
||||
> </Menu.Item>
|
||||
> <Menu.SubMenu
|
||||
> title={
|
||||
> <>
|
||||
> <PieChartOutlined />
|
||||
> <span>Option 2</span>
|
||||
> </>
|
||||
> }
|
||||
> >
|
||||
> ...
|
||||
> </Menu.SubMenu>
|
||||
> ```
|
||||
|
||||
#### SubMenuType
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
|
@ -19,39 +19,9 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*KeyQQL5iKkkAAAAAAA
|
||||
- Menu 元素为 `ul`,因而仅支持 [`li` 以及 `script-supporting` 子元素](https://html.spec.whatwg.org/multipage/grouping-content.html#the-ul-element)。因而你的子节点元素应该都在 `Menu.Item` 内使用。
|
||||
- Menu 需要计算节点结构,因而其子元素仅支持 `Menu.*` 以及对此进行封装的 HOC 组件。
|
||||
|
||||
### 4.20.0 用法升级
|
||||
|
||||
<Alert message="在 4.20.0 版本后,我们提供了 <Menu items={[...]} /> 的简写方式,有更好的性能和更方便的数据组织方式,开发者不再需要自行拼接 JSX。同时我们废弃了原先的写法,你还是可以在 4.x 继续使用,但会在控制台看到警告,并会在 5.0 后移除。"></Alert>
|
||||
|
||||
```jsx
|
||||
// >=4.20.0 可用,推荐的写法 ✅
|
||||
const items = [
|
||||
{ label: '菜单项一', key: 'item-1' }, // 菜单项务必填写 key
|
||||
{ label: '菜单项二', key: 'item-2' },
|
||||
{
|
||||
label: '子菜单',
|
||||
key: 'submenu',
|
||||
children: [{ label: '子菜单项', key: 'submenu-item-1' }],
|
||||
},
|
||||
];
|
||||
return <Menu items={items} />;
|
||||
|
||||
// <4.20.0 可用,>=4.20.0 时不推荐 🙅🏻♀️
|
||||
<Menu>
|
||||
<Menu.Item>菜单项一</Menu.Item>
|
||||
<Menu.Item>菜单项二</Menu.Item>
|
||||
<Menu.SubMenu title="子菜单">
|
||||
<Menu.Item>子菜单项</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>;
|
||||
```
|
||||
|
||||
`<4.20.0` 版本的 JSX 演示写法可以参考 [https://github.com/ant-design/ant-design/tree/4.19.5/components/menu/demo](https://github.com/ant-design/ant-design/tree/4.19.5/components/menu/demo)。
|
||||
|
||||
## 代码演示
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">基础用法(废弃的语法糖)</code>
|
||||
<code src="./demo/horizontal.tsx">顶部导航</code>
|
||||
<code src="./demo/inline.tsx">内嵌菜单</code>
|
||||
<code src="./demo/inline-collapsed.tsx">缩起内嵌菜单</code>
|
||||
@ -109,25 +79,6 @@ return <Menu items={items} />;
|
||||
| label | 菜单项标题 | ReactNode | - | |
|
||||
| title | 设置收缩时展示的悬浮标题 | string | - | |
|
||||
|
||||
> 注意:`icon` 是 `4.2.0` 新增的属性,之前的版本请使用下面的方式定义图标。
|
||||
>
|
||||
> ```jsx
|
||||
> <Menu.Item>
|
||||
> <PieChartOutlined />
|
||||
> <span>Option 1</span>
|
||||
> </Menu.Item>
|
||||
> <Menu.SubMenu
|
||||
> title={
|
||||
> <>
|
||||
> <PieChartOutlined />
|
||||
> <span>Option 2</span>
|
||||
> </>
|
||||
> }
|
||||
> >
|
||||
> ...
|
||||
> </Menu.SubMenu>
|
||||
> ```
|
||||
|
||||
#### SubMenuType
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
|
@ -528,139 +528,6 @@ exports[`renders ./components/steps/demo/customized-progress-dot.tsx extend cont
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/deprecated.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="check"
|
||||
class="anticon anticon-check ant-steps-finish-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="check"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 00-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Finished
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
In Progress
|
||||
<div
|
||||
class="ant-steps-item-subtitle"
|
||||
title="Left 00:00:08"
|
||||
>
|
||||
Left 00:00:08
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Waiting
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/error.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
|
@ -384,139 +384,6 @@ exports[`renders ./components/steps/demo/customized-progress-dot.tsx correctly 1
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/deprecated.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-finish"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="check"
|
||||
class="anticon anticon-check ant-steps-finish-icon"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="check"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 00-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Finished
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-process ant-steps-item-active"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
In Progress
|
||||
<div
|
||||
class="ant-steps-item-subtitle"
|
||||
title="Left 00:00:08"
|
||||
>
|
||||
Left 00:00:08
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item ant-steps-item-wait"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-container"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-tail"
|
||||
/>
|
||||
<div
|
||||
class="ant-steps-item-icon"
|
||||
>
|
||||
<span
|
||||
class="ant-steps-icon"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-content"
|
||||
>
|
||||
<div
|
||||
class="ant-steps-item-title"
|
||||
>
|
||||
Waiting
|
||||
</div>
|
||||
<div
|
||||
class="ant-steps-item-description"
|
||||
>
|
||||
This is a description.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/steps/demo/error.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-steps ant-steps-horizontal ant-steps-label-horizontal"
|
||||
|
@ -1,7 +0,0 @@
|
||||
## zh-CN
|
||||
|
||||
简单的步骤条。
|
||||
|
||||
## en-US
|
||||
|
||||
The most basic step bar.
|
@ -1,14 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Steps } from 'antd';
|
||||
|
||||
const { Step } = Steps;
|
||||
const description = 'This is a description.';
|
||||
const App: React.FC = () => (
|
||||
<Steps current={1}>
|
||||
<Step title="Finished" description={description} />
|
||||
<Step title="In Progress" description={description} subTitle="Left 00:00:08" />
|
||||
<Step title="Waiting" description={description} />
|
||||
</Steps>
|
||||
);
|
||||
|
||||
export default App;
|
@ -11,27 +11,9 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*677sTqCpE3wAAAAAAA
|
||||
|
||||
When a given task is complicated or has a certain sequence in the series of subtasks, we can decompose it into several steps to make things easier.
|
||||
|
||||
### Usage upgrade after 4.24.0
|
||||
|
||||
<Alert message="After version 4.24.0, we provide a simpler usage <Steps items={[...]} /> with better performance and potential of writing simpler code style in your applications. Meanwhile, we deprecated the old usage in browser console, we will remove it in antd 5.0."></Alert>
|
||||
|
||||
```jsx
|
||||
// works when >=4.24.0, recommended ✅
|
||||
const items = [{ title: 'first step' }, { title: 'second step' }, { title: 'third step' }];
|
||||
return <Steps items={items} />;
|
||||
|
||||
// works when <4.24.0, deprecated when >=4.24.0 🙅🏻♀️
|
||||
<Steps>
|
||||
<Step title="first step" />
|
||||
<Step title="second step" />
|
||||
<Step title="third step" />
|
||||
</Steps>;
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">Basic (deprecated syntactic sugar)</code>
|
||||
<code src="./demo/simple.tsx">Basic</code>
|
||||
<code src="./demo/small-size.tsx">Mini version</code>
|
||||
<code src="./demo/icon.tsx">With icon</code>
|
||||
|
@ -12,27 +12,9 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*677sTqCpE3wAAAAAAA
|
||||
|
||||
当任务复杂或者存在先后关系时,将其分解成一系列步骤,从而简化任务。
|
||||
|
||||
### 4.24.0 用法升级
|
||||
|
||||
<Alert message="在 4.24.0 版本后,我们提供了 <Steps items={[...]} /> 的简写方式,有更好的性能和更方便的数据组织方式,开发者不再需要自行拼接 JSX。同时我们废弃了原先的写法,你还是可以在 4.x 继续使用,但会在控制台看到警告,并会在 5.0 后移除。"></Alert>
|
||||
|
||||
```jsx
|
||||
// >=4.24.0 可用,推荐的写法 ✅
|
||||
const items = [{ title: '第一步' }, { title: '第二步' }, { title: '第三步' }];
|
||||
return <Steps items={items} />;
|
||||
|
||||
// <4.24.0 可用,>=4.24.0 时不推荐 🙅🏻♀️
|
||||
<Steps>
|
||||
<Step title="第一步" />
|
||||
<Step title="第二步" />
|
||||
<Step title="第三步" />
|
||||
</Steps>;
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">基本用法 (废弃的语法糖)</code>
|
||||
<code src="./demo/simple.tsx">基本用法</code>
|
||||
<code src="./demo/small-size.tsx">迷你版</code>
|
||||
<code src="./demo/icon.tsx">带图标的步骤条</code>
|
||||
|
@ -329,12 +329,6 @@ return <Table rowKey="uid" />;
|
||||
return <Table rowKey={(record) => record.uid} />;
|
||||
```
|
||||
|
||||
## Migrate to v4
|
||||
|
||||
Table removes `onRowClick`, `onRowDoubleClick`, `onRowMouseEnter`, `onRowMouseLeave` and some other api which is already deprecated in v3. If you only use api listing in official document, that's OK.
|
||||
|
||||
Besides, the breaking change is changing `dataIndex` from nest string path like `user.age` to string array path like `['user', 'age']`. This help to resolve developer should additional work on the field which contains `.`.
|
||||
|
||||
## FAQ
|
||||
|
||||
### How to hide pagination when single page or no data?
|
||||
|
@ -332,12 +332,6 @@ return <Table rowKey="uid" />;
|
||||
return <Table rowKey={(record) => record.uid} />;
|
||||
```
|
||||
|
||||
## 从 v3 升级到 v4
|
||||
|
||||
Table 移除了在 v3 中废弃的 `onRowClick`、`onRowDoubleClick`、`onRowMouseEnter`、`onRowMouseLeave` 等方法。如果你使用的 api 为文档中列举的 api,那你不用担心会丢失功能。
|
||||
|
||||
此外,比较重大的改动为 `dataIndex` 从支持路径嵌套如 `user.age` 改成了数组路径如 `['user', 'age']`。以解决过去属性名带 `.` 需要额外的数据转化问题。
|
||||
|
||||
## FAQ
|
||||
|
||||
### 如何在没有数据或只有一页数据时隐藏分页栏
|
||||
|
@ -1197,136 +1197,6 @@ exports[`renders ./components/tabs/demo/custom-tab-bar-node.tsx extend context c
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tabs/demo/deprecated.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"
|
||||
>
|
||||
<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
|
||||
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
|
||||
class="ant-tabs-dropdown"
|
||||
style="opacity:0"
|
||||
>
|
||||
<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="null-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"
|
||||
>
|
||||
<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/disabled.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top"
|
||||
|
@ -1045,117 +1045,6 @@ exports[`renders ./components/tabs/demo/custom-tab-bar-node.tsx correctly 1`] =
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tabs/demo/deprecated.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"
|
||||
>
|
||||
<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
|
||||
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/disabled.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-tabs ant-tabs-top"
|
||||
|
@ -1,7 +0,0 @@
|
||||
## zh-CN
|
||||
|
||||
默认选中第一项。
|
||||
|
||||
## en-US
|
||||
|
||||
Default activate first tab.
|
@ -1,18 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Tabs } from 'antd';
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Tabs defaultActiveKey="1">
|
||||
<Tabs.TabPane tab="Tab 1" key="1">
|
||||
Content of Tab Pane 1
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Tab 2" key="2">
|
||||
Content of Tab Pane 2
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Tab 3" key="3">
|
||||
Content of Tab Pane 3
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
);
|
||||
|
||||
export default App;
|
@ -15,33 +15,9 @@ Ant Design has 3 types of Tabs for different situations.
|
||||
- Normal Tabs: for functional aspects of a page.
|
||||
- [Radio.Button](/components/radio/#components-radio-demo-radiobutton): for secondary tabs.
|
||||
|
||||
### Usage upgrade after 4.23.0
|
||||
|
||||
<Alert message="After version 4.23.0, we provide a simpler usage <Tabs items={[...]} /> with better performance and potential of writing simpler code style in your applications. Meanwhile, we deprecated the old usage in browser console, we will remove it in antd 5.0."></Alert>
|
||||
|
||||
```jsx
|
||||
// works when >=4.23.0, recommended ✅
|
||||
const items = [
|
||||
{ label: 'Tab 1', key: 'item-1', children: 'Content 1' }, // remember to pass the key prop
|
||||
{ label: 'Tab 2', key: 'item-2', children: 'Content 2' },
|
||||
];
|
||||
return <Tabs items={items} />;
|
||||
|
||||
// works when <4.23.0, deprecated when >=4.23.0 🙅🏻♀️
|
||||
<Tabs>
|
||||
<Tabs.TabPane tab="Tab 1" key="item-1">
|
||||
Content 1
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Tab 2" key="item-2">
|
||||
Content 2
|
||||
</Tabs.TabPane>
|
||||
</Tabs>;
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">Basic usage (deprecated syntactic sugar)</code>
|
||||
<code src="./demo/basic.tsx">Basic</code>
|
||||
<code src="./demo/disabled.tsx">Disabled</code>
|
||||
<code src="./demo/centered.tsx">Centered</code>
|
||||
|
@ -18,33 +18,9 @@ Ant Design 依次提供了三级选项卡,分别用于不同的场景。
|
||||
- 既可用于容器顶部,也可用于容器内部,是最通用的 Tabs。
|
||||
- [Radio.Button](/components/radio/#components-radio-demo-radiobutton) 可作为更次级的页签来使用。
|
||||
|
||||
### 4.23.0 用法升级
|
||||
|
||||
<Alert message="在 4.23.0 版本后,我们提供了 <Tabs items={[...]} /> 的简写方式,有更好的性能和更方便的数据组织方式,开发者不再需要自行拼接 JSX。同时我们废弃了原先的写法,你还是可以在 4.x 继续使用,但会在控制台看到警告,并会在 5.0 后移除。"></Alert>
|
||||
|
||||
```jsx
|
||||
// >=4.23.0 可用,推荐的写法 ✅
|
||||
const items = [
|
||||
{ label: '项目 1', key: 'item-1', children: '内容 1' }, // 务必填写 key
|
||||
{ label: '项目 2', key: 'item-2', children: '内容 2' },
|
||||
];
|
||||
return <Tabs items={items} />;
|
||||
|
||||
// <4.23.0 可用,>=4.23.0 时不推荐 🙅🏻♀️
|
||||
<Tabs>
|
||||
<Tabs.TabPane tab="项目 1" key="item-1">
|
||||
内容 1
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="项目 2" key="item-2">
|
||||
内容 2
|
||||
</Tabs.TabPane>
|
||||
</Tabs>;
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/deprecated.tsx">基础用法(废弃的语法糖)</code>
|
||||
<code src="./demo/basic.tsx">基本</code>
|
||||
<code src="./demo/disabled.tsx">禁用</code>
|
||||
<code src="./demo/centered.tsx">居中</code>
|
||||
|
Loading…
Reference in New Issue
Block a user