chore: auto merge branches (#43662)

chore: merge master into feature
This commit is contained in:
github-actions[bot] 2023-07-19 15:01:49 +00:00 committed by GitHub
commit b90aac7d28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
128 changed files with 3510 additions and 781 deletions

View File

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

View File

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

View File

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

View File

@ -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>
);
}

View File

@ -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>
);
}

View File

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

View File

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

View File

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

View File

@ -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 ## 5.7.0
`2023-07-11` `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) - 🆕 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) - 🆕 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) - 🆕 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) - 🆕 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) - 🛠 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. - 🛠 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) - 🐞 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) - 🐞 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) - 🐞 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 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 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 `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 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 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) - 🐞 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) - 💄 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) - 💄 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 - 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 - TypeScript
- 🤖 Added `RawPurePanelProps` interface description for Popover.[#43453](https://github.com/ant-design/ant-design/pull/43453) [@thinkasany](https://github.com/thinkasany) - 🤖 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 `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) - 🤖 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 `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) - 🤖 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) - 🤖 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. - 🤖 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) - [#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) - [#43357](https://github.com/ant-design/ant-design/pull/43357) [@thinkasany](https://github.com/thinkasany)

View File

@ -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 ## 5.7.0
`2023-07-11` `2023-07-11`

View File

@ -48,3 +48,39 @@ exports[`renders components/app/demo/basic.tsx extend context correctly 1`] = `
</div> </div>
</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>
`;

View File

@ -48,3 +48,39 @@ exports[`renders components/app/demo/basic.tsx correctly 1`] = `
</div> </div>
</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>
`;

View File

@ -1,4 +1,5 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import type { NotificationConfig } from 'antd/es/notification/interface';
import App from '..'; import App from '..';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest'; import rtlTest from '../../../tests/shared/rtlTest';
@ -123,6 +124,46 @@ describe('App', () => {
expect(config?.notification).toStrictEqual({ maxCount: 30, bottom: 41 }); 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', () => { it('support className', () => {
const { container } = render( const { container } = render(
<App className="test-class"> <App className="test-class">

View File

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

View File

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

View File

@ -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>
);

View File

@ -18,7 +18,8 @@ Application wrapper for some global usages.
## Examples ## Examples
<!-- prettier-ignore --> <!-- 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 ## How to use

View File

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

View File

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

View File

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

View File

@ -343,4 +343,15 @@ describe('Button', () => {
); );
expect(window.getComputedStyle(container.querySelector('#link')!).pointerEvents).toBe('none'); 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();
});
}); });

View File

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

View File

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

View File

@ -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 ===================== // ===================== Hover =====================
{ {
// Wrapper // 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 ==================== // ==================== Disable ====================
{ {
// Wrapper // Wrapper

View File

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

View File

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

View File

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

View File

@ -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>; return RangePicker as unknown as PickerComponentClass<DateRangePickerProps>;
} }

View File

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

View File

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

View File

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

View File

@ -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>> }, 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 }; export { List, useForm, useWatch, type FormInstance };

View File

