Browse Source

chore: auto merge branches (#43662)

chore: merge master into feature
feature
github-actions[bot] 1 year ago
committed by GitHub
parent
commit
b90aac7d28
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .dumi/rehypeAntd.ts
  2. 2
      .dumi/theme/builtins/IconSearch/fields.ts
  3. 22
      .dumi/theme/builtins/ImagePreview/index.tsx
  4. 119
      .dumi/theme/builtins/TokenCompare/index.tsx
  5. 77
      .dumi/theme/builtins/VideoPlayer/index.tsx
  6. 4
      .dumi/theme/slots/Sidebar/index.tsx
  7. 4
      .github/workflows/discussion-open-check.yml
  8. 4
      .github/workflows/issue-open-check.yml
  9. 53
      CHANGELOG.en-US.md
  10. 19
      CHANGELOG.zh-CN.md
  11. 36
      components/app/__tests__/__snapshots__/demo-extend.test.ts.snap
  12. 36
      components/app/__tests__/__snapshots__/demo.test.ts.snap
  13. 41
      components/app/__tests__/index.test.tsx
  14. 4
      components/app/demo/basic.md
  15. 7
      components/app/demo/config.md
  16. 36
      components/app/demo/config.tsx
  17. 3
      components/app/index.en-US.md
  18. 1
      components/app/index.zh-CN.md
  19. 6
      components/auto-complete/index.tsx
  20. 2
      components/back-top/index.tsx
  21. 11
      components/button/__tests__/index.test.tsx
  22. 19
      components/button/button.tsx
  23. 2
      components/cascader/index.tsx
  24. 47
      components/checkbox/style/index.ts
  25. 6
      components/config-provider/__tests__/popup.test.tsx
  26. 11
      components/date-picker/__tests__/type.test.tsx
  27. 6
      components/date-picker/demo/cell-render.tsx
  28. 4
      components/date-picker/generatePicker/generateRangePicker.tsx
  29. 7
      components/date-picker/generatePicker/index.tsx
  30. 3
      components/date-picker/style/index.ts
  31. 8
      components/float-button/FloatButton.tsx
  32. 8
      components/form/Form.tsx
  33. 8
      components/form/index.en-US.md
  34. 8
      components/form/index.zh-CN.md
  35. 5
      components/form/style/index.ts
  36. 1
      components/grid/__tests__/demo.test.ts
  37. 1
      components/icon/__tests__/demo.test.ts
  38. 4
      components/icon/index.ts
  39. 4
      components/index.ts
  40. 5
      components/input-number/__tests__/prefix.test.tsx
  41. 3
      components/input-number/index.tsx
  42. 8
      components/input-number/style/index.ts
  43. 2
      components/layout/__tests__/token.test.tsx
  44. 2
      components/locale/__tests__/config.test.tsx
  45. 1401
      components/menu/__tests__/__snapshots__/demo-extend.test.ts.snap
  46. 492
      components/menu/__tests__/__snapshots__/demo.test.tsx.snap
  47. 97
      components/menu/demo/component-token.tsx
  48. 8
      components/menu/style/horizontal.tsx
  49. 275
      components/menu/style/index.tsx
  50. 25
      components/menu/style/theme.tsx
  51. 28
      components/menu/style/vertical.tsx
  52. 1
      components/message/__tests__/demo.test.ts
  53. 1
      components/notification/__tests__/demo.test.ts
  54. 8
      components/notification/useNotification.tsx
  55. 6
      components/popconfirm/PurePanel.tsx
  56. 18
      components/qr-code/__tests__/__snapshots__/demo-extend.test.ts.snap
  57. 18
      components/qr-code/__tests__/__snapshots__/demo.test.ts.snap
  58. 0
      components/qr-code/__tests__/__snapshots__/index.test.tsx.snap
  59. 2
      components/qr-code/__tests__/demo-extend.test.ts
  60. 2
      components/qr-code/__tests__/demo.test.ts
  61. 2
      components/qr-code/__tests__/image.test.ts
  62. 0
      components/qr-code/__tests__/index.test.tsx
  63. 0
      components/qr-code/demo/Popover.md
  64. 0
      components/qr-code/demo/Popover.tsx
  65. 0
      components/qr-code/demo/base.md
  66. 0
      components/qr-code/demo/base.tsx
  67. 0
      components/qr-code/demo/customColor.md
  68. 0
      components/qr-code/demo/customColor.tsx
  69. 0
      components/qr-code/demo/customSize.md
  70. 0
      components/qr-code/demo/customSize.tsx
  71. 0
      components/qr-code/demo/download.md
  72. 0
      components/qr-code/demo/download.tsx
  73. 0
      components/qr-code/demo/errorlevel.md
  74. 0
      components/qr-code/demo/errorlevel.tsx
  75. 0
      components/qr-code/demo/icon.md
  76. 0
      components/qr-code/demo/icon.tsx
  77. 0
      components/qr-code/demo/status.md
  78. 0
      components/qr-code/demo/status.tsx
  79. 0
      components/qr-code/demo/type.md
  80. 0
      components/qr-code/demo/type.tsx
  81. 0
      components/qr-code/index.en-US.md
  82. 0
      components/qr-code/index.tsx
  83. 0
      components/qr-code/index.zh-CN.md
  84. 37
      components/qr-code/interface.ts
  85. 65
      components/qr-code/style/index.ts
  86. 5
      components/qrcode/index.ts
  87. 40
      components/qrcode/interface.ts
  88. 68
      components/qrcode/style/index.ts
  89. 0
      components/radio/context.ts
  90. 0
      components/radio/index.ts
  91. 0
      components/radio/interface.ts
  92. 9
      components/radio/radioButton.tsx
  93. 5
      components/select/index.tsx
  94. 6
      components/slider/__tests__/index.test.tsx
  95. 1
      components/slider/index.zh-CN.md
  96. 13
      components/steps/style/index.tsx
  97. 5
      components/table/Table.tsx
  98. 8
      components/theme/interface/alias.ts
  99. 2
      components/theme/interface/components.ts
  100. 3
      components/theme/interface/maps/colors.ts

2
.dumi/rehypeAntd.ts

@ -64,6 +64,8 @@ function rehypeAntd(): UnifiedTransformer<HastRoot> {
const { tagName } = node;
node.properties.sourceType = tagName;
node.tagName = 'LocaleLink';
} else if (node.type === 'element' && node.tagName === 'video') {
node.tagName = 'VideoPlayer';
}
});
};

2
.dumi/theme/builtins/IconSearch/fields.ts

