diff --git a/.dumi/pages/index/components/Theme/ColorPicker.tsx b/.dumi/pages/index/components/Theme/ColorPicker.tsx index c9c6655b85..bb89b5b884 100644 --- a/.dumi/pages/index/components/Theme/ColorPicker.tsx +++ b/.dumi/pages/index/components/Theme/ColorPicker.tsx @@ -19,7 +19,7 @@ const useStyle = () => { transition: all ${token.motionDurationFast}; display: inline-block; - & > input[type="radio"] { + & > input[type='radio'] { width: 0; height: 0; opacity: 0; @@ -138,7 +138,11 @@ export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps) if (picker) { colorNode = ( - + {colorNode} ); diff --git a/.dumi/pages/index/components/Theme/index.tsx b/.dumi/pages/index/components/Theme/index.tsx index 1fdd88bafb..406d300b22 100644 --- a/.dumi/pages/index/components/Theme/index.tsx +++ b/.dumi/pages/index/components/Theme/index.tsx @@ -377,8 +377,8 @@ export default function Theme() { }, Menu: isLight ? { - colorItemBg: 'transparent', - colorSubItemBg: 'transparent', + itemBg: 'transparent', + subMenuItemBg: 'transparent', colorActiveBarWidth: 0, } : { diff --git a/.dumi/theme/builtins/InstallDependencies/index.tsx b/.dumi/theme/builtins/InstallDependencies/index.tsx index 56a0ae043a..68cc0f90f4 100644 --- a/.dumi/theme/builtins/InstallDependencies/index.tsx +++ b/.dumi/theme/builtins/InstallDependencies/index.tsx @@ -1,3 +1,4 @@ +import type { TabsProps } from 'antd'; import { Tabs } from 'antd'; import SourceCode from 'dumi/theme-default/builtins/SourceCode'; import React from 'react'; @@ -11,46 +12,51 @@ interface InstallProps { pnpm?: string; } +const npmLabel = ( + + + npm + +); + +const pnpmLabel = ( + + + pnpm + +); + +const yarnLabel = ( + + + yarn + +); + const InstallDependencies: React.FC = (props) => { const { npm, yarn, pnpm } = props; - return ( - ( + () => + [ { key: 'npm', - children: {npm}, - label: ( -
- - npm -
- ), + children: npm ? {npm} : null, + label: npmLabel, }, { key: 'yarn', - children: {yarn}, - label: ( -
- - yarn -
- ), + children: yarn ? {yarn} : null, + label: yarnLabel, }, { key: 'pnpm', - children: {pnpm}, - label: ( -
- - pnpm -
- ), + children: pnpm ? {pnpm} : null, + label: pnpmLabel, }, - ]} - /> + ].filter((item) => item.children), + [npm, yarn, pnpm], ); + return ; }; export default InstallDependencies; diff --git a/.dumi/theme/builtins/InstallDependencies/npm.tsx b/.dumi/theme/builtins/InstallDependencies/npm.tsx index e8f9ce55ee..ffd6755688 100644 --- a/.dumi/theme/builtins/InstallDependencies/npm.tsx +++ b/.dumi/theme/builtins/InstallDependencies/npm.tsx @@ -1,17 +1,27 @@ import React from 'react'; -const NpmIcon: React.FC = () => ( - - - -); +interface IconProps { + className?: string; + style?: React.CSSProperties; +} + +const NpmIcon: React.FC = (props) => { + const { className, style } = props; + return ( + + + + ); +}; export default NpmIcon; diff --git a/.dumi/theme/builtins/InstallDependencies/pnpm.tsx b/.dumi/theme/builtins/InstallDependencies/pnpm.tsx index 62d1620937..1be5a1ce3a 100644 --- a/.dumi/theme/builtins/InstallDependencies/pnpm.tsx +++ b/.dumi/theme/builtins/InstallDependencies/pnpm.tsx @@ -1,19 +1,29 @@ import React from 'react'; -const PnpmIcon: React.FC = () => ( - -); +interface IconProps { + className?: string; + style?: React.CSSProperties; +} + +const PnpmIcon: React.FC = (props) => { + const { className, style } = props; + return ( + + ); +}; export default PnpmIcon; diff --git a/.dumi/theme/builtins/InstallDependencies/yarn.tsx b/.dumi/theme/builtins/InstallDependencies/yarn.tsx index 95eec5ea8d..c79ac4eee7 100644 --- a/.dumi/theme/builtins/InstallDependencies/yarn.tsx +++ b/.dumi/theme/builtins/InstallDependencies/yarn.tsx @@ -1,18 +1,28 @@ import React from 'react'; -const YarnIcon: React.FC = () => ( - -); +interface IconProps { + className?: string; + style?: React.CSSProperties; +} + +const YarnIcon: React.FC = (props) => { + const { className, style } = props; + return ( + + ); +}; export default YarnIcon; diff --git a/.dumi/theme/common/PrevAndNext.tsx b/.dumi/theme/common/PrevAndNext.tsx index 484e756b36..6ead4ea315 100644 --- a/.dumi/theme/common/PrevAndNext.tsx +++ b/.dumi/theme/common/PrevAndNext.tsx @@ -37,7 +37,10 @@ const useStyle = createStyles(({ token }) => { `, prevNav: css` text-align: start; - + display: flex; + justify-content: flex-start; + align-items: center; + .footer-nav-icon-after { display: none; } @@ -57,7 +60,10 @@ const useStyle = createStyles(({ token }) => { `, nextNav: css` text-align: end; - + display: flex; + justify-content: flex-end; + align-items: center; + .footer-nav-icon-before { display: none; } diff --git a/.dumi/theme/common/styles/BrowserMockup.tsx b/.dumi/theme/common/styles/BrowserMockup.tsx index 1313b7620a..f0c5266bc8 100644 --- a/.dumi/theme/common/styles/BrowserMockup.tsx +++ b/.dumi/theme/common/styles/BrowserMockup.tsx @@ -47,7 +47,7 @@ export default () => ( top: -1.6em; left: 5.5em; display: block; - width: ~'calc(100% - 6em)'; + width: calc(100% - 6em); height: 1.2em; background-color: white; border-radius: 2px; diff --git a/.dumi/theme/common/styles/Markdown.tsx b/.dumi/theme/common/styles/Markdown.tsx index 03cfb0e4ff..efe65e2f57 100644 --- a/.dumi/theme/common/styles/Markdown.tsx +++ b/.dumi/theme/common/styles/Markdown.tsx @@ -180,15 +180,25 @@ const GlobalStyle: React.FC = () => { line-height: 2; } } - + .pic-plus { + & > * { + display: inline-block !important; + vertical-align: middle; + } + span { + margin: 0 20px; + color: #aaa; + font-size: 30px; + } + } .antd-site-snippet { .ant-tabs-tab { .snippet-label { display: flex; align-items: center; justify-content: center; - span { - margin-inline-start: 8px; + svg { + margin-inline-end: 8px; } } } diff --git a/.dumi/theme/common/styles/Reset.tsx b/.dumi/theme/common/styles/Reset.tsx index 8b91989889..bb4dc5fa48 100644 --- a/.dumi/theme/common/styles/Reset.tsx +++ b/.dumi/theme/common/styles/Reset.tsx @@ -53,7 +53,7 @@ export default () => { font-family: ${token.fontFamily}; line-height: ${token.lineHeight}; background: ${token.colorBgContainer}; - transition: background 1s cubic-bezier(0.075, 0.82, 0.165, 1); + transition: background-color 1s cubic-bezier(0.075, 0.82, 0.165, 1); } `} /> diff --git a/.dumi/theme/common/styles/Responsive.tsx b/.dumi/theme/common/styles/Responsive.tsx index 2b99062a57..fdb84fcf35 100644 --- a/.dumi/theme/common/styles/Responsive.tsx +++ b/.dumi/theme/common/styles/Responsive.tsx @@ -87,7 +87,7 @@ export default () => { } .prev-next-nav { - width: ~'calc(100% - 32px)'; + width: calc(100% - 32px); margin-left: 16px; .ant-row-rtl & { diff --git a/.dumi/theme/slots/Content/ColumnCard.tsx b/.dumi/theme/slots/Content/ColumnCard.tsx new file mode 100644 index 0000000000..f907bd8136 --- /dev/null +++ b/.dumi/theme/slots/Content/ColumnCard.tsx @@ -0,0 +1,188 @@ +import { RightOutlined, YuqueOutlined, ZhihuOutlined } from '@ant-design/icons'; +import { css } from '@emotion/react'; +import { Button, Card, Divider } from 'antd'; +import React from 'react'; +import useLocale from '../../../hooks/useLocale'; +import useSiteToken from '../../../hooks/useSiteToken'; + +const ANTD_IMG_URL = + 'https://picx.zhimg.com/v2-3b2bca09c2771e7a82a81562e806be4d.jpg?source=d16d100b'; + +const useStyle = () => { + const { token } = useSiteToken(); + return { + card: css` + width: 100%; + margin: 40px 0; + transition: all 0.2s; + background-color: ${token.colorFillQuaternary}; + `, + bigTitle: css` + font-size: 16px; + color: #121212; + margin-bottom: 24px; + font-weight: 600; + `, + cardBody: css` + display: flex; + justify-content: space-between; + align-items: center; + `, + left: css` + display: flex; + justify-content: flex-start; + align-items: center; + img { + width: 200px; + margin-right: 24px; + overflow: hidden; + border-radius: 8px; + } + `, + title: css` + color: #444; + font-size: 16px; + font-weight: 600; + `, + subTitle: css` + display: flex; + justify-content: flex-start; + align-items: center; + color: #646464; + font-size: 14px; + font-weight: 400; + margin-top: 8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + .logo { + font-size: 24px; + &.zhihu-logo { + color: #056de8; + } + &.yuque-logo { + color: #00b96b; + } + } + .arrowIcon { + margin: 0 8px; + color: #8a8f8d; + font-size: 12px; + } + .zl-btn { + display: flex; + align-items: center; + justify-content: center; + padding: 0; + color: #646464; + } + `, + btn: css` + display: flex; + justify-content: center; + align-items: center; + `, + }; +}; + +const locales = { + cn: { + bigTitle: '文章被以下专栏收录:', + zhiHu: '一个 UI 设计体系', + yuQue: 'Ant Design 官方专栏', + buttonText: '我有想法,去参与讨论', + }, + en: { + bigTitle: 'Articles are included in the column:', + zhiHu: 'A UI design system', + yuQue: 'Ant Design official column', + buttonText: 'Go to discuss', + }, +}; + +interface Props { + zhihuLink?: string; + yuqueLink?: string; +} + +const ColumnCard: React.FC = ({ zhihuLink, yuqueLink }) => { + const [locale] = useLocale(locales); + const { card, bigTitle, cardBody, left, title, subTitle, btn } = useStyle(); + if (!zhihuLink && !yuqueLink) { + return null; + } + return ( + +

{locale.bigTitle}

+ {zhihuLink && ( +
+
+ antd +
+

Ant Design

+
+ + + +
+
+
+ +
+ )} + {yuqueLink && ( + <> + +
+
+ antd +
+

Ant Design

+
+ + + +
+
+
+ +
+ + )} +
+ ); +}; + +export default ColumnCard; diff --git a/.dumi/theme/slots/Content/index.tsx b/.dumi/theme/slots/Content/index.tsx index 90d6c6fe29..b593e5d7be 100644 --- a/.dumi/theme/slots/Content/index.tsx +++ b/.dumi/theme/slots/Content/index.tsx @@ -16,6 +16,7 @@ import type { DemoContextProps } from '../DemoContext'; import DemoContext from '../DemoContext'; import Footer from '../Footer'; import SiteContext from '../SiteContext'; +import ColumnCard from './ColumnCard'; const useStyle = () => { const { token } = useSiteToken(); @@ -272,6 +273,12 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => { ) : null} {!meta.frontmatter.__autoDescription && meta.frontmatter.description} {children} + {(meta.frontmatter?.zhihu_url || meta.frontmatter?.yuque_url) && ( + + )} {meta.frontmatter.filename && ( { .replace(/\/$/, ''); return; } - // Mirror url must have `/`, we add this for compatible const urlObj = new URL(currentUrl.replace(window.location.origin, url)); - urlObj.pathname = `${urlObj.pathname.replace(/\/$/, '')}/`; - window.location.href = urlObj.href; + if (urlObj.host.includes('antgroup')) { + window.location.href = `${urlObj.href.replace(/\/$/, '')}/`; + } + window.location.href = urlObj.href.replace(/\/$/, ''); }, []); const onLangChange = useCallback(() => { @@ -297,7 +298,7 @@ const Header: React.FC = () => { defaultValue={pkg.version} onChange={handleVersionChange} dropdownStyle={getDropdownStyle} - dropdownMatchSelectWidth={false} + popupMatchSelectWidth={false} getPopupContainer={(trigger) => trigger.parentNode} options={versionOptions} />, diff --git a/.dumi/theme/slots/Sidebar/index.tsx b/.dumi/theme/slots/Sidebar/index.tsx index 8d1c219dd7..3a6fb7c367 100644 --- a/.dumi/theme/slots/Sidebar/index.tsx +++ b/.dumi/theme/slots/Sidebar/index.tsx @@ -1,11 +1,11 @@ -import React, { useContext } from 'react'; -import { useSidebarData } from 'dumi'; +import { css } from '@emotion/react'; import { Col, ConfigProvider, Menu } from 'antd'; +import { useSidebarData } from 'dumi'; import MobileMenu from 'rc-drawer'; -import { css } from '@emotion/react'; -import SiteContext from '../SiteContext'; +import React, { useContext } from 'react'; import useMenu from '../../../hooks/useMenu'; import useSiteToken from '../../../hooks/useSiteToken'; +import SiteContext from '../SiteContext'; const useStyle = () => { const { token } = useSiteToken(); @@ -134,7 +134,7 @@ const Sidebar: React.FC = () => { } = useSiteToken(); const menuChild = ( - + ; /** @deprecated Please use `menu` instead */ @@ -123,6 +125,7 @@ const Breadcrumb = (props: BreadcrumbProps) => { onClick, className: itemClassName, separator: itemSeparator, + dropdownProps, } = item; const mergedPath = getPath(params, path); @@ -145,10 +148,6 @@ const Breadcrumb = (props: BreadcrumbProps) => { itemProps.overlay = overlay as any; } - if (itemClassName) { - itemProps.className = itemClassName; - } - let { href } = item; if (paths.length && mergedPath !== undefined) { href = `#/${paths.join('/')}`; @@ -162,6 +161,8 @@ const Breadcrumb = (props: BreadcrumbProps) => { data: true, aria: true, })} + className={itemClassName} + dropdownProps={dropdownProps} href={href} separator={isLastItem ? '' : separator} onClick={onClick} diff --git a/components/breadcrumb/__tests__/Breadcrumb.test.tsx b/components/breadcrumb/__tests__/Breadcrumb.test.tsx index bf07b881b9..eb00b0f6ed 100644 --- a/components/breadcrumb/__tests__/Breadcrumb.test.tsx +++ b/components/breadcrumb/__tests__/Breadcrumb.test.tsx @@ -362,4 +362,26 @@ describe('Breadcrumb', () => { it('Breadcrumb.Item menu type', () => { expect().toBeTruthy(); }); + + it('dropdownProps in items should be worked', () => { + render( + , + ); + expect(document.querySelector('.ant-dropdown')).toBeTruthy(); + }); }); diff --git a/components/breadcrumb/demo/overlay.tsx b/components/breadcrumb/demo/overlay.tsx index 63bc4fb11d..5e53c812fe 100644 --- a/components/breadcrumb/demo/overlay.tsx +++ b/components/breadcrumb/demo/overlay.tsx @@ -1,5 +1,5 @@ -import React from 'react'; import { Breadcrumb } from 'antd'; +import React from 'react'; const menuItems = [ { diff --git a/components/breadcrumb/useItemRender.tsx b/components/breadcrumb/useItemRender.tsx index 11d10f3b29..0a43958c9b 100644 --- a/components/breadcrumb/useItemRender.tsx +++ b/components/breadcrumb/useItemRender.tsx @@ -11,7 +11,7 @@ type ItemRender = NonNullable; type InternalItemRenderParams = AddParameters; function getBreadcrumbName(route: InternalRouteType, params: any) { - if (route.title === undefined) { + if (route.title === undefined || route.title === null) { return null; } const paramsKeys = Object.keys(params).join('|'); diff --git a/components/button/button.tsx b/components/button/button.tsx index cdcc240687..64427df4ff 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -55,7 +55,7 @@ export interface BaseButtonProps { export type AnchorButtonProps = { href: string; - target?: string; + target?: React.HTMLAttributeAnchorTarget; onClick?: React.MouseEventHandler; } & BaseButtonProps & Omit, 'type' | 'onClick'>; @@ -210,7 +210,7 @@ const InternalButton: React.ForwardRefRenderFunction< const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined }; - const sizeFullname = useSize((ctxSize) => compactSize ?? groupSize ?? customizeSize ?? ctxSize); + const sizeFullname = useSize((ctxSize) => customizeSize ?? compactSize ?? groupSize ?? ctxSize); const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : ''; diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx index 662b51bcd4..08ab5a23bf 100644 --- a/components/cascader/index.tsx +++ b/components/cascader/index.tsx @@ -229,7 +229,7 @@ const Cascader = React.forwardRef((props: CascaderProps, ref: React.Ref compactSize ?? customizeSize ?? ctx); + const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/checkbox/Checkbox.tsx b/components/checkbox/Checkbox.tsx index 459f38b75d..f35c41b25a 100644 --- a/components/checkbox/Checkbox.tsx +++ b/components/checkbox/Checkbox.tsx @@ -2,11 +2,11 @@ import classNames from 'classnames'; import type { CheckboxRef } from 'rc-checkbox'; import RcCheckbox from 'rc-checkbox'; import * as React from 'react'; +import warning from '../_util/warning'; import { ConfigContext } from '../config-provider'; +import DisabledContext from '../config-provider/DisabledContext'; import { FormItemInputContext } from '../form/context'; -import warning from '../_util/warning'; import { GroupContext } from './Group'; -import DisabledContext from '../config-provider/DisabledContext'; import useStyle from './style'; @@ -18,6 +18,7 @@ export interface AbstractCheckboxProps { checked?: boolean; style?: React.CSSProperties; disabled?: boolean; + title?: string; onChange?: (e: T) => void; onClick?: React.MouseEventHandler; onMouseEnter?: React.MouseEventHandler; diff --git a/components/checkbox/Group.tsx b/components/checkbox/Group.tsx index ce583f6bd3..ac05a83867 100644 --- a/components/checkbox/Group.tsx +++ b/components/checkbox/Group.tsx @@ -14,6 +14,7 @@ export interface CheckboxOptionType { value: CheckboxValueType; style?: React.CSSProperties; disabled?: boolean; + title?: string; onChange?: (e: CheckboxChangeEvent) => void; } @@ -132,6 +133,7 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction {option.label} diff --git a/components/config-provider/index.en-US.md b/components/config-provider/index.en-US.md index db3a3481e7..954f39cbfe 100644 --- a/components/config-provider/index.en-US.md +++ b/components/config-provider/index.en-US.md @@ -97,7 +97,7 @@ const { } = ConfigProvider.useConfig(); ``` -| 返回值 | 说明 | 类型 | 默认值 | 版本 | +| Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | | componentDisabled | antd component disabled state | boolean | - | 5.3.0 | | componentSize | antd component size state | `small` \| `middle` \| `large` | - | 5.3.0 | diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index 57f710c392..d609ff9e51 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -7,8 +7,8 @@ import type { ReactElement } from 'react'; import * as React from 'react'; import type { Options } from 'scroll-into-view-if-needed'; import warning from '../_util/warning'; -import { ValidateMessagesContext } from '../form/context'; import type { RequiredMark } from '../form/Form'; +import ValidateMessagesContext from '../form/validateMessagesContext'; import type { Locale } from '../locale'; import LocaleProvider, { ANT_MARK } from '../locale'; import type { LocaleContextProps } from '../locale/context'; diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx index 7159b8adfd..7304cbb627 100644 --- a/components/date-picker/generatePicker/generateRangePicker.tsx +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -78,7 +78,7 @@ export default function generateRangePicker(generateConfig: GenerateCo } // ===================== Size ===================== - const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx); + const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/date-picker/generatePicker/generateSinglePicker.tsx b/components/date-picker/generatePicker/generateSinglePicker.tsx index c6c085394c..6901ca14af 100644 --- a/components/date-picker/generatePicker/generateSinglePicker.tsx +++ b/components/date-picker/generatePicker/generateSinglePicker.tsx @@ -103,7 +103,7 @@ export default function generatePicker(generateConfig: GenerateConfig< } // ===================== Size ===================== - const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx); + const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/date-picker/index.zh-CN.md b/components/date-picker/index.zh-CN.md index 3affbb210a..87f6ce0bfe 100644 --- a/components/date-picker/index.zh-CN.md +++ b/components/date-picker/index.zh-CN.md @@ -106,8 +106,8 @@ import locale from 'antd/locale/zh_CN'; | status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 | | style | 自定义输入框样式 | CSSProperties | {} | | | suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | | -| superNextIcon | 自定义 `<<` 切换图标 | ReactNode | - | 4.17.0 | -| superPrevIcon | 自定义 `>>` 切换图标 | ReactNode | - | 4.17.0 | +| superNextIcon | 自定义 `>>` 切换图标 | ReactNode | - | 4.17.0 | +| superPrevIcon | 自定义 `<<` 切换图标 | ReactNode | - | 4.17.0 | | onOpenChange | 弹出日历和关闭日历的回调 | function(open) | - | | | onPanelChange | 日历面板切换的回调 | function(value, mode) | - | | diff --git a/components/dropdown/__tests__/dropdown-button.test.tsx b/components/dropdown/__tests__/dropdown-button.test.tsx index c4e769ac3d..040d7a4bd5 100644 --- a/components/dropdown/__tests__/dropdown-button.test.tsx +++ b/components/dropdown/__tests__/dropdown-button.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { render } from '../../../tests/utils'; +import { render, waitFakeTimer } from '../../../tests/utils'; import type { DropdownProps } from '../dropdown'; import DropdownButton from '../dropdown-button'; @@ -156,4 +156,17 @@ describe('DropdownButton', () => { render(); expect(dropdownRender).toHaveBeenCalled(); }); + + it('should support focus menu when set autoFocus', async () => { + jest.useFakeTimers(); + const items = [ + { + label: 'foo', + key: '1', + }, + ]; + const { container } = render(); + await waitFakeTimer(); + expect(container.querySelector('.ant-dropdown-menu-item-active')).toBeTruthy(); + }); }); diff --git a/components/dropdown/dropdown.tsx b/components/dropdown/dropdown.tsx index eecd78ae12..eb3e18e80c 100644 --- a/components/dropdown/dropdown.tsx +++ b/components/dropdown/dropdown.tsx @@ -14,7 +14,6 @@ import { ConfigContext } from '../config-provider'; import type { MenuProps } from '../menu'; import Menu from '../menu'; import { OverrideProvider } from '../menu/OverrideContext'; -import { NoCompactStyle } from '../space/Compact'; import theme from '../theme'; import useStyle from './style'; @@ -274,7 +273,7 @@ const Dropdown: CompoundedComponent = (props) => { ); }} > - {overlayNode} + {overlayNode} ); }; diff --git a/components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap index 8e9c5799a2..993db3167a 100644 --- a/components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -855,6 +855,7 @@ Array [ aria-checked="true" class="ant-switch ant-switch-checked" role="switch" + style="margin: 16px;" type="button" >
{ } /> - + ); }; diff --git a/components/form/Form.tsx b/components/form/Form.tsx index f52410f5a1..addd149817 100644 --- a/components/form/Form.tsx +++ b/components/form/Form.tsx @@ -12,11 +12,12 @@ import { SizeContextProvider } from '../config-provider/SizeContext'; import useSize from '../config-provider/hooks/useSize'; import type { ColProps } from '../grid/col'; import type { FormContextProps } from './context'; -import { FormContext, FormProvider, ValidateMessagesContext } from './context'; +import { FormContext, FormProvider } from './context'; import useForm, { type FormInstance } from './hooks/useForm'; import useFormWarning from './hooks/useFormWarning'; import type { FormLabelAlign } from './interface'; import useStyle from './style'; +import ValidateMessagesContext from './validateMessagesContext'; export type RequiredMark = boolean | 'optional'; export type FormLayout = 'horizontal' | 'inline' | 'vertical'; @@ -186,6 +187,6 @@ const Form = React.forwardRef(InternalForm) as > & { ref?: React.Ref> }, ) => React.ReactElement; -export { useForm, List, type FormInstance, useWatch }; +export { List, useForm, useWatch, type FormInstance }; export default Form; diff --git a/components/form/context.tsx b/components/form/context.tsx index 07b117874f..ed6bb91f66 100644 --- a/components/form/context.tsx +++ b/components/form/context.tsx @@ -1,6 +1,6 @@ import { FormProvider as RcFormProvider } from 'rc-field-form'; import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext'; -import type { Meta, ValidateMessages } from 'rc-field-form/lib/interface'; +import type { Meta } from 'rc-field-form/lib/interface'; import omit from 'rc-util/lib/omit'; import type { FC, PropsWithChildren, ReactNode } from 'react'; import * as React from 'react'; @@ -92,5 +92,3 @@ export const NoFormStyle: FC = ({ children, status, override } ); }; - -export const ValidateMessagesContext = React.createContext(undefined); diff --git a/components/form/validateMessagesContext.tsx b/components/form/validateMessagesContext.tsx new file mode 100644 index 0000000000..c95aba3326 --- /dev/null +++ b/components/form/validateMessagesContext.tsx @@ -0,0 +1,7 @@ +import type { ValidateMessages } from 'rc-field-form/lib/interface'; +import { createContext } from 'react'; + +// ZombieJ: We export single file here since +// ConfigProvider use this which will make loop deps +// to import whole `rc-field-form` +export default createContext(undefined); diff --git a/components/input-number/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/input-number/__tests__/__snapshots__/demo-extend.test.ts.snap index d7e839afeb..08e054a61c 100644 --- a/components/input-number/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/input-number/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -626,6 +626,7 @@ exports[`renders components/input-number/demo/addon.tsx extend context correctly
+
+
+
+
+ + +
+
+
+ + + + + + + + + + +
+
+ +
+
+
+ + + +
+
+
+
+
+
+
+
+ + +
+
+ + ¥ + +
+
+ + + + + + + + + + +
+
+ +
+
+
+
+ + + +
+
+
+
`; diff --git a/components/input-number/__tests__/__snapshots__/demo.test.tsx.snap b/components/input-number/__tests__/__snapshots__/demo.test.tsx.snap index e7327bdac9..876fe06308 100644 --- a/components/input-number/__tests__/__snapshots__/demo.test.tsx.snap +++ b/components/input-number/__tests__/__snapshots__/demo.test.tsx.snap @@ -430,6 +430,7 @@ exports[`renders components/input-number/demo/addon.tsx correctly 1`] = `
+
+
+
+
+ + +
+
+
+ + + + + + + + + + +
+
+ +
+
+
+ + + +
+
+
+
+
+
+
+
+ + +
+
+ + ¥ + +
+
+ + + + + + + + + + +
+
+ +
+
+
+
+ + + +
+
+
+
`; diff --git a/components/input-number/__tests__/addon.test.tsx b/components/input-number/__tests__/addon.test.tsx new file mode 100644 index 0000000000..e10f6b40c8 --- /dev/null +++ b/components/input-number/__tests__/addon.test.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import InputNumber from '..'; +import { render } from '../../../tests/utils'; + +describe('addon', () => { + it('disabled status when prefix is active', () => { + const { container } = render(); + expect(container.querySelector('.ant-input-number-affix-wrapper-disabled')).toBeInTheDocument(); + }); + + it('disabled status when addon is active', () => { + const { container } = render( + , + ); + expect(container.querySelector('.ant-input-number-wrapper-disabled')).toBeInTheDocument(); + }); + + it('disabled status when prefix and addon is active', () => { + const { container } = render( + , + ); + expect(container.querySelector('.ant-input-number-wrapper-disabled')).toBeInTheDocument(); + expect(container.querySelector('.ant-input-number-affix-wrapper-disabled')).toBeInTheDocument(); + }); +}); diff --git a/components/input-number/demo/addon.tsx b/components/input-number/demo/addon.tsx index 42f49ba2d7..77e9411bce 100644 --- a/components/input-number/demo/addon.tsx +++ b/components/input-number/demo/addon.tsx @@ -1,6 +1,6 @@ -import React from 'react'; import { SettingOutlined } from '@ant-design/icons'; import { Cascader, InputNumber, Select, Space } from 'antd'; +import React from 'react'; const { Option } = Select; @@ -28,6 +28,21 @@ const App: React.FC = () => ( addonBefore={} defaultValue={100} /> + } + defaultValue={100} + disabled + controls + /> + } + defaultValue={100} + disabled + controls + /> ); diff --git a/components/input-number/index.tsx b/components/input-number/index.tsx index b08cbe483b..ef5f8e784c 100644 --- a/components/input-number/index.tsx +++ b/components/input-number/index.tsx @@ -87,7 +87,7 @@ const InputNumber = React.forwardRef((props, } = React.useContext(FormItemInputContext); const mergedStatus = getMergedStatus(contextStatus, customStatus); - const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx); + const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx); const hasPrefix = prefix != null || hasFeedback; const hasAddon = !!(addonBefore || addonAfter); @@ -179,6 +179,7 @@ const InputNumber = React.forwardRef((props, const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, wrapperClassName, hashId, { [`${wrapperClassName}-rtl`]: direction === 'rtl', + [`${prefixCls}-wrapper-disabled`]: mergedDisabled, }); const mergedGroupClassName = classNames( diff --git a/components/input-number/style/index.ts b/components/input-number/style/index.ts index 07c671de92..32b3c884e4 100644 --- a/components/input-number/style/index.ts +++ b/components/input-number/style/index.ts @@ -99,13 +99,6 @@ const genInputNumberStyles: GenerateStyle = (token: InputNumbe ...genActiveStyle(token), }, - '&-disabled': { - ...genDisabledStyle(token), - [`${componentCls}-input`]: { - cursor: 'not-allowed', - }, - }, - // ===================== Out Of Range ===================== '&-out-of-range': { [`${componentCls}-input-wrap`]: { @@ -140,9 +133,17 @@ const genInputNumberStyles: GenerateStyle = (token: InputNumbe borderRadius: borderRadiusSM, }, }, + + [`${componentCls}-wrapper-disabled > ${componentCls}-group-addon`]: { + ...genDisabledStyle(token), + }, }, }, + [`&-disabled ${componentCls}-input`]: { + cursor: 'not-allowed', + }, + [componentCls]: { '&-input': { ...resetComponent(token), @@ -338,10 +339,8 @@ const genAffixWrapperStyles: GenerateStyle = (token: InputNumb zIndex: 1, }, - '&-disabled': { - [`${componentCls}[disabled]`]: { - background: 'transparent', - }, + [`&-disabled > ${componentCls}-disabled`]: { + background: 'transparent', }, [`> div${componentCls}`]: { @@ -359,6 +358,7 @@ const genAffixWrapperStyles: GenerateStyle = (token: InputNumb }, '&::before': { + display: 'inline-block', width: 0, visibility: 'hidden', content: '"\\a0"', diff --git a/components/input/Input.tsx b/components/input/Input.tsx index 4bbae04774..1517c93ff5 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -97,7 +97,7 @@ const Input = forwardRef((props, ref) => { const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction); // ===================== Size ===================== - const mergedSize = useSize((ctx) => compactSize ?? customSize ?? ctx); + const mergedSize = useSize((ctx) => customSize ?? compactSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/input/Search.tsx b/components/input/Search.tsx index 61ddd99be6..1708308129 100644 --- a/components/input/Search.tsx +++ b/components/input/Search.tsx @@ -49,7 +49,7 @@ const Search = React.forwardRef((props, ref) => { const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls); const { compactSize } = useCompactItemContext(prefixCls, direction); - const size = useSize((ctx) => compactSize ?? customizeSize ?? ctx); + const size = useSize((ctx) => customizeSize ?? compactSize ?? ctx); const inputRef = React.useRef(null); diff --git a/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap index 9ac113d9a2..27990aa93a 100644 --- a/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -5194,7 +5194,7 @@ exports[`renders components/input/demo/compact-style.tsx extend context correctl class="ant-space-compact" >
+ + @ +
- - + + - - - + + - -
-
- +
+
+ +
diff --git a/components/input/__tests__/__snapshots__/demo.test.tsx.snap b/components/input/__tests__/__snapshots__/demo.test.tsx.snap index c7e57cf589..67460c93d3 100644 --- a/components/input/__tests__/__snapshots__/demo.test.tsx.snap +++ b/components/input/__tests__/__snapshots__/demo.test.tsx.snap @@ -1412,7 +1412,7 @@ exports[`renders components/input/demo/compact-style.tsx correctly 1`] = ` class="ant-space-compact" >
+ + @ +
- - + + - - - + + - -
-
- +
+
+ +
diff --git a/components/input/demo/group.tsx b/components/input/demo/group.tsx index 16dbaf7049..4252e71d58 100644 --- a/components/input/demo/group.tsx +++ b/components/input/demo/group.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { CopyOutlined } from '@ant-design/icons'; import { AutoComplete, @@ -12,6 +11,7 @@ import { Select, Tooltip, } from 'antd'; +import React from 'react'; const { Option } = Select; @@ -102,7 +102,7 @@ const App: React.FC = () => ( - +
diff --git a/components/input/style/index.ts b/components/input/style/index.ts index 85e4eec5a6..fac6677eb5 100644 --- a/components/input/style/index.ts +++ b/components/input/style/index.ts @@ -412,11 +412,11 @@ export const genInputGroupStyle = (token: InputToken): CSSObject => { borderRadius: 0, }, - [`& > ${componentCls}-affix-wrapper`]: { - display: 'inline-flex', - }, - - [`& > ${antCls}-picker-range`]: { + [` + & > ${componentCls}-affix-wrapper, + & > ${componentCls}-number-affix-wrapper, + & > ${antCls}-picker-range + `]: { display: 'inline-flex', }, @@ -620,6 +620,7 @@ const genAffixStyle: GenerateStyle = (token: InputToken) => { }, '&::before': { + display: 'inline-block', width: 0, visibility: 'hidden', content: '"\\a0"', diff --git a/components/menu/OverrideContext.tsx b/components/menu/OverrideContext.tsx index ba663f69f5..bec81a456b 100644 --- a/components/menu/OverrideContext.tsx +++ b/components/menu/OverrideContext.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { NoCompactStyle } from '../space/Compact'; import type { MenuProps } from './menu'; // Used for Dropdown only @@ -14,9 +15,10 @@ export interface OverrideContextProps { const OverrideContext = React.createContext(null); /** @internal Only used for Dropdown component. Do not use this in your production. */ -export const OverrideProvider: React.FC = ( - props, -) => { +export const OverrideProvider = React.forwardRef< + HTMLElement, + OverrideContextProps & { children: React.ReactNode } +>((props, ref) => { const { children, ...restProps } = props; const override = React.useContext(OverrideContext); @@ -32,8 +34,12 @@ export const OverrideProvider: React.FC{children}; -}; + return ( + + {React.cloneElement(children as React.ReactElement, { ref })} + + ); +}); /** @internal Only used for Dropdown component. Do not use this in your production. */ export default OverrideContext; diff --git a/components/progress/demo/segment.md b/components/progress/demo/segment.md index 641d824fd0..65046cc8f1 100644 --- a/components/progress/demo/segment.md +++ b/components/progress/demo/segment.md @@ -1,7 +1,7 @@ ## zh-CN -标准的进度条。`type="circle|dashboard"` 时不支持分段颜色。 +分段展示进度,可以用于细化进度语义。 ## en-US -A standard progress bar. Doesn't support trail color when `type="circle|dashboard"`. +Show several parts of progress with different status. diff --git a/components/progress/index.en-US.md b/components/progress/index.en-US.md index c5e6ded3ef..023c3066e8 100644 --- a/components/progress/index.en-US.md +++ b/components/progress/index.en-US.md @@ -50,7 +50,7 @@ Properties that shared by all types. | success | Configs of successfully progress bar | { percent: number, strokeColor: string } | - | - | | trailColor | The color of unfilled part | string | - | - | | type | To set the type, options: `line` `circle` `dashboard` | string | `line` | -| size | Progress size | number \| \[number, number] \| "small" \| "default" | "default" | v5.3.0 | +| size | Progress size | number \| \[number \| string, number] \| "small" \| "default" | "default" | v5.3.0 | ### `type="line"` diff --git a/components/progress/index.zh-CN.md b/components/progress/index.zh-CN.md index 43a803350a..61a9cc9b35 100644 --- a/components/progress/index.zh-CN.md +++ b/components/progress/index.zh-CN.md @@ -51,7 +51,7 @@ demo: | success | 成功进度条相关配置 | { percent: number, strokeColor: string } | - | - | | trailColor | 未完成的分段的颜色 | string | - | - | | type | 类型,可选 `line` `circle` `dashboard` | string | `line` | - | -| size | 进度条的尺寸 | number \| \[number, number] \| "small" \| "default" | "default" | v5.3.0 | +| size | 进度条的尺寸 | number \| \[number \| string, number] \| "small" \| "default" | "default" | v5.3.0 | ### `type="line"` diff --git a/components/progress/progress.tsx b/components/progress/progress.tsx index 9f7ea96b2e..dcc31c6465 100644 --- a/components/progress/progress.tsx +++ b/components/progress/progress.tsx @@ -50,7 +50,7 @@ export interface ProgressProps extends ProgressAriaProps { style?: React.CSSProperties; gapDegree?: number; gapPosition?: 'top' | 'bottom' | 'left' | 'right'; - size?: number | [number, number] | ProgressSize; + size?: number | [number | string, number] | ProgressSize; steps?: number; /** @deprecated Use `success` instead */ successPercent?: number; diff --git a/components/progress/utils.ts b/components/progress/utils.ts index 60c5f41453..9ea719e35f 100644 --- a/components/progress/utils.ts +++ b/components/progress/utils.ts @@ -1,7 +1,7 @@ import { presetPrimaryColors } from '@ant-design/colors'; +import warning from '../_util/warning'; import type { CircleProps } from './Circle'; import type { ProgressProps } from './progress'; -import warning from '../_util/warning'; export function validProgress(progress?: number) { if (!progress || progress < 0) { @@ -35,10 +35,10 @@ export const getPercentage = ({ percent, success, successPercent }: ProgressProp return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)]; }; -export const getStrokeColor = ({ success = {}, strokeColor }: Partial): ( - | string - | Record -)[] => { +export const getStrokeColor = ({ + success = {}, + strokeColor, +}: Partial): (string | Record)[] => { const { strokeColor: successColor } = success; return [successColor || presetPrimaryColors.green, strokeColor || null!]; }; @@ -62,7 +62,7 @@ export const getSize = ( } else if (typeof size === 'number') { [width, height] = [size, size]; } else { - [width = 14, height = 8] = size; + [width = 14, height = 8] = size as [number, number]; } width *= steps; } else if (type === 'line') { @@ -72,7 +72,7 @@ export const getSize = ( } else if (typeof size === 'number') { [width, height] = [size, size]; } else { - [width = -1, height = 8] = size; + [width = -1, height = 8] = size as [number, number]; } } else if (type === 'circle' || type === 'dashboard') { if (typeof size === 'string' || typeof size === 'undefined') { @@ -88,8 +88,8 @@ export const getSize = ( ); } - width = size[0] ?? size[1] ?? 120; - height = size[0] ?? size[1] ?? 120; + width = (size[0] ?? size[1] ?? 120) as number; + height = (size[0] ?? size[1] ?? 120) as number; } } return [width, height]; diff --git a/components/radio/group.tsx b/components/radio/group.tsx index 8d0053d2ec..92c1e3a97f 100644 --- a/components/radio/group.tsx +++ b/components/radio/group.tsx @@ -76,6 +76,7 @@ const RadioGroup = React.forwardRef((props, ref disabled={option.disabled || disabled} value={option.value} checked={value === option.value} + title={option.title} style={option.style} > {option.label} diff --git a/components/select/index.en-US.md b/components/select/index.en-US.md index e82fea16f1..59aabe7c43 100644 --- a/components/select/index.en-US.md +++ b/components/select/index.en-US.md @@ -47,12 +47,6 @@ Select component to select value from options. ## API -```tsx - -``` - ### Select props | Property | Description | Type | Default | Version | diff --git a/components/select/index.tsx b/components/select/index.tsx index 735365f8c3..9eed691872 100755 --- a/components/select/index.tsx +++ b/components/select/index.tsx @@ -175,7 +175,7 @@ const InternalSelect = < hashId, ); - const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx); + const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx); // ===================== Disabled ===================== const disabled = React.useContext(DisabledContext); diff --git a/components/select/index.zh-CN.md b/components/select/index.zh-CN.md index 67029a9e0e..7354fb4cf3 100644 --- a/components/select/index.zh-CN.md +++ b/components/select/index.zh-CN.md @@ -48,12 +48,6 @@ demo: ## API -```tsx - -``` - ### Select props | 参数 | 说明 | 类型 | 默认值 | 版本 | diff --git a/components/select/style/dropdown.tsx b/components/select/style/dropdown.tsx index 5f6708fcf0..2256397389 100644 --- a/components/select/style/dropdown.tsx +++ b/components/select/style/dropdown.tsx @@ -104,10 +104,6 @@ const genSingleStyle: GenerateStyle = (token) => { '&-content': { flex: 'auto', ...textEllipsis, - - '> *': { - ...textEllipsis, - }, }, '&-state': { diff --git a/components/select/style/index.tsx b/components/select/style/index.tsx index 4024164c71..202be12803 100644 --- a/components/select/style/index.tsx +++ b/components/select/style/index.tsx @@ -144,11 +144,6 @@ const genBaseStyle: GenerateStyle = (token) => { flex: 1, fontWeight: 'normal', ...textEllipsis, - - '> *': { - lineHeight: 'inherit', - ...textEllipsis, - }, }, // ======================= Placeholder ======================= diff --git a/components/slider/SliderTooltip.tsx b/components/slider/SliderTooltip.tsx index 5cd2a104f3..0cbbc92f2c 100644 --- a/components/slider/SliderTooltip.tsx +++ b/components/slider/SliderTooltip.tsx @@ -1,3 +1,4 @@ +import type { SliderRef } from 'rc-slider/lib/Slider'; import raf from 'rc-util/lib/raf'; import { composeRef } from 'rc-util/lib/ref'; import * as React from 'react'; @@ -5,7 +6,7 @@ import { useRef } from 'react'; import type { TooltipProps } from '../tooltip'; import Tooltip from '../tooltip'; -const SliderTooltip = React.forwardRef((props, ref) => { +const SliderTooltip = React.forwardRef((props, ref) => { const { open } = props; const innerRef = useRef(null); @@ -36,4 +37,8 @@ const SliderTooltip = React.forwardRef((props, ref) => { return ; }); +if (process.env.NODE_ENV !== 'production') { + SliderTooltip.displayName = 'SliderTooltip'; +} + export default SliderTooltip; diff --git a/components/space/Compact.tsx b/components/space/Compact.tsx index b1046365a6..c0e7cb2add 100644 --- a/components/space/Compact.tsx +++ b/components/space/Compact.tsx @@ -78,7 +78,7 @@ const Compact: React.FC = (props) => { ...restProps } = props; - const mergedSize = useSize((ctx) => size ?? ctx ?? 'middle'); + const mergedSize = useSize((ctx) => size ?? ctx); const prefixCls = getPrefixCls('space-compact', customizePrefixCls); const [wrapSSR, hashId] = useStyle(prefixCls); diff --git a/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap index 0b0ebc1972..5bacb84efe 100644 --- a/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/space/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -871,7 +871,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`] class="ant-space-compact ant-space-compact-block" >