@ -592,12 +592,18 @@ React can not get correct interaction of controlled component with async value u
} }
</style> </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) 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. `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? ### 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. 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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders components/menu/demo/component-token.tsx extend context correctly 1`] = ` exports[`renders components/menu/demo/component-token.tsx extend context correctly 1`] = `
Array [ <div
class="ant-space ant-space-vertical"
>
<div
class="ant-space-item"
style="margin-bottom: 8px;"
>
<ul <ul
class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light" class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light"
data-menu-list="true" data-menu-list="true"
@ -232,7 +238,7 @@ Array [
/> />
</div> </div>
</li> </li>
</ul>, </ul>
<div <div
aria-hidden="true" aria-hidden="true"
style="display: none;" style="display: none;"
@ -356,8 +362,873 @@ Array [
/> />
</div> </div>
</div> </div>
</div>, </div>
] </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"
>
<li
class="ant-menu-item ant-menu-item-selected"
data-menu-id="rc-menu-uuid-test-1"
role="menuitem"
style="padding-left: 24px;"
tabindex="-1"
>
<span
aria-label="pie-chart"
class="anticon anticon-pie-chart ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="pie-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
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"
>
Option 1
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item"
data-menu-id="rc-menu-uuid-test-2"
role="menuitem"
style="padding-left: 24px;"
tabindex="-1"
>
<span
aria-label="desktop"
class="anticon anticon-desktop ant-menu-item-icon"
role="img"
>
<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>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item"
data-menu-id="rc-menu-uuid-test-3"
role="menuitem"
style="padding-left: 24px;"
tabindex="-1"
>
<span
aria-label="container"
class="anticon anticon-container ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="container"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
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>
<span
class="ant-menu-title-content"
>
Option 3
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
role="none"
>
<div
aria-controls="rc-menu-uuid-test-sub1-popup"
aria-expanded="true"
aria-haspopup="true"
class="ant-menu-submenu-title"
data-menu-id="rc-menu-uuid-test-sub1"
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>
<div
class="ant-menu-submenu ant-menu-submenu-popup ant-menu ant-menu-dark"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
class="ant-menu ant-menu-sub ant-menu-inline"
data-menu-list="true"
id="rc-menu-uuid-test-sub1-popup"
role="menu"
>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-5"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 5
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-6"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 6
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-7"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 7
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-8"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 8
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</ul>
</div>
<ul
class="ant-menu ant-menu-sub ant-menu-inline"
data-menu-list="true"
id="rc-menu-uuid-test-sub1-popup"
role="menu"
>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-5"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 5
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-6"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 6
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-7"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 7
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-8"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 8
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</ul>
</li>
<li
class="ant-menu-submenu ant-menu-submenu-inline"
role="none"
>
<div
aria-controls="rc-menu-uuid-test-sub2-popup"
aria-expanded="false"
aria-haspopup="true"
class="ant-menu-submenu-title"
data-menu-id="rc-menu-uuid-test-sub2"
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>
<div
class="ant-menu-submenu ant-menu-submenu-popup ant-menu ant-menu-dark"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
class="ant-menu ant-menu-sub ant-menu-inline"
data-menu-list="true"
id="rc-menu-uuid-test-sub2-popup"
role="menu"
>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-9"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 9
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-10"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 10
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-submenu ant-menu-submenu-inline"
role="none"
>
<div
aria-controls="rc-menu-uuid-test-sub3-popup"
aria-expanded="false"
aria-haspopup="true"
class="ant-menu-submenu-title"
data-menu-id="rc-menu-uuid-test-sub3"
role="menuitem"
style="padding-left: 48px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Submenu
</span>
<i
class="ant-menu-submenu-arrow"
/>
</div>
<div
class="ant-menu-submenu ant-menu-submenu-popup ant-menu ant-menu-dark"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
class="ant-menu ant-menu-sub ant-menu-inline"
data-menu-list="true"
id="rc-menu-uuid-test-sub3-popup"
role="menu"
>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-11"
role="menuitem"
style="padding-left: 72px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 11
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-menu-item ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-12"
role="menuitem"
style="padding-left: 72px;"
tabindex="-1"
>
<span
class="ant-menu-title-content"
>
Option 12
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
<div
aria-hidden="true"
style="display: none;"
>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</div>
</div>
</div>
`; `;
exports[`renders components/menu/demo/horizontal.tsx extend context correctly 1`] = ` exports[`renders components/menu/demo/horizontal.tsx extend context correctly 1`] = `

View File

@ -1,7 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders components/menu/demo/component-token.tsx correctly 1`] = ` exports[`renders components/menu/demo/component-token.tsx correctly 1`] = `
Array [ <div
class="ant-space ant-space-vertical"
>
<div
class="ant-space-item"
style="margin-bottom:8px"
>
<ul <ul
class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light" class="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light"
data-menu-list="true" data-menu-list="true"
@ -166,12 +172,258 @@ Array [
/> />
</div> </div>
</li> </li>
</ul>, </ul>
<div <div
aria-hidden="true" aria-hidden="true"
style="display:none" 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"
>
<li
class="ant-menu-item ant-menu-item-selected"
role="menuitem"
style="padding-left:24px"
tabindex="-1"
>
<span
aria-label="pie-chart"
class="anticon anticon-pie-chart ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="pie-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
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"
>
Option 1
</span>
</li>
<li
class="ant-menu-item"
role="menuitem"
style="padding-left:24px"
tabindex="-1"
>
<span
aria-label="desktop"
class="anticon anticon-desktop ant-menu-item-icon"
role="img"
>
<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="container"
class="anticon anticon-container ant-menu-item-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="container"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
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>
<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`] = ` exports[`renders components/menu/demo/horizontal.tsx correctly 1`] = `

View File

@ -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 type { MenuProps } from 'antd';
import { ConfigProvider, Menu } from 'antd'; import { ConfigProvider, Menu, Space } from 'antd';
import React, { useState } from 'react'; import React, { useState } from 'react';
type MenuItem = Required<MenuProps>['items'][number];
const items: MenuProps['items'] = [ const items: MenuProps['items'] = [
{ {
label: 'Navigation One', 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 App: React.FC = () => {
const [current, setCurrent] = useState('mail'); const [current, setCurrent] = useState('mail');
@ -69,6 +114,7 @@ const App: React.FC = () => {
}; };
return ( return (
<Space direction="vertical">
<ConfigProvider <ConfigProvider
theme={{ theme={{
components: { components: {
@ -81,6 +127,31 @@ const App: React.FC = () => {
> >
<Menu onClick={onClick} selectedKeys={[current]} mode="horizontal" items={items} /> <Menu onClick={onClick} selectedKeys={[current]} mode="horizontal" items={items} />
</ConfigProvider> </ConfigProvider>
<ConfigProvider
theme={{
components: {
Menu: {
darkItemColor: '#91daff',
darkItemBg: '#d48806',
darkSubMenuItemBg: '#faad14',
darkItemSelectedColor: '#ffccc7',
darkItemSelectedBg: '#52c41a',
},
},
}}
>
<Menu
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
mode='inline'
theme='dark'
items={items2}
style={{
width: 256,
}}
/>
</ConfigProvider>
</Space>
); );
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

@ -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)',
}),
),
);

View File

@ -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;

View File

@ -1,37 +1,3 @@
import type { CSSProperties } from 'react'; // Legacy path. Please use `qr-code` instead.
// Keep file here in case developer import directly from the old path.
interface ImageSettings { export * from '../qr-code/interface';
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;
}

View File

@ -1,65 +1,3 @@
import { resetComponent } from '../../style'; // Legacy path. Please use `qr-code` instead.
import type { FullToken, GenerateStyle } from '../../theme/internal'; // Keep file here in case developer import directly from the old path.
import { genComponentStyleHook, mergeToken } from '../../theme/internal'; export * from '../../qr-code/style';
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)',
}),
),
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,7 @@ import type { ComponentToken as PaginationComponentToken } from '../../paginatio
import type { ComponentToken as PopconfirmComponentToken } from '../../popconfirm/style'; import type { ComponentToken as PopconfirmComponentToken } from '../../popconfirm/style';
import type { ComponentToken as PopoverComponentToken } from '../../popover/style'; import type { ComponentToken as PopoverComponentToken } from '../../popover/style';
import type { ComponentToken as ProgressComponentToken } from '../../progress/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 RadioComponentToken } from '../../radio/style';
import type { ComponentToken as RateComponentToken } from '../../rate/style'; import type { ComponentToken as RateComponentToken } from '../../rate/style';
import type { ComponentToken as ResultComponentToken } from '../../result/style'; import type { ComponentToken as ResultComponentToken } from '../../result/style';

View File

@ -13,6 +13,7 @@ export interface ColorNeutralMapToken {
/** /**
* @nameZH * @nameZH
* @nameEN Text Color
* @desc W3C标准使 * @desc W3C标准使
* @descEN Default text color which comply with W3C standards, and this color is also the darkest neutral color. * @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 * @nameZH
* @nameEN Secondary Text Color
* @desc Label Menu * @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. * @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 * @nameZH
* @nameEN Layout Background Color
* @desc B1 使 token * @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. * @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 have changed in this diff Show More