@ -165,9 +165,11 @@ const logo = [
'Weibo',
'Twitter',
'Wechat',
'WhatsApp',
'Youtube',
'AlipayCircle',
'Taobao',
'Dingtalk',
'Skype',
'Qq',
'MediumWorkmark',

22
.dumi/theme/builtins/ImagePreview/index.tsx

@ -5,6 +5,9 @@ import toArray from 'rc-util/lib/Children/toArray';
interface ImagePreviewProps {
children: React.ReactNode[];
className?: string;
/** Do not show padding & background */
pure?: boolean;
}
function isGood(className: string): boolean {
@ -26,9 +29,8 @@ function isGoodBadImg(imgMeta: any): boolean {
function isCompareImg(imgMeta: any): boolean {
return isGoodBadImg(imgMeta) || imgMeta.inline;
}
const ImagePreview: React.FC<ImagePreviewProps> = (props) => {
const { children } = props;
const { children, className: rootClassName, pure } = props;
const imgs = toArray(children).filter((ele) => ele.type === 'img');
const imgsMeta = imgs.map((img) => {
@ -67,21 +69,33 @@ const ImagePreview: React.FC<ImagePreviewProps> = (props) => {
: {};
const hasCarousel = imgs.length > 1 && !comparable;
const previewClassName = classNames({
const previewClassName = classNames(rootClassName, {
'preview-image-boxes': true,
clearfix: true,
'preview-image-boxes-compare': comparable,
'preview-image-boxes-with-carousel': hasCarousel,
});
// ===================== Render =====================
const imgWrapperCls = 'preview-image-wrapper';
return (
<div className={previewClassName}>
{!imgs.length && (
<div
className={imgWrapperCls}
style={pure ? { background: 'transparent', padding: 0 } : {}}
>
{children}
</div>
)}
{imagesList.map((_, index) => {
if (!comparable && index !== 0) {
return null;
}
const coverMeta = imgsMeta[index];
const imageWrapperClassName = classNames('preview-image-wrapper', {
const imageWrapperClassName = classNames(imgWrapperCls, {
good: coverMeta.isGood,
bad: coverMeta.isBad,
});

119
.dumi/theme/builtins/TokenCompare/index.tsx

@ -0,0 +1,119 @@
// 用于 color.md 中的颜色对比
import React from 'react';
import classNames from 'classnames';
import { theme, Space } from 'antd';
import { TinyColor } from '@ctrl/tinycolor';
import tokenMeta from 'antd/es/version/token-meta.json';
import { createStyles } from 'antd-style';
import useLocale from '../../../hooks/useLocale';
const useStyle = createStyles(({ token, css }) => {
const height = token.controlHeightLG;
const dotSize = height / 5;
return {
container: css`
background: #fff;
border-radius: ${token.borderRadiusLG}px;
overflow: hidden;
`,
row: css`
display: flex;
align-items: center;
`,
col: css`
flex: 1 1 33%;
height: ${height}px;
display: flex;
align-items: center;
justify-content: center;
border-right: 1px solid rgba(0, 0, 0, 0.1);
`,
colDark: css`
background: #000;
color: #fff;
`,
dot: css`
border-radius: 100%;
width: ${dotSize}px;
height: ${dotSize}px;
background: #000;
box-shadow: 0 0 0 1px rgba(150, 150, 150, 0.25);
`,
dotColor: css`
width: ${token.fontSize * 6}px;
white-space: nowrap;
`,
};
});
function color2Rgba(color: string) {
return `#${new TinyColor(color).toHex8().toUpperCase()}`;
}
interface ColorCircleProps {
color?: string;
}
function ColorCircle({ color }: ColorCircleProps) {
const { styles } = useStyle();
return (
<Space size={4}>
<div className={styles.dot} style={{ background: color }} />
<div className={styles.dotColor}>{color}</div>
</Space>
);
}
export interface TokenCompareProps {
tokenNames?: string;
}
export default function TokenCompare(props: TokenCompareProps) {
const { tokenNames = '' } = props;
const [, lang] = useLocale({});
const { styles } = useStyle();
const tokenList = React.useMemo(() => {
const list = tokenNames.split('|');
const lightTokens = theme.getDesignToken();
const darkTokens = theme.getDesignToken({
algorithm: theme.darkAlgorithm,
});
return list.map((tokenName) => {
const meta = tokenMeta.global[tokenName];
const name = lang === 'cn' ? meta.name : meta.nameEn;
return {
name: name.replace('颜色', '').replace('色', '').replace('Color', '').trim(),
light: color2Rgba(lightTokens[tokenName]),
dark: color2Rgba(darkTokens[tokenName]),
};
});
}, [tokenNames]);
return (
<div className={styles.container}>
{tokenList.map((data) => (
<div key={data.name} className={styles.row}>
<div className={styles.col}>{data.name}</div>
<div className={styles.col}>
<ColorCircle color={data.light} />
</div>
<div className={classNames(styles.col, styles.colDark)}>
<ColorCircle color={data.dark} />
</div>
</div>
))}
</div>
);
}

77
.dumi/theme/builtins/VideoPlayer/index.tsx

@ -0,0 +1,77 @@
import React from 'react';
import { createStyles, css } from 'antd-style';
import classNames from 'classnames';
import { PlayCircleFilled, PauseCircleFilled } from '@ant-design/icons';
const useStyles = createStyles(({ cx, token }) => {
const play = css`
position: absolute;
right: ${token.paddingLG}px;
bottom: ${token.paddingLG}px;
font-size: 64px;
display: flex;
align-items: center;
justify-content: center;
color: rgba(0, 0, 0, 0.65);
opacity: 0;
transition: opacity ${token.motionDurationSlow};
`;
return {
container: css`
position: relative;
`,
holder: css`
position: relative;
cursor: pointer;
&:hover {
.${cx(play)} {
opacity: 1;
}
}
`,
video: css`
width: 100%;
`,
play,
};
});
export default function VideoPlayer({
className,
...restProps
}: React.HtmlHTMLAttributes<HTMLVideoElement>) {
const { styles } = useStyles();
const videoRef = React.useRef<HTMLVideoElement>(null);
const [playing, setPlaying] = React.useState(false);
React.useEffect(() => {
if (playing) {
videoRef.current?.play();
} else {
videoRef.current?.pause();
}
}, [playing]);
return (
<div
className={classNames(styles.container, className)}
tabIndex={0}
role="button"
title="play or pause"
onClick={() => {
setPlaying(!playing);
}}
>
<div className={classNames(styles.holder)}>
<video ref={videoRef} className={styles.video} muted loop {...restProps} />
<div className={styles.play}>{playing ? <PauseCircleFilled /> : <PlayCircleFilled />}</div>
</div>
</div>
);
}

4
.dumi/theme/slots/Sidebar/index.tsx

@ -134,7 +134,9 @@ const Sidebar: React.FC = () => {
} = useSiteToken();
const menuChild = (
<ConfigProvider theme={{ components: { Menu: { itemBg: colorBgContainer } } }}>
<ConfigProvider
theme={{ components: { Menu: { itemBg: colorBgContainer, darkItemBg: colorBgContainer } } }}
>
<Menu
items={menuItems}
inlineIndent={30}

4
.github/workflows/discussion-open-check.yml

@ -19,7 +19,7 @@ jobs:
DING_TALK_TOKEN: |
${{ secrets.DINGDING_BOT_TOKEN }}
${{ secrets.DINGDING_BOT_COLLABORATOR_TOKEN }}
notify_title: '🔥 @${{ github.event.discussion.user.login }} 创建了讨论:${{ github.event.discussion.title }}'
notify_body: '### 🔥 @${{ github.event.discussion.user.login }} 创建了讨论:[${{ github.event.discussion.title }}](${{ github.event.discussion.html_url }}) <hr /> ![](https://gw.alipayobjects.com/zos/antfincdn/5Cl2G7JjF/jieping2022-03-20%252520xiawu11.06.04.png)'
notify_title: '🔥 @${{ github.event.discussion.user.login }} 创建了讨论:${{ github.event.discussion.title }} #${{ github.event.discussion.number }}'
notify_body: '### 🔥 @${{ github.event.discussion.user.login }} 创建了讨论:[${{ github.event.discussion.title }}](${{ github.event.discussion.html_url }}) <hr />'
notify_footer: '> 💬 欢迎前往 GitHub 进行讨论,社区可能需要你的帮助。'
at_all: false # whether to ding everybody

4
.github/workflows/issue-open-check.yml

@ -99,7 +99,7 @@ jobs:
DING_TALK_TOKEN: |
${{ secrets.DINGDING_BOT_TOKEN }}
${{ secrets.DINGDING_BOT_COLLABORATOR_TOKEN }}
notify_title: '🔥 @${{ github.event.issue.user.login }} 创建了 issue:${{ github.event.issue.title }}'
notify_body: '### 🔥 @${{ github.event.issue.user.login }} 创建了 issue:[${{ github.event.issue.title }}](${{ github.event.issue.html_url }}) <hr /> ![](https://gw.alipayobjects.com/zos/antfincdn/5Cl2G7JjF/jieping2022-03-20%252520xiawu11.06.04.png)'
notify_title: '🔥 @${{ github.event.issue.user.login }} 创建了 issue:${{ github.event.issue.title }} #${{ github.event.issue.number }}'
notify_body: '### 🔥 @${{ github.event.issue.user.login }} 创建了 issue:[${{ github.event.issue.title }}](${{ github.event.issue.html_url }}) <hr />'
notify_footer: '> 💬 欢迎前往 GitHub 进行讨论,社区可能需要你的帮助。'
at_all: false # whether to ding everybody

53
CHANGELOG.en-US.md

@ -15,6 +15,25 @@ timeline: true
---
## 5.7.1
`2023-07-19`
- 💄 Migrate Component Token of Menu from 4.x less variables. [#43576](https://github.com/ant-design/ant-design/pull/43576)
- 🐞 Fix QRCode throws `Can't resolve 'antd/lib/qr-code'` in Next.js 13. [#43572](https://github.com/ant-design/ant-design/issues/43572)
- 🐞 Fix that antd components usage in Next.js App Router, check the [documentation](/docs/react/use-with-next#using-nextjs-app-router). [#43573](https://github.com/ant-design/ant-design/pull/43573) [@li-jia-nan](https://github.com/li-jia-nan)
- 🐞 Fix InputNumber Phantom dependency issue: `Cannot find module 'rc-component/mini-decimal'`. [#43635](https://github.com/ant-design/ant-design/pull/43635)
- 🐞 Fix Checkbox both set `checked` and `indeterminate` prop will not show as `indeterminate` style. [#43626](https://github.com/ant-design/ant-design/pull/43626)
- 🐞 Fix Form.Item set `label=""` will break the line align. [#43614](https://github.com/ant-design/ant-design/pull/43614)
- 🐞 Fix notification `placement` not being respected when passed via App component. [#43522](https://github.com/ant-design/ant-design/pull/43522) [@Rajil1213](https://github.com/Rajil1213)
- 🐞 Fix Pagination jumpy page size select when search in it. [#43556](https://github.com/ant-design/ant-design/pull/43556)
- 🐞 Fix Button disabled style is missing when use with the deprecated usage of `type="ghost"`. [#43558](https://github.com/ant-design/ant-design/pull/43558) [@kiner-tang](https://github.com/kiner-tang)
- 🐞 Fix Tag extra margin when there is only `icon` inside it. [#43518](https://github.com/ant-design/ant-design/pull/43518) [@Yuiai01](https://github.com/Yuiai01)
- 🐞 Fix ColorPicker that status style is missing inside Form.Item. [#42880](https://github.com/ant-design/ant-design/pull/42880) [@RedJue](https://github.com/RedJue)
- TypeScript
- 🤖 Fix `SpaceContext` don't exported correctly. [#43501](https://github.com/ant-design/ant-design/pull/43501) [@VovkaGoodwin](https://github.com/VovkaGoodwin)
- 🤖 Improve TS definitions for some components. [#43581](https://github.com/ant-design/ant-design/pull/43581) [#43545](https://github.com/ant-design/ant-design/pull/43545) [#43588](https://github.com/ant-design/ant-design/pull/43588) [#43610](https://github.com/ant-design/ant-design/pull/43610) [#43629](https://github.com/ant-design/ant-design/pull/43629). Thanks to [@thinkasany](https://github.com/thinkasany)、[@li-jia-nan](https://github.com/li-jia-nan) for the contributions.
## 5.7.0
`2023-07-11`
@ -30,30 +49,30 @@ timeline: true
- 🆕 Alert, Drawer, Modal, Notifaction, Tag, Tabs now support hiding the close button by setting `closeIcon` to null or false. [#42828](https://github.com/ant-design/ant-design/discussions/42828) [@kiner-tang](https://github.com/kiner-tang)
- 🆕 Image supports `imageRender`, `toolbarRender` attributes to support custom rendering of preview images and toolbars, also supports new props such as `onTransform`, `minScale`, `maxScale`. Image.PreviewGroup supports `items` attribute to pass in list data, and fixes that the native attributes of the img tag are not passed to preview images The problem. [#43075](https://github.com/ant-design/ant-design/pull/43075) [@linxianxi](https://github.com/linxianxi)
- 🆕 Modify the layout style of the Image preview, the `preview` attribute supports `closeIcon`, Image.PreviewGroup supports the `fallback` attribute, and fixes the problem of loading preview resources in advance. [#43167](https://github.com/ant-design/ant-design/pull/43167) [@linxianxi](https://github.com/linxianxi)
- 🆕 Changed the layout style, Preview now supports `closeIcon`, PreviewGroup now supports `fallback`, and fixed an issue where preview resources would be loaded at the beginning.[#43167](https://github.com/ant-design/ant-design/pull/43167) [@linxianxi](https://github.com/linxianxi)
- 🛠 InputNumber was refactored to use rc-input. (#43000)。[#42762](https://github.com/ant-design/ant-design/pull/43000) [@MuxinFeng](https://github.com/MuxinFeng)
- 🆕 Changed the layout style, Preview now supports `closeIcon`, PreviewGroup now supports `fallback`, and fixed an issue where preview resources would be loaded at the beginning. [#43167](https://github.com/ant-design/ant-design/pull/43167) [@linxianxi](https://github.com/linxianxi)
- 🛠 InputNumber was refactored to use rc-input. [#42762](https://github.com/ant-design/ant-design/pull/43000) [@MuxinFeng](https://github.com/MuxinFeng)
- 🛠 Resolved Circular dependency issue in vite, rollup, meteor and microbundle. [#42750](https://github.com/ant-design/ant-design/pull/42750). Thanks to [@jrr997](https://github.com/jrr997), [@kiner-tang](https://github.com/kiner-tang) and [@MuxinFeng](https://github.com/MuxinFeng) for their contributions.
- 🐞 Remove default values (empty string) of `className` prop in Anchor, CollapsePanel, and Input.Group. [#43481](https://github.com/ant-design/ant-design/pull/43481) [@thinkasany](https://github.com/thinkasany)
- 🐞 Fix Upload progress bar missing fade motion. [#43471](https://github.com/ant-design/ant-design/pull/43471)
- 🐞 Added warning for deprecated Token `colorItemBgSelected` in Menu.[#43461](https://github.com/ant-design/ant-design/pull/43461) [@MadCcc](https://github.com/MadCcc)
- 🐞 Fixed an issue where some browsers had scroll bars that were not redrawn when style feature support was detected.[#43358](https://github.com/ant-design/ant-design/pull/43358) [@LeeeeeeM](https://github.com/LeeeeeeM)
- 🐞 Fixed an issue where the Tab component of Card would not be displayed at all when tabList is empty.[#43416](https://github.com/ant-design/ant-design/pull/43416) [@linxianxi](https://github.com/linxianxi)
- 🐞 Fixed an issue where the `form.validateMessages`` configuration would be lost when using ConfigProvider nestedly.[#43239](https://github.com/ant-design/ant-design/pull/43239) [@Wxh16144](https://github.com/Wxh16144)
- 🐞 Fixed an issue where the ripple effect of Tag click would sometimes be offset from the Tag element.[#43402](https://github.com/ant-design/ant-design/pull/43402)
- 🐞 Fixed an issue where clicking "now" in DatePicker when switching to the year-month panel would not work.[#43367](https://github.com/ant-design/ant-design/pull/43367) [@Yuiai01](https://github.com/Yuiai01)
- 🐞 Fixed an issue where the height set for the TextArea component would become invalid when the screen size changed.[#43169](https://github.com/ant-design/ant-design/pull/43169) [@MadCcc](https://github.com/MadCcc)
- 🐞 Added warning for deprecated Token `colorItemBgSelected` in Menu. [#43461](https://github.com/ant-design/ant-design/pull/43461) [@MadCcc](https://github.com/MadCcc)
- 🐞 Fixed an issue where some browsers had scroll bars that were not redrawn when style feature support was detected. [#43358](https://github.com/ant-design/ant-design/pull/43358) [@LeeeeeeM](https://github.com/LeeeeeeM)
- 🐞 Fixed an issue where the Tab component of Card would not be displayed at all when tabList is empty. [#43416](https://github.com/ant-design/ant-design/pull/43416) [@linxianxi](https://github.com/linxianxi)
- 🐞 Fixed an issue where the `form.validateMessages` configuration would be lost when using ConfigProvider nestedly. [#43239](https://github.com/ant-design/ant-design/pull/43239) [@Wxh16144](https://github.com/Wxh16144)
- 🐞 Fixed an issue where the ripple effect of Tag click would sometimes be offset from the Tag element .[#43402](https://github.com/ant-design/ant-design/pull/43402)
- 🐞 Fixed an issue where clicking "now" in DatePicker when switching to the year-month panel would not work. [#43367](https://github.com/ant-design/ant-design/pull/43367) [@Yuiai01](https://github.com/Yuiai01)
- 🐞 Fixed an issue where the height set for the TextArea component would become invalid when the screen size changed. [#43169](https://github.com/ant-design/ant-design/pull/43169) [@MadCcc](https://github.com/MadCcc)
- 💄 In Slider, the `tooltip` should be centered when there is little content. [#43430](https://github.com/ant-design/ant-design/pull/43430) [@Jomorx](https://github.com/Jomorx)
- 💄 Added `colorLink` to the seed token, and `colorLinkHover` and `colorLinkActive` will be calculated from colorLink.[#43183](https://github.com/ant-design/ant-design/pull/43183) [@MadCcc](https://github.com/MadCcc)
- 💄 Added `colorLink` to the seed token, and `colorLinkHover` and `colorLinkActive` will be calculated from colorLink. [#43183](https://github.com/ant-design/ant-design/pull/43183) [@MadCcc](https://github.com/MadCcc)
- 💄 Adjusted some tokens in Slider to component tokens. [#42428](https://github.com/ant-design/ant-design/pull/42428) [@heiyu4585](https://github.com/heiyu4585) RTL[#42428](https://github.com/ant-design/ant-design/pull/42428) [@heiyu4585](https://github.com/heiyu4585)
- RTL
- 🤖 Progress now supports animations in rtl direction.[#43316](https://github.com/ant-design/ant-design/pull/43316) [@Yuiai01](https://github.com/Yuiai01)
- 🤖 Progress now supports animations in rtl direction. [#43316](https://github.com/ant-design/ant-design/pull/43316) [@Yuiai01](https://github.com/Yuiai01)
- TypeScript
- 🤖 Added `RawPurePanelProps` interface description for Popover.[#43453](https://github.com/ant-design/ant-design/pull/43453) [@thinkasany](https://github.com/thinkasany)
- 🤖 Replaced `ref` type with `TooltipRef` instead of `unknown` for `Popconfirm`.[#43452](https://github.com/ant-design/ant-design/pull/43452) [@thinkasany](https://github.com/thinkasany)
- 🤖 Replaced `ref` type with `TooltipRef` instead of `unknown` for Popover.[#43450](https://github.com/ant-design/ant-design/pull/43450) [@Negentropy247](https://github.com/Negentropy247)
- 🤖 Improved type declaration of `GroupSizeContext` in ButtonGroup.[#43439](https://github.com/ant-design/ant-design/pull/43439) [@thinkasany](https://github.com/thinkasany)
- 🤖 Improved type declaration of `mode` property in Select.[#43413](https://github.com/ant-design/ant-design/pull/43413) [@thinkasany](https://github.com/thinkasany)
- 🤖 Replaced `ref` type with `CheckboxRef` instead of `unknown` for Checkbox.[#43424](https://github.com/ant-design/ant-design/pull/43424) [@li-jia-nan](https://github.com/li-jia-nan)
- 🤖 Added `RawPurePanelProps` interface description for Popover. [#43453](https://github.com/ant-design/ant-design/pull/43453) [@thinkasany](https://github.com/thinkasany)
- 🤖 Replaced `ref` type with `TooltipRef` instead of `unknown` for `Popconfirm`. [#43452](https://github.com/ant-design/ant-design/pull/43452) [@thinkasany](https://github.com/thinkasany)
- 🤖 Replaced `ref` type with `TooltipRef` instead of `unknown` for Popover. [#43450](https://github.com/ant-design/ant-design/pull/43450) [@Negentropy247](https://github.com/Negentropy247)
- 🤖 Improved type declaration of `GroupSizeContext` in ButtonGroup. [#43439](https://github.com/ant-design/ant-design/pull/43439) [@thinkasany](https://github.com/thinkasany)
- 🤖 Improved type declaration of `mode` property in Select. [#43413](https://github.com/ant-design/ant-design/pull/43413) [@thinkasany](https://github.com/thinkasany)
- 🤖 Replaced `ref` type with `CheckboxRef` instead of `unknown` for Checkbox. [#43424](https://github.com/ant-design/ant-design/pull/43424) [@li-jia-nan](https://github.com/li-jia-nan)
- 🤖 Improved internal type implementation for Table/Tag/Notification.
- [#43366](https://github.com/ant-design/ant-design/pull/43366) [@li-jia-nan](https://github.com/li-jia-nan)
- [#43357](https://github.com/ant-design/ant-design/pull/43357) [@thinkasany](https://github.com/thinkasany)

19
CHANGELOG.zh-CN.md

@ -15,6 +15,25 @@ timeline: true
---
## 5.7.1
`2023-07-19`
- 💄 补全 Menu 主题定制 token。[#43576](https://github.com/ant-design/ant-design/pull/43576)
- 🐞 修复 QRCode 在 Next.js 13 中报错 `Can't resolve 'antd/lib/qr-code'` 的问题。[#43572](https://github.com/ant-design/ant-design/issues/43572)
- 🐞 修复 antd 不支持在 Next.js App Router 中使用的问题,查看[使用文档](/docs/react/use-with-next#使用-nextjs-的-app-router)。[#43573](https://github.com/ant-design/ant-design/pull/43573)
- 🐞 修复 InputNumber 幽灵依赖报错 `Cannot find module 'rc-component/mini-decimal'`。[#43635](https://github.com/ant-design/ant-design/pull/43635)
- 🐞 修复 App.useApp 方式调用 notification 组件时 `placement` 属性不生效的问题。[#43522](https://github.com/ant-design/ant-design/pull/43522) [@Rajil1213](https://github.com/Rajil1213)
- 🐞 修复 Checkbox 同时配置 `checked``indeterminate` 时没有展示为 `indeterminate` 样式的问题。[#43626](https://github.com/ant-design/ant-design/pull/43626)
- 🐞 修复 Form.Item 设置 `label=""` 时垂直方向对齐偏移的问题。[#43614](https://github.com/ant-design/ant-design/pull/43614)
- 🐞 修复 Pagination 分页选择器弹层抖动的问题。[#43556](https://github.com/ant-design/ant-design/pull/43556)
- 🐞 修复 Button 幽灵按钮禁用状态丢失的问题。[#43558](https://github.com/ant-design/ant-design/pull/43558) [@kiner-tang](https://github.com/kiner-tang)
- 🐞 修复 Tag 仅传入 `icon` 时渲染多余间距的问题。[#43518](https://github.com/ant-design/ant-design/pull/43518) [@Yuiai01](https://github.com/Yuiai01)
- 🐞 修复 ColorPicker 不跟随表单校验状态改变 UI 的问题。[#42880](https://github.com/ant-design/ant-design/pull/42880) [@RedJue](https://github.com/RedJue)
- TypeScript
- 🤖 修复 `SpaceContext` 没有正确导出的问题。[#43501](https://github.com/ant-design/ant-design/pull/43501) [@VovkaGoodwin](https://github.com/VovkaGoodwin)
- 🤖 优化部分组件 TS 定义实现。[#43581](https://github.com/ant-design/ant-design/pull/43581) [#43545](https://github.com/ant-design/ant-design/pull/43545) [#43588](https://github.com/ant-design/ant-design/pull/43588) [#43610](https://github.com/ant-design/ant-design/pull/43610) [#43629](https://github.com/ant-design/ant-design/pull/43629),感谢 [@thinkasany](https://github.com/thinkasany)、[@li-jia-nan](https://github.com/li-jia-nan) 的贡献。
## 5.7.0
`2023-07-11`

36
components/app/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -48,3 +48,39 @@ exports[`renders components/app/demo/basic.tsx extend context correctly 1`] = `
</div>
</div>
`;
exports[`renders components/app/demo/config.tsx extend context correctly 1`] = `
<div
class="ant-app"
>
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
style="margin-right: 8px;"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Message for only one
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Notification for bottomLeft
</span>
</button>
</div>
</div>
</div>
`;

36
components/app/__tests__/__snapshots__/demo.test.ts.snap

@ -48,3 +48,39 @@ exports[`renders components/app/demo/basic.tsx correctly 1`] = `
</div>
</div>
`;
exports[`renders components/app/demo/config.tsx correctly 1`] = `
<div
class="ant-app"
>
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
style="margin-right:8px"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Message for only one
</span>
</button>
</div>
<div
class="ant-space-item"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Notification for bottomLeft
</span>
</button>
</div>
</div>
</div>
`;

41
components/app/__tests__/index.test.tsx

@ -1,4 +1,5 @@
import React, { useEffect } from 'react';
import type { NotificationConfig } from 'antd/es/notification/interface';
import App from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
@ -123,6 +124,46 @@ describe('App', () => {
expect(config?.notification).toStrictEqual({ maxCount: 30, bottom: 41 });
});
it('should respect notification placement config from props in priority', async () => {
let consumedConfig: AppConfig | undefined;
const Consumer = () => {
const { notification } = App.useApp();
consumedConfig = React.useContext(AppConfigContext);
useEffect(() => {
notification.success({ message: 'Notification 1' });
notification.success({ message: 'Notification 2' });
notification.success({ message: 'Notification 3' });
}, [notification]);
return <div />;
};
const config: NotificationConfig = {
placement: 'bottomLeft',
top: 100,
bottom: 50,
};
const Wrapper = () => (
<App notification={config}>
<Consumer />
</App>
);
render(<Wrapper />);
await waitFakeTimer();
expect(consumedConfig?.notification).toStrictEqual(config);
expect(document.querySelector('.ant-notification-topRight')).not.toBeInTheDocument();
expect(document.querySelector('.ant-notification-bottomLeft')).toHaveStyle({
top: '',
left: '0px',
bottom: '50px',
});
});
it('support className', () => {
const { container } = render(
<App className="test-class">

4
components/app/demo/basic.md

@ -1,7 +1,7 @@
## zh-CN
获取 `message`、`notification`、`modal` 静态方法
获取 `message`、`notification`、`modal` 实例
## en-US
Static method for `message`, `notification`, `modal`.
Get instance for `message`, `notification`, `modal`.

7
components/app/demo/config.md

@ -0,0 +1,7 @@
## zh-CN
`message`、`notification` 进行配置。
## en-US
Config for `message`, `notification`.

36
components/app/demo/config.tsx

@ -0,0 +1,36 @@
import React from 'react';
import { App, Button, Space } from 'antd';
// Sub page
const MyPage = () => {
const { message, notification } = App.useApp();
const showMessage = () => {
message.success('Success!');
};
const showNotification = () => {
notification.info({
message: `Notification`,
description: 'Hello, Ant Design!!',
});
};
return (
<Space>
<Button type="primary" onClick={showMessage}>
Message for only one
</Button>
<Button type="primary" onClick={showNotification}>
Notification for bottomLeft
</Button>
</Space>
);
};
// Entry component
export default () => (
<App message={{ maxCount: 1 }} notification={{ placement: 'bottomLeft' }}>
<MyPage />
</App>
);

3
components/app/index.en-US.md

@ -18,7 +18,8 @@ Application wrapper for some global usages.
## Examples
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">basic</code>
<code src="./demo/basic.tsx">Basic</code>
<code src="./demo/config.tsx">Hooks config</code>
## How to use

1
components/app/index.zh-CN.md

@ -20,6 +20,7 @@ demo:
<!-- prettier-ignore -->
<code src="./demo/basic.tsx">基本用法</code>
<code src="./demo/config.tsx">Hooks 配置</code>
## 如何使用

6
components/auto-complete/index.tsx

@ -16,6 +16,7 @@ import type {
DefaultOptionType,
InternalSelectProps,
RefSelectProps,
SelectProps,
} from '../select';
import Select from '../select';
@ -146,7 +147,7 @@ const AutoComplete: React.ForwardRefRenderFunction<RefSelectProps, AutoCompleteP
prefixCls={prefixCls}
popupClassName={popupClassName || dropdownClassName}
className={classNames(`${prefixCls}-auto-complete`, className)}
mode={Select.SECRET_COMBOBOX_MODE_DO_NOT_USE as any}
mode={Select.SECRET_COMBOBOX_MODE_DO_NOT_USE as SelectProps['mode']}
{...{
// Internal api
getInputElement,
@ -167,6 +168,7 @@ const RefAutoComplete = React.forwardRef<RefSelectProps, AutoCompleteProps>(
ref?: React.Ref<BaseSelectRef>;
},
) => React.ReactElement) & {
displayName?: string;
Option: typeof Option;
_InternalPanelDoNotUseOrYouWillBeFired: typeof PurePanel;
};
@ -179,7 +181,7 @@ RefAutoComplete.Option = Option;
RefAutoComplete._InternalPanelDoNotUseOrYouWillBeFired = PurePanel;
if (process.env.NODE_ENV !== 'production') {
AutoComplete.displayName = 'AutoComplete';
RefAutoComplete.displayName = 'AutoComplete';
}
export default RefAutoComplete;

2
components/back-top/index.tsx

@ -121,4 +121,4 @@ if (process.env.NODE_ENV !== 'production') {
BackTop.displayName = 'BackTop';
}
export default React.memo(BackTop);
export default BackTop;

11
components/button/__tests__/index.test.tsx

@ -343,4 +343,15 @@ describe('Button', () => {
);
expect(window.getComputedStyle(container.querySelector('#link')!).pointerEvents).toBe('none');
});
it('Correct type', () => {
const onBtnClick: React.MouseEventHandler<HTMLButtonElement> = () => {};
const onAnchorClick: React.MouseEventHandler<HTMLAnchorElement> = () => {};
const button = <Button onClick={onBtnClick} />;
const anchor = <Button href="https://ant.design" onClick={onAnchorClick} />;
expect(button).toBeTruthy();
expect(anchor).toBeTruthy();
});
});

19
components/button/button.tsx

@ -27,7 +27,9 @@ import useStyle from './style';
export type LegacyButtonType = ButtonType | 'danger';
export function convertLegacyProps(type?: LegacyButtonType): ButtonProps {
export function convertLegacyProps(
type?: LegacyButtonType,
): Pick<BaseButtonProps, 'danger' | 'type'> {
if (type === 'danger') {
return { danger: true };
}
@ -66,7 +68,9 @@ export type NativeButtonProps = {
} & BaseButtonProps &
Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type' | 'onClick'>;
export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>;
export type ButtonProps = AnchorButtonProps | NativeButtonProps;
type InternalButtonProps = Partial<AnchorButtonProps & NativeButtonProps>;
type CompoundedComponent = React.ForwardRefExoticComponent<
ButtonProps & React.RefAttributes<HTMLElement>
@ -121,7 +125,7 @@ const InternalButton: React.ForwardRefRenderFunction<
classNames: customClassNames,
style: customStyle = {},
...rest
} = props;
} = props as InternalButtonProps;
const { getPrefixCls, autoInsertSpaceInButton, direction, button } = useContext(ConfigContext);
const prefixCls = getPrefixCls('btn', customizePrefixCls);
@ -214,7 +218,7 @@ const InternalButton: React.ForwardRefRenderFunction<
const iconType = innerLoading ? 'loading' : icon;
const linkButtonRestProps = omit(rest as ButtonProps & { navigate: any }, ['navigate']);
const linkButtonRestProps = omit(rest as InternalButtonProps & { navigate: any }, ['navigate']);
const classes = classNames(
prefixCls,
@ -237,10 +241,13 @@ const InternalButton: React.ForwardRefRenderFunction<
button?.className,
);
const fullStyle = { ...button?.style, ...customStyle };
const fullStyle: React.CSSProperties = { ...button?.style, ...customStyle };
const iconClasses = classNames(customClassNames?.icon, button?.classNames?.icon);
const iconStyle = { ...(styles?.icon || {}), ...(button?.styles?.icon || {}) };
const iconStyle: React.CSSProperties = {
...(styles?.icon || {}),
...(button?.styles?.icon || {}),
};
const iconNode =
icon && !innerLoading ? (

2
components/cascader/index.tsx

@ -142,7 +142,7 @@ export interface CascaderRef {
blur: () => void;
}
const Cascader = React.forwardRef((props: CascaderProps<any>, ref: React.Ref<CascaderRef>) => {
const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref) => {
const {
prefixCls: customizePrefixCls,
size: customizeSize,

47
components/checkbox/style/index.ts

@ -146,28 +146,6 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token) => {
},
},
// ================= Indeterminate =================
{
[checkboxCls]: {
'&-indeterminate': {
// Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: {
'&:after': {
top: '50%',
insetInlineStart: '50%',
width: token.fontSizeLG / 2,
height: token.fontSizeLG / 2,
backgroundColor: token.colorPrimary,
border: 0,
transform: 'translate(-50%, -50%) scale(1)',
opacity: 1,
content: '""',
},
},
},
},
},
// ===================== Hover =====================
{
// Wrapper
@ -245,6 +223,31 @@ export const genCheckboxStyle: GenerateStyle<CheckboxToken> = (token) => {
},
},
// ================= Indeterminate =================
{
[checkboxCls]: {
'&-indeterminate': {
// Wrapper > Checkbox > inner
[`${checkboxCls}-inner`]: {
backgroundColor: token.colorBgContainer,
borderColor: token.colorBorder,
'&:after': {
top: '50%',
insetInlineStart: '50%',
width: token.fontSizeLG / 2,
height: token.fontSizeLG / 2,
backgroundColor: token.colorPrimary,
border: 0,
transform: 'translate(-50%, -50%) scale(1)',
opacity: 1,
content: '""',
},
},
},
},
},
// ==================== Disable ====================
{
// Wrapper

6
components/config-provider/__tests__/popup.test.tsx

@ -1,4 +1,4 @@
import type { TriggerProps } from '@rc-component/trigger';
import type { TriggerProps, TriggerRef } from '@rc-component/trigger';
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import React from 'react';
@ -16,9 +16,9 @@ function triggerProps(): TriggerProps {
}
jest.mock('@rc-component/trigger', () => {
const R = jest.requireActual('react');
const R: typeof React = jest.requireActual('react');
const Trigger = jest.requireActual('@rc-component/trigger').default;
return R.forwardRef((props: any, ref: any) => {
return R.forwardRef<TriggerRef, TriggerProps>((props, ref) => {
(global as any).triggerProps = props;
return <Trigger {...props} ref={ref} />;
});

11
components/date-picker/__tests__/type.test.tsx

@ -1,5 +1,6 @@
import type { Dayjs } from 'dayjs';
import * as React from 'react';
import type { DatePickerProps, RangePickerProps } from '..';
import DatePicker from '..';
import type { DatePickRef, RangePickerRef } from '../generatePicker/interface';
@ -18,7 +19,7 @@ describe('DatePicker.typescript', () => {
// https://github.com/ant-design/ant-design/issues/33417
it('DatePicker ref methods with forwardRef', () => {
const MyDatePicker = React.forwardRef((props, ref: DatePickRef<Dayjs>) => (
const MyDatePicker = React.forwardRef((props: DatePickerProps, ref: DatePickRef<Dayjs>) => (
<DatePicker {...props} ref={ref} />
));
const datePicker = (
@ -45,9 +46,11 @@ describe('DatePicker.typescript', () => {
});
it('RangePicker ref methods with forwardRef', () => {
const MyRangePicker = React.forwardRef((props, ref: RangePickerRef<Dayjs>) => (
<DatePicker.RangePicker {...props} ref={ref} />
));
const MyRangePicker = React.forwardRef(
(props: RangePickerProps, ref: RangePickerRef<Dayjs>) => (
<DatePicker.RangePicker {...props} ref={ref} />
),
);
const datePicker = (
<MyRangePicker
ref={(picker) => {

6
components/date-picker/demo/cell-render.tsx

@ -6,7 +6,8 @@ const { RangePicker } = DatePicker;
const App: React.FC = () => (
<Space direction="vertical" size={12}>
<DatePicker
cellRender={(current) => {
cellRender={(current, info) => {
if (info.type !== 'date') return info.originNode;
const style: React.CSSProperties = {};
if (current.date() === 1) {
style.border = '1px solid #1677ff';
@ -20,7 +21,8 @@ const App: React.FC = () => (
}}
/>
<RangePicker
cellRender={(current) => {
cellRender={(current, info) => {
if (info.type !== 'date') return info.originNode;
const style: React.CSSProperties = {};
if (current.date() === 1) {
style.border = '1px solid #1677ff';

4
components/date-picker/generatePicker/generateRangePicker.tsx

@ -146,5 +146,9 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
);
});
if (process.env.NODE_ENV !== 'production') {
RangePicker.displayName = 'RangePicker';
}
return RangePicker as unknown as PickerComponentClass<DateRangePickerProps>;
}

7
components/date-picker/generatePicker/index.tsx

@ -17,7 +17,7 @@ import generateRangePicker from './generateRangePicker';
import generateSinglePicker from './generateSinglePicker';
const DataPickerPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'] as const;
type DataPickerPlacement = (typeof DataPickerPlacements)[number];
type DataPickerPlacement = typeof DataPickerPlacements[number];
type InjectDefaultProps<Props> = Omit<
Props,
@ -85,6 +85,7 @@ function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
// =========================== Export ===========================
type MergedDatePickerType = typeof DatePicker & {
displayName?: string;
WeekPicker: typeof WeekPicker;
MonthPicker: typeof MonthPicker;
YearPicker: typeof YearPicker;
@ -101,6 +102,10 @@ function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
MergedDatePicker.TimePicker = TimePicker;
MergedDatePicker.QuarterPicker = QuarterPicker;
if (process.env.NODE_ENV !== 'production') {
MergedDatePicker.displayName = 'DatePicker';
}
return MergedDatePicker;
}

3
components/date-picker/style/index.ts

@ -1024,6 +1024,7 @@ const genPickerStyle: GenerateStyle<PickerToken> = (token) => {
presetsWidth,
presetsMaxWidth,
boxShadowPopoverArrow,
colorTextQuaternary,
} = token;
return [
@ -1054,7 +1055,7 @@ const genPickerStyle: GenerateStyle<PickerToken> = (token) => {
cursor: 'not-allowed',
[`${componentCls}-suffix`]: {
color: colorTextDisabled,
color: colorTextQuaternary,
},
},

8
components/float-button/FloatButton.tsx

@ -101,13 +101,13 @@ const FloatButton: React.ForwardRefRenderFunction<
);
};
if (process.env.NODE_ENV !== 'production') {
FloatButton.displayName = 'FloatButton';
}
const ForwardFloatButton = React.forwardRef<
HTMLAnchorElement | HTMLButtonElement,
FloatButtonProps
>(FloatButton) as CompoundedComponent;
if (process.env.NODE_ENV !== 'production') {
ForwardFloatButton.displayName = 'FloatButton';
}
export default ForwardFloatButton;

8
components/form/Form.tsx

@ -186,9 +186,13 @@ const InternalForm: React.ForwardRefRenderFunction<FormInstance, FormProps> = (p
);
};
const Form = React.forwardRef<FormInstance, FormProps>(InternalForm) as <Values = any>(
const Form = React.forwardRef<FormInstance, FormProps>(InternalForm) as (<Values = any>(
props: React.PropsWithChildren<FormProps<Values>> & { ref?: React.Ref<FormInstance<Values>> },
) => React.ReactElement;
) => React.ReactElement) & { displayName?: string };
if (process.env.NODE_ENV !== 'production') {
Form.displayName = 'Form';
}
export { List, useForm, useWatch, type FormInstance };

8
components/form/index.en-US.md

@ -592,12 +592,18 @@ React can not get correct interaction of controlled component with async value u
}
</style>
### `scrollToFirstError` and `scrollToField` not working on custom form control?
### `scrollToFirstError` and `scrollToField` not working?
1. use custom form control
See similar issues: [#28370](https://github.com/ant-design/ant-design/issues/28370) [#27994](https://github.com/ant-design/ant-design/issues/27994)
`scrollToFirstError` and `scrollToField` deps on `id` attribute passed to form control, please make sure that it hasn't been ignored in your custom form control. Check [codesandbox](https://codesandbox.io/s/antd-reproduction-template-forked-25nul?file=/index.js) for solution.
2. multiple forms on same page
If there are multiple forms on the page, and there are duplicate same `name` form item, the form scroll probably may find the form item with the same name in another form. You need to set a different `name` for the `Form` component to distinguish it.
### Continue, why not use `ref` to bind element?
Form can not get real DOM node when customize component not support `ref`. It will get warning in React Strict Mode if wrap with Class Component and call `findDOMNode`. So we use `id` to locate element.

8
components/form/index.zh-CN.md

@ -591,12 +591,18 @@ React 中异步更新会导致受控组件交互行为异常。当用户交互
}
</style>
### 自定义表单控件 `scrollToFirstError``scrollToField` 失效?
### `scrollToFirstError``scrollToField` 失效?
1. 使用了自定义表单控件
类似问题:[#28370](https://github.com/ant-design/ant-design/issues/28370) [#27994](https://github.com/ant-design/ant-design/issues/27994)
滚动依赖于表单控件元素上绑定的 `id` 字段,如果自定义控件没有将 `id` 赋到正确的元素上,这个功能将失效。你可以参考这个 [codesandbox](https://codesandbox.io/s/antd-reproduction-template-forked-25nul?file=/index.js)。
2. 页面内有多个表单
页面内如果有多个表单,且存在表单项 `name` 重复,表单滚动定位可能会查找到另一个表单的同名表单项上。需要给表单 `Form` 组件设置不同的 `name` 以区分。
### 继上,为何不通过 `ref` 绑定元素?
当自定义组件不支持 `ref` 时,Form 无法获取子元素真实 DOM 节点,而通过包裹 Class Component 调用 `findDOMNode` 会在 React Strict Mode 下触发警告。因而我们使用 id 来进行元素定位。

5
components/form/style/index.ts

@ -222,7 +222,7 @@ const genFormItemStyle: GenerateStyle<FormToken> = (token) => {
},
[`&${formItemCls}-no-colon::after`]: {
content: '" "',
content: '"\\a0"',
},
},
},
@ -397,7 +397,8 @@ const makeVerticalLayoutLabel = (token: FormToken): CSSObject => ({
margin: 0,
'&::after': {
display: 'none',
// https://github.com/ant-design/ant-design/issues/43538
visibility: 'hidden',
},
},
});

1
components/grid/__tests__/demo.test.ts

@ -2,4 +2,5 @@ import demoTest from '../../../tests/shared/demoTest';
demoTest('grid', {
testRootProps: false,
nameCheckPathOnly: true,
});

1
components/icon/__tests__/demo.test.ts

@ -2,4 +2,5 @@ import demoTest from '../../../tests/shared/demoTest';
demoTest('icon', {
testRootProps: false,
nameCheckPathOnly: true,
});

4
components/icon/index.ts

@ -1,7 +1,9 @@
import warning from '../_util/warning';
const Icon: React.FC = () => {
warning(false, 'Icon', 'Empty Icon');
if (process.env.NODE_ENV !== 'production') {
warning(false, 'Icon', 'Empty Icon');
}
return null;
};

4
components/index.ts

@ -95,8 +95,8 @@ export { default as Popover } from './popover';
export type { PopoverProps } from './popover';
export { default as Progress } from './progress';
export type { ProgressProps } from './progress';
export { default as QRCode } from './qrcode';
export type { QRCodeProps, QRPropsCanvas, QRPropsSvg } from './qrcode/interface';
export { default as QRCode } from './qr-code';
export type { QRCodeProps, QRPropsCanvas, QRPropsSvg } from './qr-code/interface';
export { default as Radio } from './radio';
export type { RadioChangeEvent, RadioGroupProps, RadioProps } from './radio';
export { default as Rate } from './rate';

5
components/input-number/__tests__/prefix.test.tsx

@ -1,11 +1,14 @@
import React, { forwardRef } from 'react';
import type { InputNumberProps } from '..';
import InputNumber from '..';
import focusTest from '../../../tests/shared/focusTest';
import { fireEvent, render } from '../../../tests/utils';
describe('prefix', () => {
focusTest(
forwardRef((props, ref) => <InputNumber {...props} prefix="A" ref={ref} />),
forwardRef<HTMLInputElement, InputNumberProps>((props, ref) => (
<InputNumber {...props} prefix="A" ref={ref} />
)),
{ refFocus: true },
);
it('should support className when has prefix', () => {

3
components/input-number/index.tsx

@ -2,9 +2,8 @@
import DownOutlined from '@ant-design/icons/DownOutlined';
import UpOutlined from '@ant-design/icons/UpOutlined';
import type { ValueType } from '@rc-component/mini-decimal';
import classNames from 'classnames';
import type { InputNumberProps as RcInputNumberProps } from 'rc-input-number';
import type { InputNumberProps as RcInputNumberProps, ValueType } from 'rc-input-number';
import RcInputNumber from 'rc-input-number';
import * as React from 'react';
import type { InputStatus } from '../_util/statusUtils';

8
components/input-number/style/index.ts

@ -55,8 +55,8 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
colorTextDescription,
motionDurationMid,
colorPrimary,
controlHeight,
inputPaddingHorizontal,
inputPaddingVertical,
colorBgContainer,
colorTextDisabled,
borderRadiusSM,
@ -164,8 +164,7 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
'&-input': {
...resetComponent(token),
width: '100%',
height: controlHeight - 2 * lineWidth,
padding: `0 ${inputPaddingHorizontal}px`,
padding: `${inputPaddingVertical}px ${inputPaddingHorizontal}px`,
textAlign: 'start',
backgroundColor: 'transparent',
border: 0,
@ -320,6 +319,7 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
const genAffixWrapperStyles: GenerateStyle<InputNumberToken> = (token: InputNumberToken) => {
const {
componentCls,
inputPaddingVertical,
inputPaddingHorizontal,
inputAffixPadding,
controlWidth,
@ -370,7 +370,7 @@ const genAffixWrapperStyles: GenerateStyle<InputNumberToken> = (token: InputNumb
},
[`input${componentCls}-input`]: {
padding: 0,
padding: `${inputPaddingVertical}px 0`,
},
'&::before': {

2
components/layout/__tests__/token.test.tsx

@ -24,7 +24,6 @@ describe('Layout.Token', () => {
>
<Header>
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys={['2']}
items={new Array(15).fill(null).map((_, index) => {
@ -62,7 +61,6 @@ describe('Layout.Token', () => {
>
<Header>
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys={['2']}
items={new Array(15).fill(null).map((_, index) => {

2
components/locale/__tests__/config.test.tsx

@ -53,5 +53,5 @@ describe('Locale Provider demo', () => {
expect(document.body.querySelectorAll('.ant-btn-primary span')[0]?.textContent).toBe('确 定');
Modal.destroyAll();
jest.useRealTimers();
});
}, 500000);
});

1401
components/menu/__tests__/__snapshots__/demo-extend.test.ts.snap

File diff suppressed because it is too large

492
components/menu/__tests__/__snapshots__/demo.test.tsx.snap

@ -1,95 +1,207 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders components/menu/demo/component-token.tsx correctly 1`] = `
Array [
<ul
class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light"
data-menu-list="true"
role="menu"
tabindex="0"
<div
class="ant-space ant-space-vertical"
>
<div
class="ant-space-item"
style="margin-bottom:8px"
>
<li
class="ant-menu-overflow-item ant-menu-item ant-menu-item-selected"
role="menuitem"
style="opacity:1;order:0"
tabindex="-1"
<ul
class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light"
data-menu-list="true"
role="menu"
tabindex="0"
>
<span
aria-label="mail"
class="anticon anticon-mail ant-menu-item-icon"
role="img"
<li
class="ant-menu-overflow-item ant-menu-item ant-menu-item-selected"
role="menuitem"
style="opacity:1;order:0"
tabindex="-1"
>
<svg
aria-hidden="true"
data-icon="mail"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="mail"
class="anticon anticon-mail ant-menu-item-icon"
role="img"
>
<path
d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Navigation One
</span>
</li>
<li
aria-disabled="true"
class="ant-menu-overflow-item ant-menu-item ant-menu-item-disabled"
role="menuitem"
style="opacity:1;order:1"
>
<span
aria-label="appstore"
class="anticon anticon-appstore ant-menu-item-icon"
role="img"
<svg
aria-hidden="true"
data-icon="mail"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Navigation One
</span>
</li>
<li
aria-disabled="true"
class="ant-menu-overflow-item ant-menu-item ant-menu-item-disabled"
role="menuitem"
style="opacity:1;order:1"
>
<svg
aria-hidden="true"
data-icon="appstore"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="appstore"
class="anticon anticon-appstore ant-menu-item-icon"
role="img"
>
<path
d="M464 144H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H212V212h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H612V212h200v200zM464 544H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H212V612h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H612V612h200v200z"
<svg
aria-hidden="true"
data-icon="appstore"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M464 144H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H212V212h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H612V212h200v200zM464 544H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H212V612h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H612V612h200v200z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Navigation Two
</span>
</li>
<li
class="ant-menu-overflow-item ant-menu-submenu ant-menu-submenu-horizontal"
role="none"
style="opacity:1;order:2"
>
<div
aria-expanded="false"
aria-haspopup="true"
class="ant-menu-submenu-title"
role="menuitem"
tabindex="-1"
>
<span
aria-label="setting"
class="anticon anticon-setting ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Navigation Three - Submenu
</span>
<i
class="ant-menu-submenu-arrow"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
</div>
</li>
<li
class="ant-menu-overflow-item ant-menu-item ant-menu-item-only-child"
role="menuitem"
style="opacity:1;order:3"
tabindex="-1"
>
Navigation Two
</span>
</li>
<li
class="ant-menu-overflow-item ant-menu-submenu ant-menu-submenu-horizontal"
role="none"
style="opacity:1;order:2"
<span
class="ant-menu-title-content"
>
<a
href="https://ant.design"
rel="noopener noreferrer"
target="_blank"
>
Navigation Four - Link
</a>
</span>
</li>
<li
aria-hidden="true"
class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal"
role="none"
style="opacity:0;height:0;overflow-y:hidden;order:9007199254740991;pointer-events:none;position:absolute"
>
<div
aria-expanded="false"
aria-haspopup="true"
class="ant-menu-submenu-title"
role="menuitem"
tabindex="-1"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
<i
class="ant-menu-submenu-arrow"
/>
</div>
</li>
</ul>
<div
aria-hidden="true"
style="display:none"
/>
</div>
<div
class="ant-space-item"
>
<ul
class="ant-menu ant-menu-root ant-menu-inline ant-menu-dark"
data-menu-list="true"
role="menu"
style="width:256px"
tabindex="0"
>
<div
aria-expanded="false"
aria-haspopup="true"
class="ant-menu-submenu-title"
<li
class="ant-menu-item ant-menu-item-selected"
role="menuitem"
style="padding-left:24px"
tabindex="-1"
>
<span
aria-label="setting"
class="anticon anticon-setting ant-menu-item-icon"
aria-label="pie-chart"
class="anticon anticon-pie-chart ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
data-icon="pie-chart"
fill="currentColor"
focusable="false"
height="1em"
@ -97,59 +209,61 @@ Array [
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
d="M864 518H506V160c0-4.4-3.6-8-8-8h-26a398.46 398.46 0 00-282.8 117.1 398.19 398.19 0 00-85.7 127.1A397.61 397.61 0 0072 552a398.46 398.46 0 00117.1 282.8c36.7 36.7 79.5 65.6 127.1 85.7A397.61 397.61 0 00472 952a398.46 398.46 0 00282.8-117.1c36.7-36.7 65.6-79.5 85.7-127.1A397.61 397.61 0 00872 552v-26c0-4.4-3.6-8-8-8zM705.7 787.8A331.59 331.59 0 01470.4 884c-88.1-.4-170.9-34.9-233.2-97.2C174.5 724.1 140 640.7 140 552c0-88.7 34.5-172.1 97.2-234.8 54.6-54.6 124.9-87.9 200.8-95.5V586h364.3c-7.7 76.3-41.3 147-96.6 201.8zM952 462.4l-2.6-28.2c-8.5-92.1-49.4-179-115.2-244.6A399.4 399.4 0 00589 74.6L560.7 72c-4.7-.4-8.7 3.2-8.7 7.9V464c0 4.4 3.6 8 8 8l384-1c4.7 0 8.4-4 8-8.6zm-332.2-58.2V147.6a332.24 332.24 0 01166.4 89.8c45.7 45.6 77 103.6 90 166.1l-256.4.7z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Navigation Three - Submenu
Option 1
</span>
<i
class="ant-menu-submenu-arrow"
/>
</div>
</li>
<li
class="ant-menu-overflow-item ant-menu-item ant-menu-item-only-child"
role="menuitem"
style="opacity:1;order:3"
tabindex="-1"
>
<span
class="ant-menu-title-content"
</li>
<li
class="ant-menu-item"
role="menuitem"
style="padding-left:24px"
tabindex="-1"
>
<a
href="https://ant.design"
rel="noopener noreferrer"
target="_blank"
<span
aria-label="desktop"
class="anticon anticon-desktop ant-menu-item-icon"
role="img"
>
Navigation Four - Link
</a>
</span>
</li>
<li
aria-hidden="true"
class="ant-menu-overflow-item ant-menu-overflow-item-rest ant-menu-submenu ant-menu-submenu-horizontal"
role="none"
style="opacity:0;height:0;overflow-y:hidden;order:9007199254740991;pointer-events:none;position:absolute"
>
<div
aria-expanded="false"
aria-haspopup="true"
class="ant-menu-submenu-title"
<svg
aria-hidden="true"
data-icon="desktop"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M928 140H96c-17.7 0-32 14.3-32 32v496c0 17.7 14.3 32 32 32h380v112H304c-8.8 0-16 7.2-16 16v48c0 4.4 3.6 8 8 8h432c4.4 0 8-3.6 8-8v-48c0-8.8-7.2-16-16-16H548V700h380c17.7 0 32-14.3 32-32V172c0-17.7-14.3-32-32-32zm-40 488H136V212h752v416z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Option 2
</span>
</li>
<li
class="ant-menu-item"
role="menuitem"
style="padding-left:24px"
tabindex="-1"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
aria-label="container"
class="anticon anticon-container ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
data-icon="container"
fill="currentColor"
focusable="false"
height="1em"
@ -157,21 +271,159 @@ Array [
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"
d="M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-40 824H232V687h97.9c11.6 32.8 32 62.3 59.1 84.7 34.5 28.5 78.2 44.3 123 44.3s88.5-15.7 123-44.3c27.1-22.4 47.5-51.9 59.1-84.7H792v-63H643.6l-5.2 24.7C626.4 708.5 573.2 752 512 752s-114.4-43.5-126.5-103.3l-5.2-24.7H232V136h560v752zM320 341h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zm0 160h384c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"
/>
</svg>
</span>
<i
class="ant-menu-submenu-arrow"
/>
</div>
</li>
</ul>,
<div
aria-hidden="true"
style="display:none"
/>,
]
<span
class="ant-menu-title-content"
>
Option 3
</span>
</li>
<li
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
role="none"
>
<div
aria-expanded="true"
aria-haspopup="true"
class="ant-menu-submenu-title"
role="menuitem"
style="padding-left:24px"
tabindex="-1"
>
<span
aria-label="mail"
class="anticon anticon-mail ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="mail"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0068.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Navigation One
</span>
<i
class="ant-menu-submenu-arrow"
/>
</div>
<ul
class="ant-menu ant-menu-sub ant-menu-inline"
data-menu-list="true"
role="menu"
>
<li
class="ant-menu-item ant-menu-item-only-child"
role="menuitem"
style="padding-left:48px"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 5
</span>
</li>
<li
class="ant-menu-item ant-menu-item-only-child"
role="menuitem"
style="padding-left:48px"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 6
</span>
</li>
<li
class="ant-menu-item ant-menu-item-only-child"
role="menuitem"
style="padding-left:48px"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 7
</span>
</li>
<li
class="ant-menu-item ant-menu-item-only-child"
role="menuitem"
style="padding-left:48px"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 8
</span>
</li>
</ul>
</li>
<li
class="ant-menu-submenu ant-menu-submenu-inline"
role="none"
>
<div
aria-expanded="false"
aria-haspopup="true"
class="ant-menu-submenu-title"
role="menuitem"
style="padding-left:24px"
tabindex="-1"
>
<span
aria-label="appstore"
class="anticon anticon-appstore ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="appstore"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M464 144H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H212V212h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H612V212h200v200zM464 544H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H212V612h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H612V612h200v200z"
/>
</svg>
</span>
<span
class="ant-menu-title-content"
>
Navigation Two
</span>
<i
class="ant-menu-submenu-arrow"
/>
</div>
</li>
</ul>
<div
aria-hidden="true"
style="display:none"
/>
</div>
</div>
`;
exports[`renders components/menu/demo/horizontal.tsx correctly 1`] = `

97
components/menu/demo/component-token.tsx

@ -1,8 +1,17 @@
import { AppstoreOutlined, MailOutlined, SettingOutlined } from '@ant-design/icons';
import {
AppstoreOutlined,
ContainerOutlined,
DesktopOutlined,
MailOutlined,
PieChartOutlined,
SettingOutlined,
} from '@ant-design/icons';
import type { MenuProps } from 'antd';
import { ConfigProvider, Menu } from 'antd';
import { ConfigProvider, Menu, Space } from 'antd';
import React, { useState } from 'react';
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [
{
label: 'Navigation One',
@ -60,6 +69,42 @@ const items: MenuProps['items'] = [
},
];
function getItem(
label: React.ReactNode,
key: React.Key,
icon?: React.ReactNode,
children?: MenuItem[],
type?: 'group',
): MenuItem {
return {
key,
icon,
children,
label,
type,
} as MenuItem;
}
const items2: MenuProps['items'] = [
getItem('Option 1', '1', <PieChartOutlined />),
getItem('Option 2', '2', <DesktopOutlined />),
getItem('Option 3', '3', <ContainerOutlined />),
getItem('Navigation One', 'sub1', <MailOutlined />, [
getItem('Option 5', '5'),
getItem('Option 6', '6'),
getItem('Option 7', '7'),
getItem('Option 8', '8'),
]),
getItem('Navigation Two', 'sub2', <AppstoreOutlined />, [
getItem('Option 9', '9'),
getItem('Option 10', '10'),
getItem('Submenu', 'sub3', null, [getItem('Option 11', '11'), getItem('Option 12', '12')]),
]),
];
const App: React.FC = () => {
const [current, setCurrent] = useState('mail');
@ -69,18 +114,44 @@ const App: React.FC = () => {
};
return (
<ConfigProvider
theme={{
components: {
Menu: {
horizontalItemBorderRadius: 6,
horizontalItemHoverBg: '#f5f5f5',
<Space direction="vertical">
<ConfigProvider
theme={{
components: {
Menu: {
horizontalItemBorderRadius: 6,
horizontalItemHoverBg: '#f5f5f5',
},
},
}}
>
<Menu onClick={onClick} selectedKeys={[current]} mode="horizontal" items={items} />
</ConfigProvider>
<ConfigProvider
theme={{
components: {
Menu: {
darkItemColor: '#91daff',
darkItemBg: '#d48806',
darkSubMenuItemBg: '#faad14',
darkItemSelectedColor: '#ffccc7',
darkItemSelectedBg: '#52c41a',
},
},
},
}}
>
<Menu onClick={onClick} selectedKeys={[current]} mode="horizontal" items={items} />
</ConfigProvider>
}}
>
<Menu
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
mode='inline'
theme='dark'
items={items2}
style={{
width: 256,
}}
/>
</ConfigProvider>
</Space>
);
};

8
components/menu/style/horizontal.tsx

@ -5,16 +5,16 @@ const getHorizontalStyle: GenerateStyle<MenuToken> = (token) => {
const {
componentCls,
motionDurationSlow,
menuHorizontalHeight,
horizontalLineHeight,
colorSplit,
lineWidth,
lineType,
menuItemPaddingInline,
itemPaddingInline,
} = token;
return {
[`${componentCls}-horizontal`]: {
lineHeight: `${menuHorizontalHeight}px`,
lineHeight: horizontalLineHeight,
border: 0,
borderBottom: `${lineWidth}px ${lineType} ${colorSplit}`,
boxShadow: 'none',
@ -31,7 +31,7 @@ const getHorizontalStyle: GenerateStyle<MenuToken> = (token) => {
position: 'relative',
display: 'inline-block',
verticalAlign: 'bottom',
paddingInline: menuItemPaddingInline,
paddingInline: itemPaddingInline,
},
[`> ${componentCls}-item:hover,

275
components/menu/style/index.tsx

@ -1,5 +1,6 @@
import type { CSSObject } from '@ant-design/cssinjs';
import { TinyColor } from '@ctrl/tinycolor';
import type { CSSProperties } from 'react';
import { clearFix, resetComponent, resetIcon } from '../../style';
import { genCollapseMotion, initSlideMotion, initZoomMotion } from '../../style/motion';
import type { FullToken, GenerateStyle, UseComponentStyleResult } from '../../theme/internal';
@ -30,6 +31,16 @@ export interface ComponentToken {
* @descEN Color of group title text
*/
groupTitleColor: string;
/**
* @desc
* @descEN line-height of group title
*/
groupTitleLineHeight: CSSProperties['lineHeight'];
/**
* @desc
* @descEN font-size of group title
*/
groupTitleFontSize: number;
// radius
/** @deprecated Use `itemBorderRadius` instead */
@ -229,12 +240,127 @@ export interface ComponentToken {
* @descEN Border radius of horizontal menu item
*/
horizontalItemBorderRadius: number;
/**
* @desc
* @descEN Height of menu item
*/
itemHeight: number;
/**
* @desc
* @descEN Width when collapsed
*/
collapsedWidth: number;
/**
* @desc
* @descEN Background color of popup
*/
popupBg: string;
/**
* @desc
* @descEN margin-block of menu item
*/
itemMarginBlock: CSSProperties['marginBlock'];
/**
* @desc
* @descEN padding-inline of menu item
*/
itemPaddingInline: CSSProperties['paddingInline'];
/**
* @desc
* @descEN LineHeight of horizontal menu item
*/
horizontalLineHeight: CSSProperties['lineHeight'];
/**
* @desc
* @descEN Spacing between icon and text
*/
iconMarginInlineEnd: CSSProperties['marginInlineEnd'];
/**
* @desc
* @descEN Size of icon
*/
iconSize: number;
/**
* @desc
* @descEN Size of icon when collapsed
*/
collapsedIconSize: number;
// Dark
/**
* @desc
* @descEN Color of menu item text in dark mode
*/
darkItemColor: string;
/**
* @desc
* @descEN Color of danger menu item text in dark mode
*/
darkDangerItemColor: string;
/**
* @desc
* @descEN Background of menu item in dark mode
*/
darkItemBg: string;
/**
* @desc
* @descEN Background of submenu item in dark mode
*/
darkSubMenuItemBg: string;
/**
* @desc
* @descEN Color of selected menu item in dark mode
*/
darkItemSelectedColor: string;
/**
* @desc
* @descEN Background of active menu item in dark mode
*/
darkItemSelectedBg: string;
/**
* @desc
* @descEN Background of hovered menu item in dark mode
*/
darkItemHoverBg: string;
/**
* @desc
* @descEN Color of group title text in dark mode
*/
darkGroupTitleColor: string;
/**
* @desc
* @descEN Color of hovered menu item in dark mode
*/
darkItemHoverColor: string;
/**
* @desc
* @descEN Color of disabled menu item in dark mode
*/
darkItemDisabledColor: string;
/**
* @desc
* @descEN Background of active danger menu item in dark mode
*/
darkDangerItemSelectedBg: string;
/**
* @desc
* @descEN Background of hovered danger menu item in dark mode
*/
darkDangerItemHoverColor: string;
/**
* @desc
* @descEN Color of selected danger menu item in dark mode
*/
darkDangerItemSelectedColor: string;
/**
* @desc
* @descEN Background of active danger menu item in dark mode
*/
darkDangerItemActiveBg: string;
}
export interface MenuToken extends FullToken<'Menu'> {
menuItemHeight: number;
menuHorizontalHeight: number;
menuItemPaddingInline: number;
menuArrowSize: number;
menuArrowOffset: string;
menuPanelMaskInset: number;
@ -244,13 +370,13 @@ export interface MenuToken extends FullToken<'Menu'> {
const genMenuItemStyle = (token: MenuToken): CSSObject => {
const {
componentCls,
fontSize,
motionDurationSlow,
motionDurationMid,
motionEaseInOut,
motionEaseOut,
iconCls,
controlHeightSM,
iconSize,
iconMarginInlineEnd,
} = token;
return {
@ -268,8 +394,8 @@ const genMenuItemStyle = (token: MenuToken): CSSObject => {
].join(','),
[`${componentCls}-item-icon, ${iconCls}`]: {
minWidth: fontSize,
fontSize,
minWidth: iconSize,
fontSize: iconSize,
transition: [
`font-size ${motionDurationMid} ${motionEaseOut}`,
`margin ${motionDurationSlow} ${motionEaseInOut}`,
@ -277,7 +403,7 @@ const genMenuItemStyle = (token: MenuToken): CSSObject => {
].join(','),
'+ span': {
marginInlineStart: controlHeightSM - fontSize,
marginInlineStart: iconMarginInlineEnd,
opacity: 1,
transition: [
`opacity ${motionDurationSlow} ${motionEaseInOut}`,
@ -379,7 +505,6 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
motionDurationSlow,
motionDurationMid,
motionEaseInOut,
lineHeight,
paddingXS,
padding,
colorSplit,
@ -391,6 +516,8 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
menuArrowOffset,
lineType,
menuPanelMaskInset,
groupTitleLineHeight,
groupTitleFontSize,
} = token;
return [
@ -444,8 +571,8 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
[`${componentCls}-item-group-title`]: {
padding: `${paddingXS}px ${padding}px`,
fontSize,
lineHeight,
fontSize: groupTitleFontSize,
lineHeight: groupTitleLineHeight,
transition: `all ${motionDurationSlow}`,
},
@ -666,7 +793,7 @@ const getBaseStyle: GenerateStyle<MenuToken> = (token) => {
export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResult => {
const useOriginHook = genComponentStyleHook(
'Menu',
(token, { overrideComponentToken }) => {
(token) => {
// Dropdown will handle menu style self. We do not need to handle this.
if (injectStyle === false) {
return [];
@ -675,19 +802,29 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
const {
colorBgElevated,
colorPrimary,
colorError,
colorErrorHover,
colorTextLightSolid,
controlHeightLG,
fontSize,
darkItemColor,
darkDangerItemColor,
darkItemBg,
darkSubMenuItemBg,
darkItemSelectedColor,
darkItemSelectedBg,
darkDangerItemSelectedBg,
darkItemHoverBg,
darkGroupTitleColor,
darkItemHoverColor,
darkItemDisabledColor,
darkDangerItemHoverColor,
darkDangerItemSelectedColor,
darkDangerItemActiveBg,
} = token;
const menuArrowSize = (fontSize / 7) * 5;
// Menu Token
const menuToken = mergeToken<MenuToken>(token, {
menuItemHeight: controlHeightLG,
menuItemPaddingInline: token.margin,
menuArrowSize,
menuHorizontalHeight: controlHeightLG * 1.15,
menuArrowOffset: `${menuArrowSize * 0.25}px`,
@ -695,43 +832,36 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
menuSubMenuBg: colorBgElevated,
});
const colorTextDark = new TinyColor(colorTextLightSolid).setAlpha(0.65).toRgbString();
const menuDarkToken = mergeToken<MenuToken>(menuToken, {
itemColor: darkItemColor,
itemHoverColor: darkItemHoverColor,
groupTitleColor: darkGroupTitleColor,
itemSelectedColor: darkItemSelectedColor,
itemBg: darkItemBg,
popupBg: darkItemBg,
subMenuItemBg: darkSubMenuItemBg,
itemActiveBg: 'transparent',
itemSelectedBg: darkItemSelectedBg,
activeBarHeight: 0,
activeBarBorderWidth: 0,
itemHoverBg: darkItemHoverBg,
const menuDarkToken = mergeToken<MenuToken>(
menuToken,
{
itemColor: colorTextDark,
itemHoverColor: colorTextLightSolid,
groupTitleColor: colorTextDark,
itemSelectedColor: colorTextLightSolid,
itemBg: '#001529',
subMenuItemBg: '#000c17',
itemActiveBg: 'transparent',
itemSelectedBg: colorPrimary,
activeBarWidth: 0,
activeBarHeight: 0,
activeBarBorderWidth: 0,
// Disabled
itemDisabledColor: new TinyColor(colorTextLightSolid).setAlpha(0.25).toRgbString(),
// Danger
dangerItemColor: colorError,
dangerItemHoverColor: colorErrorHover,
dangerItemSelectedColor: colorTextLightSolid,
dangerItemActiveBg: colorError,
dangerItemSelectedBg: colorError,
menuSubMenuBg: '#001529',
// Horizontal
horizontalItemSelectedColor: colorTextLightSolid,
horizontalItemSelectedBg: colorPrimary,
},
{
...overrideComponentToken,
},
);
// Disabled
itemDisabledColor: darkItemDisabledColor,
// Danger
dangerItemColor: darkDangerItemColor,
dangerItemHoverColor: darkDangerItemHoverColor,
dangerItemSelectedColor: darkDangerItemSelectedColor,
dangerItemActiveBg: darkDangerItemActiveBg,
dangerItemSelectedBg: darkDangerItemSelectedBg,
menuSubMenuBg: darkSubMenuItemBg,
// Horizontal
horizontalItemSelectedColor: colorTextLightSolid,
horizontalItemSelectedBg: colorPrimary,
});
return [
// Basic
@ -773,8 +903,20 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
lineWidthBold,
controlItemBgActive,
colorBgTextHover,
controlHeightLG,
lineHeight,
colorBgElevated,
marginXXS,
padding,
fontSize,
controlHeightSM,
fontSizeLG,
colorTextLightSolid,
colorErrorHover,
} = token;
const colorTextDark = new TinyColor(colorTextLightSolid).setAlpha(0.65).toRgbString();
return {
dropdownWidth: 160,
zIndexPopup: token.zIndexPopupBase + 50,
@ -799,7 +941,7 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
colorItemBgHover: colorBgTextHover,
itemHoverBg: colorBgTextHover,
colorItemBgActive: colorFillContent,
itemActiveBg: colorFillContent,
itemActiveBg: controlItemBgActive,
colorSubItemBg: colorFillAlter,
subMenuItemBg: colorFillAlter,
colorItemBgSelected: controlItemBgActive,
@ -833,6 +975,35 @@ export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResul
horizontalItemBorderRadius: 0,
horizontalItemHoverBg: 'transparent',
itemHeight: controlHeightLG,
groupTitleLineHeight: lineHeight,
collapsedWidth: controlHeightLG * 2,
popupBg: colorBgElevated,
itemMarginBlock: marginXXS,
itemPaddingInline: padding,
horizontalLineHeight: `${controlHeightLG * 1.15}px`,
iconSize: fontSize,
iconMarginInlineEnd: controlHeightSM - fontSize,
collapsedIconSize: fontSizeLG,
groupTitleFontSize: fontSize,
// Disabled
darkItemDisabledColor: new TinyColor(colorTextLightSolid).setAlpha(0.25).toRgbString(),
// Dark
darkItemColor: colorTextDark,
darkDangerItemColor: colorError,
darkItemBg: '#001529',
darkSubMenuItemBg: '#000c17',
darkItemSelectedColor: colorTextLightSolid,
darkItemSelectedBg: colorPrimary,
darkDangerItemSelectedBg: colorError,
darkItemHoverBg: 'transparent',
darkGroupTitleColor: colorTextDark,
darkItemHoverColor: colorTextLightSolid,
darkDangerItemHoverColor: colorErrorHover,
darkDangerItemSelectedColor: colorTextLightSolid,
darkDangerItemActiveBg: colorError,
};
},
{

25
components/menu/style/theme.tsx

@ -21,7 +21,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
motionDurationSlow,
motionEaseInOut,
motionEaseOut,
menuItemPaddingInline,
itemPaddingInline,
motionDurationMid,
itemHoverColor,
lineType,
@ -38,6 +38,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
dangerItemSelectedBg,
itemHoverBg,
itemActiveBg,
menuSubMenuBg,
// Horizontal
@ -45,6 +46,8 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
horizontalItemSelectedBg,
horizontalItemBorderRadius,
horizontalItemHoverBg,
popupBg,
} = token;
return {
@ -73,11 +76,12 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
},
// Hover
[`${componentCls}-item:hover, ${componentCls}-submenu-title:hover`]: {
[`&:not(${componentCls}-item-selected):not(${componentCls}-submenu-selected)`]: {
color: itemHoverColor,
[`${componentCls}-item:not(${componentCls}-item-selected):not(${componentCls}-submenu-selected)`]:
{
[`&:hover, > ${componentCls}-submenu-title:hover`]: {
color: itemHoverColor,
},
},
},
[`&:not(${componentCls}-horizontal)`]: {
[`${componentCls}-item:not(${componentCls}-item-selected)`]: {
@ -86,7 +90,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
},
'&:active': {
backgroundColor: itemSelectedBg,
backgroundColor: itemActiveBg,
},
},
@ -96,7 +100,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
},
'&:active': {
backgroundColor: itemSelectedBg,
backgroundColor: itemActiveBg,
},
},
},
@ -155,7 +159,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
},
[`&${componentCls}-popup > ${componentCls}`]: {
backgroundColor: itemBg,
backgroundColor: popupBg,
},
// ====================== Horizontal ======================
@ -174,7 +178,7 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
'&::after': {
position: 'absolute',
insetInline: menuItemPaddingInline,
insetInline: itemPaddingInline,
bottom: 0,
borderBottom: `${activeBarHeight}px solid transparent`,
transition: `border-color ${motionDurationSlow} ${motionEaseInOut}`,
@ -191,6 +195,9 @@ const getThemeStyle = (token: MenuToken, themeSuffix: string): CSSInterpolation
[`&-selected`]: {
color: horizontalItemSelectedColor,
backgroundColor: horizontalItemSelectedBg,
'&:hover': {
backgroundColor: horizontalItemSelectedBg,
},
'&::after': {
borderBottomWidth: activeBarHeight,
borderBottomColor: horizontalItemSelectedColor,

28
components/menu/style/vertical.tsx

@ -6,12 +6,12 @@ import type { GenerateStyle } from '../../theme/internal';
const getVerticalInlineStyle: GenerateStyle<MenuToken, CSSObject> = (token) => {
const {
componentCls,
menuItemHeight,
itemHeight,
itemMarginInline,
padding,
menuArrowSize,
marginXS,
marginXXS,
itemMarginBlock,
} = token;
const paddingWithArrow = padding + menuArrowSize + marginXS;
@ -23,20 +23,20 @@ const getVerticalInlineStyle: GenerateStyle<MenuToken, CSSObject> = (token) => {
},
[`${componentCls}-item, ${componentCls}-submenu-title`]: {
height: menuItemHeight,
lineHeight: `${menuItemHeight}px`,
height: itemHeight,
lineHeight: `${itemHeight}px`,
paddingInline: padding,
overflow: 'hidden',
textOverflow: 'ellipsis',
marginInline: itemMarginInline,
marginBlock: marginXXS,
marginBlock: itemMarginBlock,
width: `calc(100% - ${itemMarginInline * 2}px)`,
},
[`> ${componentCls}-item,
> ${componentCls}-submenu > ${componentCls}-submenu-title`]: {
height: menuItemHeight,
lineHeight: `${menuItemHeight}px`,
height: itemHeight,
lineHeight: `${itemHeight}px`,
},
[`${componentCls}-item-group-list ${componentCls}-submenu-title,
@ -50,7 +50,7 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
const {
componentCls,
iconCls,
menuItemHeight,
itemHeight,
colorTextLightSolid,
dropdownWidth,
controlHeightLG,
@ -62,11 +62,13 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
motionDurationSlow,
paddingXS,
boxShadowSecondary,
collapsedWidth,
collapsedIconSize,
} = token;
const inlineItemStyle: CSSObject = {
height: menuItemHeight,
lineHeight: `${menuItemHeight}px`,
height: itemHeight,
lineHeight: `${itemHeight}px`,
listStylePosition: 'inside',
listStyleType: 'disc',
};
@ -160,7 +162,7 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
// Inline Collapse Only
{
[`${componentCls}-inline-collapsed`]: {
width: menuItemHeight * 2,
width: collapsedWidth,
[`&${componentCls}-root`]: {
[`${componentCls}-item, ${componentCls}-submenu ${componentCls}-submenu-title`]: {
@ -188,8 +190,8 @@ const getVerticalStyle: GenerateStyle<MenuToken> = (token) => {
[`${componentCls}-item-icon, ${iconCls}`]: {
margin: 0,
fontSize: fontSizeLG,
lineHeight: `${menuItemHeight}px`,
fontSize: collapsedIconSize,
lineHeight: `${itemHeight}px`,
'+ span': {
display: 'inline-block',

1
components/message/__tests__/demo.test.ts

@ -2,4 +2,5 @@ import demoTest from '../../../tests/shared/demoTest';
demoTest('message', {
testRootProps: false,
nameCheckPathOnly: true,
});

1
components/notification/__tests__/demo.test.ts

@ -2,4 +2,5 @@ import demoTest from '../../../tests/shared/demoTest';
demoTest('notification', {
testRootProps: false,
nameCheckPathOnly: true,
});

8
components/notification/useNotification.tsx

@ -1,22 +1,23 @@
import * as React from 'react';
import classNames from 'classnames';
import { useNotification as useRcNotification } from 'rc-notification';
import type { NotificationAPI } from 'rc-notification/lib';
import * as React from 'react';
import warning from '../_util/warning';
import { ConfigContext } from '../config-provider';
import type { ComponentStyleConfig } from '../config-provider/context';
import { PureContent, getCloseIcon } from './PurePanel';
import type {
ArgsProps,
NotificationConfig,
NotificationInstance,
NotificationPlacement,
} from './interface';
import { getCloseIcon, PureContent } from './PurePanel';
import useStyle from './style';
import { getMotion, getPlacementStyle } from './util';
const DEFAULT_OFFSET = 24;
const DEFAULT_DURATION = 4.5;
const DEFAULT_PLACEMENT: NotificationPlacement = 'topRight';
// ==============================================================================
// == Holder ==
@ -125,7 +126,8 @@ export function useInternalNotification(
const realCloseIcon = getCloseIcon(noticePrefixCls, closeIcon);
return originOpen({
placement: 'topRight',
// use placement from props instead of hard-coding "topRight"
placement: notificationConfig?.placement ?? DEFAULT_PLACEMENT,
...restConfig,
content: (
<PureContent

6
components/popconfirm/PurePanel.tsx

@ -77,7 +77,11 @@ export const Overlay: React.FC<OverlayProps> = (props) => {
</Button>
)}
<ActionButton
buttonProps={{ size: 'small', ...convertLegacyProps(okType), ...okButtonProps }}
buttonProps={{
size: 'small',
...convertLegacyProps(okType),
...okButtonProps,
}}
actionFn={onConfirm}
close={close}
prefixCls={getPrefixCls('btn')}

18
components/qrcode/__tests__/__snapshots__/demo-extend.test.ts.snap → components/qr-code/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders components/qrcode/demo/Popover.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/Popover.tsx extend context correctly 1`] = `
Array [
<img
alt="icon"
@ -44,7 +44,7 @@ Array [
]
`;
exports[`renders components/qrcode/demo/base.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/base.tsx extend context correctly 1`] = `
<div
class="ant-space ant-space-vertical ant-space-align-center"
>
@ -77,7 +77,7 @@ exports[`renders components/qrcode/demo/base.tsx extend context correctly 1`] =
</div>
`;
exports[`renders components/qrcode/demo/customColor.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/customColor.tsx extend context correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
@ -113,7 +113,7 @@ exports[`renders components/qrcode/demo/customColor.tsx extend context correctly
</div>
`;
exports[`renders components/qrcode/demo/customSize.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/customSize.tsx extend context correctly 1`] = `
Array [
<div
class="ant-btn-group"
@ -205,7 +205,7 @@ Array [
]
`;
exports[`renders components/qrcode/demo/download.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/download.tsx extend context correctly 1`] = `
<div
id="myqrcode"
>
@ -230,7 +230,7 @@ exports[`renders components/qrcode/demo/download.tsx extend context correctly 1`
</div>
`;
exports[`renders components/qrcode/demo/errorlevel.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/errorlevel.tsx extend context correctly 1`] = `
Array [
<div
class="ant-qrcode"
@ -310,7 +310,7 @@ Array [
]
`;
exports[`renders components/qrcode/demo/icon.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/icon.tsx extend context correctly 1`] = `
<div
class="ant-qrcode"
style="width: 160px; height: 160px; background-color: transparent;"
@ -327,7 +327,7 @@ exports[`renders components/qrcode/demo/icon.tsx extend context correctly 1`] =
</div>
`;
exports[`renders components/qrcode/demo/status.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/status.tsx extend context correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center"
style="flex-wrap: wrap; margin-bottom: -8px;"
@ -431,7 +431,7 @@ exports[`renders components/qrcode/demo/status.tsx extend context correctly 1`]
</div>
`;
exports[`renders components/qrcode/demo/type.tsx extend context correctly 1`] = `
exports[`renders components/qr-code/demo/type.tsx extend context correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>

18
components/qrcode/__tests__/__snapshots__/demo.test.ts.snap → components/qr-code/__tests__/__snapshots__/demo.test.ts.snap

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders components/qrcode/demo/Popover.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/Popover.tsx correctly 1`] = `
<img
alt="icon"
height="100"
@ -9,7 +9,7 @@ exports[`renders components/qrcode/demo/Popover.tsx correctly 1`] = `
/>
`;
exports[`renders components/qrcode/demo/base.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/base.tsx correctly 1`] = `
<div
class="ant-space ant-space-vertical ant-space-align-center"
>
@ -42,7 +42,7 @@ exports[`renders components/qrcode/demo/base.tsx correctly 1`] = `
</div>
`;
exports[`renders components/qrcode/demo/customColor.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/customColor.tsx correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
@ -78,7 +78,7 @@ exports[`renders components/qrcode/demo/customColor.tsx correctly 1`] = `
</div>
`;
exports[`renders components/qrcode/demo/customSize.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/customSize.tsx correctly 1`] = `
Array [
<div
class="ant-btn-group"
@ -170,7 +170,7 @@ Array [
]
`;
exports[`renders components/qrcode/demo/download.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/download.tsx correctly 1`] = `
<div
id="myqrcode"
>
@ -195,7 +195,7 @@ exports[`renders components/qrcode/demo/download.tsx correctly 1`] = `
</div>
`;
exports[`renders components/qrcode/demo/errorlevel.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/errorlevel.tsx correctly 1`] = `
Array [
<div
class="ant-qrcode"
@ -275,7 +275,7 @@ Array [
]
`;
exports[`renders components/qrcode/demo/icon.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/icon.tsx correctly 1`] = `
<div
class="ant-qrcode"
style="width:160px;height:160px;background-color:transparent"
@ -292,7 +292,7 @@ exports[`renders components/qrcode/demo/icon.tsx correctly 1`] = `
</div>
`;
exports[`renders components/qrcode/demo/status.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/status.tsx correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center"
style="flex-wrap:wrap;margin-bottom:-8px"
@ -396,7 +396,7 @@ exports[`renders components/qrcode/demo/status.tsx correctly 1`] = `
</div>
`;
exports[`renders components/qrcode/demo/type.tsx correctly 1`] = `
exports[`renders components/qr-code/demo/type.tsx correctly 1`] = `
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>

0
components/qrcode/__tests__/__snapshots__/index.test.tsx.snap → components/qr-code/__tests__/__snapshots__/index.test.tsx.snap

2
components/qrcode/__tests__/demo-extend.test.ts → components/qr-code/__tests__/demo-extend.test.ts

@ -1,3 +1,3 @@
import { extendTest } from '../../../tests/shared/demoTest';
extendTest('qrcode');
extendTest('qr-code');

2
components/qrcode/__tests__/demo.test.ts → components/qr-code/__tests__/demo.test.ts

@ -1,3 +1,3 @@
import demoTest from '../../../tests/shared/demoTest';
demoTest('qrcode');
demoTest('qr-code');

2
components/qrcode/__tests__/image.test.ts → components/qr-code/__tests__/image.test.ts

@ -1,5 +1,5 @@
import { imageDemoTest } from '../../../tests/shared/imageTest';
describe('QRCode image', () => {
imageDemoTest('qrcode');
imageDemoTest('qr-code');
});

0
components/qrcode/__tests__/index.test.tsx → components/qr-code/__tests__/index.test.tsx

0
components/qrcode/demo/Popover.md → components/qr-code/demo/Popover.md

0
components/qrcode/demo/Popover.tsx → components/qr-code/demo/Popover.tsx

0
components/qrcode/demo/base.md → components/qr-code/demo/base.md

0
components/qrcode/demo/base.tsx → components/qr-code/demo/base.tsx

0
components/qrcode/demo/customColor.md → components/qr-code/demo/customColor.md

0
components/qrcode/demo/customColor.tsx → components/qr-code/demo/customColor.tsx

0
components/qrcode/demo/customSize.md → components/qr-code/demo/customSize.md

0
components/qrcode/demo/customSize.tsx → components/qr-code/demo/customSize.tsx

0
components/qrcode/demo/download.md → components/qr-code/demo/download.md

0
components/qrcode/demo/download.tsx → components/qr-code/demo/download.tsx

0
components/qrcode/demo/errorlevel.md → components/qr-code/demo/errorlevel.md

0
components/qrcode/demo/errorlevel.tsx → components/qr-code/demo/errorlevel.tsx

0
components/qrcode/demo/icon.md → components/qr-code/demo/icon.md

0
components/qrcode/demo/icon.tsx → components/qr-code/demo/icon.tsx

0
components/qrcode/demo/status.md → components/qr-code/demo/status.md

0
components/qrcode/demo/status.tsx → components/qr-code/demo/status.tsx

0
components/qrcode/demo/type.md → components/qr-code/demo/type.md

0
components/qrcode/demo/type.tsx → components/qr-code/demo/type.tsx

0
components/qrcode/index.en-US.md → components/qr-code/index.en-US.md

0
components/qrcode/index.tsx → components/qr-code/index.tsx

0
components/qrcode/index.zh-CN.md → components/qr-code/index.zh-CN.md

37
components/qr-code/interface.ts

@ -0,0 +1,37 @@
import type { CSSProperties } from 'react';
interface ImageSettings {
src: string;
height: number;
width: number;
excavate: boolean;
x?: number;
y?: number;
}
export interface QRProps {
value: string;
type?: 'canvas' | 'svg';
size?: number;
color?: string;
style?: CSSProperties;
includeMargin?: boolean;
imageSettings?: ImageSettings;
bgColor?: string;
}
export type QRPropsCanvas = QRProps & React.CanvasHTMLAttributes<HTMLCanvasElement>;
export type QRPropsSvg = QRProps & React.SVGAttributes<SVGSVGElement>;
export interface QRCodeProps extends QRProps {
className?: string;
rootClassName?: string;
prefixCls?: string;
icon?: string;
iconSize?: number;
bordered?: boolean;
errorLevel?: 'L' | 'M' | 'Q' | 'H';
status?: 'active' | 'expired' | 'loading';
onRefresh?: () => void;
}

65
components/qr-code/style/index.ts

@ -0,0 +1,65 @@
import { resetComponent } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {}
interface QRCodeToken extends FullToken<'QRCode'> {
QRCodeExpiredTextColor: string;
QRCodeMaskBackgroundColor: string;
}
const genQRCodeStyle: GenerateStyle<QRCodeToken> = (token) => {
const { componentCls } = token;
return {
[componentCls]: {
...resetComponent(token),
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: token.paddingSM,
backgroundColor: token.colorWhite,
borderRadius: token.borderRadiusLG,
border: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
position: 'relative',
width: '100%',
height: '100%',
overflow: 'hidden',
[`& > ${componentCls}-mask`]: {
position: 'absolute',
insetBlockStart: 0,
insetInlineStart: 0,
zIndex: 10,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
color: token.colorText,
lineHeight: token.lineHeight,
background: token.QRCodeMaskBackgroundColor,
textAlign: 'center',
[`& > ${componentCls}-expired`]: {
color: token.QRCodeExpiredTextColor,
},
},
'&-icon': {
marginBlockEnd: token.marginXS,
fontSize: token.controlHeight,
},
},
[`${componentCls}-borderless`]: {
borderColor: 'transparent',
},
};
};
export default genComponentStyleHook<'QRCode'>('QRCode', (token) =>
genQRCodeStyle(
mergeToken<QRCodeToken>(token, {
QRCodeExpiredTextColor: 'rgba(0, 0, 0, 0.88)',
QRCodeMaskBackgroundColor: 'rgba(255, 255, 255, 0.96)',
}),
),
);

5
components/qrcode/index.ts

@ -0,0 +1,5 @@
// Legacy path. Please use `qr-code` instead.
// Keep file here in case developer import directly from the old path.
import QRCode from '../qr-code';
export default QRCode;

40
components/qrcode/interface.ts

@ -1,37 +1,3 @@
import type { CSSProperties } from 'react';
interface ImageSettings {
src: string;
height: number;
width: number;
excavate: boolean;
x?: number;
y?: number;
}
export interface QRProps {
value: string;
type?: 'canvas' | 'svg';
size?: number;
color?: string;
style?: CSSProperties;
includeMargin?: boolean;
imageSettings?: ImageSettings;
bgColor?: string;
}
export type QRPropsCanvas = QRProps & React.CanvasHTMLAttributes<HTMLCanvasElement>;
export type QRPropsSvg = QRProps & React.SVGAttributes<SVGSVGElement>;
export interface QRCodeProps extends QRProps {
className?: string;
rootClassName?: string;
prefixCls?: string;
icon?: string;
iconSize?: number;
bordered?: boolean;
errorLevel?: 'L' | 'M' | 'Q' | 'H';
status?: 'active' | 'expired' | 'loading';
onRefresh?: () => void;
}
// Legacy path. Please use `qr-code` instead.
// Keep file here in case developer import directly from the old path.
export * from '../qr-code/interface';

68
components/qrcode/style/index.ts

@ -1,65 +1,3 @@
import { resetComponent } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {}
interface QRCodeToken extends FullToken<'QRCode'> {
QRCodeExpiredTextColor: string;
QRCodeMaskBackgroundColor: string;
}
const genQRCodeStyle: GenerateStyle<QRCodeToken> = (token) => {
const { componentCls } = token;
return {
[componentCls]: {
...resetComponent(token),
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: token.paddingSM,
backgroundColor: token.colorWhite,
borderRadius: token.borderRadiusLG,
border: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
position: 'relative',
width: '100%',
height: '100%',
overflow: 'hidden',
[`& > ${componentCls}-mask`]: {
position: 'absolute',
insetBlockStart: 0,
insetInlineStart: 0,
zIndex: 10,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
color: token.colorText,
lineHeight: token.lineHeight,
background: token.QRCodeMaskBackgroundColor,
textAlign: 'center',
[`& > ${componentCls}-expired`]: {
color: token.QRCodeExpiredTextColor,
},
},
'&-icon': {
marginBlockEnd: token.marginXS,
fontSize: token.controlHeight,
},
},
[`${componentCls}-borderless`]: {
borderColor: 'transparent',
},
};
};
export default genComponentStyleHook<'QRCode'>('QRCode', (token) =>
genQRCodeStyle(
mergeToken<QRCodeToken>(token, {
QRCodeExpiredTextColor: 'rgba(0, 0, 0, 0.88)',
QRCodeMaskBackgroundColor: 'rgba(255, 255, 255, 0.96)',
}),
),
);
// Legacy path. Please use `qr-code` instead.
// Keep file here in case developer import directly from the old path.
export * from '../../qr-code/style';

0
components/radio/context.tsx → components/radio/context.ts

0
components/radio/index.tsx → components/radio/index.ts

0
components/radio/interface.tsx → components/radio/interface.ts

9
components/radio/radioButton.tsx

@ -1,4 +1,5 @@
import * as React from 'react';
import type { CheckboxRef } from '../checkbox';
import type { AbstractCheckboxProps } from '../checkbox/Checkbox';
import { ConfigContext } from '../config-provider';
import { RadioOptionTypeContextProvider } from './context';
@ -7,17 +8,17 @@ import Radio from './radio';
export type RadioButtonProps = AbstractCheckboxProps<RadioChangeEvent>;
const RadioButton = (props: RadioButtonProps, ref: React.Ref<any>) => {
const RadioButton: React.ForwardRefRenderFunction<CheckboxRef, RadioButtonProps> = (props, ref) => {
const { getPrefixCls } = React.useContext(ConfigContext);
const { prefixCls: customizePrefixCls, ...radioProps } = props;
const prefixCls = getPrefixCls('radio', customizePrefixCls);
return (
<RadioOptionTypeContextProvider value="button">
<Radio prefixCls={prefixCls} {...radioProps} type="radio" ref={ref} />
<RadioOptionTypeContextProvider value='button'>
<Radio prefixCls={prefixCls} {...radioProps} type='radio' ref={ref} />
</RadioOptionTypeContextProvider>
);
};
export default React.forwardRef(RadioButton);
export default React.forwardRef<CheckboxRef, RadioButtonProps>(RadioButton);

5
components/select/index.tsx

@ -285,6 +285,7 @@ const Select = React.forwardRef(InternalSelect) as unknown as (<
ref?: React.Ref<BaseSelectRef>;
},
) => React.ReactElement) & {
displayName?: string;
SECRET_COMBOBOX_MODE_DO_NOT_USE: string;
Option: typeof Option;
OptGroup: typeof OptGroup;
@ -300,4 +301,8 @@ Select.Option = Option;
Select.OptGroup = OptGroup;
Select._InternalPanelDoNotUseOrYouWillBeFired = PurePanel;
if (process.env.NODE_ENV !== 'production') {
Select.displayName = 'Select';
}
export default Select;

6
components/slider/__tests__/index.test.tsx

@ -6,7 +6,7 @@ import rtlTest from '../../../tests/shared/rtlTest';
import { act, fireEvent, render } from '../../../tests/utils';
import { resetWarned } from '../../_util/warning';
import ConfigProvider from '../../config-provider';
import type { TooltipProps } from '../../tooltip';
import type { TooltipProps, TooltipRef } from '../../tooltip';
import SliderTooltip from '../SliderTooltip';
function tooltipProps(): TooltipProps {
@ -14,10 +14,10 @@ function tooltipProps(): TooltipProps {
}
jest.mock('../../tooltip', () => {
const ReactReal = jest.requireActual('react');
const ReactReal: typeof React = jest.requireActual('react');
const Tooltip = jest.requireActual('../../tooltip');
const TooltipComponent = Tooltip.default;
return ReactReal.forwardRef((props: TooltipProps, ref: any) => {
return ReactReal.forwardRef<TooltipRef, TooltipProps>((props, ref) => {
(global as any).tooltipProps = props;
return <TooltipComponent {...props} ref={ref} />;
});

1
components/slider/index.zh-CN.md

@ -35,7 +35,6 @@ demo:
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| autoFocus | 自动获取焦点 | boolean | false | |
| allowClear | 支持清除, 单选模式有效 | boolean | false | |
| defaultValue | 设置初始取值。当 `range` 为 false 时,使用 number,否则用 \[number, number] | number \| \[number, number] | 0 \| \[0, 0] | |
| disabled | 值为 true 时,滑块为禁用状态 | boolean | false | |
| keyboard | 支持使用键盘操作 handler | boolean | true | 5.2.0+ |

13
components/steps/style/index.tsx

@ -1,6 +1,6 @@
import type { CSSObject } from '@ant-design/cssinjs';
import type { CSSProperties } from 'react';
import { resetComponent } from '../../style';
import { genFocusOutline, resetComponent } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import genStepsCustomIconStyle from './custom-icon';
@ -171,6 +171,7 @@ const genStepsItemStatusStyle = (status: StepItemStatusEnum, token: StepsToken):
const genStepsItemStyle: GenerateStyle<StepsToken, CSSObject> = (token) => {
const { componentCls, motionDurationSlow } = token;
const stepsItemCls = `${componentCls}-item`; // .ant-steps-item
const stepItemIconCls = `${stepsItemCls}-icon`;
return {
[stepsItemCls]: {
@ -189,12 +190,18 @@ const genStepsItemStyle: GenerateStyle<StepsToken, CSSObject> = (token) => {
},
[`${stepsItemCls}-container`]: {
outline: 'none',
[`&:focus-visible`]: {
[stepItemIconCls]: {
...genFocusOutline(token),
},
},
},
[`${stepsItemCls}-icon, ${stepsItemCls}-content`]: {
[`${stepItemIconCls}, ${stepsItemCls}-content`]: {
display: 'inline-block',
verticalAlign: 'top',
},
[`${stepsItemCls}-icon`]: {
[stepItemIconCls]: {
width: token.iconSize,
height: token.iconSize,
marginTop: 0,

5
components/table/Table.tsx

@ -23,6 +23,7 @@ const Table = <RecordType extends AnyObject = AnyObject>(
};
const ForwardTable = React.forwardRef(Table) as unknown as RefTable & {
displayName?: string;
SELECTION_COLUMN: typeof SELECTION_COLUMN;
EXPAND_COLUMN: typeof EXPAND_COLUMN;
SELECTION_ALL: typeof SELECTION_ALL;
@ -42,4 +43,8 @@ ForwardTable.Column = Column;
ForwardTable.ColumnGroup = ColumnGroup;
ForwardTable.Summary = Summary;
if (process.env.NODE_ENV !== 'production') {
ForwardTable.displayName = 'Table';
}
export default ForwardTable;

8
components/theme/interface/alias.ts

@ -61,7 +61,7 @@ export interface AliasToken extends MapToken {
colorBorderBg: string;
/**
* @nameZH 线
* @nameEN Separator color
* @nameEN Separator Color
* @desc 线 colorBorderSecondary
* @descEN Used as the color of separator, this color is the same as colorBorderSecondary but with transparency.
*/
@ -70,21 +70,21 @@ export interface AliasToken extends MapToken {
// Text
/**
* @nameZH
* @nameEN Placeholder text color
* @nameEN Placeholder Text Color
* @desc
* @descEN Control the color of placeholder text.
*/
colorTextPlaceholder: string;
/**
* @nameZH
* @nameEN Disabled text color
* @nameEN Disabled Text Color
* @desc
* @descEN Control the color of text in disabled state.
*/
colorTextDisabled: string;
/**
* @nameZH
* @nameEN Heading font color
* @nameEN Heading Text Color
* @desc
* @descEN Control the font color of heading.
*/

2
components/theme/interface/components.ts

@ -33,7 +33,7 @@ import type { ComponentToken as PaginationComponentToken } from '../../paginatio
import type { ComponentToken as PopconfirmComponentToken } from '../../popconfirm/style';
import type { ComponentToken as PopoverComponentToken } from '../../popover/style';
import type { ComponentToken as ProgressComponentToken } from '../../progress/style';
import type { ComponentToken as QRCodeComponentToken } from '../../qrcode/style';
import type { ComponentToken as QRCodeComponentToken } from '../../qr-code/style';
import type { ComponentToken as RadioComponentToken } from '../../radio/style';
import type { ComponentToken as RateComponentToken } from '../../rate/style';
import type { ComponentToken as ResultComponentToken } from '../../result/style';

3
components/theme/interface/maps/colors.ts

@ -13,6 +13,7 @@ export interface ColorNeutralMapToken {
/**
* @nameZH
* @nameEN Text Color
* @desc W3C标准使
* @descEN Default text color which comply with W3C standards, and this color is also the darkest neutral color.
*/
@ -20,6 +21,7 @@ export interface ColorNeutralMapToken {
/**
* @nameZH
* @nameEN Secondary Text Color
* @desc Label Menu
* @descEN The second level of text color is generally used in scenarios where text color is not emphasized, such as label text, menu text selection state, etc.
*/
@ -91,6 +93,7 @@ export interface ColorNeutralMapToken {
/**
* @nameZH
* @nameEN Layout Background Color
* @desc B1 使 token
* @descEN This color is used for the background color of the overall layout of the page. This token will only be used when it is necessary to be at the B1 visual level in the page. Other usages are wrong.
*/

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save