mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 09:26:06 +08:00
merge featrue into master (#30636)
* feat: add Table expandable fixed (#29959) * fix: Use flex gap of space (#30023) * fix: use flex gap when supported * test: update snapshot * refactor: Use single hooks * feat: Allow breadcrumb component in PageHeader (#30019) * Allow breadcrumb component in PageHeader * Allow breadcrumb component in PageHeader * Allow breadcrumb component in PageHeader * Rename variable rename var from _breadcrumbRender to breadcrumbRenderDomFromProps * feat: add onChange for Statistic.Countdown (#30265) * feat: add onChange for countdown * update the demo * feat(upload): add onDrop (#30319) * feat(upload): Add onDrop * Replace "if prop" logic with existential operator * Remove redundant conditional * feat(upload): itemRender add actions params (#30236) * feat(upload): itemRender add actions params * chore: optimize type definition * chore: update doc * chore: rename actions * chore: trigger ci * chore: rename method name of actions * feat: Add missing dutch translations (#30389) * feat: Add missing dutch translations * fix: Translate remaining english values * fix: Update snapshot for ui tests * test: increase code coverage to 100% (#30415) * test: fix Space code coverage * test: should use nl_BE locale for DatePicker * fix: Switch tabIndex type (#30416) * feat: updated Romanian internationalization (#30419) * feat: updated Romanian internationalization * fixed lint error * feat: Menu support accessibility & keyboard access (#30382) * chore: Use focus style * fix: prefixCls * fix: prefixCls * fix: inline tooltip * fix: inlineCollapse logic * fix: ts definition * test: Update snapshot * test: Update snapshot * fix: dropdown logic * test: Update snapshot * test: Fix some test case * bump rc-menu * test: More test case * fix test finder * test: fix test case * test: Update snapshot * test: Update snapshot * chore: Update ssr effect * test: Update ConfigProvider snapshot * test: Fix Table Filter test case * test: Fix table test case * chore: Update style * chore: beauti css * bump rc-menu * test: update snapshot * test: update snapshot * test: Fix menu test * test: Fix test case * test: Coverage * chore: clean up * bump rc-menu * ehance accessibility style * feat(radioGroup): support data-* and aria-* props (#30507) close #30501 * feat: Typography add italic type (#30458) * Typography增加斜体字支持 * update snapshot * 文档添加版本号 Co-authored-by: lidahao <lidahao@sisyphe.com.cn> * chore: alpha Menu fix merge (#30546) * chore: Update script * bump alpha version * chore: Update script desc * chore: bump rc-tabs & rc-mentions * chore: Adjust style * chore: 4.16.0-alpha.1 * test: Fix mention test case * fix: sider of layout width style * chore: bump 4.16.0-alpha.2 * fix: Tabs tabBarGutter should work as expected (#30545) close #30526 * feat: Table summary support sticky mode (#30631) * chore: Bump rc-table * feat: Patch summary fixed color * fix: style className * test: Update snapshot Co-authored-by: xrkffgg <xrkffgg@gmail.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: 二货机器人 <smith3816@gmail.com> Co-authored-by: gepd <guillermoepd@hotmail.com> Co-authored-by: appleshell <appleshell@outlook.com> Co-authored-by: Eric Bonow <ebonow@hotmail.com> Co-authored-by: xrkffgg <xrkffgg@vip.qq.com> Co-authored-by: Kermit <kermitlx@outlook.com> Co-authored-by: Lewis <lewisfidlers@gmail.com> Co-authored-by: afc163 <afc163@gmail.com> Co-authored-by: Ștefan Filip <stefy.filip@gmail.com> Co-authored-by: vldh <alwaysloseall@sina.com> Co-authored-by: lidahao <lidahao@sisyphe.com.cn>
This commit is contained in:
parent
9275866f24
commit
0d1b1c40a6
@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { detectFlexGapSupported } from '../../_util/styleChecker';
|
import { detectFlexGapSupported } from '../styleChecker';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [flexible, setFlexible] = React.useState(false);
|
const [flexible, setFlexible] = React.useState(false);
|
@ -15038,20 +15038,22 @@ exports[`ConfigProvider components List prefixCls 1`] = `
|
|||||||
|
|
||||||
exports[`ConfigProvider components Menu configProvider 1`] = `
|
exports[`ConfigProvider components Menu configProvider 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="config-menu config-menu-light config-menu-root config-menu-inline"
|
class="config-menu config-menu-root config-menu-inline config-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="config-menu-submenu config-menu-submenu-inline config-menu-submenu-open"
|
class="config-menu-submenu config-menu-submenu-inline config-menu-submenu-open"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-owns="bamboo$Menu"
|
|
||||||
class="config-menu-submenu-title"
|
class="config-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
style="padding-left:24px"
|
style="padding-left:24px"
|
||||||
|
tabindex="-1"
|
||||||
title="bamboo"
|
title="bamboo"
|
||||||
>
|
>
|
||||||
bamboo
|
bamboo
|
||||||
@ -15061,11 +15063,10 @@ exports[`ConfigProvider components Menu configProvider 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="config-menu config-menu-sub config-menu-inline"
|
class="config-menu config-menu-sub config-menu-inline"
|
||||||
id="bamboo$Menu"
|
data-menu-list="true"
|
||||||
role="menu"
|
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class=" config-menu-item-group"
|
class="config-menu-item-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-menu-item-group-title"
|
class="config-menu-item-group-title"
|
||||||
@ -15080,6 +15081,7 @@ exports[`ConfigProvider components Menu configProvider 1`] = `
|
|||||||
class="config-menu-item config-menu-item-only-child"
|
class="config-menu-item config-menu-item-only-child"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left:48px"
|
style="padding-left:48px"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</li>
|
</li>
|
||||||
@ -15092,20 +15094,22 @@ exports[`ConfigProvider components Menu configProvider 1`] = `
|
|||||||
|
|
||||||
exports[`ConfigProvider components Menu configProvider componentSize large 1`] = `
|
exports[`ConfigProvider components Menu configProvider componentSize large 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="config-menu config-menu-light config-menu-root config-menu-inline"
|
class="config-menu config-menu-root config-menu-inline config-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="config-menu-submenu config-menu-submenu-inline config-menu-submenu-open"
|
class="config-menu-submenu config-menu-submenu-inline config-menu-submenu-open"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-owns="bamboo$Menu"
|
|
||||||
class="config-menu-submenu-title"
|
class="config-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
style="padding-left:24px"
|
style="padding-left:24px"
|
||||||
|
tabindex="-1"
|
||||||
title="bamboo"
|
title="bamboo"
|
||||||
>
|
>
|
||||||
bamboo
|
bamboo
|
||||||
@ -15115,11 +15119,10 @@ exports[`ConfigProvider components Menu configProvider componentSize large 1`] =
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="config-menu config-menu-sub config-menu-inline"
|
class="config-menu config-menu-sub config-menu-inline"
|
||||||
id="bamboo$Menu"
|
data-menu-list="true"
|
||||||
role="menu"
|
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class=" config-menu-item-group"
|
class="config-menu-item-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-menu-item-group-title"
|
class="config-menu-item-group-title"
|
||||||
@ -15134,6 +15137,7 @@ exports[`ConfigProvider components Menu configProvider componentSize large 1`] =
|
|||||||
class="config-menu-item config-menu-item-only-child"
|
class="config-menu-item config-menu-item-only-child"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left:48px"
|
style="padding-left:48px"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</li>
|
</li>
|
||||||
@ -15146,20 +15150,22 @@ exports[`ConfigProvider components Menu configProvider componentSize large 1`] =
|
|||||||
|
|
||||||
exports[`ConfigProvider components Menu configProvider componentSize middle 1`] = `
|
exports[`ConfigProvider components Menu configProvider componentSize middle 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="config-menu config-menu-light config-menu-root config-menu-inline"
|
class="config-menu config-menu-root config-menu-inline config-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="config-menu-submenu config-menu-submenu-inline config-menu-submenu-open"
|
class="config-menu-submenu config-menu-submenu-inline config-menu-submenu-open"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-owns="bamboo$Menu"
|
|
||||||
class="config-menu-submenu-title"
|
class="config-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
style="padding-left:24px"
|
style="padding-left:24px"
|
||||||
|
tabindex="-1"
|
||||||
title="bamboo"
|
title="bamboo"
|
||||||
>
|
>
|
||||||
bamboo
|
bamboo
|
||||||
@ -15169,11 +15175,10 @@ exports[`ConfigProvider components Menu configProvider componentSize middle 1`]
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="config-menu config-menu-sub config-menu-inline"
|
class="config-menu config-menu-sub config-menu-inline"
|
||||||
id="bamboo$Menu"
|
data-menu-list="true"
|
||||||
role="menu"
|
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class=" config-menu-item-group"
|
class="config-menu-item-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="config-menu-item-group-title"
|
class="config-menu-item-group-title"
|
||||||
@ -15188,6 +15193,7 @@ exports[`ConfigProvider components Menu configProvider componentSize middle 1`]
|
|||||||
class="config-menu-item config-menu-item-only-child"
|
class="config-menu-item config-menu-item-only-child"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left:48px"
|
style="padding-left:48px"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</li>
|
</li>
|
||||||
@ -15200,20 +15206,22 @@ exports[`ConfigProvider components Menu configProvider componentSize middle 1`]
|
|||||||
|
|
||||||
exports[`ConfigProvider components Menu configProvider virtual and dropdownMatchSelectWidth 1`] = `
|
exports[`ConfigProvider components Menu configProvider virtual and dropdownMatchSelectWidth 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
class="ant-menu ant-menu-root ant-menu-inline ant-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-owns="bamboo$Menu"
|
|
||||||
class="ant-menu-submenu-title"
|
class="ant-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
style="padding-left:24px"
|
style="padding-left:24px"
|
||||||
|
tabindex="-1"
|
||||||
title="bamboo"
|
title="bamboo"
|
||||||
>
|
>
|
||||||
bamboo
|
bamboo
|
||||||
@ -15223,11 +15231,10 @@ exports[`ConfigProvider components Menu configProvider virtual and dropdownMatch
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||||
id="bamboo$Menu"
|
data-menu-list="true"
|
||||||
role="menu"
|
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class=" ant-menu-item-group"
|
class="ant-menu-item-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-menu-item-group-title"
|
class="ant-menu-item-group-title"
|
||||||
@ -15242,6 +15249,7 @@ exports[`ConfigProvider components Menu configProvider virtual and dropdownMatch
|
|||||||
class="ant-menu-item ant-menu-item-only-child"
|
class="ant-menu-item ant-menu-item-only-child"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left:48px"
|
style="padding-left:48px"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</li>
|
</li>
|
||||||
@ -15254,20 +15262,22 @@ exports[`ConfigProvider components Menu configProvider virtual and dropdownMatch
|
|||||||
|
|
||||||
exports[`ConfigProvider components Menu normal 1`] = `
|
exports[`ConfigProvider components Menu normal 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
class="ant-menu ant-menu-root ant-menu-inline ant-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-owns="bamboo$Menu"
|
|
||||||
class="ant-menu-submenu-title"
|
class="ant-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
style="padding-left:24px"
|
style="padding-left:24px"
|
||||||
|
tabindex="-1"
|
||||||
title="bamboo"
|
title="bamboo"
|
||||||
>
|
>
|
||||||
bamboo
|
bamboo
|
||||||
@ -15277,11 +15287,10 @@ exports[`ConfigProvider components Menu normal 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||||
id="bamboo$Menu"
|
data-menu-list="true"
|
||||||
role="menu"
|
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class=" ant-menu-item-group"
|
class="ant-menu-item-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-menu-item-group-title"
|
class="ant-menu-item-group-title"
|
||||||
@ -15296,6 +15305,7 @@ exports[`ConfigProvider components Menu normal 1`] = `
|
|||||||
class="ant-menu-item ant-menu-item-only-child"
|
class="ant-menu-item ant-menu-item-only-child"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left:48px"
|
style="padding-left:48px"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</li>
|
</li>
|
||||||
@ -15308,20 +15318,22 @@ exports[`ConfigProvider components Menu normal 1`] = `
|
|||||||
|
|
||||||
exports[`ConfigProvider components Menu prefixCls 1`] = `
|
exports[`ConfigProvider components Menu prefixCls 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="prefix-Menu prefix-Menu-light prefix-Menu-root prefix-Menu-inline"
|
class="prefix-Menu prefix-Menu-root prefix-Menu-inline prefix-Menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="prefix-Menu-submenu prefix-Menu-submenu-inline prefix-Menu-submenu-open"
|
class="prefix-Menu-submenu prefix-Menu-submenu-inline prefix-Menu-submenu-open"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-owns="bamboo$Menu"
|
|
||||||
class="prefix-Menu-submenu-title"
|
class="prefix-Menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
style="padding-left:24px"
|
style="padding-left:24px"
|
||||||
|
tabindex="-1"
|
||||||
title="bamboo"
|
title="bamboo"
|
||||||
>
|
>
|
||||||
bamboo
|
bamboo
|
||||||
@ -15331,11 +15343,11 @@ exports[`ConfigProvider components Menu prefixCls 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
class="prefix-Menu prefix-Menu-sub prefix-Menu-inline"
|
class="prefix-Menu prefix-Menu-sub prefix-Menu-inline"
|
||||||
id="bamboo$Menu"
|
data-menu-list="true"
|
||||||
role="menu"
|
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class=" prefix-Menu-item-group"
|
class="prefix-Menu-item-group"
|
||||||
|
prefixcls="prefix-Menu"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="prefix-Menu-item-group-title"
|
class="prefix-Menu-item-group-title"
|
||||||
@ -15348,8 +15360,10 @@ exports[`ConfigProvider components Menu prefixCls 1`] = `
|
|||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="prefix-Menu-item prefix-Menu-item-only-child"
|
class="prefix-Menu-item prefix-Menu-item-only-child"
|
||||||
|
prefixcls="prefix-Menu"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left:48px"
|
style="padding-left:48px"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Light
|
Light
|
||||||
</li>
|
</li>
|
||||||
@ -22853,12 +22867,15 @@ exports[`ConfigProvider components Table configProvider 1`] = `
|
|||||||
class="config-table-filter-dropdown"
|
class="config-table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="config-dropdown-menu config-dropdown-menu-light config-dropdown-menu-root config-dropdown-menu-vertical"
|
class="config-dropdown-menu config-dropdown-menu-root config-dropdown-menu-vertical config-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="config-dropdown-menu-item"
|
class="config-dropdown-menu-item"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="config-checkbox-wrapper"
|
class="config-checkbox-wrapper"
|
||||||
@ -22881,13 +22898,14 @@ exports[`ConfigProvider components Table configProvider 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="config-dropdown-menu-submenu config-dropdown-menu-submenu-vertical"
|
class="config-dropdown-menu-submenu config-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="config-dropdown-menu-submenu-title"
|
class="config-dropdown-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Submenu"
|
title="Submenu"
|
||||||
>
|
>
|
||||||
Submenu
|
Submenu
|
||||||
@ -23124,12 +23142,15 @@ exports[`ConfigProvider components Table configProvider componentSize large 1`]
|
|||||||
class="config-table-filter-dropdown"
|
class="config-table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="config-dropdown-menu config-dropdown-menu-light config-dropdown-menu-root config-dropdown-menu-vertical"
|
class="config-dropdown-menu config-dropdown-menu-root config-dropdown-menu-vertical config-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="config-dropdown-menu-item"
|
class="config-dropdown-menu-item"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="config-checkbox-wrapper"
|
class="config-checkbox-wrapper"
|
||||||
@ -23152,13 +23173,14 @@ exports[`ConfigProvider components Table configProvider componentSize large 1`]
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="config-dropdown-menu-submenu config-dropdown-menu-submenu-vertical"
|
class="config-dropdown-menu-submenu config-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="config-dropdown-menu-submenu-title"
|
class="config-dropdown-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Submenu"
|
title="Submenu"
|
||||||
>
|
>
|
||||||
Submenu
|
Submenu
|
||||||
@ -23395,12 +23417,15 @@ exports[`ConfigProvider components Table configProvider componentSize middle 1`]
|
|||||||
class="config-table-filter-dropdown"
|
class="config-table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="config-dropdown-menu config-dropdown-menu-light config-dropdown-menu-root config-dropdown-menu-vertical"
|
class="config-dropdown-menu config-dropdown-menu-root config-dropdown-menu-vertical config-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="config-dropdown-menu-item"
|
class="config-dropdown-menu-item"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="config-checkbox-wrapper"
|
class="config-checkbox-wrapper"
|
||||||
@ -23423,13 +23448,14 @@ exports[`ConfigProvider components Table configProvider componentSize middle 1`]
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="config-dropdown-menu-submenu config-dropdown-menu-submenu-vertical"
|
class="config-dropdown-menu-submenu config-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="config-dropdown-menu-submenu-title"
|
class="config-dropdown-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Submenu"
|
title="Submenu"
|
||||||
>
|
>
|
||||||
Submenu
|
Submenu
|
||||||
@ -23666,12 +23692,15 @@ exports[`ConfigProvider components Table configProvider virtual and dropdownMatc
|
|||||||
class="ant-table-filter-dropdown"
|
class="ant-table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item"
|
class="ant-dropdown-menu-item"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="ant-checkbox-wrapper"
|
class="ant-checkbox-wrapper"
|
||||||
@ -23694,13 +23723,14 @@ exports[`ConfigProvider components Table configProvider virtual and dropdownMatc
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-dropdown-menu-submenu-title"
|
class="ant-dropdown-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Submenu"
|
title="Submenu"
|
||||||
>
|
>
|
||||||
Submenu
|
Submenu
|
||||||
@ -23937,12 +23967,15 @@ exports[`ConfigProvider components Table normal 1`] = `
|
|||||||
class="ant-table-filter-dropdown"
|
class="ant-table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item"
|
class="ant-dropdown-menu-item"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="ant-checkbox-wrapper"
|
class="ant-checkbox-wrapper"
|
||||||
@ -23965,13 +23998,14 @@ exports[`ConfigProvider components Table normal 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-dropdown-menu-submenu-title"
|
class="ant-dropdown-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Submenu"
|
title="Submenu"
|
||||||
>
|
>
|
||||||
Submenu
|
Submenu
|
||||||
@ -24208,12 +24242,15 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
|
|||||||
class="prefix-Table-filter-dropdown"
|
class="prefix-Table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item"
|
class="ant-dropdown-menu-item"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="ant-checkbox-wrapper"
|
class="ant-checkbox-wrapper"
|
||||||
@ -24236,13 +24273,14 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-dropdown-menu-submenu-title"
|
class="ant-dropdown-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Submenu"
|
title="Submenu"
|
||||||
>
|
>
|
||||||
Submenu
|
Submenu
|
||||||
|
@ -77,10 +77,10 @@ The following APIs are shared by DatePicker, RangePicker.
|
|||||||
|
|
||||||
### Common Methods
|
### Common Methods
|
||||||
|
|
||||||
| Name | Description | Version |
|
| Name | Description | Version |
|
||||||
| --- | --- | --- |
|
| ------- | ------------ | ------- |
|
||||||
| blur() | Remove focus | |
|
| blur() | Remove focus | |
|
||||||
| focus() | Get focus | |
|
| focus() | Get focus | |
|
||||||
|
|
||||||
### DatePicker
|
### DatePicker
|
||||||
|
|
||||||
|
@ -5,8 +5,15 @@ import { PickerLocale } from '../generatePicker';
|
|||||||
// Merge into a locale object
|
// Merge into a locale object
|
||||||
const locale: PickerLocale = {
|
const locale: PickerLocale = {
|
||||||
lang: {
|
lang: {
|
||||||
|
monthPlaceholder: 'Selecteer maand',
|
||||||
placeholder: 'Selecteer datum',
|
placeholder: 'Selecteer datum',
|
||||||
|
quarterPlaceholder: 'Selecteer kwartaal',
|
||||||
|
rangeMonthPlaceholder: ['Begin maand', 'Eind maand'],
|
||||||
rangePlaceholder: ['Begin datum', 'Eind datum'],
|
rangePlaceholder: ['Begin datum', 'Eind datum'],
|
||||||
|
rangeWeekPlaceholder: ['Begin week', 'Eind week'],
|
||||||
|
rangeYearPlaceholder: ['Begin jaar', 'Eind jaar'],
|
||||||
|
weekPlaceholder: 'Selecteer week',
|
||||||
|
yearPlaceholder: 'Selecteer jaar',
|
||||||
...CalendarLocale,
|
...CalendarLocale,
|
||||||
},
|
},
|
||||||
timePickerLocale: {
|
timePickerLocale: {
|
||||||
|
@ -5,8 +5,15 @@ import { PickerLocale } from '../generatePicker';
|
|||||||
// Merge into a locale object
|
// Merge into a locale object
|
||||||
const locale: PickerLocale = {
|
const locale: PickerLocale = {
|
||||||
lang: {
|
lang: {
|
||||||
|
monthPlaceholder: 'Selecteer maand',
|
||||||
placeholder: 'Selecteer datum',
|
placeholder: 'Selecteer datum',
|
||||||
|
quarterPlaceholder: 'Selecteer kwartaal',
|
||||||
|
rangeMonthPlaceholder: ['Begin maand', 'Eind maand'],
|
||||||
rangePlaceholder: ['Begin datum', 'Eind datum'],
|
rangePlaceholder: ['Begin datum', 'Eind datum'],
|
||||||
|
rangeWeekPlaceholder: ['Begin week', 'Eind week'],
|
||||||
|
rangeYearPlaceholder: ['Begin jaar', 'Eind jaar'],
|
||||||
|
weekPlaceholder: 'Selecteer week',
|
||||||
|
yearPlaceholder: 'Selecteer jaar',
|
||||||
...CalendarLocale,
|
...CalendarLocale,
|
||||||
},
|
},
|
||||||
timePickerLocale: {
|
timePickerLocale: {
|
||||||
|
@ -71,7 +71,9 @@ describe('DropdownButton', () => {
|
|||||||
<Menu.Item>foo</Menu.Item>
|
<Menu.Item>foo</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
const wrapper = mount(<Dropdown.Button mouseEnterDelay={1} mouseLeaveDelay={2} overlay={menu} />);
|
const wrapper = mount(
|
||||||
|
<Dropdown.Button mouseEnterDelay={1} mouseLeaveDelay={2} overlay={menu} />,
|
||||||
|
);
|
||||||
expect(wrapper.find('Dropdown').props().mouseEnterDelay).toBe(1);
|
expect(wrapper.find('Dropdown').props().mouseEnterDelay).toBe(1);
|
||||||
expect(wrapper.find('Dropdown').props().mouseLeaveDelay).toBe(2);
|
expect(wrapper.find('Dropdown').props().mouseLeaveDelay).toBe(2);
|
||||||
});
|
});
|
||||||
|
@ -29,9 +29,11 @@ interface DropdownButtonInterface extends React.FC<DropdownButtonProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DropdownButton: DropdownButtonInterface = props => {
|
const DropdownButton: DropdownButtonInterface = props => {
|
||||||
const { getPopupContainer: getContextPopupContainer, getPrefixCls, direction } = React.useContext(
|
const {
|
||||||
ConfigContext,
|
getPopupContainer: getContextPopupContainer,
|
||||||
);
|
getPrefixCls,
|
||||||
|
direction,
|
||||||
|
} = React.useContext(ConfigContext);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
|
@ -101,8 +101,7 @@ const Dropdown: DropdownInterface = props => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// menu cannot be selectable in dropdown defaultly
|
// menu cannot be selectable in dropdown defaultly
|
||||||
// menu should be focusable in dropdown defaultly
|
const { selectable = false, expandIcon } = overlayProps;
|
||||||
const { selectable = false, focusable = true, expandIcon } = overlayProps;
|
|
||||||
|
|
||||||
const overlayNodeExpandIcon =
|
const overlayNodeExpandIcon =
|
||||||
typeof expandIcon !== 'undefined' && React.isValidElement(expandIcon) ? (
|
typeof expandIcon !== 'undefined' && React.isValidElement(expandIcon) ? (
|
||||||
@ -119,7 +118,6 @@ const Dropdown: DropdownInterface = props => {
|
|||||||
: cloneElement(overlayNode, {
|
: cloneElement(overlayNode, {
|
||||||
mode: 'vertical',
|
mode: 'vertical',
|
||||||
selectable,
|
selectable,
|
||||||
focusable,
|
|
||||||
expandIcon: overlayNodeExpandIcon,
|
expandIcon: overlayNodeExpandIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-hidden,
|
&-hidden,
|
||||||
&-menu-hidden {
|
&-menu-hidden,
|
||||||
|
&-menu-submenu-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import ResponsiveObserve, {
|
|||||||
ScreenMap,
|
ScreenMap,
|
||||||
responsiveArray,
|
responsiveArray,
|
||||||
} from '../_util/responsiveObserve';
|
} from '../_util/responsiveObserve';
|
||||||
import useFlexGapSupport from './hooks/useFlexGapSupport';
|
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
|
||||||
|
|
||||||
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
|
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
|
||||||
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between');
|
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between');
|
||||||
|
@ -21,7 +21,6 @@ const dimensionMaxMap = {
|
|||||||
|
|
||||||
export interface SiderContextProps {
|
export interface SiderContextProps {
|
||||||
siderCollapsed?: boolean;
|
siderCollapsed?: boolean;
|
||||||
collapsedWidth?: number | string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SiderContext: React.Context<SiderContextProps> = React.createContext({});
|
export const SiderContext: React.Context<SiderContextProps> = React.createContext({});
|
||||||
@ -219,7 +218,6 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>(
|
|||||||
<SiderContext.Provider
|
<SiderContext.Provider
|
||||||
value={{
|
value={{
|
||||||
siderCollapsed: collapsed,
|
siderCollapsed: collapsed,
|
||||||
collapsedWidth,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{renderSider()}
|
{renderSider()}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -204,16 +204,16 @@ describe('Layout', () => {
|
|||||||
</Sider>,
|
</Sider>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find('.ant-menu-item').simulate('mouseenter');
|
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy();
|
expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy();
|
||||||
wrapper.find('.ant-menu-item').simulate('mouseout');
|
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseout');
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
wrapper.setProps({ collapsed: true });
|
wrapper.setProps({ collapsed: true });
|
||||||
wrapper.find('.ant-menu-item').simulate('mouseenter');
|
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('.ant-tooltip-inner').length).toBeTruthy();
|
expect(wrapper.find('.ant-tooltip-inner').length).toBeTruthy();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
@import '../../style/mixins/index';
|
@import '../../style/mixins/index';
|
||||||
|
|
||||||
@layout-prefix-cls: ~'@{ant-prefix}-layout';
|
@layout-prefix-cls: ~'@{ant-prefix}-layout';
|
||||||
|
@layout-menu-prefix-cls: ~'@{ant-prefix}-menu';
|
||||||
|
|
||||||
.@{layout-prefix-cls} {
|
.@{layout-prefix-cls} {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -66,6 +67,10 @@
|
|||||||
// https://github.com/ant-design/ant-design/issues/7967
|
// https://github.com/ant-design/ant-design/issues/7967
|
||||||
// solution from https://stackoverflow.com/a/33132624/3040605
|
// solution from https://stackoverflow.com/a/33132624/3040605
|
||||||
padding-top: 0.1px;
|
padding-top: 0.1px;
|
||||||
|
|
||||||
|
.@{layout-menu-prefix-cls}.@{layout-menu-prefix-cls}-inline-collapsed {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-has-trigger {
|
&-has-trigger {
|
||||||
|
@ -211251,7 +211251,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
Annuleren
|
Annuleer
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@ -211329,7 +211329,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
class="ant-input ant-transfer-list-search"
|
class="ant-input ant-transfer-list-search"
|
||||||
placeholder="Zoeken"
|
placeholder="Zoek hier"
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
/>
|
/>
|
||||||
@ -211521,7 +211521,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
class="ant-input ant-transfer-list-search"
|
class="ant-input ant-transfer-list-search"
|
||||||
placeholder="Zoeken"
|
placeholder="Zoek hier"
|
||||||
type="text"
|
type="text"
|
||||||
value=""
|
value=""
|
||||||
/>
|
/>
|
||||||
@ -212763,7 +212763,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
Annuleren
|
Annuleer
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
|
|
||||||
import { Modal } from '../..';
|
import { Modal } from '../..';
|
||||||
|
|
||||||
import zhCN from '../zh_CN';
|
import zhCN from '../zh_CN';
|
||||||
|
|
||||||
class Demo extends React.Component {
|
class Demo extends React.Component {
|
||||||
|
@ -1,21 +1,37 @@
|
|||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
import Pagination from 'rc-pagination/lib/locale/nl_BE';
|
import Pagination from 'rc-pagination/lib/locale/nl_BE';
|
||||||
import DatePicker from '../date-picker/locale/nl_BE';
|
import DatePicker from '../date-picker/locale/nl_BE';
|
||||||
import TimePicker from '../time-picker/locale/nl_BE';
|
import TimePicker from '../time-picker/locale/nl_BE';
|
||||||
import Calendar from '../calendar/locale/nl_BE';
|
import Calendar from '../calendar/locale/nl_BE';
|
||||||
import { Locale } from '../locale-provider';
|
import { Locale } from '../locale-provider';
|
||||||
|
|
||||||
|
const typeTemplate = '${label} is geen geldige ${type}';
|
||||||
|
|
||||||
const localeValues: Locale = {
|
const localeValues: Locale = {
|
||||||
locale: 'nl-be',
|
locale: 'nl-be',
|
||||||
Pagination,
|
Pagination,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
TimePicker,
|
TimePicker,
|
||||||
Calendar,
|
Calendar,
|
||||||
|
global: {
|
||||||
|
placeholder: 'Maak een selectie',
|
||||||
|
},
|
||||||
Table: {
|
Table: {
|
||||||
filterTitle: 'FilterMenu',
|
cancelSort: 'Klik om sortering te annuleren',
|
||||||
|
collapse: 'Rij inklappen',
|
||||||
|
emptyText: 'Geen data',
|
||||||
|
expand: 'Rij uitklappen',
|
||||||
filterConfirm: 'OK',
|
filterConfirm: 'OK',
|
||||||
|
filterEmptyText: 'Geen filters',
|
||||||
filterReset: 'Reset',
|
filterReset: 'Reset',
|
||||||
|
filterTitle: 'Filteren',
|
||||||
selectAll: 'Selecteer huidige pagina',
|
selectAll: 'Selecteer huidige pagina',
|
||||||
selectInvert: 'Selecteer huidige pagina',
|
selectInvert: 'Keer volgorde om',
|
||||||
|
selectNone: 'Maak selectie leeg',
|
||||||
|
selectionAll: 'Selecteer alle data',
|
||||||
|
sortTitle: 'Sorteren',
|
||||||
|
triggerAsc: 'Klik om oplopend te sorteren',
|
||||||
|
triggerDesc: 'Klik om aflopend te sorteren',
|
||||||
},
|
},
|
||||||
Modal: {
|
Modal: {
|
||||||
okText: 'OK',
|
okText: 'OK',
|
||||||
@ -27,20 +43,92 @@ const localeValues: Locale = {
|
|||||||
cancelText: 'Annuleer',
|
cancelText: 'Annuleer',
|
||||||
},
|
},
|
||||||
Transfer: {
|
Transfer: {
|
||||||
searchPlaceholder: 'Zoek hier',
|
|
||||||
itemUnit: 'item',
|
itemUnit: 'item',
|
||||||
itemsUnit: 'items',
|
itemsUnit: 'items',
|
||||||
|
remove: 'Verwijder',
|
||||||
|
removeAll: 'Verwijder alles',
|
||||||
|
removeCurrent: 'Verwijder huidige pagina',
|
||||||
|
searchPlaceholder: 'Zoek hier',
|
||||||
|
selectAll: 'Selecteer alles',
|
||||||
|
selectCurrent: 'Selecteer huidige pagina',
|
||||||
|
selectInvert: 'Huidige pagina omkeren',
|
||||||
|
titles: ['', ''],
|
||||||
},
|
},
|
||||||
Upload: {
|
Upload: {
|
||||||
|
downloadFile: 'Bestand downloaden',
|
||||||
|
previewFile: 'Preview file',
|
||||||
|
removeFile: 'Verwijder bestand',
|
||||||
|
uploadError: 'Fout tijdens uploaden',
|
||||||
uploading: 'Uploaden...',
|
uploading: 'Uploaden...',
|
||||||
removeFile: 'Bestand verwijderen',
|
|
||||||
uploadError: 'Upload fout',
|
|
||||||
previewFile: 'Preview bestand',
|
|
||||||
downloadFile: 'Download bestand',
|
|
||||||
},
|
},
|
||||||
Empty: {
|
Empty: {
|
||||||
description: 'Geen gegevens',
|
description: 'Geen gegevens',
|
||||||
},
|
},
|
||||||
|
Icon: {
|
||||||
|
icon: 'icoon',
|
||||||
|
},
|
||||||
|
Text: {
|
||||||
|
edit: 'Bewerken',
|
||||||
|
copy: 'kopiëren',
|
||||||
|
copied: 'Gekopieerd',
|
||||||
|
expand: 'Uitklappen',
|
||||||
|
},
|
||||||
|
PageHeader: {
|
||||||
|
back: 'Terug',
|
||||||
|
},
|
||||||
|
Form: {
|
||||||
|
optional: '(optioneel)',
|
||||||
|
defaultValidateMessages: {
|
||||||
|
default: 'Validatiefout voor ${label}',
|
||||||
|
required: 'Gelieve ${label} in te vullen',
|
||||||
|
enum: '${label} moet één van [${enum}] zijn',
|
||||||
|
whitespace: '${label} mag geen blanco teken zijn',
|
||||||
|
date: {
|
||||||
|
format: '${label} heeft een ongeldig formaat',
|
||||||
|
parse: '${label} kan niet naar een datum omgezet worden',
|
||||||
|
invalid: '${label} is een ongeldige datum',
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
string: typeTemplate,
|
||||||
|
method: typeTemplate,
|
||||||
|
array: typeTemplate,
|
||||||
|
object: typeTemplate,
|
||||||
|
number: typeTemplate,
|
||||||
|
date: typeTemplate,
|
||||||
|
boolean: typeTemplate,
|
||||||
|
integer: typeTemplate,
|
||||||
|
float: typeTemplate,
|
||||||
|
regexp: typeTemplate,
|
||||||
|
email: typeTemplate,
|
||||||
|
url: typeTemplate,
|
||||||
|
hex: typeTemplate,
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: '${label} moet ${len} karakters lang zijn',
|
||||||
|
min: '${label} moet minimaal ${min} karakters lang zijn',
|
||||||
|
max: '${label} mag maximaal ${max} karakters lang zijn',
|
||||||
|
range: '${label} moet tussen ${min}-${max} karakters lang zijn',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: '${label} moet gelijk zijn aan ${len}',
|
||||||
|
min: '${label} moet minimaal ${min} zijn',
|
||||||
|
max: '${label} mag maximaal ${max} zijn',
|
||||||
|
range: '${label} moet tussen ${min}-${max} liggen',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: 'Moeten ${len} ${label} zijn',
|
||||||
|
min: 'Minimaal ${min} ${label}',
|
||||||
|
max: 'maximaal ${max} ${label}',
|
||||||
|
range: 'Het aantal ${label} moet tussen ${min}-${max} liggen',
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
mismatch: '${label} komt niet overeen met het patroon ${pattern}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Image: {
|
||||||
|
preview: 'Voorbeeld',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default localeValues;
|
export default localeValues;
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
import Pagination from 'rc-pagination/lib/locale/nl_NL';
|
import Pagination from 'rc-pagination/lib/locale/nl_NL';
|
||||||
import DatePicker from '../date-picker/locale/nl_NL';
|
import DatePicker from '../date-picker/locale/nl_NL';
|
||||||
import TimePicker from '../time-picker/locale/nl_NL';
|
import TimePicker from '../time-picker/locale/nl_NL';
|
||||||
import Calendar from '../calendar/locale/nl_NL';
|
import Calendar from '../calendar/locale/nl_NL';
|
||||||
import { Locale } from '../locale-provider';
|
import { Locale } from '../locale-provider';
|
||||||
|
|
||||||
|
const typeTemplate = '${label} is geen geldige ${type}';
|
||||||
|
|
||||||
const localeValues: Locale = {
|
const localeValues: Locale = {
|
||||||
locale: 'nl',
|
locale: 'nl',
|
||||||
Pagination,
|
Pagination,
|
||||||
@ -14,36 +17,49 @@ const localeValues: Locale = {
|
|||||||
placeholder: 'Maak een selectie',
|
placeholder: 'Maak een selectie',
|
||||||
},
|
},
|
||||||
Table: {
|
Table: {
|
||||||
filterTitle: 'Filteren',
|
cancelSort: 'Klik om sortering te annuleren',
|
||||||
filterConfirm: 'OK',
|
|
||||||
filterReset: 'Reset',
|
|
||||||
selectAll: 'Selecteer huidige pagina',
|
|
||||||
selectInvert: 'Deselecteer huidige pagina',
|
|
||||||
sortTitle: 'Sorteren',
|
|
||||||
expand: 'Rij uitklappen',
|
|
||||||
collapse: 'Rij inklappen',
|
collapse: 'Rij inklappen',
|
||||||
|
emptyText: 'Geen data',
|
||||||
|
expand: 'Rij uitklappen',
|
||||||
|
filterConfirm: 'OK',
|
||||||
|
filterEmptyText: 'Geen filters',
|
||||||
|
filterReset: 'Reset',
|
||||||
|
filterTitle: 'Filteren',
|
||||||
|
selectAll: 'Selecteer huidige pagina',
|
||||||
|
selectInvert: 'Keer volgorde om',
|
||||||
|
selectNone: 'Maak selectie leeg',
|
||||||
|
selectionAll: 'Selecteer alle data',
|
||||||
|
sortTitle: 'Sorteren',
|
||||||
|
triggerAsc: 'Klik om oplopend te sorteren',
|
||||||
|
triggerDesc: 'Klik om aflopend te sorteren',
|
||||||
},
|
},
|
||||||
Modal: {
|
Modal: {
|
||||||
okText: 'OK',
|
okText: 'OK',
|
||||||
cancelText: 'Annuleren',
|
cancelText: 'Annuleer',
|
||||||
justOkText: 'OK',
|
justOkText: 'OK',
|
||||||
},
|
},
|
||||||
Popconfirm: {
|
Popconfirm: {
|
||||||
okText: 'OK',
|
okText: 'OK',
|
||||||
cancelText: 'Annuleren',
|
cancelText: 'Annuleer',
|
||||||
},
|
},
|
||||||
Transfer: {
|
Transfer: {
|
||||||
titles: ['', ''],
|
|
||||||
searchPlaceholder: 'Zoeken',
|
|
||||||
itemUnit: 'item',
|
itemUnit: 'item',
|
||||||
itemsUnit: 'items',
|
itemsUnit: 'items',
|
||||||
|
remove: 'Verwijder',
|
||||||
|
removeAll: 'Verwijder alles',
|
||||||
|
removeCurrent: 'Verwijder huidige pagina',
|
||||||
|
searchPlaceholder: 'Zoek hier',
|
||||||
|
selectAll: 'Selecteer alles',
|
||||||
|
selectCurrent: 'Selecteer huidige pagina',
|
||||||
|
selectInvert: 'Huidige pagina omkeren',
|
||||||
|
titles: ['', ''],
|
||||||
},
|
},
|
||||||
Upload: {
|
Upload: {
|
||||||
uploading: 'Uploaden...',
|
downloadFile: 'Bestand downloaden',
|
||||||
|
previewFile: 'Preview file',
|
||||||
removeFile: 'Verwijder bestand',
|
removeFile: 'Verwijder bestand',
|
||||||
uploadError: 'Fout tijdens uploaden',
|
uploadError: 'Fout tijdens uploaden',
|
||||||
previewFile: 'Bekijk bestand',
|
uploading: 'Uploaden...',
|
||||||
downloadFile: 'Downloaden bestand',
|
|
||||||
},
|
},
|
||||||
Empty: {
|
Empty: {
|
||||||
description: 'Geen gegevens',
|
description: 'Geen gegevens',
|
||||||
@ -53,13 +69,66 @@ const localeValues: Locale = {
|
|||||||
},
|
},
|
||||||
Text: {
|
Text: {
|
||||||
edit: 'Bewerken',
|
edit: 'Bewerken',
|
||||||
copy: 'Kopieren',
|
copy: 'kopiëren',
|
||||||
copied: 'Gekopieerd',
|
copied: 'Gekopieerd',
|
||||||
expand: 'Uitklappen',
|
expand: 'Uitklappen',
|
||||||
},
|
},
|
||||||
PageHeader: {
|
PageHeader: {
|
||||||
back: 'Terug',
|
back: 'Terug',
|
||||||
},
|
},
|
||||||
|
Form: {
|
||||||
|
optional: '(optioneel)',
|
||||||
|
defaultValidateMessages: {
|
||||||
|
default: 'Validatiefout voor ${label}',
|
||||||
|
required: 'Gelieve ${label} in te vullen',
|
||||||
|
enum: '${label} moet één van [${enum}] zijn',
|
||||||
|
whitespace: '${label} mag geen blanco teken zijn',
|
||||||
|
date: {
|
||||||
|
format: '${label} heeft een ongeldig formaat',
|
||||||
|
parse: '${label} kan niet naar een datum omgezet worden',
|
||||||
|
invalid: '${label} is een ongeldige datum',
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
string: typeTemplate,
|
||||||
|
method: typeTemplate,
|
||||||
|
array: typeTemplate,
|
||||||
|
object: typeTemplate,
|
||||||
|
number: typeTemplate,
|
||||||
|
date: typeTemplate,
|
||||||
|
boolean: typeTemplate,
|
||||||
|
integer: typeTemplate,
|
||||||
|
float: typeTemplate,
|
||||||
|
regexp: typeTemplate,
|
||||||
|
email: typeTemplate,
|
||||||
|
url: typeTemplate,
|
||||||
|
hex: typeTemplate,
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: '${label} moet ${len} karakters lang zijn',
|
||||||
|
min: '${label} moet minimaal ${min} karakters lang zijn',
|
||||||
|
max: '${label} mag maximaal ${max} karakters lang zijn',
|
||||||
|
range: '${label} moet tussen ${min}-${max} karakters lang zijn',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: '${label} moet gelijk zijn aan ${len}',
|
||||||
|
min: '${label} moet minimaal ${min} zijn',
|
||||||
|
max: '${label} mag maximaal ${max} zijn',
|
||||||
|
range: '${label} moet tussen ${min}-${max} liggen',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: 'Moeten ${len} ${label} zijn',
|
||||||
|
min: 'Minimaal ${min} ${label}',
|
||||||
|
max: 'maximaal ${max} ${label}',
|
||||||
|
range: 'Het aantal ${label} moet tussen ${min}-${max} liggen',
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
mismatch: '${label} komt niet overeen met het patroon ${pattern}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Image: {
|
||||||
|
preview: 'Voorbeeld',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default localeValues;
|
export default localeValues;
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
/* eslint-disable no-template-curly-in-string */
|
||||||
import Pagination from 'rc-pagination/lib/locale/ro_RO';
|
import Pagination from 'rc-pagination/lib/locale/ro_RO';
|
||||||
import DatePicker from '../date-picker/locale/ro_RO';
|
import DatePicker from '../date-picker/locale/ro_RO';
|
||||||
import TimePicker from '../time-picker/locale/ro_RO';
|
import TimePicker from '../time-picker/locale/ro_RO';
|
||||||
import Calendar from '../calendar/locale/ro_RO';
|
import Calendar from '../calendar/locale/ro_RO';
|
||||||
import { Locale } from '../locale-provider';
|
import { Locale } from '../locale-provider';
|
||||||
|
|
||||||
|
const typeTemplate = '${label} nu conține tipul corect (${type})';
|
||||||
|
|
||||||
const localeValues: Locale = {
|
const localeValues: Locale = {
|
||||||
locale: 'ro',
|
locale: 'ro',
|
||||||
Pagination,
|
Pagination,
|
||||||
@ -17,11 +20,18 @@ const localeValues: Locale = {
|
|||||||
filterTitle: 'Filtrează',
|
filterTitle: 'Filtrează',
|
||||||
filterConfirm: 'OK',
|
filterConfirm: 'OK',
|
||||||
filterReset: 'Resetează',
|
filterReset: 'Resetează',
|
||||||
|
filterEmptyText: 'Fără filtre',
|
||||||
|
emptyText: 'Nu există date',
|
||||||
selectAll: 'Selectează pagina curentă',
|
selectAll: 'Selectează pagina curentă',
|
||||||
selectInvert: 'Inversează pagina curentă',
|
selectInvert: 'Inversează pagina curentă',
|
||||||
|
selectNone: 'Șterge selecția',
|
||||||
|
selectionAll: 'Selectează toate datele',
|
||||||
sortTitle: 'Ordonează',
|
sortTitle: 'Ordonează',
|
||||||
expand: 'Extinde rândul',
|
expand: 'Extinde rândul',
|
||||||
collapse: 'Micșorează rândul',
|
collapse: 'Micșorează rândul',
|
||||||
|
triggerDesc: 'Apasă pentru ordonare descrescătoare',
|
||||||
|
triggerAsc: 'Apasă pentru ordonare crescătoare',
|
||||||
|
cancelSort: 'Apasă pentru a anula ordonarea',
|
||||||
},
|
},
|
||||||
Modal: {
|
Modal: {
|
||||||
okText: 'OK',
|
okText: 'OK',
|
||||||
@ -37,6 +47,12 @@ const localeValues: Locale = {
|
|||||||
searchPlaceholder: 'Căutare',
|
searchPlaceholder: 'Căutare',
|
||||||
itemUnit: 'element',
|
itemUnit: 'element',
|
||||||
itemsUnit: 'elemente',
|
itemsUnit: 'elemente',
|
||||||
|
remove: 'Șterge',
|
||||||
|
selectCurrent: 'Selectează pagina curentă',
|
||||||
|
removeCurrent: 'Șterge pagina curentă',
|
||||||
|
selectAll: 'Selectează toate datele',
|
||||||
|
removeAll: 'Șterge toate datele',
|
||||||
|
selectInvert: 'Inversează pagina curentă',
|
||||||
},
|
},
|
||||||
Upload: {
|
Upload: {
|
||||||
uploading: 'Se transferă...',
|
uploading: 'Se transferă...',
|
||||||
@ -60,6 +76,59 @@ const localeValues: Locale = {
|
|||||||
PageHeader: {
|
PageHeader: {
|
||||||
back: 'înapoi',
|
back: 'înapoi',
|
||||||
},
|
},
|
||||||
|
Form: {
|
||||||
|
optional: '(opțional)',
|
||||||
|
defaultValidateMessages: {
|
||||||
|
default: 'Eroare la validarea câmpului ${label}',
|
||||||
|
required: 'Vă rugăm introduceți ${label}',
|
||||||
|
enum: '${label} trebuie să fie una din valorile [${enum}]',
|
||||||
|
whitespace: '${label} nu poate fi gol',
|
||||||
|
date: {
|
||||||
|
format: '${label} - data nu este în formatul corect',
|
||||||
|
parse: '${label} nu poate fi convertit la o dată',
|
||||||
|
invalid: '${label} este o dată invalidă',
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
string: typeTemplate,
|
||||||
|
method: typeTemplate,
|
||||||
|
array: typeTemplate,
|
||||||
|
object: typeTemplate,
|
||||||
|
number: typeTemplate,
|
||||||
|
date: typeTemplate,
|
||||||
|
boolean: typeTemplate,
|
||||||
|
integer: typeTemplate,
|
||||||
|
float: typeTemplate,
|
||||||
|
regexp: typeTemplate,
|
||||||
|
email: typeTemplate,
|
||||||
|
url: typeTemplate,
|
||||||
|
hex: typeTemplate,
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: '${label} trebuie să conțină ${len} caractere',
|
||||||
|
min: '${label} trebuie să conțină cel puțin ${min} caractere',
|
||||||
|
max: '${label} trebuie să conțină cel mult ${max} caractere',
|
||||||
|
range: '${label} trebuie să conțină între ${min}-${max} caractere',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: '${label} trebuie să conțină ${len} cifre',
|
||||||
|
min: '${label} trebuie să fie minim ${min}',
|
||||||
|
max: '${label} trebuie să fie maxim ${max}',
|
||||||
|
range: '${label} trebuie să fie între ${min}-${max}',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: '${label} trebuie să conțină ${len} elemente',
|
||||||
|
min: '${label} trebuie să conțină cel puțin ${min} elemente',
|
||||||
|
max: '${label} trebuie să conțină cel mult ${max} elemente',
|
||||||
|
range: '${label} trebuie să conțină între ${min}-${max} elemente',
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
mismatch: '${label} nu respectă șablonul ${pattern}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Image: {
|
||||||
|
preview: 'Preview',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default localeValues;
|
export default localeValues;
|
||||||
|
@ -81,14 +81,14 @@ describe('Mentions', () => {
|
|||||||
it('loading', () => {
|
it('loading', () => {
|
||||||
const wrapper = mount(<Mentions loading />);
|
const wrapper = mount(<Mentions loading />);
|
||||||
simulateInput(wrapper, '@');
|
simulateInput(wrapper, '@');
|
||||||
expect(wrapper.find('.ant-mentions-dropdown-menu-item').length).toBe(1);
|
expect(wrapper.find('li.ant-mentions-dropdown-menu-item').length).toBe(1);
|
||||||
expect(wrapper.find('.ant-spin').length).toBeTruthy();
|
expect(wrapper.find('.ant-spin').length).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('notFoundContent', () => {
|
it('notFoundContent', () => {
|
||||||
const wrapper = mount(<Mentions notFoundContent={<span className="bamboo-light" />} />);
|
const wrapper = mount(<Mentions notFoundContent={<span className="bamboo-light" />} />);
|
||||||
simulateInput(wrapper, '@');
|
simulateInput(wrapper, '@');
|
||||||
expect(wrapper.find('.ant-mentions-dropdown-menu-item').length).toBe(1);
|
expect(wrapper.find('li.ant-mentions-dropdown-menu-item').length).toBe(1);
|
||||||
expect(wrapper.find('.bamboo-light').length).toBeTruthy();
|
expect(wrapper.find('.bamboo-light').length).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,12 +4,16 @@ import { DirectionType } from '../config-provider';
|
|||||||
export type MenuTheme = 'light' | 'dark';
|
export type MenuTheme = 'light' | 'dark';
|
||||||
|
|
||||||
export interface MenuContextProps {
|
export interface MenuContextProps {
|
||||||
|
prefixCls: string;
|
||||||
inlineCollapsed: boolean;
|
inlineCollapsed: boolean;
|
||||||
antdMenuTheme?: MenuTheme;
|
antdMenuTheme?: MenuTheme;
|
||||||
direction?: DirectionType;
|
direction?: DirectionType;
|
||||||
|
firstLevel: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MenuContext = createContext<MenuContextProps>({
|
const MenuContext = createContext<MenuContextProps>({
|
||||||
|
prefixCls: '',
|
||||||
|
firstLevel: true,
|
||||||
inlineCollapsed: false,
|
inlineCollapsed: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -14,77 +14,72 @@ export interface MenuItemProps extends Omit<RcMenuItemProps, 'title'> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class MenuItem extends React.Component<MenuItemProps> {
|
export default class MenuItem extends React.Component<MenuItemProps> {
|
||||||
static isMenuItem = true;
|
static contextType = MenuContext;
|
||||||
|
|
||||||
|
context: MenuContextProps;
|
||||||
|
|
||||||
renderItemChildren(inlineCollapsed: boolean) {
|
renderItemChildren(inlineCollapsed: boolean) {
|
||||||
const { icon, children, level, rootPrefixCls } = this.props;
|
const { prefixCls, firstLevel } = this.context;
|
||||||
|
const { icon, children } = this.props;
|
||||||
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
|
// inline-collapsed.md demo 依赖 span 来隐藏文字,有 icon 属性,则内部包裹一个 span
|
||||||
// ref: https://github.com/ant-design/ant-design/pull/23456
|
// ref: https://github.com/ant-design/ant-design/pull/23456
|
||||||
if (!icon || (isValidElement(children) && children.type === 'span')) {
|
if (!icon || (isValidElement(children) && children.type === 'span')) {
|
||||||
if (children && inlineCollapsed && level === 1 && typeof children === 'string') {
|
if (children && inlineCollapsed && firstLevel && typeof children === 'string') {
|
||||||
return (
|
return <div className={`${prefixCls}-inline-collapsed-noicon`}>{children.charAt(0)}</div>;
|
||||||
<div className={`${rootPrefixCls}-inline-collapsed-noicon`}>{children.charAt(0)}</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
return <span>{children}</span>;
|
return <span className={`${prefixCls}-title-content`}>{children}</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderItem = ({ siderCollapsed }: SiderContextProps) => {
|
renderItem = ({ siderCollapsed }: SiderContextProps) => {
|
||||||
const { level, className, children, rootPrefixCls } = this.props;
|
const { prefixCls, firstLevel, inlineCollapsed, direction } = this.context;
|
||||||
|
const { className, children } = this.props;
|
||||||
const { title, icon, danger, ...rest } = this.props;
|
const { title, icon, danger, ...rest } = this.props;
|
||||||
|
|
||||||
return (
|
let tooltipTitle = title;
|
||||||
<MenuContext.Consumer>
|
if (typeof title === 'undefined') {
|
||||||
{({ inlineCollapsed, direction }: MenuContextProps) => {
|
tooltipTitle = firstLevel ? children : '';
|
||||||
let tooltipTitle = title;
|
} else if (title === false) {
|
||||||
if (typeof title === 'undefined') {
|
tooltipTitle = '';
|
||||||
tooltipTitle = level === 1 ? children : '';
|
}
|
||||||
} else if (title === false) {
|
const tooltipProps: TooltipProps = {
|
||||||
tooltipTitle = '';
|
title: tooltipTitle,
|
||||||
}
|
};
|
||||||
const tooltipProps: TooltipProps = {
|
|
||||||
title: tooltipTitle,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!siderCollapsed && !inlineCollapsed) {
|
if (!siderCollapsed && !inlineCollapsed) {
|
||||||
tooltipProps.title = null;
|
tooltipProps.title = null;
|
||||||
// Reset `visible` to fix control mode tooltip display not correct
|
// Reset `visible` to fix control mode tooltip display not correct
|
||||||
// ref: https://github.com/ant-design/ant-design/issues/16742
|
// ref: https://github.com/ant-design/ant-design/issues/16742
|
||||||
tooltipProps.visible = false;
|
tooltipProps.visible = false;
|
||||||
}
|
}
|
||||||
const childrenLength = toArray(children).length;
|
const childrenLength = toArray(children).length;
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
{...tooltipProps}
|
{...tooltipProps}
|
||||||
placement={direction === 'rtl' ? 'left' : 'right'}
|
placement={direction === 'rtl' ? 'left' : 'right'}
|
||||||
overlayClassName={`${rootPrefixCls}-inline-collapsed-tooltip`}
|
overlayClassName={`${prefixCls}-inline-collapsed-tooltip`}
|
||||||
>
|
>
|
||||||
<Item
|
<Item
|
||||||
{...rest}
|
{...rest}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
{
|
{
|
||||||
[`${rootPrefixCls}-item-danger`]: danger,
|
[`${prefixCls}-item-danger`]: danger,
|
||||||
[`${rootPrefixCls}-item-only-child`]:
|
[`${prefixCls}-item-only-child`]: (icon ? childrenLength + 1 : childrenLength) === 1,
|
||||||
(icon ? childrenLength + 1 : childrenLength) === 1,
|
},
|
||||||
},
|
className,
|
||||||
className,
|
)}
|
||||||
)}
|
title={typeof title === 'string' ? title : undefined}
|
||||||
title={title}
|
>
|
||||||
>
|
{cloneElement(icon, {
|
||||||
{cloneElement(icon, {
|
className: classNames(
|
||||||
className: classNames(
|
isValidElement(icon) ? icon.props?.className : '',
|
||||||
isValidElement(icon) ? icon.props?.className : '',
|
`${prefixCls}-item-icon`,
|
||||||
`${rootPrefixCls}-item-icon`,
|
),
|
||||||
),
|
})}
|
||||||
})}
|
{this.renderItemChildren(inlineCollapsed)}
|
||||||
{this.renderItemChildren(inlineCollapsed)}
|
</Item>
|
||||||
</Item>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</MenuContext.Consumer>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,11 +7,10 @@ import { isValidElement } from '../_util/reactNode';
|
|||||||
|
|
||||||
interface TitleEventEntity {
|
interface TitleEventEntity {
|
||||||
key: string;
|
key: string;
|
||||||
domEvent: Event;
|
domEvent: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SubMenuProps {
|
export interface SubMenuProps {
|
||||||
rootPrefixCls?: string;
|
|
||||||
className?: string;
|
className?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
level?: number;
|
level?: number;
|
||||||
@ -28,14 +27,15 @@ export interface SubMenuProps {
|
|||||||
class SubMenu extends React.Component<SubMenuProps, any> {
|
class SubMenu extends React.Component<SubMenuProps, any> {
|
||||||
static contextType = MenuContext;
|
static contextType = MenuContext;
|
||||||
|
|
||||||
// fix issue:https://github.com/ant-design/ant-design/issues/8666
|
context: MenuContextProps;
|
||||||
static isSubMenu = 1;
|
|
||||||
|
|
||||||
renderTitle(inlineCollapsed: boolean) {
|
renderTitle(inlineCollapsed: boolean) {
|
||||||
const { icon, title, level, rootPrefixCls } = this.props;
|
const { icon, title, level } = this.props;
|
||||||
|
const { prefixCls } = this.context;
|
||||||
|
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
return inlineCollapsed && level === 1 && title && typeof title === 'string' ? (
|
return inlineCollapsed && level === 1 && title && typeof title === 'string' ? (
|
||||||
<div className={`${rootPrefixCls}-inline-collapsed-noicon`}>{title.charAt(0)}</div>
|
<div className={`${prefixCls}-inline-collapsed-noicon`}>{title.charAt(0)}</div>
|
||||||
) : (
|
) : (
|
||||||
title
|
title
|
||||||
);
|
);
|
||||||
@ -46,27 +46,27 @@ class SubMenu extends React.Component<SubMenuProps, any> {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{icon}
|
{icon}
|
||||||
{titleIsSpan ? title : <span>{title}</span>}
|
{titleIsSpan ? title : <span className={`${prefixCls}-title-content`}>{title}</span>}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { rootPrefixCls, popupClassName } = this.props;
|
const { popupClassName } = this.props;
|
||||||
|
const { prefixCls, inlineCollapsed, antdMenuTheme } = this.context;
|
||||||
return (
|
return (
|
||||||
<MenuContext.Consumer>
|
<MenuContext.Provider
|
||||||
{({ inlineCollapsed, antdMenuTheme }: MenuContextProps) => (
|
value={{
|
||||||
<RcSubMenu
|
...this.context,
|
||||||
{...omit(this.props, ['icon'])}
|
firstLevel: false,
|
||||||
title={this.renderTitle(inlineCollapsed)}
|
}}
|
||||||
popupClassName={classNames(
|
>
|
||||||
rootPrefixCls,
|
<RcSubMenu
|
||||||
`${rootPrefixCls}-${antdMenuTheme}`,
|
{...omit(this.props, ['icon'])}
|
||||||
popupClassName,
|
title={this.renderTitle(inlineCollapsed)}
|
||||||
)}
|
popupClassName={classNames(prefixCls, `${prefixCls}-${antdMenuTheme}`, popupClassName)}
|
||||||
/>
|
/>
|
||||||
)}
|
</MenuContext.Provider>
|
||||||
</MenuContext.Consumer>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,12 +2,16 @@
|
|||||||
|
|
||||||
exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-vertical"
|
class="ant-menu ant-menu-root ant-menu-vertical ant-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-item"
|
class="ant-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-1"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-label="mail"
|
aria-label="mail"
|
||||||
@ -28,13 +32,17 @@ exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span
|
||||||
|
class="ant-menu-title-content"
|
||||||
|
>
|
||||||
Navigation One
|
Navigation One
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-item"
|
class="ant-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-2"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-label="mail"
|
aria-label="mail"
|
||||||
@ -61,13 +69,16 @@ exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-controls="rc-menu-uuid-test-3-popup"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-menu-submenu-title"
|
class="ant-menu-submenu-title"
|
||||||
role="button"
|
data-menu-id="rc-menu-uuid-test-3"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-label="mail"
|
aria-label="mail"
|
||||||
@ -88,7 +99,9 @@ exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span
|
||||||
|
class="ant-menu-title-content"
|
||||||
|
>
|
||||||
Navigation One
|
Navigation One
|
||||||
</span>
|
</span>
|
||||||
<i
|
<i
|
||||||
@ -98,13 +111,16 @@ exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-controls="rc-menu-uuid-test-4-popup"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-menu-submenu-title"
|
class="ant-menu-submenu-title"
|
||||||
role="button"
|
data-menu-id="rc-menu-uuid-test-4"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-label="mail"
|
aria-label="mail"
|
||||||
@ -138,16 +154,19 @@ exports[`Menu Menu.Item with icon children auto wrap span 1`] = `
|
|||||||
|
|
||||||
exports[`Menu rtl render component should be rendered correctly in RTL direction 1`] = `
|
exports[`Menu rtl render component should be rendered correctly in RTL direction 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-rtl ant-menu-vertical"
|
class="ant-menu ant-menu-root ant-menu-vertical ant-menu-light ant-menu-rtl"
|
||||||
direction="rtl"
|
data-menu-list="true"
|
||||||
|
dir="rtl"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-item"
|
class="ant-menu-item"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
/>
|
/>
|
||||||
<li
|
<li
|
||||||
class=" ant-menu-item-group"
|
class="ant-menu-item-group"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-menu-item-group-title"
|
class="ant-menu-item-group-title"
|
||||||
@ -158,14 +177,14 @@ exports[`Menu rtl render component should be rendered correctly in RTL direction
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-menu-submenu-title"
|
class="ant-menu-submenu-title"
|
||||||
role="button"
|
role="menuitem"
|
||||||
title=""
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="ant-menu-submenu-arrow"
|
class="ant-menu-submenu-arrow"
|
||||||
@ -177,13 +196,17 @@ exports[`Menu rtl render component should be rendered correctly in RTL direction
|
|||||||
|
|
||||||
exports[`Menu should controlled collapse work 1`] = `
|
exports[`Menu should controlled collapse work 1`] = `
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
class="ant-menu ant-menu-root ant-menu-inline ant-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-item"
|
class="ant-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-1"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left: 24px;"
|
style="padding-left: 24px;"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-label="pie-chart"
|
aria-label="pie-chart"
|
||||||
@ -204,7 +227,9 @@ exports[`Menu should controlled collapse work 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span
|
||||||
|
class="ant-menu-title-content"
|
||||||
|
>
|
||||||
Option 1
|
Option 1
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
@ -213,13 +238,17 @@ exports[`Menu should controlled collapse work 1`] = `
|
|||||||
|
|
||||||
exports[`Menu should controlled collapse work 2`] = `
|
exports[`Menu should controlled collapse work 2`] = `
|
||||||
<ul
|
<ul
|
||||||
class="ant-menu ant-menu-light ant-menu-inline-collapsed ant-menu-root ant-menu-inline"
|
class="ant-menu ant-menu-root ant-menu-vertical ant-menu-light ant-menu-inline-collapsed"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-menu-item"
|
class="ant-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-1"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
style="padding-left: 24px;"
|
style="padding-left: 24px;"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-label="pie-chart"
|
aria-label="pie-chart"
|
||||||
@ -240,7 +269,9 @@ exports[`Menu should controlled collapse work 2`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span
|
||||||
|
class="ant-menu-title-content"
|
||||||
|
>
|
||||||
Option 1
|
Option 1
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -14,7 +14,6 @@ import Tooltip from '../../tooltip';
|
|||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import collapseMotion from '../../_util/motion';
|
import collapseMotion from '../../_util/motion';
|
||||||
import { sleep } from '../../../tests/utils';
|
|
||||||
|
|
||||||
const { SubMenu } = Menu;
|
const { SubMenu } = Menu;
|
||||||
|
|
||||||
@ -22,35 +21,45 @@ const noop = () => {};
|
|||||||
|
|
||||||
const expectSubMenuBehavior = (menu, enter = noop, leave = noop) => {
|
const expectSubMenuBehavior = (menu, enter = noop, leave = noop) => {
|
||||||
if (!menu.prop('openKeys') && !menu.prop('defaultOpenKeys')) {
|
if (!menu.prop('openKeys') && !menu.prop('defaultOpenKeys')) {
|
||||||
expect(menu.find('.ant-menu-sub').length).toBe(0);
|
expect(menu.find('ul.ant-menu-sub').length).toBe(0);
|
||||||
}
|
}
|
||||||
menu.update();
|
menu.update();
|
||||||
expect(menu.find('.ant-menu-sub').length).toBe(0);
|
expect(menu.find('ul.ant-menu-sub').length).toBe(0);
|
||||||
const AnimationClassNames = {
|
const AnimationClassNames = {
|
||||||
horizontal: 'ant-slide-up-leave',
|
horizontal: 'ant-slide-up-leave',
|
||||||
inline: 'ant-motion-collapse-leave',
|
inline: 'ant-motion-collapse-leave',
|
||||||
vertical: 'ant-zoom-big-leave',
|
vertical: 'ant-zoom-big-leave',
|
||||||
};
|
};
|
||||||
const mode = menu.prop('mode') || 'horizontal';
|
const mode = menu.prop('mode') || 'horizontal';
|
||||||
enter();
|
|
||||||
menu.update();
|
act(() => {
|
||||||
|
enter();
|
||||||
|
jest.runAllTimers();
|
||||||
|
menu.update();
|
||||||
|
});
|
||||||
|
|
||||||
function getSubMenu() {
|
function getSubMenu() {
|
||||||
if (mode === 'inline') {
|
if (mode === 'inline') {
|
||||||
return menu.find('.ant-menu-sub.ant-menu-inline').hostNodes().at(0);
|
return menu.find('ul.ant-menu-sub.ant-menu-inline').hostNodes().at(0);
|
||||||
}
|
}
|
||||||
return menu.find('.ant-menu-submenu-popup').hostNodes().at(0);
|
return menu.find('div.ant-menu-submenu-popup').hostNodes().at(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
getSubMenu().hasClass('ant-menu-hidden') || getSubMenu().hasClass(AnimationClassNames[mode]),
|
getSubMenu().hasClass('ant-menu-hidden') || getSubMenu().hasClass(AnimationClassNames[mode]),
|
||||||
).toBe(false);
|
).toBeFalsy();
|
||||||
leave();
|
|
||||||
menu.update();
|
|
||||||
|
|
||||||
expect(
|
act(() => {
|
||||||
getSubMenu().hasClass('ant-menu-hidden') || getSubMenu().hasClass(AnimationClassNames[mode]),
|
leave();
|
||||||
).toBe(true);
|
jest.runAllTimers();
|
||||||
|
menu.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (getSubMenu().length) {
|
||||||
|
expect(
|
||||||
|
getSubMenu().hasClass('ant-menu-hidden') || getSubMenu().hasClass(AnimationClassNames[mode]),
|
||||||
|
).toBeTruthy();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Menu', () => {
|
describe('Menu', () => {
|
||||||
@ -93,11 +102,16 @@ describe('Menu', () => {
|
|||||||
</Menu>
|
</Menu>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let div;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
div = document.createElement('div');
|
||||||
|
document.body.appendChild(div);
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
document.body.removeChild(div);
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -115,7 +129,7 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="2">menu2</Menu.Item>
|
<Menu.Item key="2">menu2</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-menu-submenu-selected').length).toBe(1);
|
expect(wrapper.find('li.ant-menu-submenu-selected').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('forceSubMenuRender', () => {
|
it('forceSubMenuRender', () => {
|
||||||
@ -145,7 +159,7 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="2">menu2</Menu.Item>
|
<Menu.Item key="2">menu2</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
expect(wrapper.exists('.ant-menu-sub')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept defaultOpenKeys in mode inline', () => {
|
it('should accept defaultOpenKeys in mode inline', () => {
|
||||||
@ -171,7 +185,7 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="2">menu2</Menu.Item>
|
<Menu.Item key="2">menu2</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
expect(wrapper.find('PopupTrigger').first().prop('visible')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept openKeys in mode horizontal', () => {
|
it('should accept openKeys in mode horizontal', () => {
|
||||||
@ -184,7 +198,7 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="2">menu2</Menu.Item>
|
<Menu.Item key="2">menu2</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
expect(wrapper.find('PopupTrigger').first().prop('visible')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept openKeys in mode inline', () => {
|
it('should accept openKeys in mode inline', () => {
|
||||||
@ -197,7 +211,7 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="2">menu2</Menu.Item>
|
<Menu.Item key="2">menu2</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
expect(wrapper.find('InlineSubMenuList').first().prop('open')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept openKeys in mode vertical', () => {
|
it('should accept openKeys in mode vertical', () => {
|
||||||
@ -210,7 +224,7 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="2">menu2</Menu.Item>
|
<Menu.Item key="2">menu2</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
expect(wrapper.find('PopupTrigger').first().prop('visible')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test submenu in mode horizontal', () => {
|
it('test submenu in mode horizontal', () => {
|
||||||
@ -309,29 +323,28 @@ describe('Menu', () => {
|
|||||||
</SubMenu>
|
</SubMenu>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
|
||||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
|
||||||
|
|
||||||
|
expect(wrapper.find('InlineSubMenuList').prop('open')).toBeTruthy();
|
||||||
|
|
||||||
|
// inlineCollapsed
|
||||||
wrapper.setProps({ inlineCollapsed: true });
|
wrapper.setProps({ inlineCollapsed: true });
|
||||||
// 动画结束后套样式;
|
|
||||||
jest.runAllTimers();
|
|
||||||
wrapper.update();
|
|
||||||
wrapper.simulate('transitionEnd', { propertyName: 'width' });
|
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.find('ul.ant-menu-root').at(0).hasClass('ant-menu-vertical')).toBe(true);
|
expect(wrapper.find('ul.ant-menu-root').hasClass('ant-menu-vertical')).toBeTruthy();
|
||||||
expect(wrapper.find('ul.ant-menu-sub:not(.ant-menu-hidden)').length).toBe(0);
|
expect(wrapper.find('PopupTrigger').prop('visible')).toBeFalsy();
|
||||||
|
|
||||||
|
// !inlineCollapsed
|
||||||
wrapper.setProps({ inlineCollapsed: false });
|
wrapper.setProps({ inlineCollapsed: false });
|
||||||
jest.runAllTimers();
|
act(() => {
|
||||||
wrapper.update();
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
expect(wrapper.find('ul.ant-menu-sub').last().hasClass('ant-menu-inline')).toBeTruthy();
|
||||||
expect(wrapper.find('ul.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
expect(wrapper.find('InlineSubMenuList').prop('open')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('inlineCollapsed should works well when specify a not existed default openKeys', () => {
|
it('inlineCollapsed should works well when specify a not existed default openKeys', () => {
|
||||||
@ -435,11 +448,16 @@ describe('Menu', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('inline menu collapseMotion should be triggered', async () => {
|
it('inline menu collapseMotion should be triggered', async () => {
|
||||||
jest.useRealTimers();
|
const cloneMotion = {
|
||||||
const onAppearEnd = jest.spyOn(collapseMotion, 'onAppearEnd');
|
...collapseMotion,
|
||||||
collapseMotion.motionDeadline = 1;
|
motionDeadline: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
const onOpenChange = jest.fn();
|
||||||
|
const onEnterEnd = jest.spyOn(cloneMotion, 'onEnterEnd');
|
||||||
|
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Menu mode="inline">
|
<Menu mode="inline" motion={cloneMotion} onOpenChange={onOpenChange}>
|
||||||
<SubMenu key="1" title="submenu1">
|
<SubMenu key="1" title="submenu1">
|
||||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||||
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
||||||
@ -447,10 +465,16 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="2">menu2</Menu.Item>
|
<Menu.Item key="2">menu2</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
wrapper.find('.ant-menu-submenu-title').simulate('click');
|
|
||||||
await sleep(3000);
|
wrapper.find('div.ant-menu-submenu-title').simulate('click');
|
||||||
expect(onAppearEnd).toHaveBeenCalledTimes(1);
|
|
||||||
onAppearEnd.mockRestore();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(onOpenChange).toHaveBeenCalled();
|
||||||
|
expect(onEnterEnd).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('vertical with hover(default)', () => {
|
it('vertical with hover(default)', () => {
|
||||||
@ -539,7 +563,7 @@ describe('Menu', () => {
|
|||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find('.ant-menu-item').simulate('mouseenter');
|
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
||||||
act(() => {
|
act(() => {
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
});
|
});
|
||||||
@ -601,7 +625,7 @@ describe('Menu', () => {
|
|||||||
<Menu.Item key="test2">Navigation Two</Menu.Item>
|
<Menu.Item key="test2">Navigation Two</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
wrapper.find('Menu').at(1).simulate('mouseenter');
|
wrapper.find('ul.ant-menu-root').simulate('mouseenter');
|
||||||
expect(onMouseEnter).toHaveBeenCalled();
|
expect(onMouseEnter).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -620,10 +644,16 @@ describe('Menu', () => {
|
|||||||
</a>
|
</a>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
|
{ attachTo: div },
|
||||||
);
|
);
|
||||||
wrapper.find('MenuItem').first().simulate('mouseenter');
|
|
||||||
jest.runAllTimers();
|
wrapper.find('li.ant-menu-item').first().simulate('mouseenter');
|
||||||
wrapper.update();
|
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
expect(wrapper.find('.ant-tooltip-inner').length).toBe(0);
|
expect(wrapper.find('.ant-tooltip-inner').length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -664,7 +694,7 @@ describe('Menu', () => {
|
|||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.find('.ant-menu-item').simulate('mouseenter');
|
wrapper.find('.ant-menu-item').hostNodes().simulate('mouseenter');
|
||||||
jest.runAllTimers();
|
jest.runAllTimers();
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
@ -715,20 +745,25 @@ describe('Menu', () => {
|
|||||||
</Menu.SubMenu>
|
</Menu.SubMenu>
|
||||||
</Menu>,
|
</Menu>,
|
||||||
);
|
);
|
||||||
expect(wrapper.find('.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 1');
|
expect(wrapper.find('li.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 1');
|
||||||
wrapper.find('.ant-menu-item').at(1).simulate('click');
|
wrapper.find('li.ant-menu-item').at(1).simulate('click');
|
||||||
expect(wrapper.find('.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 2');
|
expect(wrapper.find('li.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 2');
|
||||||
wrapper.setProps({ inlineCollapsed: true });
|
wrapper.setProps({ inlineCollapsed: true });
|
||||||
jest.runAllTimers();
|
|
||||||
wrapper.update();
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
wrapper
|
wrapper
|
||||||
.find('Trigger')
|
.find('PopupTrigger')
|
||||||
.map(node => node.prop('popupVisible'))
|
.map(node => node.prop('popupVisible'))
|
||||||
.findIndex(node => !!node),
|
.findIndex(node => !!node),
|
||||||
).toBe(-1);
|
).toBe(-1);
|
||||||
|
|
||||||
wrapper.setProps({ inlineCollapsed: false });
|
wrapper.setProps({ inlineCollapsed: false });
|
||||||
expect(wrapper.find('.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 2');
|
expect(wrapper.find('li.ant-menu-item-selected').getDOMNode().textContent).toBe('Option 2');
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -776,4 +811,14 @@ describe('Menu', () => {
|
|||||||
wrapper.find('button').simulate('click');
|
wrapper.find('button').simulate('click');
|
||||||
expect(onOpenChange).toHaveBeenCalledWith([]);
|
expect(onOpenChange).toHaveBeenCalledWith([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Use first char as Icon when collapsed', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<Menu mode="inline" inlineCollapsed>
|
||||||
|
<Menu.Item>Bamboo</Menu.Item>
|
||||||
|
</Menu>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(wrapper.find('.ant-menu-inline-collapsed-noicon').text()).toEqual('B');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import RcMenu, { Divider, ItemGroup, MenuProps as RcMenuProps } from 'rc-menu';
|
import RcMenu, { Divider, ItemGroup, MenuProps as RcMenuProps } from 'rc-menu';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import omit from 'rc-util/lib/omit';
|
||||||
import SubMenu, { SubMenuProps } from './SubMenu';
|
import SubMenu, { SubMenuProps } from './SubMenu';
|
||||||
import Item, { MenuItemProps } from './MenuItem';
|
import Item, { MenuItemProps } from './MenuItem';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
@ -17,16 +18,16 @@ export type MenuMode = 'vertical' | 'vertical-left' | 'vertical-right' | 'horizo
|
|||||||
export interface MenuProps extends RcMenuProps {
|
export interface MenuProps extends RcMenuProps {
|
||||||
theme?: MenuTheme;
|
theme?: MenuTheme;
|
||||||
inlineIndent?: number;
|
inlineIndent?: number;
|
||||||
focusable?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type InternalMenuProps = MenuProps & SiderContextProps;
|
type InternalMenuProps = MenuProps &
|
||||||
|
SiderContextProps & {
|
||||||
|
collapsedWidth?: string | number;
|
||||||
|
};
|
||||||
|
|
||||||
class InternalMenu extends React.Component<InternalMenuProps> {
|
class InternalMenu extends React.Component<InternalMenuProps> {
|
||||||
static defaultProps: Partial<MenuProps> = {
|
static defaultProps: Partial<MenuProps> = {
|
||||||
className: '',
|
|
||||||
theme: 'light', // or dark
|
theme: 'light', // or dark
|
||||||
focusable: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: InternalMenuProps) {
|
constructor(props: InternalMenuProps) {
|
||||||
@ -56,7 +57,17 @@ class InternalMenu extends React.Component<InternalMenuProps> {
|
|||||||
renderMenu = ({ getPopupContainer, getPrefixCls, direction }: ConfigConsumerProps) => {
|
renderMenu = ({ getPopupContainer, getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||||
const rootPrefixCls = getPrefixCls();
|
const rootPrefixCls = getPrefixCls();
|
||||||
|
|
||||||
const { prefixCls: customizePrefixCls, className, theme, expandIcon } = this.props;
|
const {
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
className,
|
||||||
|
theme,
|
||||||
|
expandIcon,
|
||||||
|
...restProps
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const passedProps = omit(restProps, ['siderCollapsed', 'collapsedWidth']);
|
||||||
|
const inlineCollapsed = this.getInlineCollapsed();
|
||||||
|
|
||||||
const defaultMotions = {
|
const defaultMotions = {
|
||||||
horizontal: { motionName: `${rootPrefixCls}-slide-up` },
|
horizontal: { motionName: `${rootPrefixCls}-slide-up` },
|
||||||
inline: collapseMotion,
|
inline: collapseMotion,
|
||||||
@ -64,25 +75,22 @@ class InternalMenu extends React.Component<InternalMenuProps> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('menu', customizePrefixCls);
|
const prefixCls = getPrefixCls('menu', customizePrefixCls);
|
||||||
const menuClassName = classNames(
|
const menuClassName = classNames(`${prefixCls}-${theme}`, className);
|
||||||
`${prefixCls}-${theme}`,
|
|
||||||
{
|
|
||||||
[`${prefixCls}-inline-collapsed`]: this.getInlineCollapsed(),
|
|
||||||
},
|
|
||||||
className,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuContext.Provider
|
<MenuContext.Provider
|
||||||
value={{
|
value={{
|
||||||
inlineCollapsed: this.getInlineCollapsed() || false,
|
prefixCls,
|
||||||
|
inlineCollapsed: inlineCollapsed || false,
|
||||||
antdMenuTheme: theme,
|
antdMenuTheme: theme,
|
||||||
direction,
|
direction,
|
||||||
|
firstLevel: true,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RcMenu
|
<RcMenu
|
||||||
getPopupContainer={getPopupContainer}
|
getPopupContainer={getPopupContainer}
|
||||||
{...this.props}
|
{...passedProps}
|
||||||
|
inlineCollapsed={inlineCollapsed}
|
||||||
className={menuClassName}
|
className={menuClassName}
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
direction={direction}
|
direction={direction}
|
||||||
|
@ -3,6 +3,13 @@
|
|||||||
@import './status';
|
@import './status';
|
||||||
|
|
||||||
@menu-prefix-cls: ~'@{ant-prefix}-menu';
|
@menu-prefix-cls: ~'@{ant-prefix}-menu';
|
||||||
|
@menu-animation-duration-normal: 0.15s;
|
||||||
|
|
||||||
|
.accessibility-focus() {
|
||||||
|
box-shadow: 0 0 0 2px fade(@primary-color, 20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Should remove icon style compatible in v5
|
||||||
|
|
||||||
// default theme
|
// default theme
|
||||||
.@{menu-prefix-cls} {
|
.@{menu-prefix-cls} {
|
||||||
@ -18,9 +25,14 @@
|
|||||||
background: @menu-bg;
|
background: @menu-bg;
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: @box-shadow-base;
|
box-shadow: @box-shadow-base;
|
||||||
transition: background 0.3s, width 0.3s cubic-bezier(0.2, 0, 0, 1) 0s;
|
transition: background @animation-duration-slow,
|
||||||
|
width @animation-duration-slow cubic-bezier(0.2, 0, 0, 1) 0s;
|
||||||
.clearfix();
|
.clearfix();
|
||||||
|
|
||||||
|
&&-root:focus-visible {
|
||||||
|
.accessibility-focus();
|
||||||
|
}
|
||||||
|
|
||||||
ul,
|
ul,
|
||||||
ol {
|
ol {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -28,7 +40,8 @@
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-hidden {
|
&-hidden,
|
||||||
|
&-submenu-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,16 +51,18 @@
|
|||||||
color: @menu-item-group-title-color;
|
color: @menu-item-group-title-color;
|
||||||
font-size: @menu-item-group-title-font-size;
|
font-size: @menu-item-group-title-font-size;
|
||||||
line-height: @menu-item-group-height;
|
line-height: @menu-item-group-height;
|
||||||
transition: all 0.3s;
|
transition: all @animation-duration-slow;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-horizontal &-submenu {
|
&-horizontal &-submenu {
|
||||||
transition: border-color 0.3s @ease-in-out, background 0.3s @ease-in-out;
|
transition: border-color @animation-duration-slow @ease-in-out,
|
||||||
|
background @animation-duration-slow @ease-in-out;
|
||||||
}
|
}
|
||||||
&-submenu,
|
&-submenu,
|
||||||
&-submenu-inline {
|
&-submenu-inline {
|
||||||
transition: border-color 0.3s @ease-in-out, background 0.3s @ease-in-out,
|
transition: border-color @animation-duration-slow @ease-in-out,
|
||||||
padding 0.15s @ease-in-out;
|
background @animation-duration-slow @ease-in-out,
|
||||||
|
padding @menu-animation-duration-normal @ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-submenu-selected {
|
&-submenu-selected {
|
||||||
@ -61,7 +76,8 @@
|
|||||||
|
|
||||||
&-submenu &-sub {
|
&-submenu &-sub {
|
||||||
cursor: initial;
|
cursor: initial;
|
||||||
transition: background 0.3s @ease-in-out, padding 0.3s @ease-in-out;
|
transition: background @animation-duration-slow @ease-in-out,
|
||||||
|
padding @animation-duration-slow @ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-item a {
|
&-item a {
|
||||||
@ -172,7 +188,7 @@
|
|||||||
|
|
||||||
&-horizontal &-item,
|
&-horizontal &-item,
|
||||||
&-horizontal &-submenu-title {
|
&-horizontal &-submenu-title {
|
||||||
transition: border-color 0.3s, background 0.3s;
|
transition: border-color @animation-duration-slow, background @animation-duration-slow;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-item,
|
&-item,
|
||||||
@ -183,17 +199,22 @@
|
|||||||
padding: @menu-item-padding;
|
padding: @menu-item-padding;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: border-color 0.3s, background 0.3s, padding 0.15s @ease-in-out;
|
transition: border-color @animation-duration-slow, background @animation-duration-slow,
|
||||||
|
padding @animation-duration-slow @ease-in-out;
|
||||||
|
|
||||||
.@{menu-prefix-cls}-item-icon,
|
.@{menu-prefix-cls}-item-icon,
|
||||||
.@{iconfont-css-prefix} {
|
.@{iconfont-css-prefix} {
|
||||||
min-width: 14px;
|
min-width: 14px;
|
||||||
margin-right: @menu-icon-margin-right;
|
|
||||||
font-size: @menu-icon-size;
|
font-size: @menu-icon-size;
|
||||||
transition: font-size 0.15s @ease-out, margin 0.3s @ease-in-out, color 0.3s;
|
transition: font-size @menu-animation-duration-normal @ease-out,
|
||||||
|
margin @animation-duration-slow @ease-in-out, color @animation-duration-slow;
|
||||||
+ span {
|
+ span {
|
||||||
|
margin-left: @menu-icon-margin-right;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity 0.3s @ease-in-out, width 0.3s @ease-in-out, color 0.3s;
|
// transition: opacity @animation-duration-slow @ease-in-out,
|
||||||
|
// width @animation-duration-slow @ease-in-out, color @animation-duration-slow;
|
||||||
|
transition: opacity @animation-duration-slow @ease-in-out, margin @animation-duration-slow,
|
||||||
|
color @animation-duration-slow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +224,10 @@
|
|||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
.accessibility-focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > &-item-divider {
|
& > &-item-divider {
|
||||||
@ -248,7 +273,7 @@
|
|||||||
background-color: @menu-bg;
|
background-color: @menu-bg;
|
||||||
border-radius: @border-radius-base;
|
border-radius: @border-radius-base;
|
||||||
&-submenu-title::after {
|
&-submenu-title::after {
|
||||||
transition: transform 0.3s @ease-in-out;
|
transition: transform @animation-duration-slow @ease-in-out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,10 +289,11 @@
|
|||||||
width: 10px;
|
width: 10px;
|
||||||
color: @menu-item-color;
|
color: @menu-item-color;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
transition: transform 0.3s @ease-in-out;
|
transition: transform @animation-duration-slow @ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-arrow {
|
&-arrow {
|
||||||
|
// →
|
||||||
&::before,
|
&::before,
|
||||||
&::after {
|
&::after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -275,8 +301,9 @@
|
|||||||
height: 1.5px;
|
height: 1.5px;
|
||||||
background-color: currentColor;
|
background-color: currentColor;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
transition: background 0.3s @ease-in-out, transform 0.3s @ease-in-out, top 0.3s @ease-in-out,
|
transition: background @animation-duration-slow @ease-in-out,
|
||||||
color 0.3s @ease-in-out;
|
transform @animation-duration-slow @ease-in-out, top @animation-duration-slow @ease-in-out,
|
||||||
|
color @animation-duration-slow @ease-in-out;
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
&::before {
|
&::before {
|
||||||
@ -292,7 +319,9 @@
|
|||||||
color: @menu-highlight-color;
|
color: @menu-highlight-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.@{menu-prefix-cls}-inline-collapsed &-arrow,
|
||||||
&-inline &-arrow {
|
&-inline &-arrow {
|
||||||
|
// ↓
|
||||||
&::before {
|
&::before {
|
||||||
transform: rotate(-45deg) translateX(2.5px);
|
transform: rotate(-45deg) translateX(2.5px);
|
||||||
}
|
}
|
||||||
@ -306,6 +335,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-open&-inline > &-title > &-arrow {
|
&-open&-inline > &-title > &-arrow {
|
||||||
|
// ↑
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
&::after {
|
&::after {
|
||||||
transform: rotate(-45deg) translateX(-2.5px);
|
transform: rotate(-45deg) translateX(-2.5px);
|
||||||
@ -398,7 +428,8 @@
|
|||||||
border-right: @menu-item-active-border-width solid @menu-highlight-color;
|
border-right: @menu-item-active-border-width solid @menu-highlight-color;
|
||||||
transform: scaleY(0.0001);
|
transform: scaleY(0.0001);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: transform 0.15s @ease-out, opacity 0.15s @ease-out;
|
transition: transform @menu-animation-duration-normal @ease-out,
|
||||||
|
opacity @menu-animation-duration-normal @ease-out;
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -444,7 +475,8 @@
|
|||||||
&::after {
|
&::after {
|
||||||
transform: scaleY(1);
|
transform: scaleY(1);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: transform 0.15s @ease-in-out, opacity 0.15s @ease-in-out;
|
transition: transform @menu-animation-duration-normal @ease-in-out,
|
||||||
|
opacity @menu-animation-duration-normal @ease-in-out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,12 +489,33 @@
|
|||||||
.@{menu-prefix-cls}-submenu-title {
|
.@{menu-prefix-cls}-submenu-title {
|
||||||
padding-right: 34px;
|
padding-right: 34px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Motion enhance for first level
|
||||||
|
&.@{menu-prefix-cls}-root {
|
||||||
|
.@{menu-prefix-cls}-item,
|
||||||
|
.@{menu-prefix-cls}-submenu-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
transition: border-color @animation-duration-slow, background @animation-duration-slow,
|
||||||
|
padding 0.1s @ease-out;
|
||||||
|
|
||||||
|
> .@{menu-prefix-cls}-title-content {
|
||||||
|
flex: auto;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
> * {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-inline-collapsed {
|
&&-inline-collapsed {
|
||||||
&:not(.@{ant-prefix}-layout-sider-children > ul) {
|
width: @menu-collapsed-width;
|
||||||
width: @menu-collapsed-width;
|
|
||||||
}
|
|
||||||
> .@{menu-prefix-cls}-item,
|
> .@{menu-prefix-cls}-item,
|
||||||
> .@{menu-prefix-cls}-item-group
|
> .@{menu-prefix-cls}-item-group
|
||||||
> .@{menu-prefix-cls}-item-group-list
|
> .@{menu-prefix-cls}-item-group-list
|
||||||
@ -475,8 +528,9 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
padding: 0 ~'calc(50% - @{menu-icon-size-lg} / 2)';
|
padding: 0 ~'calc(50% - @{menu-icon-size-lg} / 2)';
|
||||||
text-overflow: clip;
|
text-overflow: clip;
|
||||||
|
|
||||||
.@{menu-prefix-cls}-submenu-arrow {
|
.@{menu-prefix-cls}-submenu-arrow {
|
||||||
display: none;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{menu-prefix-cls}-item-icon,
|
.@{menu-prefix-cls}-item-icon,
|
||||||
@ -486,7 +540,6 @@
|
|||||||
line-height: @menu-item-height;
|
line-height: @menu-item-height;
|
||||||
+ span {
|
+ span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-width: 0;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount, render } from 'enzyme';
|
import { mount, render } from 'enzyme';
|
||||||
import PageHeader from '..';
|
import PageHeader from '..';
|
||||||
|
import Breadcrumb from '../../breadcrumb';
|
||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
@ -50,6 +51,20 @@ describe('PageHeader', () => {
|
|||||||
expect(wrapper.find('.ant-page-header-back')).toHaveLength(0);
|
expect(wrapper.find('.ant-page-header-back')).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('pageHeader should have breadcrumb (component)', () => {
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: 'index',
|
||||||
|
breadcrumbName: 'First-level Menu',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const wrapper = mount(
|
||||||
|
<PageHeader title="Page Title" breadcrumb={<Breadcrumb routes={routes} />} />,
|
||||||
|
);
|
||||||
|
expect(wrapper.find('.ant-breadcrumb')).toHaveLength(1);
|
||||||
|
expect(wrapper.find('.ant-page-header-back')).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('pageHeader support breadcrumbRender', () => {
|
it('pageHeader support breadcrumbRender', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<PageHeader title="Page Title" breadcrumbRender={() => <div id="test">test</div>} />,
|
<PageHeader title="Page Title" breadcrumbRender={() => <div id="test">test</div>} />,
|
||||||
|
@ -16,7 +16,7 @@ export interface PageHeaderProps {
|
|||||||
title?: React.ReactNode;
|
title?: React.ReactNode;
|
||||||
subTitle?: React.ReactNode;
|
subTitle?: React.ReactNode;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
breadcrumb?: BreadcrumbProps;
|
breadcrumb?: BreadcrumbProps | React.ReactElement<typeof Breadcrumb>;
|
||||||
breadcrumbRender?: (props: PageHeaderProps, defaultDom: React.ReactNode) => React.ReactNode;
|
breadcrumbRender?: (props: PageHeaderProps, defaultDom: React.ReactNode) => React.ReactNode;
|
||||||
tags?: React.ReactElement<TagType> | React.ReactElement<TagType>[];
|
tags?: React.ReactElement<TagType> | React.ReactElement<TagType>[];
|
||||||
footer?: React.ReactNode;
|
footer?: React.ReactNode;
|
||||||
@ -156,10 +156,13 @@ const PageHeader: React.FC<PageHeaderProps> = props => {
|
|||||||
|
|
||||||
const defaultBreadcrumbDom = getDefaultBreadcrumbDom();
|
const defaultBreadcrumbDom = getDefaultBreadcrumbDom();
|
||||||
|
|
||||||
|
const isBreadcrumbComponent = breadcrumb && 'props' in breadcrumb;
|
||||||
// support breadcrumbRender function
|
// support breadcrumbRender function
|
||||||
const breadcrumbDom =
|
const breadcrumbRenderDomFromProps =
|
||||||
breadcrumbRender?.(props, defaultBreadcrumbDom) || defaultBreadcrumbDom;
|
breadcrumbRender?.(props, defaultBreadcrumbDom) || defaultBreadcrumbDom;
|
||||||
|
|
||||||
|
const breadcrumbDom = isBreadcrumbComponent ? breadcrumb : breadcrumbRenderDomFromProps;
|
||||||
|
|
||||||
const className = classNames(prefixCls, customizeClassName, {
|
const className = classNames(prefixCls, customizeClassName, {
|
||||||
'has-breadcrumb': !!breadcrumbDom,
|
'has-breadcrumb': !!breadcrumbDom,
|
||||||
'has-footer': !!footer,
|
'has-footer': !!footer,
|
||||||
|
@ -192,4 +192,15 @@ describe('Radio Group', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support data-* or aria-* props', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
createRadioGroup({
|
||||||
|
'data-radio-group-id': 'radio-group-id',
|
||||||
|
'aria-label': 'radio-group',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(wrapper.getDOMNode().getAttribute('data-radio-group-id')).toBe('radio-group-id');
|
||||||
|
expect(wrapper.getDOMNode().getAttribute('aria-label')).toBe('radio-group');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ import { RadioGroupProps, RadioChangeEvent, RadioGroupButtonStyle } from './inte
|
|||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import SizeContext from '../config-provider/SizeContext';
|
import SizeContext from '../config-provider/SizeContext';
|
||||||
import { RadioGroupContextProvider } from './context';
|
import { RadioGroupContextProvider } from './context';
|
||||||
|
import getDataOrAriaProps from '../_util/getDataOrAriaProps';
|
||||||
|
|
||||||
const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref) => {
|
const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref) => {
|
||||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||||
@ -91,6 +92,7 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
{...getDataOrAriaProps(props)}
|
||||||
className={classString}
|
className={classString}
|
||||||
style={style}
|
style={style}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
|
@ -20,19 +20,23 @@ export default function Item({
|
|||||||
split,
|
split,
|
||||||
wrap,
|
wrap,
|
||||||
}: ItemProps) {
|
}: ItemProps) {
|
||||||
const { horizontalSize, verticalSize, latestIndex } = React.useContext(SpaceContext);
|
const { horizontalSize, verticalSize, latestIndex, supportFlexGap } = React.useContext(
|
||||||
|
SpaceContext,
|
||||||
|
);
|
||||||
|
|
||||||
let style: React.CSSProperties = {};
|
let style: React.CSSProperties = {};
|
||||||
|
|
||||||
if (direction === 'vertical') {
|
if (!supportFlexGap) {
|
||||||
if (index < latestIndex) {
|
if (direction === 'vertical') {
|
||||||
style = { marginBottom: horizontalSize / (split ? 2 : 1) };
|
if (index < latestIndex) {
|
||||||
|
style = { marginBottom: horizontalSize / (split ? 2 : 1) };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
style = {
|
||||||
|
...(index < latestIndex && { [marginDirection]: horizontalSize / (split ? 2 : 1) }),
|
||||||
|
...(wrap && { paddingBottom: verticalSize }),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
style = {
|
|
||||||
...(index < latestIndex && { [marginDirection]: horizontalSize / (split ? 2 : 1) }),
|
|
||||||
...(wrap && { paddingBottom: verticalSize }),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children === null || children === undefined) {
|
if (children === null || children === undefined) {
|
||||||
|
@ -408,6 +408,61 @@ exports[`renders ./components/space/demo/debug.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/space/demo/gap-in-line.md correctly 1`] = `
|
||||||
|
Array [
|
||||||
|
<button
|
||||||
|
aria-checked="false"
|
||||||
|
class="ant-switch"
|
||||||
|
role="switch"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-switch-handle"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-switch-inner"
|
||||||
|
/>
|
||||||
|
</button>,
|
||||||
|
<div
|
||||||
|
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||||
|
style="flex-wrap:wrap;margin-bottom:-8px;width:310px;background:blue"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px;padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px;padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px;padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/space/demo/size.md correctly 1`] = `
|
exports[`renders ./components/space/demo/size.md correctly 1`] = `
|
||||||
Array [
|
Array [
|
||||||
<div
|
<div
|
||||||
|
24
components/space/__tests__/gap.test.js
Normal file
24
components/space/__tests__/gap.test.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { mount } from 'enzyme';
|
||||||
|
import Space from '..';
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
import * as styleChecker from '../../_util/styleChecker';
|
||||||
|
|
||||||
|
jest.mock('../../_util/styleChecker', () => ({
|
||||||
|
canUseDocElement: () => true,
|
||||||
|
isStyleSupport: () => true,
|
||||||
|
detectFlexGapSupported: () => true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('flex gap', () => {
|
||||||
|
it('should render width empty children', () => {
|
||||||
|
const wrapper = mount(
|
||||||
|
<Space>
|
||||||
|
<span />
|
||||||
|
<span />
|
||||||
|
</Space>,
|
||||||
|
);
|
||||||
|
expect(wrapper.getDOMNode().style['column-gap']).toBe('8px');
|
||||||
|
expect(wrapper.getDOMNode().style['row-gap']).toBe('8px');
|
||||||
|
});
|
||||||
|
});
|
48
components/space/demo/gap-in-line.md
Normal file
48
components/space/demo/gap-in-line.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
order: 99
|
||||||
|
title:
|
||||||
|
zh-CN: Flex gap 样式
|
||||||
|
en-US: Flex gap style
|
||||||
|
debug: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
Debug usage
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
Debug usage
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Space, Switch } from 'antd';
|
||||||
|
|
||||||
|
const style: React.CSSProperties = {
|
||||||
|
width: 150,
|
||||||
|
height: 100,
|
||||||
|
background: 'red',
|
||||||
|
};
|
||||||
|
|
||||||
|
const Demo = () => {
|
||||||
|
const [singleCol, setSingleCol] = React.useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Switch
|
||||||
|
checked={singleCol}
|
||||||
|
onChange={() => {
|
||||||
|
setSingleCol(!singleCol);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Space style={{ width: singleCol ? 307 : 310, background: 'blue' }} size={[8, 8]} wrap>
|
||||||
|
<div style={style} />
|
||||||
|
<div style={style} />
|
||||||
|
<div style={style} />
|
||||||
|
<div style={style} />
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(<Demo />, mountNode);
|
||||||
|
```
|
@ -4,11 +4,13 @@ import toArray from 'rc-util/lib/Children/toArray';
|
|||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import { SizeType } from '../config-provider/SizeContext';
|
import { SizeType } from '../config-provider/SizeContext';
|
||||||
import Item from './Item';
|
import Item from './Item';
|
||||||
|
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
|
||||||
|
|
||||||
export const SpaceContext = React.createContext({
|
export const SpaceContext = React.createContext({
|
||||||
latestIndex: 0,
|
latestIndex: 0,
|
||||||
horizontalSize: 0,
|
horizontalSize: 0,
|
||||||
verticalSize: 0,
|
verticalSize: 0,
|
||||||
|
supportFlexGap: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type SpaceSize = SizeType | number;
|
export type SpaceSize = SizeType | number;
|
||||||
@ -51,6 +53,8 @@ const Space: React.FC<SpaceProps> = props => {
|
|||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const supportFlexGap = useFlexGapSupport();
|
||||||
|
|
||||||
const [horizontalSize, verticalSize] = React.useMemo(
|
const [horizontalSize, verticalSize] = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
((Array.isArray(size) ? size : [size, size]) as [SpaceSize, SpaceSize]).map(item =>
|
((Array.isArray(size) ? size : [size, size]) as [SpaceSize, SpaceSize]).map(item =>
|
||||||
@ -61,10 +65,6 @@ const Space: React.FC<SpaceProps> = props => {
|
|||||||
|
|
||||||
const childNodes = toArray(children, { keepEmpty: true });
|
const childNodes = toArray(children, { keepEmpty: true });
|
||||||
|
|
||||||
if (childNodes.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mergedAlign = align === undefined && direction === 'horizontal' ? 'center' : align;
|
const mergedAlign = align === undefined && direction === 'horizontal' ? 'center' : align;
|
||||||
const prefixCls = getPrefixCls('space', customizePrefixCls);
|
const prefixCls = getPrefixCls('space', customizePrefixCls);
|
||||||
const cn = classNames(
|
const cn = classNames(
|
||||||
@ -105,18 +105,33 @@ const Space: React.FC<SpaceProps> = props => {
|
|||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const spaceContext = React.useMemo(
|
||||||
|
() => ({ horizontalSize, verticalSize, latestIndex, supportFlexGap }),
|
||||||
|
[horizontalSize, verticalSize, latestIndex, supportFlexGap],
|
||||||
|
);
|
||||||
|
|
||||||
|
// =========================== Render ===========================
|
||||||
|
if (childNodes.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gapStyle: React.CSSProperties = {};
|
||||||
|
if (supportFlexGap) {
|
||||||
|
gapStyle.columnGap = horizontalSize;
|
||||||
|
gapStyle.rowGap = verticalSize;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn}
|
className={cn}
|
||||||
style={{
|
style={{
|
||||||
|
...gapStyle,
|
||||||
...(wrap && { flexWrap: 'wrap', marginBottom: -verticalSize }),
|
...(wrap && { flexWrap: 'wrap', marginBottom: -verticalSize }),
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
>
|
>
|
||||||
<SpaceContext.Provider value={{ horizontalSize, verticalSize, latestIndex }}>
|
<SpaceContext.Provider value={spaceContext}>{nodes}</SpaceContext.Provider>
|
||||||
{nodes}
|
|
||||||
</SpaceContext.Provider>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,7 @@ interface CountdownProps extends StatisticProps {
|
|||||||
value?: countdownValueType;
|
value?: countdownValueType;
|
||||||
format?: string;
|
format?: string;
|
||||||
onFinish?: () => void;
|
onFinish?: () => void;
|
||||||
|
onChange?: (value?: countdownValueType) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTime(value?: countdownValueType) {
|
function getTime(value?: countdownValueType) {
|
||||||
@ -48,8 +49,15 @@ class Countdown extends React.Component<CountdownProps, {}> {
|
|||||||
startTimer = () => {
|
startTimer = () => {
|
||||||
if (this.countdownId) return;
|
if (this.countdownId) return;
|
||||||
|
|
||||||
|
const { onChange, value } = this.props;
|
||||||
|
const timestamp = getTime(value);
|
||||||
|
|
||||||
this.countdownId = window.setInterval(() => {
|
this.countdownId = window.setInterval(() => {
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
|
|
||||||
|
if (onChange && timestamp > Date.now()) {
|
||||||
|
onChange(timestamp - Date.now());
|
||||||
|
}
|
||||||
}, REFRESH_INTERVAL);
|
}, REFRESH_INTERVAL);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -325,6 +325,29 @@ exports[`renders ./components/statistic/demo/countdown.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-col ant-col-12"
|
||||||
|
style="padding-left:8px;padding-right:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-statistic"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-statistic-title"
|
||||||
|
>
|
||||||
|
Countdown
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-statistic-content"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-statistic-content-value"
|
||||||
|
>
|
||||||
|
00:00:10
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -116,6 +116,21 @@ describe('Statistic', () => {
|
|||||||
expect(onMouseLeave).toHaveBeenCalled();
|
expect(onMouseLeave).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('time onchange', () => {
|
||||||
|
it("called if time has't passed", async () => {
|
||||||
|
const deadline = Date.now() + 10 * 1000;
|
||||||
|
let remainingTime;
|
||||||
|
|
||||||
|
const onChange = value => {
|
||||||
|
remainingTime = value;
|
||||||
|
};
|
||||||
|
const wrapper = mount(<Statistic.Countdown value={deadline} onChange={onChange} />);
|
||||||
|
wrapper.update();
|
||||||
|
await sleep(100)
|
||||||
|
expect(remainingTime).toBeGreaterThan(0)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('time finished', () => {
|
describe('time finished', () => {
|
||||||
it('not call if time already passed', () => {
|
it('not call if time already passed', () => {
|
||||||
const now = Date.now() - 1000;
|
const now = Date.now() - 1000;
|
||||||
|
@ -23,6 +23,12 @@ function onFinish() {
|
|||||||
console.log('finished!');
|
console.log('finished!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onChange(val) {
|
||||||
|
if (4.95 * 1000 < val && val < 5 * 1000) {
|
||||||
|
console.log('changed!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
@ -34,6 +40,9 @@ ReactDOM.render(
|
|||||||
<Col span={24} style={{ marginTop: 32 }}>
|
<Col span={24} style={{ marginTop: 32 }}>
|
||||||
<Countdown title="Day Level" value={deadline} format="D 天 H 时 m 分 s 秒" />
|
<Countdown title="Day Level" value={deadline} format="D 天 H 时 m 分 s 秒" />
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Countdown title="Countdown" value={Date.now() + 10 * 1000} onChange={onChange} />
|
||||||
|
</Col>
|
||||||
</Row>,
|
</Row>,
|
||||||
mountNode,
|
mountNode,
|
||||||
);
|
);
|
||||||
|
@ -40,3 +40,4 @@ Display statistic number.
|
|||||||
| value | Set target countdown time | number \| moment | - | |
|
| value | Set target countdown time | number \| moment | - | |
|
||||||
| valueStyle | Set value css style | CSSProperties | - | |
|
| valueStyle | Set value css style | CSSProperties | - | |
|
||||||
| onFinish | Trigger when time's up | () => void | - | |
|
| onFinish | Trigger when time's up | () => void | - | |
|
||||||
|
| onChange | Trigger when time's changing | (value: number) => void | - | 4.16.0 |
|
||||||
|
@ -41,3 +41,4 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/rcBNhLBrKbE/Statistic.svg
|
|||||||
| value | 数值内容 | number \| moment | - | |
|
| value | 数值内容 | number \| moment | - | |
|
||||||
| valueStyle | 设置数值的样式 | CSSProperties | - | |
|
| valueStyle | 设置数值的样式 | CSSProperties | - | |
|
||||||
| onFinish | 倒计时完成时触发 | () => void | - | |
|
| onFinish | 倒计时完成时触发 | () => void | - | |
|
||||||
|
| onChange | 倒计时时间变化时触发 | (value: number) => void | - | 4.16.0 |
|
||||||
|
@ -27,6 +27,7 @@ export interface SwitchProps {
|
|||||||
autoFocus?: boolean;
|
autoFocus?: boolean;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
tabIndex?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CompoundedComponent
|
interface CompoundedComponent
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable react/no-multi-comp */
|
/* eslint-disable react/no-multi-comp */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import Table from '..';
|
import Table from '..';
|
||||||
import Input from '../../input';
|
import Input from '../../input';
|
||||||
import Tooltip from '../../tooltip';
|
import Tooltip from '../../tooltip';
|
||||||
@ -11,11 +12,12 @@ import ConfigProvider from '../../config-provider';
|
|||||||
// https://github.com/Semantic-Org/Semantic-UI-React/blob/72c45080e4f20b531fda2e3e430e384083d6766b/test/specs/modules/Dropdown/Dropdown-test.js#L73
|
// https://github.com/Semantic-Org/Semantic-UI-React/blob/72c45080e4f20b531fda2e3e430e384083d6766b/test/specs/modules/Dropdown/Dropdown-test.js#L73
|
||||||
const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => {} } };
|
const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => {} } };
|
||||||
|
|
||||||
function getDropdownWrapper(wrapper) {
|
|
||||||
return mount(wrapper.find('Trigger').first().instance().getComponent());
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Table.filter', () => {
|
describe('Table.filter', () => {
|
||||||
|
window.requestAnimationFrame = function (callback) {
|
||||||
|
return window.setTimeout(callback, 16);
|
||||||
|
};
|
||||||
|
window.cancelAnimationFrame = window.clearTimeout;
|
||||||
|
|
||||||
const filterFn = (value, record) => record.name.indexOf(value) !== -1;
|
const filterFn = (value, record) => record.name.indexOf(value) !== -1;
|
||||||
const column = {
|
const column = {
|
||||||
title: 'Name',
|
title: 'Name',
|
||||||
@ -96,6 +98,8 @@ describe('Table.filter', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders empty menu correctly', () => {
|
it('renders empty menu correctly', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
createTable({
|
createTable({
|
||||||
@ -108,11 +112,18 @@ describe('Table.filter', () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
wrapper.find('span.ant-dropdown-trigger').simulate('click', nativeEvent);
|
wrapper.find('span.ant-dropdown-trigger').simulate('click', nativeEvent);
|
||||||
expect(wrapper.find('Empty').length).toBe(1);
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.find('Empty').length).toBeTruthy();
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
expect(console.error).not.toHaveBeenCalled();
|
expect(console.error).not.toHaveBeenCalled();
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error.mockRestore();
|
console.error.mockRestore();
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders radio filter correctly', () => {
|
it('renders radio filter correctly', () => {
|
||||||
@ -548,24 +559,44 @@ describe('Table.filter', () => {
|
|||||||
// Open
|
// Open
|
||||||
wrapper.find('.ant-table-filter-trigger').simulate('click');
|
wrapper.find('.ant-table-filter-trigger').simulate('click');
|
||||||
|
|
||||||
let dropdownWrapper = getDropdownWrapper(wrapper);
|
function getFilterMenu() {
|
||||||
|
return wrapper.find('FilterDropdown');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seems raf not trigger when in useEffect for async update
|
||||||
|
// Need trigger multiple times
|
||||||
|
function refreshTimer() {
|
||||||
|
for (let i = 0; i < 3; i += 1) {
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open Level2
|
||||||
|
getFilterMenu().find('div.ant-dropdown-menu-submenu-title').at(0).simulate('mouseEnter');
|
||||||
|
refreshTimer();
|
||||||
|
|
||||||
|
// Open Level3
|
||||||
|
getFilterMenu().find('div.ant-dropdown-menu-submenu-title').at(1).simulate('mouseEnter');
|
||||||
|
refreshTimer();
|
||||||
|
|
||||||
|
// Select Level3 value
|
||||||
|
getFilterMenu().find('li.ant-dropdown-menu-item').last().simulate('click');
|
||||||
|
getFilterMenu().find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
|
||||||
|
refreshTimer();
|
||||||
|
|
||||||
// select
|
|
||||||
dropdownWrapper.find('.ant-dropdown-menu-submenu-title').at(0).simulate('mouseEnter');
|
|
||||||
jest.runAllTimers();
|
|
||||||
dropdownWrapper = getDropdownWrapper(wrapper);
|
|
||||||
dropdownWrapper.find('.ant-dropdown-menu-submenu-title').at(1).simulate('mouseEnter');
|
|
||||||
jest.runAllTimers();
|
|
||||||
dropdownWrapper = getDropdownWrapper(wrapper);
|
|
||||||
dropdownWrapper.find('MenuItem').last().simulate('click');
|
|
||||||
dropdownWrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
|
|
||||||
onChange.mock.calls.forEach(([, currentFilters]) => {
|
onChange.mock.calls.forEach(([, currentFilters]) => {
|
||||||
const [, val] = Object.entries(currentFilters)[0];
|
const [, val] = Object.entries(currentFilters)[0];
|
||||||
expect(val).toEqual(['Jack']);
|
expect(val).toEqual(['Jack']);
|
||||||
});
|
});
|
||||||
wrapper.update();
|
|
||||||
expect(renderedNames(wrapper)).toEqual(['Jack']);
|
expect(renderedNames(wrapper)).toEqual(['Jack']);
|
||||||
dropdownWrapper.find('MenuItem').last().simulate('click');
|
|
||||||
|
// What's this? Is that a coverage case?
|
||||||
|
getFilterMenu().find('li.ant-dropdown-menu-item').last().simulate('click');
|
||||||
|
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import { mount, render } from 'enzyme';
|
import { mount, render } from 'enzyme';
|
||||||
import Table from '..';
|
import Table from '..';
|
||||||
import Checkbox from '../../checkbox';
|
import Checkbox from '../../checkbox';
|
||||||
@ -6,6 +7,9 @@ import { resetWarned } from '../../_util/devWarning';
|
|||||||
import ConfigProvider from '../../config-provider';
|
import ConfigProvider from '../../config-provider';
|
||||||
|
|
||||||
describe('Table.rowSelection', () => {
|
describe('Table.rowSelection', () => {
|
||||||
|
window.requestAnimationFrame = callback => window.setTimeout(callback, 16);
|
||||||
|
window.cancelAnimationFrame = window.clearTimeout;
|
||||||
|
|
||||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -335,6 +339,8 @@ describe('Table.rowSelection', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fires selectInvert event', () => {
|
it('fires selectInvert event', () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const order = [];
|
const order = [];
|
||||||
const handleSelectInvert = jest.fn().mockImplementation(() => {
|
const handleSelectInvert = jest.fn().mockImplementation(() => {
|
||||||
order.push('onSelectInvert');
|
order.push('onSelectInvert');
|
||||||
@ -353,14 +359,24 @@ describe('Table.rowSelection', () => {
|
|||||||
checkboxes.at(1).simulate('change', { target: { checked: true } });
|
checkboxes.at(1).simulate('change', { target: { checked: true } });
|
||||||
|
|
||||||
// Open
|
// Open
|
||||||
wrapper.find('Trigger').setState({ popupVisible: true });
|
wrapper.find('span.ant-dropdown-trigger').simulate('mouseEnter');
|
||||||
|
|
||||||
const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent());
|
// enzyme has bug for state sync.
|
||||||
dropdownWrapper.find('.ant-dropdown-menu-item').at(1).simulate('click');
|
// Let fresh multiple times to force sync back.
|
||||||
|
for (let i = 0; i < 3; i += 1) {
|
||||||
|
act(() => {
|
||||||
|
jest.runAllTimers();
|
||||||
|
wrapper.update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper.find('li.ant-dropdown-menu-item').at(1).simulate('click');
|
||||||
|
|
||||||
expect(handleSelectInvert).toHaveBeenCalledWith([1, 2, 3]);
|
expect(handleSelectInvert).toHaveBeenCalledWith([1, 2, 3]);
|
||||||
|
|
||||||
expect(order).toEqual(['onChange', 'onSelectInvert', 'onChange']);
|
expect(order).toEqual(['onChange', 'onSelectInvert', 'onChange']);
|
||||||
|
|
||||||
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fires selectNone event', () => {
|
it('fires selectNone event', () => {
|
||||||
@ -416,12 +432,12 @@ describe('Table.rowSelection', () => {
|
|||||||
wrapper.find('Trigger').setState({ popupVisible: true });
|
wrapper.find('Trigger').setState({ popupVisible: true });
|
||||||
|
|
||||||
const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent());
|
const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent());
|
||||||
expect(dropdownWrapper.find('.ant-dropdown-menu-item').length).toBe(4);
|
expect(dropdownWrapper.find('li.ant-dropdown-menu-item').length).toBe(4);
|
||||||
|
|
||||||
dropdownWrapper.find('.ant-dropdown-menu-item').at(2).simulate('click');
|
dropdownWrapper.find('li.ant-dropdown-menu-item').at(2).simulate('click');
|
||||||
expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]);
|
expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]);
|
||||||
|
|
||||||
dropdownWrapper.find('.ant-dropdown-menu-item').at(3).simulate('click');
|
dropdownWrapper.find('li.ant-dropdown-menu-item').at(3).simulate('click');
|
||||||
expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]);
|
expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -456,12 +472,12 @@ describe('Table.rowSelection', () => {
|
|||||||
wrapper.find('Trigger').setState({ popupVisible: true });
|
wrapper.find('Trigger').setState({ popupVisible: true });
|
||||||
|
|
||||||
const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent());
|
const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent());
|
||||||
expect(dropdownWrapper.find('.ant-dropdown-menu-item').length).toBe(2);
|
expect(dropdownWrapper.find('li.ant-dropdown-menu-item').length).toBe(2);
|
||||||
|
|
||||||
dropdownWrapper.find('.ant-dropdown-menu-item').at(0).simulate('click');
|
dropdownWrapper.find('li.ant-dropdown-menu-item').at(0).simulate('click');
|
||||||
expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]);
|
expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]);
|
||||||
|
|
||||||
dropdownWrapper.find('.ant-dropdown-menu-item').at(1).simulate('click');
|
dropdownWrapper.find('li.ant-dropdown-menu-item').at(1).simulate('click');
|
||||||
expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]);
|
expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -601,12 +601,16 @@ exports[`Table.filter should support getPopupContainer 1`] = `
|
|||||||
class="ant-table-filter-dropdown"
|
class="ant-table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item"
|
class="ant-dropdown-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-boy"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="ant-checkbox-wrapper"
|
class="ant-checkbox-wrapper"
|
||||||
@ -630,7 +634,9 @@ exports[`Table.filter should support getPopupContainer 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item"
|
class="ant-dropdown-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-girl"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="ant-checkbox-wrapper"
|
class="ant-checkbox-wrapper"
|
||||||
@ -654,13 +660,16 @@ exports[`Table.filter should support getPopupContainer 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-controls="rc-menu-uuid-test-title-popup"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-dropdown-menu-submenu-title"
|
class="ant-dropdown-menu-submenu-title"
|
||||||
role="button"
|
data-menu-id="rc-menu-uuid-test-title"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Title"
|
title="Title"
|
||||||
>
|
>
|
||||||
Title
|
Title
|
||||||
@ -833,12 +842,16 @@ exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] =
|
|||||||
class="ant-table-filter-dropdown"
|
class="ant-table-filter-dropdown"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item"
|
class="ant-dropdown-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-boy"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="ant-checkbox-wrapper"
|
class="ant-checkbox-wrapper"
|
||||||
@ -862,7 +875,9 @@ exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] =
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item"
|
class="ant-dropdown-menu-item"
|
||||||
|
data-menu-id="rc-menu-uuid-test-girl"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="ant-checkbox-wrapper"
|
class="ant-checkbox-wrapper"
|
||||||
@ -886,13 +901,16 @@ exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] =
|
|||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||||
role="menuitem"
|
role="none"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-controls="rc-menu-uuid-test-title-popup"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
class="ant-dropdown-menu-submenu-title"
|
class="ant-dropdown-menu-submenu-title"
|
||||||
role="button"
|
data-menu-id="rc-menu-uuid-test-title"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
title="Title"
|
title="Title"
|
||||||
>
|
>
|
||||||
Title
|
Title
|
||||||
|
@ -1051,25 +1051,32 @@ exports[`Table.rowSelection should support getPopupContainer 1`] = `
|
|||||||
style="opacity: 0; pointer-events: none;"
|
style="opacity: 0; pointer-events: none;"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||||
|
data-menu-id="rc-menu-uuid-test-all"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Select all data
|
Select all data
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||||
|
data-menu-id="rc-menu-uuid-test-invert"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Invert current page
|
Invert current page
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||||
|
data-menu-id="rc-menu-uuid-test-none"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Clear all data
|
Clear all data
|
||||||
</li>
|
</li>
|
||||||
@ -1384,25 +1391,32 @@ exports[`Table.rowSelection should support getPopupContainer from ConfigProvider
|
|||||||
style="opacity: 0; pointer-events: none;"
|
style="opacity: 0; pointer-events: none;"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
|
||||||
|
data-menu-list="true"
|
||||||
role="menu"
|
role="menu"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||||
|
data-menu-id="rc-menu-uuid-test-all"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Select all data
|
Select all data
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||||
|
data-menu-id="rc-menu-uuid-test-invert"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Invert current page
|
Invert current page
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
|
||||||
|
data-menu-id="rc-menu-uuid-test-none"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
Clear all data
|
Clear all data
|
||||||
</li>
|
</li>
|
||||||
|
@ -15882,7 +15882,7 @@ exports[`renders ./components/table/demo/sticky.md correctly 1`] = `
|
|||||||
class="ant-table-container"
|
class="ant-table-container"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="ant-table-header ant-table-sticky-header"
|
class="ant-table-header ant-table-sticky-holder"
|
||||||
style="overflow:hidden;top:0"
|
style="overflow:hidden;top:0"
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
@ -16756,6 +16756,41 @@ exports[`renders ./components/table/demo/sticky.md correctly 1`] = `
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-table-summary ant-table-sticky-holder"
|
||||||
|
style="overflow:hidden;bottom:0"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
style="table-layout:fixed;visibility:hidden"
|
||||||
|
>
|
||||||
|
<colgroup />
|
||||||
|
<tfoot
|
||||||
|
class="ant-table-summary"
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last ant-table-cell-fix-sticky"
|
||||||
|
colspan="2"
|
||||||
|
style="position:sticky;left:0"
|
||||||
|
>
|
||||||
|
Fix Left
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="ant-table-cell"
|
||||||
|
colspan="8"
|
||||||
|
>
|
||||||
|
Scroll Context
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
class="ant-table-cell ant-table-cell-fix-right ant-table-cell-fix-right-first ant-table-cell-fix-sticky"
|
||||||
|
style="position:sticky;right:0"
|
||||||
|
>
|
||||||
|
Fix Right
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
|
@ -94,7 +94,25 @@ for (let i = 0; i < 100; i++) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Table columns={columns} dataSource={data} scroll={{ x: 1500 }} sticky />,
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
dataSource={data}
|
||||||
|
scroll={{ x: 1500 }}
|
||||||
|
summary={pageData => (
|
||||||
|
<Table.Summary fixed>
|
||||||
|
<Table.Summary.Row>
|
||||||
|
<Table.Summary.Cell index={0} colSpan={2}>
|
||||||
|
Fix Left
|
||||||
|
</Table.Summary.Cell>
|
||||||
|
<Table.Summary.Cell index={2} colSpan={8}>
|
||||||
|
Scroll Context
|
||||||
|
</Table.Summary.Cell>
|
||||||
|
<Table.Summary.Cell index={10}>Fix Right</Table.Summary.Cell>
|
||||||
|
</Table.Summary.Row>
|
||||||
|
</Table.Summary>
|
||||||
|
)}
|
||||||
|
sticky
|
||||||
|
/>,
|
||||||
mountNode,
|
mountNode,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
@ -37,19 +37,21 @@ function renderFilterItems({
|
|||||||
// wrapped with <div /> to avoid react warning
|
// wrapped with <div /> to avoid react warning
|
||||||
// https://github.com/ant-design/ant-design/issues/25979
|
// https://github.com/ant-design/ant-design/issues/25979
|
||||||
return (
|
return (
|
||||||
<div
|
<MenuItem key="empty">
|
||||||
style={{
|
<div
|
||||||
margin: '16px 0',
|
style={{
|
||||||
}}
|
margin: '16px 0',
|
||||||
>
|
|
||||||
<Empty
|
|
||||||
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
|
||||||
description={locale.filterEmptyText}
|
|
||||||
imageStyle={{
|
|
||||||
height: 24,
|
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
</div>
|
<Empty
|
||||||
|
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
||||||
|
description={locale.filterEmptyText}
|
||||||
|
imageStyle={{
|
||||||
|
height: 24,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return filters.map((filter, index) => {
|
return filters.map((filter, index) => {
|
||||||
|
@ -148,9 +148,9 @@ One of the Table `columns` prop for describing the table's columns, Column has t
|
|||||||
|
|
||||||
### ColumnGroup
|
### ColumnGroup
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default |
|
||||||
| --- | --- | --- | --- |
|
| -------- | ------------------------- | --------- | ------- |
|
||||||
| title | Title of the column group | ReactNode | - |
|
| title | Title of the column group | ReactNode | - |
|
||||||
|
|
||||||
### pagination
|
### pagination
|
||||||
|
|
||||||
@ -166,22 +166,27 @@ More about pagination, please check [`Pagination`](/components/pagination/).
|
|||||||
|
|
||||||
Properties for expandable.
|
Properties for expandable.
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default | Version |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| childrenColumnName | The column contains children to display | string | children |
|
| childrenColumnName | The column contains children to display | string | children | |
|
||||||
| columnWidth | Set the width of the expand column | string \| number | - |
|
| columnWidth | Set the width of the expand column | string \| number | - | |
|
||||||
| defaultExpandAllRows | Expand all rows initially | boolean | false |
|
| defaultExpandAllRows | Expand all rows initially | boolean | false | |
|
||||||
| defaultExpandedRowKeys | Initial expanded row keys | string\[] | - |
|
| defaultExpandedRowKeys | Initial expanded row keys | string\[] | - | |
|
||||||
| expandedRowClassName | Expanded row's className | function(record, index, indent): string | - |
|
| expandedRowClassName | Expanded row's className | function(record, index, indent): string | - | |
|
||||||
| expandedRowKeys | Current expanded row keys | string\[] | - |
|
| expandedRowKeys | Current expanded row keys | string\[] | - | |
|
||||||
| expandedRowRender | Expanded container render for each row | function(record, index, indent, expanded): ReactNode | - |
|
| expandedRowRender | Expanded container render for each row | function(record, index, indent, expanded): ReactNode | - | |
|
||||||
| expandIcon | Customize row expand Icon. Ref [example](https://codesandbox.io/s/fervent-bird-nuzpr) | function(props): ReactNode | - |
|
| expandIcon | Customize row expand Icon. Ref [example](https://codesandbox.io/s/fervent-bird-nuzpr) | function(props): ReactNode | - | |
|
||||||
| expandIconColumnIndex | Customize expand icon column index. Not render when `-1` | number | - |
|
| expandIconColumnIndex | Customize expand icon column index. Not render when `-1` | number | - | |
|
||||||
| expandRowByClick | Whether to expand row by clicking anywhere in the whole row | boolean | false |
|
| expandRowByClick | Whether to expand row by clicking anywhere in the whole row | boolean | false | |
|
||||||
| indentSize | Indent size in pixels of tree data | number | 15 |
|
| fixed | Whether the expansion icon is fixed. Optional true `left` `right` | boolean \| string | false | 4.16.0 |
|
||||||
| rowExpandable | Enable row can be expandable | (record) => boolean | - |
|
| indentSize | Indent size in pixels of tree data | number | 15 | |
|
||||||
| onExpand | Callback executed when the row expand icon is clicked | function(expanded, record) | - |
|
| rowExpandable | Enable row can be expandable | (record) => boolean | - | |
|
||||||
| onExpandedRowsChange | Callback executed when the expanded rows change | function(expandedRows) | - |
|
| onExpand | Callback executed when the row expand icon is clicked | function(expanded, record) | - | |
|
||||||
|
| onExpandedRowsChange | Callback executed when the expanded rows change | function(expandedRows) | - | |
|
||||||
|
|
||||||
|
- `fixed`
|
||||||
|
- When set to true or `left` and `expandIconColumnIndex` is not set or is 0, enable fixed
|
||||||
|
- When set to true or `right` and `expandIconColumnIndex` is set to the number of table columns, enable fixed
|
||||||
|
|
||||||
### rowSelection
|
### rowSelection
|
||||||
|
|
||||||
|
@ -173,22 +173,27 @@ const columns = [
|
|||||||
|
|
||||||
展开功能的配置。
|
展开功能的配置。
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| childrenColumnName | 指定树形结构的列名 | string | children |
|
| childrenColumnName | 指定树形结构的列名 | string | children | |
|
||||||
| columnWidth | 自定义展开列宽度 | string \| number | - |
|
| columnWidth | 自定义展开列宽度 | string \| number | - | |
|
||||||
| defaultExpandAllRows | 初始时,是否展开所有行 | boolean | false |
|
| defaultExpandAllRows | 初始时,是否展开所有行 | boolean | false | |
|
||||||
| defaultExpandedRowKeys | 默认展开的行 | string\[] | - |
|
| defaultExpandedRowKeys | 默认展开的行 | string\[] | - | |
|
||||||
| expandedRowClassName | 展开行的 className | function(record, index, indent): string | - |
|
| expandedRowClassName | 展开行的 className | function(record, index, indent): string | - | |
|
||||||
| expandedRowKeys | 展开的行,控制属性 | string\[] | - |
|
| expandedRowKeys | 展开的行,控制属性 | string\[] | - | |
|
||||||
| expandedRowRender | 额外的展开行 | function(record, index, indent, expanded): ReactNode | - |
|
| expandedRowRender | 额外的展开行 | function(record, index, indent, expanded): ReactNode | - | |
|
||||||
| expandIcon | 自定义展开图标,参考[示例](https://codesandbox.io/s/fervent-bird-nuzpr) | function(props): ReactNode | - |
|
| expandIcon | 自定义展开图标,参考[示例](https://codesandbox.io/s/fervent-bird-nuzpr) | function(props): ReactNode | - | |
|
||||||
| expandIconColumnIndex | 自定义展开按钮的列顺序,`-1` 时不展示 | number | - |
|
| expandIconColumnIndex | 自定义展开按钮的列顺序,`-1` 时不展示 | number | - | |
|
||||||
| expandRowByClick | 通过点击行来展开子行 | boolean | false |
|
| expandRowByClick | 通过点击行来展开子行 | boolean | false | |
|
||||||
| indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 |
|
| fixed | 控制展开图标是否固定,可选 true `left` `right` | boolean \| string | false | 4.16.0 |
|
||||||
| rowExpandable | 设置是否允许行展开 | (record) => boolean | - |
|
| indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 | |
|
||||||
| onExpand | 点击展开图标时触发 | function(expanded, record) | - |
|
| rowExpandable | 设置是否允许行展开 | (record) => boolean | - | |
|
||||||
| onExpandedRowsChange | 展开的行变化时触发 | function(expandedRows) | - |
|
| onExpand | 点击展开图标时触发 | function(expanded, record) | - | |
|
||||||
|
| onExpandedRowsChange | 展开的行变化时触发 | function(expandedRows) | - | |
|
||||||
|
|
||||||
|
- `fixed`
|
||||||
|
- 当设置为 true 或 `left` 且 `expandIconColumnIndex` 未设置或为 0 时,开启固定
|
||||||
|
- 当设置为 true 或 `right` 且 `expandIconColumnIndex` 设置为表格列数时,开启固定
|
||||||
|
|
||||||
### rowSelection
|
### rowSelection
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
@table-header-icon-color: #bfbfbf;
|
@table-header-icon-color: #bfbfbf;
|
||||||
@table-header-icon-color-hover: darken(@table-header-icon-color, 10%);
|
@table-header-icon-color-hover: darken(@table-header-icon-color, 10%);
|
||||||
@table-header-sort-active-filter-bg: lighten(@table-header-sort-active-bg, 2%);
|
@table-header-sort-active-filter-bg: lighten(@table-header-sort-active-bg, 2%);
|
||||||
@table-sticky-zindex: calc(@zindex-table-fixed + 1);
|
@table-sticky-zindex: (@zindex-table-fixed + 1);
|
||||||
@table-sticky-scroll-bar-active-bg: fade(@table-sticky-scroll-bar-bg, 80%);
|
@table-sticky-scroll-bar-active-bg: fade(@table-sticky-scroll-bar-bg, 80%);
|
||||||
|
|
||||||
.@{table-prefix-cls}-wrapper {
|
.@{table-prefix-cls}-wrapper {
|
||||||
@ -147,7 +147,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =========================== Summary ============================
|
// =========================== Summary ============================
|
||||||
tfoot {
|
&-summary {
|
||||||
|
background: @table-bg;
|
||||||
|
|
||||||
|
div& {
|
||||||
|
box-shadow: 0 -@border-width-base 0 @table-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
> tr {
|
> tr {
|
||||||
> th,
|
> th,
|
||||||
> td {
|
> td {
|
||||||
@ -622,7 +628,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&-sticky {
|
&-sticky {
|
||||||
&-header {
|
&-holder {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
z-index: @table-sticky-zindex;
|
z-index: @table-sticky-zindex;
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,242 @@ exports[`Tabs rtl render component should be rendered correctly in RTL direction
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`Tabs tabBarGutter should work 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"
|
||||||
|
style="margin-left:0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-selected="true"
|
||||||
|
class="ant-tabs-tab-btn"
|
||||||
|
role="tab"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-tabs-tab ant-tabs-tab-active"
|
||||||
|
style="margin-left:0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-selected="true"
|
||||||
|
class="ant-tabs-tab-btn"
|
||||||
|
role="tab"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-tabs-tab ant-tabs-tab-active"
|
||||||
|
style="margin-left:0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-selected="true"
|
||||||
|
class="ant-tabs-tab-btn"
|
||||||
|
role="tab"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</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="margin-left:0;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"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
aria-hidden="false"
|
||||||
|
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||||
|
role="tabpanel"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
aria-hidden="false"
|
||||||
|
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||||
|
role="tabpanel"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Tabs tabBarGutter should work 2`] = `
|
||||||
|
<div
|
||||||
|
class="ant-tabs ant-tabs-left"
|
||||||
|
>
|
||||||
|
<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"
|
||||||
|
style="margin-top:0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-selected="true"
|
||||||
|
class="ant-tabs-tab-btn"
|
||||||
|
role="tab"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-tabs-tab ant-tabs-tab-active"
|
||||||
|
style="margin-top:0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-selected="true"
|
||||||
|
class="ant-tabs-tab-btn"
|
||||||
|
role="tab"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-tabs-tab ant-tabs-tab-active"
|
||||||
|
style="margin-top:0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-selected="true"
|
||||||
|
class="ant-tabs-tab-btn"
|
||||||
|
role="tab"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</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="margin-left:0;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-left"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-hidden="false"
|
||||||
|
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||||
|
role="tabpanel"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
aria-hidden="false"
|
||||||
|
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||||
|
role="tabpanel"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
aria-hidden="false"
|
||||||
|
class="ant-tabs-tabpane ant-tabs-tabpane-active"
|
||||||
|
role="tabpanel"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Tabs tabPosition remove card 1`] = `
|
exports[`Tabs tabPosition remove card 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-tabs ant-tabs-left"
|
class="ant-tabs ant-tabs-left"
|
||||||
|
@ -85,4 +85,11 @@ describe('Tabs', () => {
|
|||||||
);
|
);
|
||||||
errorSpy.mockRestore();
|
errorSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('tabBarGutter should work', () => {
|
||||||
|
const wrapper = mount(<Tabs tabBarGutter={0}><TabPane /><TabPane /><TabPane /></Tabs>);
|
||||||
|
expect(wrapper).toMatchRenderedSnapshot();
|
||||||
|
const wrapper2 = mount(<Tabs tabBarGutter={0} tabPosition="left"><TabPane /><TabPane /><TabPane /></Tabs>);
|
||||||
|
expect(wrapper2).toMatchRenderedSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,7 @@ import { TimePickerLocale } from '../index';
|
|||||||
|
|
||||||
const locale: TimePickerLocale = {
|
const locale: TimePickerLocale = {
|
||||||
placeholder: 'Selecteer tijd',
|
placeholder: 'Selecteer tijd',
|
||||||
|
rangePlaceholder: ['Start tijd', 'Eind tijd'],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default locale;
|
export default locale;
|
||||||
|
@ -2,6 +2,7 @@ import { TimePickerLocale } from '../index';
|
|||||||
|
|
||||||
const locale: TimePickerLocale = {
|
const locale: TimePickerLocale = {
|
||||||
placeholder: 'Selecteer tijd',
|
placeholder: 'Selecteer tijd',
|
||||||
|
rangePlaceholder: ['Start tijd', 'Eind tijd'],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default locale;
|
export default locale;
|
||||||
|
@ -67,10 +67,11 @@ export interface BlockProps extends TypographyProps {
|
|||||||
delete?: boolean;
|
delete?: boolean;
|
||||||
strong?: boolean;
|
strong?: boolean;
|
||||||
keyboard?: boolean;
|
keyboard?: boolean;
|
||||||
|
italic?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapperDecorations(
|
function wrapperDecorations(
|
||||||
{ mark, code, underline, delete: del, strong, keyboard }: BlockProps,
|
{ mark, code, underline, delete: del, strong, keyboard, italic }: BlockProps,
|
||||||
content: React.ReactNode,
|
content: React.ReactNode,
|
||||||
) {
|
) {
|
||||||
let currentContent = content;
|
let currentContent = content;
|
||||||
@ -87,6 +88,7 @@ function wrapperDecorations(
|
|||||||
wrap(code, 'code');
|
wrap(code, 'code');
|
||||||
wrap(mark, 'mark');
|
wrap(mark, 'mark');
|
||||||
wrap(keyboard, 'kbd');
|
wrap(keyboard, 'kbd');
|
||||||
|
wrap(italic, 'i');
|
||||||
|
|
||||||
return currentContent;
|
return currentContent;
|
||||||
}
|
}
|
||||||
|
@ -997,6 +997,18 @@ exports[`renders ./components/typography/demo/text.md correctly 1`] = `
|
|||||||
</strong>
|
</strong>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-bottom:8px"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="ant-typography"
|
||||||
|
>
|
||||||
|
<i>
|
||||||
|
Ant Design (italic)
|
||||||
|
</i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-space-item"
|
class="ant-space-item"
|
||||||
>
|
>
|
||||||
|
@ -32,6 +32,7 @@ ReactDOM.render(
|
|||||||
<Text underline>Ant Design (underline)</Text>
|
<Text underline>Ant Design (underline)</Text>
|
||||||
<Text delete>Ant Design (delete)</Text>
|
<Text delete>Ant Design (delete)</Text>
|
||||||
<Text strong>Ant Design (strong)</Text>
|
<Text strong>Ant Design (strong)</Text>
|
||||||
|
<Text italic>Ant Design (italic)</Text>
|
||||||
<Link href="https://ant.design" target="_blank">
|
<Link href="https://ant.design" target="_blank">
|
||||||
Ant Design (Link)
|
Ant Design (Link)
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -29,6 +29,7 @@ Basic text writing, including headings, body text, lists, and more.
|
|||||||
| mark | Marked style | boolean | false | |
|
| mark | Marked style | boolean | false | |
|
||||||
| onClick | Set the handler to handle click event | (event) => void | - | |
|
| onClick | Set the handler to handle click event | (event) => void | - | |
|
||||||
| strong | Bold style | boolean | false | |
|
| strong | Bold style | boolean | false | |
|
||||||
|
| italic | Italic style | boolean | false | 4.16.0 |
|
||||||
| type | Content type | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
| type | Content type | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
||||||
| underline | Underlined style | boolean | false | |
|
| underline | Underlined style | boolean | false | |
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ Basic text writing, including headings, body text, lists, and more.
|
|||||||
| level | Set content importance. Match with `h1`, `h2`, `h3`, `h4`, `h5` | number: 1, 2, 3, 4, 5 | 1 | 5: 4.6.0 |
|
| level | Set content importance. Match with `h1`, `h2`, `h3`, `h4`, `h5` | number: 1, 2, 3, 4, 5 | 1 | 5: 4.6.0 |
|
||||||
| mark | Marked style | boolean | false | |
|
| mark | Marked style | boolean | false | |
|
||||||
| onClick | Set the handler to handle click event | (event) => void | - | |
|
| onClick | Set the handler to handle click event | (event) => void | - | |
|
||||||
|
| italic | Italic style | boolean | false | 4.16.0 |
|
||||||
| type | Content type | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
| type | Content type | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
||||||
| underline | Underlined style | boolean | false | |
|
| underline | Underlined style | boolean | false | |
|
||||||
|
|
||||||
@ -61,6 +63,7 @@ Basic text writing, including headings, body text, lists, and more.
|
|||||||
| mark | Marked style | boolean | false | |
|
| mark | Marked style | boolean | false | |
|
||||||
| onClick | Set the handler to handle click event | (event) => void | - | |
|
| onClick | Set the handler to handle click event | (event) => void | - | |
|
||||||
| strong | Bold style | boolean | false | |
|
| strong | Bold style | boolean | false | |
|
||||||
|
| italic | Italic style | boolean | false | 4.16.0 |
|
||||||
| type | Content type | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
| type | Content type | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
||||||
| underline | Underlined style | boolean | false | |
|
| underline | Underlined style | boolean | false | |
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/GOM1KQ24O/Typography.svg
|
|||||||
| mark | 添加标记样式 | boolean | false | |
|
| mark | 添加标记样式 | boolean | false | |
|
||||||
| onClick | 点击 Text 时的回调 | (event) => void | - | |
|
| onClick | 点击 Text 时的回调 | (event) => void | - | |
|
||||||
| strong | 是否加粗 | boolean | false | |
|
| strong | 是否加粗 | boolean | false | |
|
||||||
|
| italic | 是否斜体 | boolean | false | 4.16.0 |
|
||||||
| type | 文本类型 | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
| type | 文本类型 | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
||||||
| underline | 添加下划线样式 | boolean | false | |
|
| underline | 添加下划线样式 | boolean | false | |
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/GOM1KQ24O/Typography.svg
|
|||||||
| level | 重要程度,相当于 `h1`、`h2`、`h3`、`h4`、`h5` | number: 1, 2, 3, 4, 5 | 1 | 5: 4.6.0 |
|
| level | 重要程度,相当于 `h1`、`h2`、`h3`、`h4`、`h5` | number: 1, 2, 3, 4, 5 | 1 | 5: 4.6.0 |
|
||||||
| mark | 添加标记样式 | boolean | false | |
|
| mark | 添加标记样式 | boolean | false | |
|
||||||
| onClick | 点击 Title 时的回调 | (event) => void | - | |
|
| onClick | 点击 Title 时的回调 | (event) => void | - | |
|
||||||
|
| italic | 是否斜体 | boolean | false | 4.16.0 |
|
||||||
| type | 文本类型 | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
| type | 文本类型 | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
||||||
| underline | 添加下划线样式 | boolean | false | |
|
| underline | 添加下划线样式 | boolean | false | |
|
||||||
|
|
||||||
@ -62,6 +64,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/GOM1KQ24O/Typography.svg
|
|||||||
| mark | 添加标记样式 | boolean | false | |
|
| mark | 添加标记样式 | boolean | false | |
|
||||||
| onClick | 点击 Paragraph 时的回调 | (event) => void | - | |
|
| onClick | 点击 Paragraph 时的回调 | (event) => void | - | |
|
||||||
| strong | 是否加粗 | boolean | false | |
|
| strong | 是否加粗 | boolean | false | |
|
||||||
|
| italic | 是否斜体 | boolean | false | 4.16.0 |
|
||||||
| type | 文本类型 | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
| type | 文本类型 | `secondary` \| `success` \| `warning` \| `danger` | - | success: 4.6.0 |
|
||||||
| underline | 添加下划线样式 | boolean | false | |
|
| underline | 添加下划线样式 | boolean | false | |
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
|
|||||||
onPreview,
|
onPreview,
|
||||||
onDownload,
|
onDownload,
|
||||||
onChange,
|
onChange,
|
||||||
|
onDrop,
|
||||||
previewFile,
|
previewFile,
|
||||||
disabled,
|
disabled,
|
||||||
locale: propLocale,
|
locale: propLocale,
|
||||||
@ -278,8 +279,11 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onFileDrop = (e: React.DragEvent<HTMLDivElement>) => {
|
const onFileDrop = (e: React.DragEvent<HTMLDivElement>) => {
|
||||||
e.stopPropagation();
|
|
||||||
setDragState(e.type);
|
setDragState(e.type);
|
||||||
|
|
||||||
|
if (e.type === 'drop') {
|
||||||
|
onDrop?.(e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test needs
|
// Test needs
|
||||||
|
@ -272,7 +272,13 @@ const ListItem = React.forwardRef(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={listContainerNameClass} style={style} ref={ref}>
|
<div className={listContainerNameClass} style={style} ref={ref}>
|
||||||
{itemRender ? itemRender(item, file, items) : item}
|
{itemRender
|
||||||
|
? itemRender(item, file, items, {
|
||||||
|
download: onDownload.bind(null, file),
|
||||||
|
preview: onPreview.bind(null, file),
|
||||||
|
remove: onClose.bind(null, file),
|
||||||
|
})
|
||||||
|
: item}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -80,11 +80,11 @@ const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProp
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// ============================= Events =============================
|
// ============================= Events =============================
|
||||||
const onInternalPreview = (file: UploadFile, e: React.SyntheticEvent<HTMLElement>) => {
|
const onInternalPreview = (file: UploadFile, e?: React.SyntheticEvent<HTMLElement>) => {
|
||||||
if (!onPreview) {
|
if (!onPreview) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e?.preventDefault();
|
||||||
return onPreview(file);
|
return onPreview(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,20 +114,54 @@ exports[`Upload List itemRender 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="ant-upload-list-text-container"
|
class="ant-upload-list-text-container"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="custom-item-render"
|
class="custom-item-render"
|
||||||
>
|
>
|
||||||
uid:-1 name: xxx.png status: removed url: https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png 1/2
|
<span>
|
||||||
</span>
|
uid:-1 name: xxx.png status: removed url: https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png 1/2
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="custom-item-render-action-remove"
|
||||||
|
>
|
||||||
|
remove
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="custom-item-render-action-download"
|
||||||
|
>
|
||||||
|
download
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="custom-item-render-action-preview"
|
||||||
|
>
|
||||||
|
preview
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="ant-upload-list-text-container"
|
class="ant-upload-list-text-container"
|
||||||
>
|
>
|
||||||
<span
|
<div
|
||||||
class="custom-item-render"
|
class="custom-item-render"
|
||||||
>
|
>
|
||||||
uid:-2 name: yyy.png status: removed url: https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png 2/2
|
<span>
|
||||||
</span>
|
uid:-2 name: yyy.png status: removed url: https://zos.alipayobjects.com/rmsportal/IQKRngzUuFzJzGzRJXUs.png 2/2
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="custom-item-render-action-remove"
|
||||||
|
>
|
||||||
|
remove
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="custom-item-render-action-download"
|
||||||
|
>
|
||||||
|
download
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="custom-item-render-action-preview"
|
||||||
|
>
|
||||||
|
preview
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@ -35,4 +35,21 @@ describe('Upload.Dragger', () => {
|
|||||||
|
|
||||||
jest.useRealTimers();
|
jest.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('support onDrop when files are dropped onto upload area', () => {
|
||||||
|
const onDrop = jest.fn();
|
||||||
|
const wrapper = mount(
|
||||||
|
<Upload.Dragger onDrop={onDrop}>
|
||||||
|
<div />
|
||||||
|
</Upload.Dragger>,
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.find('.ant-upload-drag-container').simulate('drop', {
|
||||||
|
dataTransfer: {
|
||||||
|
files: [new File(['foo'], 'foo.png', { type: 'image/png' })],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(onDrop).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -100,7 +100,24 @@ describe('Upload.typescript', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
const upload = (
|
const upload = (
|
||||||
<Upload fileList={fileList} defaultFileList={fileList}>
|
<Upload fileList={fileList} defaultFileList={fileList} />
|
||||||
|
)
|
||||||
|
expect(upload).toBeTruthy();
|
||||||
|
});
|
||||||
|
it('itemRender', () => {
|
||||||
|
const upload = (
|
||||||
|
<Upload
|
||||||
|
itemRender={(node, file, list, actions) => (
|
||||||
|
<div>
|
||||||
|
{node}
|
||||||
|
{file.name}
|
||||||
|
{list.length}
|
||||||
|
<span onClick={actions.remove}>remove</span>
|
||||||
|
<span onClick={actions.download}>download</span>
|
||||||
|
<span onClick={actions.preview}>preview</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
>
|
||||||
<span>click to upload</span>
|
<span>click to upload</span>
|
||||||
</Upload>
|
</Upload>
|
||||||
);
|
);
|
||||||
|
@ -1162,20 +1162,52 @@ describe('Upload List', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('itemRender', () => {
|
it('itemRender', () => {
|
||||||
const itemRender = (originNode, file, currFileList) => {
|
const onDownload = jest.fn();
|
||||||
|
const onRemove = jest.fn();
|
||||||
|
const onPreview = jest.fn();
|
||||||
|
const itemRender = (originNode, file, currFileList, actions) => {
|
||||||
const { name, status, uid, url } = file;
|
const { name, status, uid, url } = file;
|
||||||
const index = currFileList.indexOf(file);
|
const index = currFileList.indexOf(file);
|
||||||
return (
|
return (
|
||||||
<span className="custom-item-render">
|
<div className="custom-item-render">
|
||||||
{`uid:${uid} name: ${name} status: ${status} url: ${url} ${index + 1}/${
|
<span>
|
||||||
currFileList.length
|
{`uid:${uid} name: ${name} status: ${status} url: ${url} ${index + 1}/${
|
||||||
}`}
|
currFileList.length
|
||||||
</span>
|
}`}
|
||||||
|
</span>
|
||||||
|
<span onClick={actions.remove} className="custom-item-render-action-remove">
|
||||||
|
remove
|
||||||
|
</span>
|
||||||
|
<span onClick={actions.download} className="custom-item-render-action-download">
|
||||||
|
download
|
||||||
|
</span>
|
||||||
|
<span onClick={actions.preview} className="custom-item-render-action-preview">
|
||||||
|
preview
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const wrapper = mount(<UploadList locale={{}} items={fileList} itemRender={itemRender} />);
|
const wrapper = mount(
|
||||||
|
<UploadList
|
||||||
|
onDownload={onDownload}
|
||||||
|
onPreview={onPreview}
|
||||||
|
onRemove={onRemove}
|
||||||
|
locale={{}}
|
||||||
|
items={fileList}
|
||||||
|
itemRender={itemRender}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
expect(wrapper.render()).toMatchSnapshot();
|
expect(wrapper.render()).toMatchSnapshot();
|
||||||
|
|
||||||
|
wrapper.find('.custom-item-render-action-remove').first().simulate('click');
|
||||||
|
expect(onRemove.mock.calls[0][0]).toEqual(fileList[0]);
|
||||||
|
|
||||||
|
wrapper.find('.custom-item-render-action-download').first().simulate('click');
|
||||||
|
expect(onDownload.mock.calls[0][0]).toEqual(fileList[0]);
|
||||||
|
|
||||||
|
wrapper.find('.custom-item-render-action-preview').first().simulate('click');
|
||||||
|
expect(onPreview.mock.calls[0][0]).toEqual(fileList[0]);
|
||||||
|
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@ const props = {
|
|||||||
message.error(`${info.file.name} file upload failed.`);
|
message.error(`${info.file.name} file upload failed.`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onDrop(e) {
|
||||||
|
console.log('Dropped files', e.dataTransfer.files);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
|
@ -31,7 +31,7 @@ Uploading is the process of publishing information (web pages, text, pictures, v
|
|||||||
| headers | Set request headers, valid above IE10 | object | - | |
|
| headers | Set request headers, valid above IE10 | object | - | |
|
||||||
| iconRender | Custom show icon | (file: UploadFile, listType?: UploadListType) => ReactNode | - | |
|
| iconRender | Custom show icon | (file: UploadFile, listType?: UploadListType) => ReactNode | - | |
|
||||||
| isImageUrl | Customize if render <img /> in thumbnail | (file: UploadFile) => boolean | [(inside implementation)](https://github.com/ant-design/ant-design/blob/4ad5830eecfb87471cd8ac588c5d992862b70770/components/upload/utils.tsx#L47-L68) | |
|
| isImageUrl | Customize if render <img /> in thumbnail | (file: UploadFile) => boolean | [(inside implementation)](https://github.com/ant-design/ant-design/blob/4ad5830eecfb87471cd8ac588c5d992862b70770/components/upload/utils.tsx#L47-L68) | |
|
||||||
| itemRender | Custom item of uploadList | (originNode: ReactElement, file: UploadFile, fileList?: object\[]) => React.ReactNode | - | 4.7.0 |
|
| itemRender | Custom item of uploadList | (originNode: ReactElement, file: UploadFile, fileList: object\[], actions: { download: function, preview: function, remove: function }) => React.ReactNode | - | 4.16.0 |
|
||||||
| listType | Built-in stylesheets, support for three types: `text`, `picture` or `picture-card` | string | `text` | |
|
| listType | Built-in stylesheets, support for three types: `text`, `picture` or `picture-card` | string | `text` | |
|
||||||
| maxCount | Limit the number of uploaded files. Will replace current one when `maxCount` is `1` | number | - | 4.10.0 |
|
| maxCount | Limit the number of uploaded files. Will replace current one when `maxCount` is `1` | number | - | 4.10.0 |
|
||||||
| method | The http method of upload request | string | `post` | |
|
| method | The http method of upload request | string | `post` | |
|
||||||
@ -43,6 +43,7 @@ Uploading is the process of publishing information (web pages, text, pictures, v
|
|||||||
| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon`, `showRemoveIcon`, `showDownloadIcon`, `removeIcon` and `downloadIcon` individually | boolean \| { showPreviewIcon?: boolean, showDownloadIcon?: boolean, showRemoveIcon?: boolean, removeIcon?: ReactNode \| (file: UploadFile) => ReactNode, downloadIcon?: ReactNode \| (file: UploadFile) => ReactNode } | true | function: 4.7.0 |
|
| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon`, `showRemoveIcon`, `showDownloadIcon`, `removeIcon` and `downloadIcon` individually | boolean \| { showPreviewIcon?: boolean, showDownloadIcon?: boolean, showRemoveIcon?: boolean, removeIcon?: ReactNode \| (file: UploadFile) => ReactNode, downloadIcon?: ReactNode \| (file: UploadFile) => ReactNode } | true | function: 4.7.0 |
|
||||||
| withCredentials | The ajax upload with cookie sent | boolean | false | |
|
| withCredentials | The ajax upload with cookie sent | boolean | false | |
|
||||||
| onChange | A callback function, can be executed when uploading state is changing, see [onChange](#onChange) | function | - | |
|
| onChange | A callback function, can be executed when uploading state is changing, see [onChange](#onChange) | function | - | |
|
||||||
|
| onDrop | A callback function executed when files are dragged and dropped into upload area | (event: React.DragEvent) => void | - | 4.16.0 |
|
||||||
| onDownload | Click the method to download the file, pass the method to perform the method logic, do not pass the default jump to the new TAB | function(file): void | (Jump to new TAB) | |
|
| onDownload | Click the method to download the file, pass the method to perform the method logic, do not pass the default jump to the new TAB | function(file): void | (Jump to new TAB) | |
|
||||||
| onPreview | A callback function, will be executed when file link or preview icon is clicked | function(file) | - | |
|
| onPreview | A callback function, will be executed when file link or preview icon is clicked | function(file) | - | |
|
||||||
| onRemove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is false or a Promise which resolve(false) or reject | function(file): boolean \| Promise | - | |
|
| onRemove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is false or a Promise which resolve(false) or reject | function(file): boolean \| Promise | - | |
|
||||||
|
@ -32,7 +32,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/QaeBt_ZMg/Upload.svg
|
|||||||
| headers | 设置上传的请求头部,IE10 以上有效 | object | - | |
|
| headers | 设置上传的请求头部,IE10 以上有效 | object | - | |
|
||||||
| iconRender | 自定义显示 icon | (file: UploadFile, listType?: UploadListType) => ReactNode | - | |
|
| iconRender | 自定义显示 icon | (file: UploadFile, listType?: UploadListType) => ReactNode | - | |
|
||||||
| isImageUrl | 自定义缩略图是否使用 <img /> 标签进行显示 | (file: UploadFile) => boolean | [(内部实现)](https://github.com/ant-design/ant-design/blob/4ad5830eecfb87471cd8ac588c5d992862b70770/components/upload/utils.tsx#L47-L68) | |
|
| isImageUrl | 自定义缩略图是否使用 <img /> 标签进行显示 | (file: UploadFile) => boolean | [(内部实现)](https://github.com/ant-design/ant-design/blob/4ad5830eecfb87471cd8ac588c5d992862b70770/components/upload/utils.tsx#L47-L68) | |
|
||||||
| itemRender | 自定义上传列表项 | (originNode: ReactElement, file: UploadFile, fileList?: object\[]) => React.ReactNode | - | 4.7.0 |
|
| itemRender | 自定义上传列表项 | (originNode: ReactElement, file: UploadFile, fileList: object\[], actions: { download: function, preview: function, remove: function }) => React.ReactNode | - | 4.16.0 |
|
||||||
| listType | 上传列表的内建样式,支持三种基本样式 `text`, `picture` 和 `picture-card` | string | `text` | |
|
| listType | 上传列表的内建样式,支持三种基本样式 `text`, `picture` 和 `picture-card` | string | `text` | |
|
||||||
| maxCount | 限制上传数量。当为 1 时,始终用最新上传的文件代替当前文件 | number | - | 4.10.0 |
|
| maxCount | 限制上传数量。当为 1 时,始终用最新上传的文件代替当前文件 | number | - | 4.10.0 |
|
||||||
| method | 上传请求的 http method | string | `post` | |
|
| method | 上传请求的 http method | string | `post` | |
|
||||||
@ -44,6 +44,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/QaeBt_ZMg/Upload.svg
|
|||||||
| showUploadList | 是否展示文件列表, 可设为一个对象,用于单独设定 `showPreviewIcon`, `showRemoveIcon`, `showDownloadIcon`, `removeIcon` 和 `downloadIcon` | boolean \| { showPreviewIcon?: boolean, showRemoveIcon?: boolean, showDownloadIcon?: boolean, removeIcon?: ReactNode \| (file: UploadFile) => ReactNode, downloadIcon?: ReactNode \| (file: UploadFile) => ReactNode } | true | function: 4.7.0 |
|
| showUploadList | 是否展示文件列表, 可设为一个对象,用于单独设定 `showPreviewIcon`, `showRemoveIcon`, `showDownloadIcon`, `removeIcon` 和 `downloadIcon` | boolean \| { showPreviewIcon?: boolean, showRemoveIcon?: boolean, showDownloadIcon?: boolean, removeIcon?: ReactNode \| (file: UploadFile) => ReactNode, downloadIcon?: ReactNode \| (file: UploadFile) => ReactNode } | true | function: 4.7.0 |
|
||||||
| withCredentials | 上传请求时是否携带 cookie | boolean | false | |
|
| withCredentials | 上传请求时是否携带 cookie | boolean | false | |
|
||||||
| onChange | 上传文件改变时的状态,详见 [onChange](#onChange) | function | - | |
|
| onChange | 上传文件改变时的状态,详见 [onChange](#onChange) | function | - | |
|
||||||
|
| onDrop | 当文件被拖入上传区域时执行的回调功能 | (event: React.DragEvent) => void | - | 4.16.0 |
|
||||||
| onDownload | 点击下载文件时的回调,如果没有指定,则默认跳转到文件 url 对应的标签页 | function(file): void | (跳转新标签页) | |
|
| onDownload | 点击下载文件时的回调,如果没有指定,则默认跳转到文件 url 对应的标签页 | function(file): void | (跳转新标签页) | |
|
||||||
| onPreview | 点击文件链接或预览图标时的回调 | function(file) | - | |
|
| onPreview | 点击文件链接或预览图标时的回调 | function(file) | - | |
|
||||||
| onRemove | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除 | function(file): boolean \| Promise | - | |
|
| onRemove | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除 | function(file): boolean \| Promise | - | |
|
||||||
|
@ -69,7 +69,12 @@ export type UploadListProgressProps = Omit<ProgressProps, 'percent' | 'type'>;
|
|||||||
export type ItemRender<T = any> = (
|
export type ItemRender<T = any> = (
|
||||||
originNode: React.ReactElement,
|
originNode: React.ReactElement,
|
||||||
file: UploadFile,
|
file: UploadFile,
|
||||||
fileList?: Array<UploadFile<T>>,
|
fileList: Array<UploadFile<T>>,
|
||||||
|
actions: {
|
||||||
|
download: () => void;
|
||||||
|
preview: () => void;
|
||||||
|
remove: () => void;
|
||||||
|
},
|
||||||
) => React.ReactNode;
|
) => React.ReactNode;
|
||||||
|
|
||||||
type PreviewFileHandler = (file: File | Blob) => PromiseLike<string>;
|
type PreviewFileHandler = (file: File | Blob) => PromiseLike<string>;
|
||||||
@ -96,6 +101,7 @@ export interface UploadProps<T = any> {
|
|||||||
FileList: RcFile[],
|
FileList: RcFile[],
|
||||||
) => BeforeUploadValueType | Promise<BeforeUploadValueType>;
|
) => BeforeUploadValueType | Promise<BeforeUploadValueType>;
|
||||||
onChange?: (info: UploadChangeParam) => void;
|
onChange?: (info: UploadChangeParam) => void;
|
||||||
|
onDrop?: (event: React.DragEvent<HTMLDivElement>) => void;
|
||||||
listType?: UploadListType;
|
listType?: UploadListType;
|
||||||
className?: string;
|
className?: string;
|
||||||
onPreview?: (file: UploadFile<T>) => void;
|
onPreview?: (file: UploadFile<T>) => void;
|
||||||
|
@ -125,8 +125,8 @@
|
|||||||
"rc-field-form": "~1.20.0",
|
"rc-field-form": "~1.20.0",
|
||||||
"rc-image": "~5.2.4",
|
"rc-image": "~5.2.4",
|
||||||
"rc-input-number": "~7.1.0",
|
"rc-input-number": "~7.1.0",
|
||||||
"rc-mentions": "~1.5.0",
|
"rc-mentions": "~1.6.0",
|
||||||
"rc-menu": "~8.10.0",
|
"rc-menu": "~9.0.0-alpha.6",
|
||||||
"rc-motion": "^2.4.0",
|
"rc-motion": "^2.4.0",
|
||||||
"rc-notification": "~4.5.2",
|
"rc-notification": "~4.5.2",
|
||||||
"rc-pagination": "~3.1.6",
|
"rc-pagination": "~3.1.6",
|
||||||
@ -138,8 +138,8 @@
|
|||||||
"rc-slider": "~9.7.1",
|
"rc-slider": "~9.7.1",
|
||||||
"rc-steps": "~4.1.0",
|
"rc-steps": "~4.1.0",
|
||||||
"rc-switch": "~3.2.0",
|
"rc-switch": "~3.2.0",
|
||||||
"rc-table": "~7.13.0",
|
"rc-table": "~7.15.1",
|
||||||
"rc-tabs": "~11.7.0",
|
"rc-tabs": "~11.9.0",
|
||||||
"rc-textarea": "~0.3.0",
|
"rc-textarea": "~0.3.0",
|
||||||
"rc-tooltip": "~5.1.1",
|
"rc-tooltip": "~5.1.1",
|
||||||
"rc-tree": "~4.1.0",
|
"rc-tree": "~4.1.0",
|
||||||
|
@ -24,7 +24,9 @@ async function checkVersion() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function checkBranch({ current }) {
|
async function checkBranch({ current }) {
|
||||||
if (current !== 'master' && current !== '4.0-prepare') {
|
if (version.includes('-alpha.')) {
|
||||||
|
console.log(chalk.cyan('😃 Alpha version. Skip branch check.'));
|
||||||
|
} else if (current !== 'master' && current !== '4.0-prepare') {
|
||||||
console.log(chalk.yellow('🤔 You are not in the master branch!'));
|
console.log(chalk.yellow('🤔 You are not in the master branch!'));
|
||||||
exitProcess();
|
exitProcess();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user