Merge branch 'next' into refactor/skeleton

This commit is contained in:
ice 2025-01-21 21:29:55 +08:00 committed by GitHub
commit 095910c934
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
125 changed files with 774 additions and 339 deletions

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { FastColor } from '@ant-design/fast-color';
import type { ColorInput } from '@ant-design/fast-color';
// @ts-ignore
import { TinyColor } from 'dumi-plugin-color-chunk/component';
import { createStyles } from 'antd-style';
const useStyle = createStyles(({ token, css }) => ({
@ -22,7 +22,7 @@ const useStyle = createStyles(({ token, css }) => ({
}));
interface ColorChunkProps {
value: ColorInput;
value: any;
}
const ColorChunk: React.FC<React.PropsWithChildren<ColorChunkProps>> = (props) => {
@ -30,7 +30,7 @@ const ColorChunk: React.FC<React.PropsWithChildren<ColorChunkProps>> = (props) =
const { value, children } = props;
const dotColor = React.useMemo(() => {
const _color = new FastColor(value).toHexString();
const _color = new TinyColor(value).toHex8String();
return _color.endsWith('ff') ? _color.slice(0, -2) : _color;
}, [value]);

View File

@ -1,7 +1,6 @@
import React, { Suspense, useContext } from 'react';
import { BugOutlined, CodeOutlined, ExperimentOutlined } from '@ant-design/icons';
import { ConfigProvider, Tooltip, Button } from 'antd';
import classNames from 'classnames';
import { DumiDemoGrid, FormattedMessage, DumiDemo } from 'dumi';
import { css, Global } from '@emotion/react';
@ -42,13 +41,16 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => {
const demos = React.useMemo(
() =>
items.map((item: any) => {
items.reduce<typeof items>((acc, item) => {
const { previewerProps } = item;
const { debug } = previewerProps;
return {
if (debug && !showDebug) {
return acc;
}
return acc.concat({
...item,
previewerProps: {
...item.previewerProps,
...previewerProps,
expand: expandAll,
// always override debug property, because dumi will hide debug demo in production
debug: false,
@ -58,17 +60,13 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => {
*/
originDebug: debug,
},
};
}),
});
}, []),
[expandAll, showDebug],
);
return (
<div
className={classNames('demo-wrapper', {
'demo-wrapper-show-debug': showDebug,
})}
>
<div className="demo-wrapper">
<Global
styles={css`
:root {
@ -117,8 +115,8 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => {
<DumiDemoGrid
items={demos}
demoRender={(item) => (
<Suspense fallback={<DemoFallback />}>
<DumiDemo key={item.demo.id} {...item} />
<Suspense key={item.demo.id} fallback={<DemoFallback />}>
<DumiDemo {...item} />
</Suspense>
)}
/>

View File

@ -325,7 +325,6 @@ const GlobalDemoStyles: React.FC = () => {
&-debug {
border-color: ${token.purple3};
display: none;
}
&-debug &-title a {
@ -335,10 +334,6 @@ const GlobalDemoStyles: React.FC = () => {
.demo-wrapper {
position: relative;
&-show-debug .code-box-debug {
display: block;
}
}
.all-code-box-controls {

View File

@ -1,19 +1,6 @@
import React from 'react';
import type { AvatarListItem } from '@qixian.cs/github-contributors-list/dist/AvatarList';
import { Avatar, Skeleton, Tooltip } from 'antd';
const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 3 }) => (
<li>
{Array.from({ length: num }).map<React.ReactNode>((_, i) => (
<Skeleton.Avatar
size="small"
active
key={i}
style={{ marginInlineStart: i === 0 ? 0 : -8 }}
/>
))}
</li>
);
import { Avatar, Tooltip } from 'antd';
interface ContributorAvatarProps {
loading?: boolean;
@ -23,11 +10,7 @@ interface ContributorAvatarProps {
const ContributorAvatar: React.FC<ContributorAvatarProps> = (props) => {
const {
item: { username, url } = {},
loading,
} = props;
if (loading) {
return <AvatarPlaceholder />;
}
if (username?.includes('github-actions')) {
return null;
}

View File

@ -1,5 +1,5 @@
import React, { useContext, useLayoutEffect, useMemo, useState } from 'react';
import { Col, Flex, Space, Typography } from 'antd';
import { Col, Flex, Space, Typography, Skeleton } from 'antd';
import classNames from 'classnames';
import { FormattedMessage, useRouteMeta } from 'dumi';
@ -20,6 +20,11 @@ const Footer = React.lazy(() => import('../Footer'));
const PrevAndNext = React.lazy(() => import('../../common/PrevAndNext'));
const EditButton = React.lazy(() => import('../../common/EditButton'));
const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 6 }) =>
Array.from({ length: num }).map<React.ReactNode>((_, i) => (
<Skeleton.Avatar size="small" active key={i} style={{ marginInlineStart: i === 0 ? 0 : -8 }} />
));
const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
const meta = useRouteMeta();
const { pathname, hash } = useLocation();
@ -87,7 +92,7 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
/>
)}
<div style={{ minHeight: 'calc(100vh - 64px)' }}>{children}</div>
<InViewSuspense>
<InViewSuspense fallback={null}>
<ColumnCard
zhihuLink={meta.frontmatter.zhihu_url}
yuqueLink={meta.frontmatter.yuque_url}
@ -95,7 +100,7 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
/>
</InViewSuspense>
<div style={{ marginTop: 120 }}>
<InViewSuspense fallback={<div style={{ height: 50 }} />}>
<InViewSuspense fallback={<AvatarPlaceholder />}>
<Contributors filename={meta.frontmatter.filename} />
</InViewSuspense>
</div>

View File

@ -15,6 +15,22 @@ tag: vVERSION
---
## 5.23.2
`2025-01-20`
- 🐞 Fix Space.Compact throwing `Should not use more than one & in a selector` warning. [#52489](https://github.com/ant-design/ant-design/pull/52489)
- 💄 Fix the Layout switching sidebar button style was lost. [#52477](https://github.com/ant-design/ant-design/pull/52477)
- 💄 Fix the scroll bar height is not 0 when the first row of the virtual scroll Table is collapsed. [#52447](https://github.com/ant-design/ant-design/pull/52447) [@LeeSSHH](https://github.com/LeeSSHH)
- 💄 Fix the last item in Descriptions did not correctly fill the remaining space. [#52410](https://github.com/ant-design/ant-design/pull/52410) [@anyuxuan](https://github.com/anyuxuan)
- 💄 Fix extra margin for the last item in Radio. [#52433](https://github.com/ant-design/ant-design/pull/52433)
- 💄 Fix the Input/Mentions clear button padding was incorrect. [#52407](https://github.com/ant-design/ant-design/pull/52407) [@ustcfury](https://github.com/ustcfury)
- 💄 Fix rounded corners of `addonAfter` in Input compact mode. [#52490](https://github.com/ant-design/ant-design/pull/52490) [@DDDDD12138](https://github.com/DDDDD12138)
- 💄 Fix Menu.Item links were still clickable and lacked disabled styles when in disabled state. [#52402](https://github.com/ant-design/ant-design/pull/52402) [@aojunhao123](https://github.com/aojunhao123)
- TypeScript
- 🤖 MISC: Optimize PurePanel to use React.ComponentType type. [#52480](https://github.com/ant-design/ant-design/pull/52480)
- 🤖 Fix missing token type for Skeleton and Rate. [#52406](https://github.com/ant-design/ant-design/pull/52406) [@coding-ice](https://github.com/coding-ice)
## 5.23.1
`2025-01-13`

View File

@ -15,6 +15,22 @@ tag: vVERSION
---
## 5.23.2
`2025-01-20`
- 🐞 修复 Space.Compact 抛出 `Should not use more than one & in a selector` 警告信息的问题。[#52489](https://github.com/ant-design/ant-design/pull/52489)
- 💄 修复 Layout 切换侧边栏按钮样式丢失的问题。[#52477](https://github.com/ant-design/ant-design/pull/52477)
- 💄 修复 Table 收起虚拟滚动表格第一行时滚动条高度不为 0 的问题。[#52447](https://github.com/ant-design/ant-design/pull/52447) [@LeeSSHH](https://github.com/LeeSSHH)
- 💄 修复 Descriptions 最后一项未正确填充满剩余空间的问题。[#52410](https://github.com/ant-design/ant-design/pull/52410) [@anyuxuan](https://github.com/anyuxuan)
- 💄 修复 Radio.Group 最后一项多余 margin 的问题。[#52433](https://github.com/ant-design/ant-design/pull/52433)
- 💄 修复 Input/Mentions 清除按钮 padding 不正确的问题。[#52407](https://github.com/ant-design/ant-design/pull/52407) [@ustcfury](https://github.com/ustcfury)
- 💄 修复 Input 紧凑模式中 `addonAfter` 的圆角问题。[#52490](https://github.com/ant-design/ant-design/pull/52490) [@DDDDD12138](https://github.com/DDDDD12138)
- 💄 修复 Menu.Item 在禁用状态下链接仍可点击且缺少禁用样式的问题。[#52402](https://github.com/ant-design/ant-design/pull/52402) [@aojunhao123](https://github.com/aojunhao123)
- TypeScript
- 🤖 MISC: 优化 PurePanel 使用 React.ComponentType 类型。[#52480](https://github.com/ant-design/ant-design/pull/52480)
- 🤖 修复 Skeleton 和 Rate 缺失的 token 类型。[#52406](https://github.com/ant-design/ant-design/pull/52406) [@coding-ice](https://github.com/coding-ice)
## 5.23.1
`2025-01-13`

View File

@ -20,8 +20,8 @@
[npm-image]: https://img.shields.io/npm/v/antd.svg?style=flat-square
[npm-url]: https://npmjs.org/package/antd
[github-action-image]: https://github.com/ant-design/ant-design/workflows/%E2%9C%85%20test/badge.svg
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
[github-action-image]: https://github.com/ant-design/ant-design/actions/workflows/test.yml/badge.svg
[github-action-url]: https://github.com/ant-design/ant-design/actions/workflows/test.yml
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square

View File

@ -20,8 +20,8 @@ An enterprise-class UI design language and React UI library.
[npm-image]: https://img.shields.io/npm/v/antd.svg?style=flat-square
[npm-url]: https://npmjs.org/package/antd
[github-action-image]: https://github.com/ant-design/ant-design/workflows/%E2%9C%85%20test/badge.svg
[github-action-url]: https://github.com/ant-design/ant-design/actions?query=workflow%3A%22%E2%9C%85+test%22
[github-action-image]: https://github.com/ant-design/ant-design/actions/workflows/test.yml/badge.svg
[github-action-url]: https://github.com/ant-design/ant-design/actions/workflows/test.yml
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square

View File

@ -19,7 +19,7 @@ export interface BaseProps {
/* istanbul ignore next */
const genPurePanel = <ComponentProps extends BaseProps = BaseProps>(
Component: any,
Component: React.ComponentType<Readonly<ComponentProps>>,
alignPropName?: 'align' | 'dropdownAlign' | 'popupAlign',
postProps?: (props: ComponentProps) => ComponentProps,
defaultPrefixCls?: string,

View File

@ -1,3 +0,0 @@
const isNumeric = (value: any): boolean => !isNaN(parseFloat(value)) && isFinite(value);
export default isNumeric;

View File

@ -6,8 +6,8 @@ import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点',
indicator: '指示器节点',
root: '根元素',
indicator: '指示器元素',
},
en: {
root: 'Root element',

View File

@ -6,9 +6,9 @@ import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点',
indicator: '指示器节点',
content: '文本节点',
root: '根元素',
indicator: '指示器元素',
content: '文本元素',
},
en: {
root: 'Root element',

View File

@ -310,7 +310,7 @@ const InternalCompoundedButton = React.forwardRef<
<IconWrapper prefixCls={prefixCls} className={iconClasses} style={iconStyle}>
{icon}
</IconWrapper>
) : typeof loading === 'object' && loading.icon ? (
) : loading && typeof loading === 'object' && loading.icon ? (
<IconWrapper prefixCls={prefixCls} className={iconClasses} style={iconStyle}>
{loading.icon}
</IconWrapper>

View File

@ -2,6 +2,7 @@ import React from 'react';
import { Button, ConfigProvider, Flex } from 'antd';
const App: React.FC = () => (
<Flex gap="small" vertical>
<ConfigProvider
theme={{
components: {
@ -23,7 +24,6 @@ const App: React.FC = () => (
},
}}
>
<Flex gap="small" vertical>
<Flex wrap gap="small">
<Button type="text">TEXT</Button>
<Button type="primary">CONTAINED</Button>
@ -36,7 +36,18 @@ const App: React.FC = () => (
<Button type="primary" disabled>
CONTAINED
</Button>
<ConfigProvider
theme={{
components: {
Button: {
colorBorderDisabled: 'rgba(0, 0, 0, 0.12)',
colorBgContainerDisabled: 'transparent',
},
},
}}
>
<Button disabled>OUTLINED</Button>
</ConfigProvider>
</Flex>
<Flex wrap gap="small">
<Button type="text" size="small">
@ -47,8 +58,16 @@ const App: React.FC = () => (
</Button>
<Button size="small">OUTLINED</Button>
</Flex>
</Flex>
</ConfigProvider>
<Flex gap="small" wrap>
<ConfigProvider theme={{ components: { Button: { colorBorderDisabled: 'red' } } }}>
<Button disabled>Custom Red Disabled</Button>
</ConfigProvider>
<ConfigProvider theme={{ components: { Button: { borderColorDisabled: 'blue' } } }}>
<Button disabled>Legacy Blue Disabled</Button>
</ConfigProvider>
</Flex>
</Flex>
);
export default App;

View File

@ -11,11 +11,10 @@ import { prepareComponentToken, prepareToken } from './token';
const genButtonCompactStyle: GenerateStyle<ButtonToken> = (token) => {
const { componentCls, colorPrimaryHover, lineWidth, calc } = token;
const insetOffset = calc(lineWidth).mul(-1).equal();
const getCompactBorderStyle = (vertical?: boolean) =>
({
[`${componentCls}-compact${vertical ? '-vertical' : ''}-item${componentCls}-primary:not([disabled])`]:
{
'& + &::before': {
const getCompactBorderStyle = (vertical?: boolean) => {
const selector = `${componentCls}-compact${vertical ? '-vertical' : ''}-item${componentCls}-primary:not([disabled])`;
return {
[`${selector} + ${selector}::before`]: {
position: 'absolute',
top: vertical ? insetOffset : 0,
insetInlineStart: vertical ? 0 : insetOffset,
@ -23,9 +22,9 @@ const genButtonCompactStyle: GenerateStyle<ButtonToken> = (token) => {
content: '""',
width: vertical ? '100%' : lineWidth,
height: vertical ? lineWidth : '100%',
},
},
}) as CSSObject;
} as CSSObject,
};
};
// Special styles for Primary Button
return {
...getCompactBorderStyle(),

View File

@ -171,7 +171,7 @@ const genGhostButtonStyle = (
textColor: string | false,
borderColor: string | false,
textColorDisabled: string | false,
borderColorDisabled: string | false,
colorBorderDisabled: string | false,
hoverStyle?: CSSObject,
activeStyle?: CSSObject,
): CSSObject => ({
@ -196,7 +196,7 @@ const genGhostButtonStyle = (
'&:disabled': {
cursor: 'not-allowed',
color: textColorDisabled || undefined,
borderColor: borderColorDisabled || undefined,
borderColor: colorBorderDisabled || undefined,
},
},
});

View File

@ -83,6 +83,7 @@ export interface ComponentToken {
*/
defaultActiveBorderColor: string;
/**
* @deprecated use `colorBorderDisabled` instead
* @desc
* @descEN Border color of disabled button
*/
@ -239,12 +240,13 @@ export interface ButtonToken extends FullToken<'Button'> {
export const prepareToken: (token: Parameters<GenStyleFn<'Button'>>[0]) => ButtonToken = (
token,
) => {
const { paddingInline, onlyIconSize } = token;
const { paddingInline, onlyIconSize, borderColorDisabled } = token;
const buttonToken = mergeToken<ButtonToken>(token, {
buttonPaddingHorizontal: paddingInline,
buttonPaddingVertical: 0,
buttonIconOnlyFontSize: onlyIconSize,
colorBorderDisabled: borderColorDisabled,
});
return buttonToken;
@ -268,7 +270,7 @@ export const prepareComponentToken: GetDefaultToken<'Button'> = (token) => {
dangerShadow: `0 ${token.controlOutlineWidth}px 0 ${token.colorErrorOutline}`,
primaryColor: token.colorTextLightSolid,
dangerColor: token.colorTextLightSolid,
borderColorDisabled: token.colorBorder,
borderColorDisabled: token.colorBorderDisabled,
defaultGhostColor: token.colorBgContainer,
ghostBg: 'transparent',
defaultGhostBorderColor: token.colorBgContainer,

View File

@ -1,5 +1,5 @@
import React from 'react';
import type { ValidateMessages } from 'rc-field-form/es/interface';
import type { ValidateMessages } from '@rc-component/form/lib/interface';
import scrollIntoView from 'scroll-into-view-if-needed';
import ConfigProvider from '..';

View File

@ -192,13 +192,19 @@ export type SelectConfig = ComponentStyleConfig & Pick<SelectProps, 'showSearch'
export type SpaceConfig = ComponentStyleConfig & Pick<SpaceProps, 'size' | 'classNames' | 'styles'>;
export type TooltipConfig = Pick<TooltipProps, 'className' | 'style' | 'styles' | 'classNames'>;
export type TooltipConfig = Pick<
TooltipProps,
'className' | 'style' | 'styles' | 'classNames' | 'arrow'
>;
export type PopoverConfig = Pick<PopoverProps, 'className' | 'style' | 'styles' | 'classNames'>;
export type PopoverConfig = Pick<
PopoverProps,
'className' | 'style' | 'styles' | 'classNames' | 'arrow'
>;
export type PopconfirmConfig = Pick<
PopconfirmProps,
'className' | 'style' | 'styles' | 'classNames'
'className' | 'style' | 'styles' | 'classNames' | 'arrow'
>;
export type SliderConfig = ComponentStyleConfig & Pick<SliderProps, 'styles' | 'classNames'>;

View File

@ -163,9 +163,9 @@ const {
| timeline | Set Timeline common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| timePicker | Set TimePicker common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| tour | Set Tour common props | { closeIcon?: React.ReactNode } | - | 5.14.0 |
| tooltip | Set Tooltip common props | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip#api), styles?: [Tooltip\["styles"\]](/components/tooltip#api) } | - | 5.23.0 |
| popover | Set Popover common props | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover#api), styles?: [Popover\["styles"\]](/components/popover#api) } | - | 5.23.0 |
| popconfirm | Set Popconfirm common props | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm#api) } | - | 5.23.0 |
| tooltip | Set Tooltip common props | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip#api), styles?: [Tooltip\["styles"\]](/components/tooltip#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 |
| popover | Set Popover common props | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover#api), styles?: [Popover\["styles"\]](/components/popover#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 |
| popconfirm | Set Popconfirm common props | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 |
| transfer | Set Transfer common props | { className?: string, style?: React.CSSProperties, selectionsIcon?: React.ReactNode } | - | 5.7.0, selectionsIcon: 5.14.0 |
| tree | Set Tree common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| typography | Set Typography common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -165,9 +165,9 @@ const {
| timeline | 设置 Timeline 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| timePicker | 设置 TimePicker 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| tour | 设置 Tour 组件的通用属性 | { closeIcon?: React.ReactNode } | - | 5.14.0 |
| tooltip | 设置 Tooltip 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip-cn#api), styles?: [Tooltip\["styles"\]](/components/tooltip-cn#api) } | - | 5.23.0 |
| popover | 设置 Popover 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover-cn#api), styles?: [Popover\["styles"\]](/components/popover-cn#api) } | - | 5.23.0 |
| popconfirm | 设置 Popconfirm 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm-cn#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm-cn#api) } | - | 5.23.0 |
| tooltip | 设置 Tooltip 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Tooltip\["classNames"\]](/components/tooltip-cn#api), styles?: [Tooltip\["styles"\]](/components/tooltip-cn#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 |
| popover | 设置 Popover 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popover\["classNames"\]](/components/popover-cn#api), styles?: [Popover\["styles"\]](/components/popover-cn#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 |
| popconfirm | 设置 Popconfirm 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?:[Popconfirm\["classNames"\]](/components/popconfirm-cn#api), styles?: [Popconfirm\["styles"\]](/components/popconfirm-cn#api), arrow: boolean \| { pointAtCenter: boolean } } | - | 5.23.0, arrow: 6.0.0 |
| transfer | 设置 Transfer 组件的通用属性 | { className?: string, style?: React.CSSProperties, selectionsIcon?: React.ReactNode } | - | 5.7.0, selectionsIcon: 5.14.0 |
| tree | 设置 Tree 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
| typography | 设置 Typography 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |

View File

@ -6,7 +6,7 @@ import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点',
root: '根元素',
header: '头部元素',
title: '标题元素',
extra: '额外内容',

View File

@ -1,11 +1,16 @@
import * as React from 'react';
import FieldForm, { List, useWatch } from '@rc-component/form';
import type { FormProps as RcFormProps } from '@rc-component/form/lib/Form';
import type {
FormRef,
InternalNamePath,
ValidateErrorEntity,
} from '@rc-component/form/lib/interface';
import classNames from 'classnames';
import FieldForm, { List, useWatch } from 'rc-field-form';
import type { FormProps as RcFormProps } from 'rc-field-form/lib/Form';
import type { FormRef, InternalNamePath, ValidateErrorEntity } from 'rc-field-form/lib/interface';
import type { Options } from 'scroll-into-view-if-needed';
import { ConfigContext } from '../config-provider';
import type { Variant } from '../config-provider';
import DisabledContext, { DisabledContextProvider } from '../config-provider/DisabledContext';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import useSize from '../config-provider/hooks/useSize';
@ -18,7 +23,6 @@ import type { FeedbackIcons } from './FormItem';
import useForm from './hooks/useForm';
import type { FormInstance } from './hooks/useForm';
import useFormWarning from './hooks/useFormWarning';
import type { Variant } from '../config-provider';
import type { FormLabelAlign } from './interface';
import useStyle from './style';
import ValidateMessagesContext from './validateMessagesContext';

View File

@ -1,9 +1,9 @@
import * as React from 'react';
import type { Meta } from '@rc-component/form/lib/interface';
import isVisible from '@rc-component/util/lib/Dom/isVisible';
import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
import omit from '@rc-component/util/lib/omit';
import classNames from 'classnames';
import type { Meta } from 'rc-field-form/lib/interface';
import type { FormItemProps } from '.';
import { Row } from '../../grid';

View File

@ -3,8 +3,8 @@ import CheckCircleFilled from '@ant-design/icons/CheckCircleFilled';
import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
import LoadingOutlined from '@ant-design/icons/LoadingOutlined';
import type { Meta } from '@rc-component/form/lib/interface';
import classNames from 'classnames';
import type { Meta } from 'rc-field-form/lib/interface';
import type { FeedbackIcons, ValidateStatus } from '.';
import { FormContext, FormItemInputContext } from '../context';

View File

@ -1,11 +1,11 @@
import * as React from 'react';
import type { JSX } from 'react';
import { Field, FieldContext, ListContext } from '@rc-component/form';
import type { FieldProps } from '@rc-component/form/lib/Field';
import type { InternalNamePath, Meta } from '@rc-component/form/lib/interface';
import useState from '@rc-component/util/lib/hooks/useState';
import { supportRef } from '@rc-component/util/lib/ref';
import classNames from 'classnames';
import { Field, FieldContext, ListContext } from 'rc-field-form';
import type { FieldProps } from 'rc-field-form/lib/Field';
import type { InternalNamePath, Meta } from 'rc-field-form/lib/interface';
import { cloneElement } from '../../_util/reactNode';
import { devUseWarning } from '../../_util/warning';

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { List } from 'rc-field-form';
import type { StoreValue, ValidatorRule } from 'rc-field-form/lib/interface';
import { List } from '@rc-component/form';
import type { StoreValue, ValidatorRule } from '@rc-component/form/lib/interface';
import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';

View File

@ -1,5 +1,5 @@
import React from 'react';
import type { FormRef } from 'rc-field-form/lib/interface';
import type { FormRef } from '@rc-component/form/lib/interface';
import Form, { FormInstance } from '..';
import { fireEvent, render } from '../../../tests/utils';

View File

@ -1,9 +1,9 @@
import type { PropsWithChildren, ReactNode } from 'react';
import * as React from 'react';
import { FormProvider as RcFormProvider } from '@rc-component/form';
import type { FormProviderProps as RcFormProviderProps } from '@rc-component/form/lib/FormContext';
import type { Meta } from '@rc-component/form/lib/interface';
import omit from '@rc-component/util/lib/omit';
import { FormProvider as RcFormProvider } from 'rc-field-form';
import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext';
import type { Meta } from 'rc-field-form/lib/interface';
import type { Variant } from '../config-provider';
import type { ColProps } from '../grid/col';

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import type { FormInstance as RcFormInstance } from '@rc-component/form';
import { useForm as useRcForm } from '@rc-component/form';
import { getDOM } from '@rc-component/util/lib/Dom/findDOMNode';
import type { FormInstance as RcFormInstance } from 'rc-field-form';
import { useForm as useRcForm } from 'rc-field-form';
import scrollIntoView from 'scroll-into-view-if-needed';
import type { InternalNamePath, NamePath, ScrollOptions } from '../interface';

View File

@ -1,4 +1,5 @@
import type { Rule, RuleObject, RuleRender } from 'rc-field-form/lib/interface';
import type { Rule, RuleObject, RuleRender } from '@rc-component/form/lib/interface';
import { FormProvider } from './context';
import ErrorList from './ErrorList';
import type { ErrorListProps } from './ErrorList';

View File

@ -1,3 +1,8 @@
export type { InternalNamePath, NamePath, Store, StoreValue } from 'rc-field-form/lib/interface';
export type {
InternalNamePath,
NamePath,
Store,
StoreValue,
} from '@rc-component/form/lib/interface';
export type { Options as ScrollOptions } from 'scroll-into-view-if-needed';
export type FormLabelAlign = 'left' | 'right';

View File

@ -1,4 +1,4 @@
import type { Meta } from 'rc-field-form/lib/interface';
import type { Meta } from '@rc-component/form/lib/interface';
import type { ValidateStatus } from './FormItem';
import type { InternalNamePath } from './interface';

View File

@ -1,7 +1,7 @@
import { createContext } from 'react';
import type { ValidateMessages } from 'rc-field-form/lib/interface';
import type { ValidateMessages } from '@rc-component/form/lib/interface';
// ZombieJ: We export single file here since
// ConfigProvider use this which will make loop deps
// to import whole `rc-field-form`
// to import whole `rc-component/form`
export default createContext<ValidateMessages | undefined>(undefined);

View File

@ -642,6 +642,14 @@ const genGroupStyle: GenerateStyle<InputToken> = (token: InputToken) => {
borderEndEndRadius: 0,
},
},
// Fix the issue of input use `addonAfter` param in space compact mode
// https://github.com/ant-design/ant-design/issues/52483
[`&:not(${componentCls}-compact-first-item)${componentCls}-compact-item`]: {
[`${componentCls}-affix-wrapper`]: {
borderStartStartRadius: 0,
borderEndStartRadius: 0,
},
},
},
},
};

View File

@ -6,7 +6,6 @@ import RightOutlined from '@ant-design/icons/RightOutlined';
import omit from '@rc-component/util/lib/omit';
import classNames from 'classnames';
import isNumeric from '../_util/isNumeric';
import { ConfigContext } from '../config-provider';
import { LayoutContext } from './context';
import useStyle from './style/sider';
@ -20,6 +19,8 @@ const dimensionMaxMap = {
xxl: '1599.98px',
};
const isNumeric = (value: any) => !Number.isNaN(Number.parseFloat(value)) && isFinite(value);
export interface SiderContextProps {
siderCollapsed?: boolean;
}
@ -152,7 +153,6 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>((props, ref) => {
handleSetCollapsed(!collapsed, 'clickTrigger');
};
const renderSider = () => {
const divProps = omit(otherProps, ['collapsed']);
const rawWidth = collapsed ? collapsedWidth : width;
// use "px" as fallback unit for width
@ -171,11 +171,14 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>((props, ref) => {
{trigger || <BarsOutlined />}
</span>
) : null;
const reverseIcon = (direction === 'rtl') === !reverseArrow;
const iconObj = {
expanded: reverseIcon ? <RightOutlined /> : <LeftOutlined />,
collapsed: reverseIcon ? <LeftOutlined /> : <RightOutlined />,
};
const status = collapsed ? 'collapsed' : 'expanded';
const defaultTrigger = iconObj[status];
const triggerDom =
@ -208,18 +211,19 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>((props, ref) => {
hashId,
cssVarCls,
);
return (
const contextValue = React.useMemo<SiderContextProps>(
() => ({ siderCollapsed: collapsed }),
[collapsed],
);
return wrapCSSVar(
<SiderContext.Provider value={contextValue}>
<aside className={siderCls} {...divProps} style={divStyle} ref={ref}>
<div className={`${prefixCls}-children`}>{children}</div>
{collapsible || (below && zeroWidthTrigger) ? triggerDom : null}
</aside>
);
};
const contextValue = React.useMemo(() => ({ siderCollapsed: collapsed }), [collapsed]);
return wrapCSSVar(
<SiderContext.Provider value={contextValue}>{renderSider()}</SiderContext.Provider>,
</SiderContext.Provider>,
);
});

View File

@ -19,7 +19,7 @@ const genSiderStyle: GenerateStyle<LayoutToken, CSSObject> = (token) => {
headerHeight,
zeroTriggerWidth,
zeroTriggerHeight,
borderRadius,
borderRadiusLG,
lightSiderBg,
lightTriggerColor,
lightTriggerBg,
@ -74,7 +74,7 @@ const genSiderStyle: GenerateStyle<LayoutToken, CSSObject> = (token) => {
overflow: 'hidden',
},
[`${componentCls}-zero-width-trigger`]: {
'&-trigger': {
position: 'absolute',
top: headerHeight,
insetInlineEnd: token.calc(zeroTriggerWidth).mul(-1).equal(),
@ -87,11 +87,7 @@ const genSiderStyle: GenerateStyle<LayoutToken, CSSObject> = (token) => {
alignItems: 'center',
justifyContent: 'center',
background: siderBg,
borderStartStartRadius: 0,
borderStartEndRadius: borderRadius,
borderEndEndRadius: borderRadius,
borderEndStartRadius: 0,
borderRadius: `0 ${unit(borderRadiusLG)} ${unit(borderRadiusLG)} 0`,
cursor: 'pointer',
transition: `background ${motionDurationSlow} ease`,
@ -109,10 +105,7 @@ const genSiderStyle: GenerateStyle<LayoutToken, CSSObject> = (token) => {
'&-right': {
insetInlineStart: token.calc(zeroTriggerWidth).mul(-1).equal(),
borderStartStartRadius: borderRadius,
borderStartEndRadius: 0,
borderEndEndRadius: 0,
borderEndStartRadius: borderRadius,
borderRadius: `${unit(borderRadiusLG)} 0 0 ${unit(borderRadiusLG)}`,
},
},
},

View File

@ -24,7 +24,7 @@ const localeValues: Locale = {
selectAll: 'Cari səhifəni seç',
selectInvert: 'Mövcud səhifənin elementlərinin sırasını tərs çevir',
filterEmptyText: 'Filter yoxdur',
filterCheckall: 'Bütün maddələri seç',
filterCheckAll: 'Bütün maddələri seç',
filterSearchPlaceholder: 'Filterlərdə axtar',
selectNone: 'Bütün məlumatı sil',
selectionAll: 'Bütün məlumatı seç',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Скінуць',
filterEmptyText: 'Без фільтраў',
filterCheckall: 'Выбраць усё',
filterCheckAll: 'Выбраць усё',
filterSearchPlaceholder: 'Пошук фільтраў',
emptyText: 'Няма даных',
selectAll: 'Выбраць усё',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Potvrdit',
filterReset: 'Obnovit',
filterEmptyText: 'Žádné filtry',
filterCheckall: 'Vybrat všechny položky',
filterCheckAll: 'Vybrat všechny položky',
filterSearchPlaceholder: 'Vyhledat ve filtrech',
emptyText: 'Žádná data',
selectAll: 'Vybrat všechny řádky na současné stránce',

View File

@ -22,7 +22,7 @@ const localeValues: Locale = {
filterReset: 'Zurücksetzen',
filterEmptyText: 'Keine Filter',
filterSearchPlaceholder: 'Suche in Filtern',
filterCheckall: 'Alle auswählen',
filterCheckAll: 'Alle auswählen',
selectAll: 'Selektiere Alle',
selectInvert: 'Selektion Invertieren',
selectionAll: 'Wählen Sie alle Daten aus',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'ΟΚ',
filterReset: 'Επαναφορά',
filterEmptyText: 'Χωρίς φίλτρα',
filterCheckall: 'Επιλογή όλων',
filterCheckAll: 'Επιλογή όλων',
filterSearchPlaceholder: 'Αναζήτηση στα φίλτρα',
emptyText: 'Δεν υπάρχουν δεδομένα',
selectAll: 'Επιλογή τρέχουσας σελίδας',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Reset',
filterEmptyText: 'No filters',
filterCheckall: 'Select all items',
filterCheckAll: 'Select all items',
filterSearchPlaceholder: 'Search in filters',
emptyText: 'No data',
selectAll: 'Select current page',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Reset',
filterEmptyText: 'No filters',
filterCheckall: 'Select all items',
filterCheckAll: 'Select all items',
filterSearchPlaceholder: 'Search in filters',
emptyText: 'No data',
selectAll: 'Select current page',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Aceptar',
filterReset: 'Reiniciar',
filterEmptyText: 'Sin filtros',
filterCheckall: 'Seleccionar todo',
filterCheckAll: 'Seleccionar todo',
filterSearchPlaceholder: 'Buscar en filtros',
emptyText: 'Sin datos',
selectAll: 'Seleccionar todo',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Nulli',
filterEmptyText: 'Filtreid pole',
filterCheckall: 'Vali kõik',
filterCheckAll: 'Vali kõik',
filterSearchPlaceholder: 'Otsi filtritest',
emptyText: 'Andmed puuduvad',
selectAll: 'Vali kõik',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Onartu',
filterReset: 'Garbitu',
filterEmptyText: 'Iragazkirik gabe',
filterCheckall: 'Hautatu dena',
filterCheckAll: 'Hautatu dena',
filterSearchPlaceholder: 'Bilatu iragazkietan',
emptyText: 'Daturik gabe',
selectAll: 'Hautatu dena',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'تایید',
filterReset: 'پاک کردن',
filterEmptyText: 'بدون فیلتر',
filterCheckall: 'انتخاب همه‌ی موارد',
filterCheckAll: 'انتخاب همه‌ی موارد',
filterSearchPlaceholder: 'جستجو در فیلترها',
emptyText: 'بدون داده',
selectAll: 'انتخاب صفحه‌ی کنونی',

View File

@ -18,7 +18,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Réinitialiser',
filterEmptyText: 'Aucun filtre',
filterCheckall: 'Tout sélectionner',
filterCheckAll: 'Tout sélectionner',
filterSearchPlaceholder: 'Chercher dans les filtres',
emptyText: 'Aucune donnée',
selectAll: 'Sélectionner la page actuelle',

View File

@ -18,7 +18,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Réinitialiser',
filterEmptyText: 'Aucun filtre',
filterCheckall: 'Tout sélectionner',
filterCheckAll: 'Tout sélectionner',
filterSearchPlaceholder: 'Chercher dans les filtres',
emptyText: 'Aucune donnée',
selectAll: 'Sélectionner la page actuelle',

View File

@ -18,7 +18,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Réinitialiser',
filterEmptyText: 'Aucun filtre',
filterCheckall: 'Tout sélectionner',
filterCheckAll: 'Tout sélectionner',
filterSearchPlaceholder: 'Chercher dans les filtres',
emptyText: 'Aucune donnée',
selectAll: 'Sélectionner la page actuelle',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Reset',
filterEmptyText: 'Tidak ada filter',
filterCheckall: 'Pilih semua item',
filterCheckAll: 'Pilih semua item',
filterSearchPlaceholder: 'Cari di filter',
emptyText: 'Tidak ada data',
selectAll: 'Pilih halaman saat ini',

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import type { ValidateMessages } from 'rc-field-form/lib/interface';
import type { ValidateMessages } from '@rc-component/form/lib/interface';
import { devUseWarning } from '../_util/warning';
import type { PickerLocale as DatePickerLocale } from '../date-picker/generatePicker';

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Reset',
filterEmptyText: 'Senza filtri',
filterCheckall: 'Seleziona tutti',
filterCheckAll: 'Seleziona tutti',
filterSearchPlaceholder: 'Cerca nei filtri',
emptyText: 'Senza dati',
selectAll: 'Seleziona pagina corrente',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'リセット',
filterEmptyText: 'フィルターなし',
filterCheckall: 'すべてを選択',
filterCheckAll: 'すべてを選択',
filterSearchPlaceholder: 'フィルターで検索',
emptyText: 'データなし',
selectAll: 'ページ単位で選択',

View File

@ -26,7 +26,7 @@ const localeValues: Locale = {
selectInvert: 'ಪ್ರಸ್ತುತ ಪುಟವನ್ನು ತಿರುಗಿಸಿ',
sortTitle: 'ವಿಂಗಡಿಸಿ',
filterEmptyText: 'ಫಿಲ್ಟರ್ ಇಲ್ಲ',
filterCheckall: 'ಎಲ್ಲಾ ಐಟಂಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ',
filterCheckAll: 'ಎಲ್ಲಾ ಐಟಂಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ',
filterSearchPlaceholder: 'ಫಿಲ್ಟರ್‌ಗಳೊಂದಿಗೆ ಹುಡುಕಿ',
selectNone: 'ಯಾವುದನ್ನೂ ಆಯ್ಕೆ ಮಾಡಬೇಡಿ',
selectionAll: 'ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಆಯ್ಕೆಮಾಡಿ',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: '확인',
filterReset: '초기화',
filterEmptyText: '필터 없음',
filterCheckall: '전체 선택',
filterCheckAll: '전체 선택',
filterSearchPlaceholder: '필터 검색',
emptyText: '데이터 없음',
selectAll: '전체 선택',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Gerai',
filterReset: 'Atstatyti',
filterEmptyText: 'Be filtrų',
filterCheckall: 'Pasirinkti visus',
filterCheckAll: 'Pasirinkti visus',
filterSearchPlaceholder: 'Ieškoti filtruose',
emptyText: 'Nėra duomenų',
selectAll: 'Pasirinkti viską',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Тийм',
filterReset: 'Цэвэрлэх',
filterEmptyText: 'Шүүлтүүр байхгүй',
filterCheckall: 'Бүх зүйлийг сонгоно уу',
filterCheckAll: 'Бүх зүйлийг сонгоно уу',
filterSearchPlaceholder: 'Шүүлтүүрээс хайх',
emptyText: 'Өгөгдөл алга',
selectAll: 'Бүгдийг сонгох',

View File

@ -24,7 +24,7 @@ const localeValues: Locale = {
selectAll: 'Pilih Semua',
selectInvert: 'Terbalikkan',
filterEmptyText: 'Tiada Saringan',
filterCheckall: 'Semak Semua',
filterCheckAll: 'Semak Semua',
filterSearchPlaceholder: 'Cari',
selectNone: 'Kosong Semua',
selectionAll: 'Semua Data',

View File

@ -22,7 +22,7 @@ const localeValues: Locale = {
filterConfirm: 'အိုကေ',
filterReset: 'ပြန်လည်သတ်မှတ်ပါ။',
filterEmptyText: 'စစ်ထုတ်မှုများမရှိပါ။',
filterCheckall: 'ပစ္စည်းအားလုံးကို ရွေးပါ။',
filterCheckAll: 'ပစ္စည်းအားလုံးကို ရွေးပါ။',
filterSearchPlaceholder: 'စစ်ထုတ်မှုများတွင် ရှာဖွေပါ။',
selectAll: 'လက်ရှိစာမျက်နှာကို ရွေးပါ။',
selectInvert: 'လက်ရှိစာမျက်နှာကို ပြောင်းလိုက်ပါ။',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'हो',
filterReset: 'रीसेट',
filterEmptyText: 'कुनै फिल्टर छैन',
filterCheckall: 'सबै छान्नु',
filterCheckAll: 'सबै छान्नु',
filterSearchPlaceholder: 'फिल्टर भित्र खोज्नुहोस्',
emptyText: 'डाटा छैन',
selectAll: 'सबै छान्नुुहोस्',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Usuń filtry',
filterEmptyText: 'Brak filtrów',
filterCheckall: 'Wybierz wszystkie elementy',
filterCheckAll: 'Wybierz wszystkie elementy',
filterSearchPlaceholder: 'Szukaj w filtrach',
emptyText: 'Brak danych',
selectAll: 'Zaznacz bieżącą stronę',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Resetar',
filterEmptyText: 'Sem filtros',
filterCheckall: 'Selecionar todos os itens',
filterCheckAll: 'Selecionar todos os itens',
filterSearchPlaceholder: 'Pesquisar nos filtros',
emptyText: 'Sem conteúdo',
selectAll: 'Selecionar página atual',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Aplicar',
filterReset: 'Repor',
filterEmptyText: 'Sem filtros',
filterCheckall: 'Selecionar todos os itens',
filterCheckAll: 'Selecionar todos os itens',
filterSearchPlaceholder: 'Pesquisar nos filtros',
emptyText: 'Sem dados',
selectAll: 'Selecionar página atual',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Сбросить',
filterEmptyText: 'Без фильтров',
filterCheckall: 'Выбрать все элементы',
filterCheckAll: 'Выбрать все элементы',
filterSearchPlaceholder: 'Поиск в фильтрах',
emptyText: 'Нет данных',
selectAll: 'Выбрать всё',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'හරි',
filterReset: 'යළි සකසන්න',
filterEmptyText: 'පෙරහන් නැත',
filterCheckall: 'සියළු අථක තෝරන්න',
filterCheckAll: 'සියළු අථක තෝරන්න',
filterSearchPlaceholder: 'පෙරහන් තුළ සොයන්න',
emptyText: 'දත්ත නැත',
selectAll: 'වත්මන් පිටුව තෝරන්න',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Obnoviť',
filterEmptyText: 'Žiadne filtre',
filterCheckall: 'Vyber všetky položky',
filterCheckAll: 'Vyber všetky položky',
filterSearchPlaceholder: 'Vyhľadaj vo filtroch',
emptyText: 'Žiadne dáta',
selectAll: 'Označ všetky položky',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Återställ',
filterEmptyText: 'Inga filter',
filterCheckall: 'Markera alla objekt',
filterCheckAll: 'Markera alla objekt',
filterSearchPlaceholder: 'Sök i filter',
emptyText: 'Ingen data',
selectAll: 'Markera nuvarande sida',

View File

@ -26,7 +26,7 @@ const localeValues: Locale = {
selectInvert: 'தலைகீழாக மாற்று',
sortTitle: 'தலைப்பை வரிசைப்படுத்தவும்',
filterEmptyText: 'No filters',
filterCheckall: 'அனைத்து பொருட்களையும் தேர்ந்தெடுக்கவும்',
filterCheckAll: 'அனைத்து பொருட்களையும் தேர்ந்தெடுக்கவும்',
filterSearchPlaceholder: 'வடிப்பான்களில் தேடவும்',
expand: 'வரிசையை விரிவாக்கு',
collapse: 'வரிசையைச் சுருக்கு',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'ยืนยัน',
filterReset: 'รีเซ็ต',
filterEmptyText: 'ไม่มีตัวกรอง',
filterCheckall: 'เลือกรายการทั้งหมด',
filterCheckAll: 'เลือกรายการทั้งหมด',
filterSearchPlaceholder: 'ค้นหาตัวกรอง',
emptyText: 'ไม่มีข้อมูล',
selectAll: 'เลือกทั้งหมดในหน้านี้',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Tamam',
filterReset: 'Sıfırla',
filterEmptyText: 'Filtre yok',
filterCheckall: 'Tümünü seç',
filterCheckAll: 'Tümünü seç',
selectAll: 'Tüm sayfayı seç',
selectInvert: 'Tersini seç',
selectionAll: 'Tümünü seç',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Скинути',
filterEmptyText: 'Фільтри відсутні',
filterCheckall: 'Обрати всі',
filterCheckAll: 'Обрати всі',
filterSearchPlaceholder: 'Пошук у фільтрах',
emptyText: 'Даних немає',
selectAll: 'Обрати всі на сторінці',

View File

@ -26,7 +26,7 @@ const localeValues: Locale = {
filterConfirm: 'OK',
filterReset: 'Bekor qilish',
filterEmptyText: 'Filtrlarsiz',
filterCheckall: 'Barcha elementlarni tanlash',
filterCheckAll: 'Barcha elementlarni tanlash',
filterSearchPlaceholder: 'Filtrlarda qidiruv',
emptyText: "Ma'lumotlar topilmadi",
selectAll: 'Barchasini tanlash',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: 'Đồng ý',
filterReset: 'Bỏ lọc',
filterEmptyText: 'Không có bộ lọc',
filterCheckall: 'Chọn tất cả',
filterCheckAll: 'Chọn tất cả',
filterSearchPlaceholder: 'Tìm kiếm bộ lọc',
emptyText: 'Trống',
selectAll: 'Chọn tất cả',

View File

@ -22,7 +22,7 @@ const localeValues: Locale = {
filterConfirm: '确定',
filterReset: '重置',
filterEmptyText: '无筛选项',
filterCheckall: '全选',
filterCheckAll: '全选',
filterSearchPlaceholder: '在筛选项中搜索',
emptyText: '暂无数据',
selectAll: '全选当页',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: '確定',
filterReset: '重置',
filterEmptyText: '無篩選項',
filterCheckall: '全選',
filterCheckAll: '全選',
filterSearchPlaceholder: '在篩選項中搜尋',
emptyText: '暫無數據',
selectAll: '全部選取',

View File

@ -21,7 +21,7 @@ const localeValues: Locale = {
filterConfirm: '確定',
filterReset: '重置',
filterEmptyText: '無篩選項',
filterCheckall: '全選',
filterCheckAll: '全選',
filterSearchPlaceholder: '在篩選項中搜尋',
emptyText: '暫無數據',
selectAll: '全部選取',

View File

@ -1,4 +1,5 @@
import React from 'react';
import { render as testLibRender } from '@testing-library/react';
import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
import notification from '..';
@ -235,4 +236,39 @@ describe('notification.hooks', () => {
});
expect(getNoticeCount()).toBe(0);
});
it('should hide close btn when closeIcon setting to null or false', () => {
const Demo = () => {
const Holder = (className: string, closeIcon?: React.ReactNode) => {
const [api, holder] = notification.useNotification({ closeIcon });
React.useEffect(() => {
api.info({
className,
message: 'Notification Title',
duration: 0,
});
}, []);
return holder;
};
return (
<>
{Holder('normal')}
{Holder('custom', <span className="custom-close-icon">Close</span>)}
{Holder('with-null', null)}
{Holder('with-false', false)}
</>
);
};
// We use origin testing lib here since StrictMode will render multiple times
testLibRender(<Demo />);
expect(document.querySelectorAll('.normal .ant-notification-notice-close').length).toBe(1);
expect(document.querySelectorAll('.custom .custom-close-icon').length).toBe(1);
expect(document.querySelectorAll('.with-null .ant-notification-notice-close').length).toBe(0);
expect(document.querySelectorAll('.with-false .ant-notification-notice-close').length).toBe(0);
});
});

View File

@ -78,4 +78,5 @@ export interface NotificationConfig {
duration?: number;
showProgress?: boolean;
pauseOnHover?: boolean;
closeIcon?: React.ReactNode;
}

View File

@ -74,7 +74,8 @@ const genStackStyle: GenerateStyle<NotificationToken> = (token) => {
return {
[`${componentCls}-stack`]: {
[`& > ${componentCls}-notice-wrapper`]: {
transition: `all ${token.motionDurationSlow}, backdrop-filter 0s`,
transition: `transform ${token.motionDurationSlow}, backdrop-filter 0s`,
willChange: 'transform, opacity',
position: 'absolute',
...genStackChildrenStyle(token),

View File

@ -17,7 +17,7 @@ import type {
} from './interface';
import { getCloseIcon, PureContent } from './PurePanel';
import useStyle from './style';
import { getMotion, getPlacementStyle } from './util';
import { getMotion, getPlacementStyle, getCloseIconConfig } from './util';
const DEFAULT_OFFSET = 24;
const DEFAULT_DURATION = 4.5;
@ -158,7 +158,7 @@ export function useInternalNotification(
const realCloseIcon = getCloseIcon(
noticePrefixCls,
typeof closeIcon !== 'undefined' ? closeIcon : notification?.closeIcon,
getCloseIconConfig(closeIcon, notificationConfig, notification),
);
return originOpen({

View File

@ -1,7 +1,8 @@
import type * as React from 'react';
import type { CSSMotionProps } from 'rc-motion';
import type { NotificationPlacement } from './interface';
import type { NotificationConfig, NotificationPlacement } from './interface';
import type { NotificationConfig as CPNotificationConfig } from '../config-provider/context';
export function getPlacementStyle(placement: NotificationPlacement, top: number, bottom: number) {
let style: React.CSSProperties;
@ -67,3 +68,17 @@ export function getMotion(prefixCls: string): CSSMotionProps {
motionName: `${prefixCls}-fade`,
};
}
export function getCloseIconConfig(
closeIcon: React.ReactNode,
notificationConfig?: NotificationConfig,
notification?: CPNotificationConfig,
) {
if (typeof closeIcon !== 'undefined') {
return closeIcon;
}
if (typeof notificationConfig?.closeIcon !== 'undefined') {
return notificationConfig.closeIcon;
}
return notification?.closeIcon;
}

View File

@ -6,6 +6,7 @@ import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
import Button from '../../button';
import ConfigProvider from '../../config-provider';
// TODO: Remove this. Mock for React 19
jest.mock('react-dom', () => {
@ -353,4 +354,67 @@ describe('Popconfirm', () => {
expect(popconfirmElement.style.backgroundColor).toBe('blue');
expect(popconfirmBodyElement.style.color).toBe('red');
});
it('ConfigProvider support arrow props', () => {
const TooltipTestComponent = () => {
const [configArrow, setConfigArrow] = React.useState(true);
return (
<ConfigProvider
popconfirm={{
arrow: configArrow,
}}
>
<button onClick={() => setConfigArrow(false)} className="configArrow" type="button">
showconfigArrow
</button>
<Popconfirm open title>
<div className="target">target</div>
</Popconfirm>
</ConfigProvider>
);
};
const { container } = render(<TooltipTestComponent />);
const getTooltipArrow = () => container.querySelector('.ant-popover-arrow');
const configbtn = container.querySelector('.configArrow');
expect(getTooltipArrow()).not.toBeNull();
fireEvent.click(configbtn!);
expect(getTooltipArrow()).toBeNull();
});
it('ConfigProvider with arrow set to false, Tooltip arrow controlled by prop', () => {
const TooltipTestComponent = () => {
const [arrow, setArrow] = React.useState(true);
return (
<ConfigProvider
popover={{
arrow: false,
}}
>
<button onClick={() => setArrow(!arrow)} className="toggleArrow" type="button">
toggleArrow
</button>
<Popconfirm open arrow={arrow} title>
<div className="target">target</div>
</Popconfirm>
</ConfigProvider>
);
};
const { container } = render(<TooltipTestComponent />);
const getTooltipArrow = () => container.querySelector('.ant-popover-arrow');
const toggleArrowBtn = container.querySelector('.toggleArrow');
// Initial render, arrow should be visible because Tooltip's arrow prop is true
expect(getTooltipArrow()).not.toBeNull();
// Click the toggleArrow button to hide the arrow
fireEvent.click(toggleArrowBtn!);
expect(getTooltipArrow()).toBeNull();
// Click the toggleArrow button again to show the arrow
fireEvent.click(toggleArrowBtn!);
expect(getTooltipArrow()).not.toBeNull();
});
});

View File

@ -6,7 +6,7 @@ import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点 (包含箭头、内容元素)',
root: '根元素 (包含箭头、内容元素)',
body: '内容元素',
},
en: {

View File

@ -10,6 +10,7 @@ import { ConfigContext } from '../config-provider';
import type { PopoverProps } from '../popover';
import Popover from '../popover';
import type { AbstractTooltipProps, TooltipRef } from '../tooltip';
import useMergedArrow from '../tooltip/hook/useMergedArrow';
import PurePanel, { Overlay } from './PurePanel';
import useStyle from './style';
@ -49,6 +50,7 @@ const InternalPopconfirm = React.forwardRef<TooltipRef, PopconfirmProps>((props,
onOpenChange,
overlayStyle,
styles,
arrow: popconfirmArrow,
classNames: popconfirmClassNames,
...restProps
} = props;
@ -58,6 +60,7 @@ const InternalPopconfirm = React.forwardRef<TooltipRef, PopconfirmProps>((props,
value: props.open,
defaultValue: props.defaultOpen,
});
const mergedArrow = useMergedArrow(popconfirmArrow, popconfirm?.arrow);
const settingOpen: PopoverProps['onOpenChange'] = (value, e) => {
setOpen(value, true);
@ -96,6 +99,7 @@ const InternalPopconfirm = React.forwardRef<TooltipRef, PopconfirmProps>((props,
return wrapCSSVar(
<Popover
arrow={mergedArrow}
{...omit(restProps, ['title'])}
trigger={trigger}
placement={placement}

View File

@ -166,4 +166,67 @@ describe('Popover', () => {
expect(popoverElement.style.backgroundColor).toBe('blue');
expect(popoverBodyElement.style.color).toBe('red');
});
it('ConfigProvider support arrow props', () => {
const TooltipTestComponent = () => {
const [configArrow, setConfigArrow] = React.useState(true);
return (
<ConfigProvider
popover={{
arrow: configArrow,
}}
>
<button onClick={() => setConfigArrow(false)} className="configArrow" type="button">
showconfigArrow
</button>
<Popover open>
<div className="target">target</div>
</Popover>
</ConfigProvider>
);
};
const { container } = render(<TooltipTestComponent />);
const getTooltipArrow = () => container.querySelector('.ant-popover-arrow');
const configbtn = container.querySelector('.configArrow');
expect(getTooltipArrow()).not.toBeNull();
fireEvent.click(configbtn!);
expect(getTooltipArrow()).toBeNull();
});
it('ConfigProvider with arrow set to false, Tooltip arrow controlled by prop', () => {
const TooltipTestComponent = () => {
const [arrow, setArrow] = React.useState(true);
return (
<ConfigProvider
popover={{
arrow: false,
}}
>
<button onClick={() => setArrow(!arrow)} className="toggleArrow" type="button">
toggleArrow
</button>
<Popover open arrow={arrow}>
<div className="target">target</div>
</Popover>
</ConfigProvider>
);
};
const { container } = render(<TooltipTestComponent />);
const getTooltipArrow = () => container.querySelector('.ant-popover-arrow');
const toggleArrowBtn = container.querySelector('.toggleArrow');
// Initial render, arrow should be visible because Tooltip's arrow prop is true
expect(getTooltipArrow()).not.toBeNull();
// Click the toggleArrow button to hide the arrow
fireEvent.click(toggleArrowBtn!);
expect(getTooltipArrow()).toBeNull();
// Click the toggleArrow button again to show the arrow
fireEvent.click(toggleArrowBtn!);
expect(getTooltipArrow()).not.toBeNull();
});
});

View File

@ -6,7 +6,7 @@ import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点 (包含箭头、内容元素)',
root: '根元素 (包含箭头、内容元素)',
body: '内容元素',
},
en: {

View File

@ -10,6 +10,7 @@ import { cloneElement } from '../_util/reactNode';
import { ConfigContext } from '../config-provider';
import type { AbstractTooltipProps, TooltipRef } from '../tooltip';
import Tooltip from '../tooltip';
import useMergedArrow from '../tooltip/hook/useMergedArrow';
import PurePanel, { Overlay } from './PurePanel';
// CSSINJS
import useStyle from './style';
@ -39,13 +40,15 @@ const InternalPopover = React.forwardRef<TooltipRef, PopoverProps>((props, ref)
styles,
classNames: popoverClassNames,
motion,
...otherProps
arrow: popoverArrow,
...restProps
} = props;
const { popover, getPrefixCls } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('popover', customizePrefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
const rootPrefixCls = getPrefixCls();
const mergedArrow = useMergedArrow(popoverArrow, popover?.arrow);
const rootClassNames = classNames(
overlayClassName,
@ -84,11 +87,12 @@ const InternalPopover = React.forwardRef<TooltipRef, PopoverProps>((props, ref)
return wrapCSSVar(
<Tooltip
arrow={mergedArrow}
placement={placement}
trigger={trigger}
mouseEnterDelay={mouseEnterDelay}
mouseLeaveDelay={mouseLeaveDelay}
{...otherProps}
{...restProps}
prefixCls={prefixCls}
classNames={{ root: rootClassNames, body: bodyClassNames }}
styles={{

View File

@ -9383,6 +9383,41 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
</div>
</div>
</div>
<div
class="ant-space-item"
>
<div
class="ant-space-compact"
>
<button
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-compact-item ant-btn-compact-first-item"
type="button"
>
<span>
Button
</span>
</button>
<span
class="ant-input-group-wrapper ant-input-group-wrapper-outlined ant-input-compact-item ant-input-compact-last-item"
>
<span
class="ant-input-wrapper ant-input-group"
>
<input
class="ant-input ant-input-outlined"
placeholder="input here"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
$
</span>
</span>
</span>
</div>
</div>
</div>
`;

View File

@ -2040,6 +2040,41 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
</div>
</div>
</div>
<div
class="ant-space-item"
>
<div
class="ant-space-compact"
>
<button
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-compact-item ant-btn-compact-first-item"
type="button"
>
<span>
Button
</span>
</button>
<span
class="ant-input-group-wrapper ant-input-group-wrapper-outlined ant-input-compact-item ant-input-compact-last-item"
>
<span
class="ant-input-wrapper ant-input-group"
>
<input
class="ant-input ant-input-outlined"
placeholder="input here"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
$
</span>
</span>
</span>
</div>
</div>
</div>
`;

View File

@ -202,6 +202,10 @@ const App: React.FC = () => (
<Input placeholder="input here" />
<ColorPicker />
</Space.Compact>
<Space.Compact>
<Button type="primary">Button</Button>
<Input placeholder="input here" addonAfter="$" />
</Space.Compact>
</Space>
);

View File

@ -89,7 +89,7 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
useSizes(items, containerSize);
// ====================== Resizable =======================
const resizableInfos = useResizable(items, itemPxSizes);
const resizableInfos = useResizable(items, itemPxSizes, isRTL);
const [onOffsetStart, onOffsetUpdate, onOffsetEnd, onCollapse, movingIndex] = useResize(
items,
@ -97,6 +97,7 @@ const Splitter: React.FC<React.PropsWithChildren<SplitterProps>> = (props) => {
itemPtgSizes,
containerSize,
updateSizes,
isRTL,
);
// ======================== Events ========================

View File

@ -8,7 +8,7 @@ export type ResizableInfo = {
endCollapsible: boolean;
};
export default function useResizable(items: ItemType[], pxSizes: number[]) {
export default function useResizable(items: ItemType[], pxSizes: number[], isRTL: boolean) {
return React.useMemo(() => {
const resizeInfos: ResizableInfo[] = [];
@ -52,8 +52,8 @@ export default function useResizable(items: ItemType[], pxSizes: number[]) {
resizeInfos[i] = {
resizable: mergedResizable,
startCollapsible: !!startCollapsible,
endCollapsible: !!endCollapsible,
startCollapsible: !!(isRTL ? endCollapsible : startCollapsible),
endCollapsible: !!(isRTL ? startCollapsible : endCollapsible),
};
}

View File

@ -13,6 +13,7 @@ export default function useResize(
percentSizes: number[],
containerSize: number | undefined,
updateSizes: (sizes: number[]) => void,
isRTL: boolean,
) {
const limitSizes = items.map((item) => [item.min, item.max]);
@ -119,9 +120,10 @@ export default function useResize(
// ======================= Collapse =======================
const onCollapse = (index: number, type: 'start' | 'end') => {
const currentSizes = getPxSizes();
const adjustedType = isRTL ? (type === 'start' ? 'end' : 'start') : type;
const currentIndex = type === 'start' ? index : index + 1;
const targetIndex = type === 'start' ? index + 1 : index;
const currentIndex = adjustedType === 'start' ? index : index + 1;
const targetIndex = adjustedType === 'start' ? index + 1 : index;
const currentSize = currentSizes[currentIndex];
const targetSize = currentSizes[targetIndex];

View File

@ -7,7 +7,7 @@ import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点',
root: '根元素',
header: '头部元素',
title: '标题元素',
content: '内容元素',

View File

@ -203,6 +203,11 @@ const FilterDropdown = <RecordType extends AnyObject = AnyObject>(
deprecatedList.forEach(([deprecatedName, newName]) => {
warning.deprecated(!(deprecatedName in column), deprecatedName, newName);
});
warning.deprecated(
!('filterCheckall' in locale),
'filterCheckall' as 'deprecated',
'locale.filterCheckAll',
);
}
const mergedVisible =
@ -416,7 +421,7 @@ const FilterDropdown = <RecordType extends AnyObject = AnyObject>(
className={`${tablePrefixCls}-filter-dropdown-checkall`}
onChange={onCheckAll}
>
{locale.filterCheckall}
{locale?.filterCheckall ?? locale?.filterCheckAll}
</Checkbox>
) : null}
<Tree<FilterTreeDataNode>

View File

@ -43,7 +43,11 @@ export interface TableLocale {
filterConfirm?: React.ReactNode;
filterReset?: React.ReactNode;
filterEmptyText?: React.ReactNode;
/**
* @deprecated Please use `filterCheckAll` instead.
*/
filterCheckall?: React.ReactNode;
filterCheckAll?: React.ReactNode;
filterSearchPlaceholder?: string;
emptyText?: React.ReactNode | (() => React.ReactNode);
selectAll?: React.ReactNode;

View File

@ -4,7 +4,11 @@ import { ConfigProvider, Flex, Tag } from 'antd';
const App: React.FC = () => (
<ConfigProvider
theme={{ components: { Tag: { defaultBg: '#f9f0ff', defaultColor: '#4b34d3' } } }}
theme={{
components: {
Tag: { defaultBg: '#f9f0ff', defaultColor: '#4b34d3', colorBorderDisabled: '#FF0000' },
},
}}
>
<Flex gap="small" align="center" wrap>
<Tag>
@ -38,6 +42,9 @@ const App: React.FC = () => (
<Tag icon={<SyncOutlined spin />} color="processing">
processing
</Tag>
<Tag color="success" disabled>
disabled
</Tag>
</Flex>
</ConfigProvider>
);

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