feat: merge master

This commit is contained in:
叶枫 2023-12-27 14:42:51 +08:00
commit 81ab20be35
28 changed files with 270 additions and 231 deletions

View File

@ -1,7 +1,8 @@
import { RightOutlined, YuqueOutlined, ZhihuOutlined } from '@ant-design/icons';
import { createStyles } from 'antd-style';
import React from 'react';
import { RightOutlined, YuqueOutlined, ZhihuOutlined } from '@ant-design/icons';
import { Button, Card, Divider } from 'antd';
import { createStyles } from 'antd-style';
import useLocale from '../../../hooks/useLocale';
import JuejinLogo from './JuejinLogo';
@ -10,81 +11,81 @@ const ANTD_IMG_URL =
const useStyle = createStyles(({ token, css }) => ({
card: css`
width: 100%;
margin: 40px 0;
transition: all 0.2s;
background-color: ${token.colorFillQuaternary};
`,
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;
`,
font-size: 16px;
color: #121212;
margin-bottom: 24px;
font-weight: 600;
`,
cardBody: css`
display: flex;
justify-content: space-between;
align-items: center;
`,
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;
display: flex;
justify-content: flex-start;
align-items: center;
img {
width: 200px;
margin-right: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.logo {
width: 24px;
height: 24px;
font-size: 24px;
&.zhihu-logo {
color: #056de8;
}
&.yuque-logo {
color: #00b96b;
}
&.juejin-logo {
color: #1e80ff;
}
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 {
width: 24px;
height: 24px;
font-size: 24px;
&.zhihu-logo {
color: #056de8;
}
.arrowIcon {
margin: 0 8px;
color: #8a8f8d;
font-size: 12px;
&.yuque-logo {
color: #00b96b;
}
.zl-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 0;
color: #646464;
&.juejin-logo {
color: #1e80ff;
}
`,
btn: css`
}
.arrowIcon {
margin: 0 8px;
color: #8a8f8d;
font-size: 12px;
}
.zl-btn {
display: flex;
justify-content: center;
align-items: center;
`,
justify-content: center;
padding: 0;
color: #646464;
}
`,
btn: css`
display: flex;
justify-content: center;
align-items: center;
`,
}));
const locales = {

View File

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

View File

@ -1,48 +1,40 @@
import React, { useContext } from 'react';
import ContributorsList from '@qixian.cs/github-contributors-list';
import { createStyles } from 'antd-style';
import classNames from 'classnames';
import { useIntl } from 'dumi';
import { createStyles } from 'antd-style';
import ContributorsList from '@qixian.cs/github-contributors-list';
import ContributorAvatar from './ContributorAvatar';
import SiteContext from '../SiteContext';
import ContributorAvatar from './ContributorAvatar';
const useStyle = createStyles(({ token, css }) => {
const { antCls } = token;
return {
contributorsList: css`
const useStyle = createStyles(({ token, css }) => ({
contributorsList: css`
margin-top: 120px !important;
`,
listMobile: css`
margin: 1em 0 !important;
`,
title: css`
`,
listMobile: css`
margin: 1em 0 !important;
`,
title: css`
font-size: 12px;
opacity: 0.45;
opacity: 0.5;
margin-bottom: 8px;
`,
list: css`
display: flex;
flex-wrap: wrap;
clear: both;
li {
height: 24px;
}
li,
${antCls}-avatar + ${antCls}-avatar {
transition: all ${token.motionDurationSlow};
margin-inline-end: -8px;
}
&:hover {
li,
${antCls}-avatar {
margin-inline-end: 0;
list: css`
display: flex;
flex-wrap: wrap;
clear: both;
li {
height: 24px;
transition: all ${token.motionDurationSlow};
margin-inline-end: -8px;
}
&:hover {
li {
margin-inline-end: 0;
}
}
}
`,
};
});
}));
interface ContributorsProps {
filename?: string;
@ -67,12 +59,7 @@ const Contributors: React.FC<ContributorsProps> = ({ filename }) => {
fileName={filename}
className={styles.list}
renderItem={(item, loading) => (
<ContributorAvatar
key={item?.username}
username={item?.username}
url={item?.url}
loading={loading}
/>
<ContributorAvatar item={item} loading={loading} key={item?.url} />
)}
/>
</div>

View File

@ -1,7 +1,7 @@
import React, { useMemo } from 'react';
import classNames from 'classnames';
import { Anchor } from 'antd';
import { createStyles, useTheme } from 'antd-style';
import classNames from 'classnames';
import { useRouteMeta, useTabMeta } from 'dumi';
const useStyle = createStyles(({ token, css }) => {

View File

@ -1,8 +1,8 @@
import React, { useState, useLayoutEffect, useMemo } from 'react';
import { Typography, Space, Skeleton, Avatar } from 'antd';
import { useRouteMeta } from 'dumi';
import DayJS from 'dayjs';
import React, { useLayoutEffect, useMemo, useState } from 'react';
import { CalendarOutlined } from '@ant-design/icons';
import { Avatar, Skeleton, Space, Typography } from 'antd';
import DayJS from 'dayjs';
import { useRouteMeta } from 'dumi';
const AuthorAvatar: React.FC<{ name: string; avatar: string }> = ({ name, avatar }) => {
const [loading, setLoading] = useState(true);
@ -26,7 +26,7 @@ const AuthorAvatar: React.FC<{ name: string; avatar: string }> = ({ name, avatar
);
};
const DocMeta: React.FC<{}> = () => {
const DocMeta: React.FC = () => {
const meta = useRouteMeta();
const mergedAuthorInfos = useMemo(() => {

View File

@ -1,9 +1,9 @@
import React, { Suspense, useContext, useLayoutEffect, useMemo } from 'react';
import { Col, Skeleton, Space, Typography } from 'antd';
import { createStyles } from 'antd-style';
import classNames from 'classnames';
import { FormattedMessage, useRouteMeta } from 'dumi';
import type { ReactNode } from 'react';
import React, { Suspense, useContext, useLayoutEffect, useMemo } from 'react';
import { Col, Space, Typography, Skeleton } from 'antd';
import { createStyles } from 'antd-style';
import useLayoutState from '../../../hooks/useLayoutState';
import useLocation from '../../../hooks/useLocation';
import type { DemoContextProps } from '../DemoContext';
@ -21,22 +21,20 @@ const EditButton = React.lazy(() => import('../../common/EditButton'));
const useStyle = createStyles(({ token, css }) => ({
articleWrapper: css`
padding: 0 170px 32px 64px;
padding: 0 170px 32px 64px;
&.rtl {
padding: 0 64px 144px 170px;
}
@media only screen and (max-width: ${token.screenLG}px) {
&,
&.rtl {
padding: 0 64px 144px 170px;
padding: 0 48px;
}
@media only screen and (max-width: ${token.screenLG}px) {
&,
&.rtl {
padding: 0 48px;
}
}
`,
}
`,
}));
const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
const meta = useRouteMeta();
const { pathname, hash } = useLocation();
const { direction } = useContext(SiteContext);

View File

@ -1,9 +1,10 @@
import { defineConfig } from 'dumi';
import path from 'path';
import { defineConfig } from 'dumi';
import * as fs from 'fs-extra';
import rehypeAntd from './.dumi/rehypeAntd';
import remarkAntd from './.dumi/remarkAntd';
import { version } from './package.json';
import * as fs from 'fs-extra';
export default defineConfig({
plugins: ['dumi-plugin-color-chunk'],
@ -35,6 +36,8 @@ export default defineConfig({
'antd/es': path.join(__dirname, 'components'),
'antd/locale': path.join(__dirname, 'components/locale'),
antd: path.join(__dirname, 'components'),
// https://github.com/ant-design/ant-design/issues/46628
'@ant-design/icons$': '@ant-design/icons/lib',
},
extraRehypePlugins: [rehypeAntd],
extraRemarkPlugins: [remarkAntd],

View File

@ -2,14 +2,20 @@
name: PullRequest Contributor Welcome
on:
pull_request:
pull_request_target:
types:
- closed
paths:
- 'components/**'
permissions:
contents: read
jobs:
comment:
permissions:
issues: write # for actions-cool/maintain-one-comment to modify or create issue comments
pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments
if: github.event.pull_request.merged == true && github.repository == 'ant-design/ant-design'
runs-on: ubuntu-latest
steps:
@ -25,4 +31,4 @@ jobs:
<img src="https://github.com/ant-design/ant-design/assets/5378891/e24c6080-bf38-4523-b1cd-f6c43ad7375f" height="200" />
<!-- WELCOME_CONTRIBUTION -->
body-include: '<!-- WELCOME_CONTRIBUTION -->'
body-include: '<!-- WELCOME_CONTRIBUTION -->'

View File

@ -20,7 +20,7 @@ tag: vVERSION
`2023-12-22`
- 💄 修复 Tabs 在 可编辑模式下只剩新增按钮时按钮的样式问题[#46585](https://github.com/ant-design/ant-design/pull/46585) [@hzyhbk](https://github.com/hzyhbk)
- 💄 修复 Tabs 在可编辑模式下只剩新增按钮时的样式问题[#46585](https://github.com/ant-design/ant-design/pull/46585) [@hzyhbk](https://github.com/hzyhbk)
- 💄 修复 Progress `strokeLinecap` 不生效的问题。[#46551](https://github.com/ant-design/ant-design/pull/46551) [@ZN1996](https://github.com/ZN1996)
- 🐞 修复 ColorPicker 配置 `prefixCls` 不生效的问题。[#46561](https://github.com/ant-design/ant-design/pull/46561)

View File

@ -4,6 +4,7 @@ import type { BaseSelectRef } from 'rc-select';
import toArray from 'rc-util/lib/Children/toArray';
import omit from 'rc-util/lib/omit';
import { useZIndex } from '../_util/hooks/useZIndex';
import genPurePanel from '../_util/PurePanel';
import { isValidElement } from '../_util/reactNode';
import type { InputStatus } from '../_util/statusUtils';
@ -18,7 +19,6 @@ import type {
SelectProps,
} from '../select';
import Select from '../select';
import { useZIndex } from '../_util/hooks/useZIndex';
const { Option } = Select;
@ -161,9 +161,8 @@ const RefAutoComplete = React.forwardRef<RefSelectProps, AutoCompleteProps>(
ValueType = any,
OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,
>(
props: React.PropsWithChildren<AutoCompleteProps<ValueType, OptionType>> & {
ref?: React.Ref<BaseSelectRef>;
},
props: React.PropsWithChildren<AutoCompleteProps<ValueType, OptionType>> &
React.RefAttributes<BaseSelectRef>,
) => React.ReactElement) & {
displayName?: string;
Option: typeof Option;

View File

@ -363,7 +363,7 @@ const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref)
return wrapCascaderCSSVar(wrapSelectCSSVar(renderNode));
}) as unknown as (<OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(
props: React.PropsWithChildren<CascaderProps<OptionType>> & { ref?: React.Ref<CascaderRef> },
props: React.PropsWithChildren<CascaderProps<OptionType>> & React.RefAttributes<CascaderRef>,
) => React.ReactElement) & {
displayName: string;
SHOW_PARENT: typeof SHOW_PARENT;

View File

@ -1,26 +1,27 @@
import * as React from 'react';
import { useMemo } from 'react';
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 { InternalNamePath, ValidateErrorEntity } from 'rc-field-form/lib/interface';
import * as React from 'react';
import { useMemo } from 'react';
import type { Options } from 'scroll-into-view-if-needed';
import { ConfigContext } from '../config-provider';
import DisabledContext, { DisabledContextProvider } from '../config-provider/DisabledContext';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import useSize from '../config-provider/hooks/useSize';
import type { SizeType } from '../config-provider/SizeContext';
import SizeContext 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, VariantContext } from './context';
import type { FeedbackIcons } from './FormItem';
import useForm, { type FormInstance } from './hooks/useForm';
import useFormWarning from './hooks/useFormWarning';
import type { Variant } from './hooks/useVariants';
import type { FormLabelAlign } from './interface';
import useStyle from './style';
import ValidateMessagesContext from './validateMessagesContext';
import type { FeedbackIcons } from './FormItem';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import type { Variant } from './hooks/useVariants';
export type RequiredMark =
| boolean
@ -213,7 +214,7 @@ const InternalForm: React.ForwardRefRenderFunction<FormInstance, FormProps> = (p
};
const Form = React.forwardRef<FormInstance, FormProps>(InternalForm) as (<Values = any>(
props: React.PropsWithChildren<FormProps<Values>> & { ref?: React.Ref<FormInstance<Values>> },
props: React.PropsWithChildren<FormProps<Values>> & React.RefAttributes<FormInstance<Values>>,
) => React.ReactElement) & { displayName?: string };
if (process.env.NODE_ENV !== 'production') {

View File

@ -36,7 +36,7 @@ export type { CollapsePanelProps, CollapseProps } from './collapse';
export { default as ColorPicker } from './color-picker';
export type { ColorPickerProps } from './color-picker';
export { default as ConfigProvider } from './config-provider';
export type { ThemeConfig } from './config-provider';
export type { ConfigProviderProps, ThemeConfig } from './config-provider';
export { default as DatePicker } from './date-picker';
export type { DatePickerProps } from './date-picker';
export { default as Descriptions } from './descriptions';

View File

@ -1,22 +1,23 @@
import * as React from 'react';
import DownOutlined from '@ant-design/icons/DownOutlined';
import UpOutlined from '@ant-design/icons/UpOutlined';
import classNames from 'classnames';
import type { InputNumberProps as RcInputNumberProps, ValueType } from 'rc-input-number';
import RcInputNumber from 'rc-input-number';
import * as React from 'react';
import type { InputStatus } from '../_util/statusUtils';
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
import { devUseWarning } from '../_util/warning';
import ConfigProvider, { ConfigContext } from '../config-provider';
import DisabledContext from '../config-provider/DisabledContext';
import type { SizeType } from '../config-provider/SizeContext';
import useSize from '../config-provider/hooks/useSize';
import { FormItemInputContext, NoFormStyle } from '../form/context';
import { NoCompactStyle, useCompactItemContext } from '../space/Compact';
import useStyle from './style';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import { devUseWarning } from '../_util/warning';
import useSize from '../config-provider/hooks/useSize';
import type { SizeType } from '../config-provider/SizeContext';
import { FormItemInputContext, NoFormStyle } from '../form/context';
import type { Variant } from '../form/hooks/useVariants';
import useVariant from '../form/hooks/useVariants';
import { NoCompactStyle, useCompactItemContext } from '../space/Compact';
import useStyle from './style';
export interface InputNumberProps<T extends ValueType = ValueType>
extends Omit<RcInputNumberProps<T>, 'prefix' | 'size' | 'controls'> {
@ -195,9 +196,7 @@ const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props,
});
const TypedInputNumber = InputNumber as unknown as (<T extends ValueType = ValueType>(
props: React.PropsWithChildren<InputNumberProps<T>> & {
ref?: React.Ref<HTMLInputElement>;
},
props: React.PropsWithChildren<InputNumberProps<T>> & React.RefAttributes<HTMLInputElement>,
) => React.ReactElement) & {
displayName?: string;
_InternalPanelDoNotUseOrYouWillBeFired: typeof PureInputNumber;

View File

@ -17,17 +17,17 @@ import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty';
import DisabledContext from '../config-provider/DisabledContext';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import useSize from '../config-provider/hooks/useSize';
import type { SizeType } from '../config-provider/SizeContext';
import { FormItemInputContext } from '../form/context';
import type { Variant } from '../form/hooks/useVariants';
import useVariants from '../form/hooks/useVariants';
import { useCompactItemContext } from '../space/Compact';
import useStyle from './style';
import useBuiltinPlacements from './useBuiltinPlacements';
import useIcons from './useIcons';
import useShowArrow from './useShowArrow';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import type { Variant } from '../form/hooks/useVariants';
import useVariants from '../form/hooks/useVariants';
type RawValue = string | number;
@ -306,9 +306,8 @@ const Select = React.forwardRef(InternalSelect) as unknown as (<
ValueType = any,
OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,
>(
props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & {
ref?: React.Ref<BaseSelectRef>;
},
props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> &
React.RefAttributes<BaseSelectRef>,
) => React.ReactElement) & {
displayName?: string;
SECRET_COMBOBOX_MODE_DO_NOT_USE: string;

View File

@ -80,15 +80,15 @@ export default function getArrowStyle<
// >>>>> Top
...isInject(!!arrowPlacement.top, {
[[
`&-placement-top ${componentCls}-arrow`,
`&-placement-topLeft ${componentCls}-arrow`,
`&-placement-topRight ${componentCls}-arrow`,
`&-placement-top > ${componentCls}-arrow`,
`&-placement-topLeft > ${componentCls}-arrow`,
`&-placement-topRight > ${componentCls}-arrow`,
].join(',')]: {
bottom: arrowDistance,
transform: 'translateY(100%) rotate(180deg)',
},
[`&-placement-top ${componentCls}-arrow`]: {
[`&-placement-top > ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: '50%',
@ -96,14 +96,14 @@ export default function getArrowStyle<
transform: 'translateX(-50%) translateY(100%) rotate(180deg)',
},
[`&-placement-topLeft ${componentCls}-arrow`]: {
[`&-placement-topLeft > ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: arrowOffsetHorizontal,
},
},
[`&-placement-topRight ${componentCls}-arrow`]: {
[`&-placement-topRight > ${componentCls}-arrow`]: {
right: {
_skip_check_: true,
value: arrowOffsetHorizontal,
@ -114,15 +114,15 @@ export default function getArrowStyle<
// >>>>> Bottom
...isInject(!!arrowPlacement.bottom, {
[[
`&-placement-bottom ${componentCls}-arrow`,
`&-placement-bottomLeft ${componentCls}-arrow`,
`&-placement-bottomRight ${componentCls}-arrow`,
`&-placement-bottom > ${componentCls}-arrow`,
`&-placement-bottomLeft > ${componentCls}-arrow`,
`&-placement-bottomRight > ${componentCls}-arrow`,
].join(',')]: {
top: arrowDistance,
transform: `translateY(-100%)`,
},
[`&-placement-bottom ${componentCls}-arrow`]: {
[`&-placement-bottom > ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: '50%',
@ -130,14 +130,14 @@ export default function getArrowStyle<
transform: `translateX(-50%) translateY(-100%)`,
},
[`&-placement-bottomLeft ${componentCls}-arrow`]: {
[`&-placement-bottomLeft > ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: arrowOffsetHorizontal,
},
},
[`&-placement-bottomRight ${componentCls}-arrow`]: {
[`&-placement-bottomRight > ${componentCls}-arrow`]: {
right: {
_skip_check_: true,
value: arrowOffsetHorizontal,
@ -148,9 +148,9 @@ export default function getArrowStyle<
// >>>>> Left
...isInject(!!arrowPlacement.left, {
[[
`&-placement-left ${componentCls}-arrow`,
`&-placement-leftTop ${componentCls}-arrow`,
`&-placement-leftBottom ${componentCls}-arrow`,
`&-placement-left > ${componentCls}-arrow`,
`&-placement-leftTop > ${componentCls}-arrow`,
`&-placement-leftBottom > ${componentCls}-arrow`,
].join(',')]: {
right: {
_skip_check_: true,
@ -159,7 +159,7 @@ export default function getArrowStyle<
transform: 'translateX(100%) rotate(90deg)',
},
[`&-placement-left ${componentCls}-arrow`]: {
[`&-placement-left > ${componentCls}-arrow`]: {
top: {
_skip_check_: true,
value: '50%',
@ -167,11 +167,11 @@ export default function getArrowStyle<
transform: 'translateY(-50%) translateX(100%) rotate(90deg)',
},
[`&-placement-leftTop ${componentCls}-arrow`]: {
[`&-placement-leftTop > ${componentCls}-arrow`]: {
top: arrowOffsetVertical,
},
[`&-placement-leftBottom ${componentCls}-arrow`]: {
[`&-placement-leftBottom > ${componentCls}-arrow`]: {
bottom: arrowOffsetVertical,
},
}),
@ -179,9 +179,9 @@ export default function getArrowStyle<
// >>>>> Right
...isInject(!!arrowPlacement.right, {
[[
`&-placement-right ${componentCls}-arrow`,
`&-placement-rightTop ${componentCls}-arrow`,
`&-placement-rightBottom ${componentCls}-arrow`,
`&-placement-right > ${componentCls}-arrow`,
`&-placement-rightTop > ${componentCls}-arrow`,
`&-placement-rightBottom > ${componentCls}-arrow`,
].join(',')]: {
left: {
_skip_check_: true,
@ -190,7 +190,7 @@ export default function getArrowStyle<
transform: 'translateX(-100%) rotate(-90deg)',
},
[`&-placement-right ${componentCls}-arrow`]: {
[`&-placement-right > ${componentCls}-arrow`]: {
top: {
_skip_check_: true,
value: '50%',
@ -198,11 +198,11 @@ export default function getArrowStyle<
transform: 'translateY(-50%) translateX(-100%) rotate(-90deg)',
},
[`&-placement-rightTop ${componentCls}-arrow`]: {
[`&-placement-rightTop > ${componentCls}-arrow`]: {
top: arrowOffsetVertical,
},
[`&-placement-rightBottom ${componentCls}-arrow`]: {
[`&-placement-rightBottom > ${componentCls}-arrow`]: {
bottom: arrowOffsetVertical,
},
}),

View File

@ -17,13 +17,11 @@ import type { INTERNAL_SELECTION_ITEM } from './hooks/useSelection';
import type { InternalTableProps, TableProps } from './InternalTable';
export type RefTable = <RecordType extends AnyObject = AnyObject>(
props: React.PropsWithChildren<TableProps<RecordType>> & { ref?: React.Ref<Reference> },
props: React.PropsWithChildren<TableProps<RecordType>> & React.RefAttributes<Reference>,
) => React.ReactElement;
export type RefInternalTable = <RecordType extends AnyObject = AnyObject>(
props: React.PropsWithChildren<InternalTableProps<RecordType>> & {
ref?: React.Ref<Reference>;
},
props: React.PropsWithChildren<InternalTableProps<RecordType>> & React.RefAttributes<Reference>,
) => React.ReactElement;
export { ExpandableConfig, GetRowKey };
@ -61,7 +59,7 @@ export interface TableLocale {
export type SortOrder = 'descend' | 'ascend' | null;
const TableActions = ['paginate', 'sort', 'filter'] as const;
export type TableAction = typeof TableActions[number];
export type TableAction = (typeof TableActions)[number];
export type CompareFn<T> = (a: T, b: T, sortOrder?: SortOrder) => number;

View File

@ -1,4 +1,6 @@
import type { CSSInterpolation, DerivativeFunc } from '@ant-design/cssinjs';
import type { AnyObject } from '../../_util/type';
import type { AliasToken } from './alias';
import type { ComponentTokenMap } from './components';
import type { MapToken } from './maps';
@ -37,6 +39,6 @@ export type { SeedToken } from './seeds';
export type UseComponentStyleResult = [(node: React.ReactNode) => React.ReactElement, string];
export type GenerateStyle<
ComponentToken extends object = AliasToken,
ComponentToken extends AnyObject = AliasToken,
ReturnType = CSSInterpolation,
> = (token: ComponentToken) => ReturnType;

View File

@ -1,3 +1,5 @@
import type { AnyObject } from '../../_util/type';
declare const CSSINJS_STATISTIC: any;
const enableStatistic =
@ -8,7 +10,7 @@ let recording = true;
* This function will do as `Object.assign` in production. But will use Object.defineProperty:get to
* pass all value access in development. To support statistic field usage with alias token.
*/
export function merge<T extends object>(...objs: Partial<T>[]): T {
export function merge<T extends AnyObject>(...objs: Partial<T>[]): T {
/* istanbul ignore next */
if (!enableStatistic) {
return Object.assign({}, ...objs);
@ -48,7 +50,7 @@ export const _statistic_build_: typeof statistic = {};
function noop() {}
/** Statistic token usage case. Should use `merge` function if you do not want spread record. */
export default function statisticToken<T extends object>(token: T) {
const statisticToken = <T extends AnyObject>(token: T) => {
let tokenKeys: Set<string> | undefined;
let proxy = token;
let flush: (componentName: string, componentToken: Record<string, string | number>) => void =
@ -78,4 +80,6 @@ export default function statisticToken<T extends object>(token: T) {
}
return { token: proxy, keys: tokenKeys, flush };
}
};
export default statisticToken;

View File

@ -1,12 +1,14 @@
import * as React from 'react';
import type { KeyWise, TransferProps } from '..';
import { groupKeysMap } from '../../_util/transKeys';
import type { AnyObject } from '../../_util/type';
function useData<RecordType extends object>(
const useData = <RecordType extends AnyObject>(
dataSource?: RecordType[],
rowKey?: TransferProps<RecordType>['rowKey'],
targetKeys?: string[],
) {
) => {
const mergedDataSource = React.useMemo(
() =>
(dataSource || []).map((record: KeyWise<RecordType>) => {
@ -35,6 +37,6 @@ function useData<RecordType extends object>(
}, [mergedDataSource, targetKeys, rowKey]);
return [mergedDataSource, leftDataSource, rightDataSource];
}
};
export default useData;

View File

@ -7,6 +7,7 @@ import RcTreeSelect, { SHOW_ALL, SHOW_CHILD, SHOW_PARENT, TreeNode } from 'rc-tr
import type { BaseOptionType, DefaultOptionType } from 'rc-tree-select/lib/TreeSelect';
import omit from 'rc-util/lib/omit';
import { useZIndex } from '../_util/hooks/useZIndex';
import type { SelectCommonPlacement } from '../_util/motion';
import { getTransitionName } from '../_util/motion';
import genPurePanel from '../_util/PurePanel';
@ -16,22 +17,21 @@ import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty';
import DisabledContext from '../config-provider/DisabledContext';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import useSize from '../config-provider/hooks/useSize';
import type { SizeType } from '../config-provider/SizeContext';
import { FormItemInputContext } from '../form/context';
import type { Variant } from '../form/hooks/useVariants';
import useVariant from '../form/hooks/useVariants';
import useSelectStyle from '../select/style';
import useBuiltinPlacements from '../select/useBuiltinPlacements';
import useShowArrow from '../select/useShowArrow';
import useIcons from '../select/useIcons';
import useShowArrow from '../select/useShowArrow';
import { useCompactItemContext } from '../space/Compact';
import type { AntTreeNodeProps, TreeProps } from '../tree';
import type { SwitcherIcon } from '../tree/Tree';
import SwitcherIconCom from '../tree/utils/iconUtil';
import useStyle from './style';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import { useZIndex } from '../_util/hooks/useZIndex';
import type { Variant } from '../form/hooks/useVariants';
import useVariant from '../form/hooks/useVariants';
type RawValue = string | number;
@ -319,9 +319,8 @@ const TreeSelectRef = React.forwardRef(InternalTreeSelect) as <
ValueType = any,
OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType,
>(
props: React.PropsWithChildren<TreeSelectProps<ValueType, OptionType>> & {
ref?: React.Ref<BaseSelectRef>;
},
props: React.PropsWithChildren<TreeSelectProps<ValueType, OptionType>> &
React.RefAttributes<BaseSelectRef>,
) => React.ReactElement;
type InternalTreeSelectType = typeof TreeSelectRef;

View File

@ -21,10 +21,8 @@ export interface DirectoryTreeProps<T extends BasicDataNode = DataNode> extends
}
type DirectoryTreeCompoundedComponent = (<T extends BasicDataNode | DataNode = DataNode>(
props: React.PropsWithChildren<DirectoryTreeProps<T>> & { ref?: React.Ref<RcTree> },
) => React.ReactElement) & {
displayName?: string;
};
props: React.PropsWithChildren<DirectoryTreeProps<T>> & React.RefAttributes<RcTree>,
) => React.ReactElement) & { displayName?: string };
export interface DirectoryTreeState {
expandedKeys?: Key[];

View File

@ -1,7 +1,8 @@
import React from 'react';
import debounce from 'lodash/debounce';
import type RcTree from 'rc-tree';
import type { Key } from 'rc-tree/lib/interface';
import React from 'react';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
@ -30,7 +31,7 @@ describe('Directory Tree', () => {
(debounce as any).mockRestore();
});
function createTree(props?: TreeProps & { ref?: React.Ref<RcTree> }) {
function createTree(props?: TreeProps & React.RefAttributes<RcTree>) {
return (
<DirectoryTree {...props}>
<TreeNode key="0-0">

View File

@ -25,7 +25,7 @@ export type {
export type { DataNode, BasicDataNode };
type CompoundedComponent = (<T extends BasicDataNode | DataNode = DataNode>(
props: React.PropsWithChildren<TreeProps<T>> & { ref?: React.Ref<RcTree> },
props: React.PropsWithChildren<TreeProps<T>> & React.RefAttributes<RcTree>,
) => React.ReactElement) & {
TreeNode: typeof TreeNode;
DirectoryTree: typeof DirectoryTree;

View File

@ -182,7 +182,7 @@ export const genBaseStyle = (prefixCls: string, token: TreeToken): CSSObject =>
},
[`&-active ${treeCls}-node-content-wrapper`]: {
...genFocusOutline(token),
background: token.controlItemBgHover,
},
[`&:not(${treeNodeCls}-disabled).filter-node ${treeCls}-title`]: {

View File

@ -1,3 +1,4 @@
import * as React from 'react';
import CheckOutlined from '@ant-design/icons/CheckOutlined';
import CopyOutlined from '@ant-design/icons/CopyOutlined';
import EditOutlined from '@ant-design/icons/EditOutlined';
@ -10,7 +11,7 @@ import useIsomorphicLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import omit from 'rc-util/lib/omit';
import { composeRef } from 'rc-util/lib/ref';
import * as React from 'react';
import { isStyleSupport } from '../../_util/styleChecker';
import TransButton from '../../_util/transButton';
import { ConfigContext } from '../../config-provider';
@ -18,10 +19,10 @@ import useLocale from '../../locale/useLocale';
import type { TooltipProps } from '../../tooltip';
import Tooltip from '../../tooltip';
import Editable from '../Editable';
import type { TypographyProps } from '../Typography';
import Typography from '../Typography';
import useMergedConfig from '../hooks/useMergedConfig';
import useUpdatedEffect from '../hooks/useUpdatedEffect';
import type { TypographyProps } from '../Typography';
import Typography from '../Typography';
import Ellipsis from './Ellipsis';
import EllipsisTooltip from './EllipsisTooltip';
@ -315,7 +316,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
setIsNativeEllipsis(currentEllipsis);
}
}
}, [enableEllipsis, cssEllipsis, children, cssLineClamp, isNativeVisible]);
}, [enableEllipsis, cssEllipsis, children, cssLineClamp, isNativeVisible, ellipsisWidth]);
// https://github.com/ant-design/ant-design/issues/36786
// Use IntersectionObserver to check if element is invisible
@ -495,7 +496,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
];
return (
<ResizeObserver onResize={onResize} disabled={!mergedEnableEllipsis || cssEllipsis}>
<ResizeObserver onResize={onResize} disabled={!mergedEnableEllipsis}>
{(resizeRef: React.RefObject<HTMLElement>) => (
<EllipsisTooltip
tooltipProps={tooltipProps}

View File

@ -1,6 +1,7 @@
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
import React from 'react';
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
import { act } from 'react-dom/test-utils';
import { fireEvent, render, triggerResize, waitFakeTimer, waitFor } from '../../../tests/utils';
import type { EllipsisConfig } from '../Base';
import Base from '../Base';
@ -17,6 +18,8 @@ describe('Typography.Ellipsis', () => {
let mockRectSpy: ReturnType<typeof spyElementPrototypes>;
let getWidthTimes = 0;
let computeSpy: jest.SpyInstance<CSSStyleDeclaration>;
let offsetWidth: number;
let scrollWidth: number;
beforeAll(() => {
jest.useFakeTimers();
@ -32,9 +35,12 @@ describe('Typography.Ellipsis', () => {
offsetWidth: {
get: () => {
getWidthTimes += 1;
return 100;
return offsetWidth;
},
},
scrollWidth: {
get: () => scrollWidth,
},
getBoundingClientRect() {
let html = this.innerHTML;
html = html.replace(/<[^>]*>/g, '');
@ -48,6 +54,11 @@ describe('Typography.Ellipsis', () => {
.mockImplementation(() => ({ fontSize: 12 }) as unknown as CSSStyleDeclaration);
});
beforeEach(() => {
offsetWidth = 100;
scrollWidth = 0;
});
afterEach(() => {
errorSpy.mockReset();
getWidthTimes = 0;
@ -507,4 +518,25 @@ describe('Typography.Ellipsis', () => {
mockRectSpy.mockRestore();
Math.ceil = originalCeil;
});
// https://github.com/ant-design/ant-design/issues/46580
it('dynamic to be ellipsis should show tooltip', async () => {
const ref = React.createRef<HTMLElement>();
render(
<Base ellipsis={{ tooltip: 'bamboo' }} component="p" ref={ref}>
less
</Base>,
);
// Force to narrow
offsetWidth = 1;
scrollWidth = 100;
triggerResize(ref.current!);
await waitFakeTimer();
fireEvent.mouseEnter(ref.current!);
await waitFakeTimer();
expect(document.querySelector('.ant-tooltip')).toBeTruthy();
});
});

View File

@ -114,7 +114,7 @@
],
"dependencies": {
"@ant-design/colors": "^7.0.0",
"@ant-design/cssinjs": "^1.18.1",
"@ant-design/cssinjs": "^1.18.2",
"@ant-design/icons": "^5.2.6",
"@ant-design/react-slick": "~1.0.2",
"@babel/runtime": "^7.23.4",
@ -314,7 +314,7 @@
"size-limit": "^11.0.0",
"stylelint": "^16.0.0",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-config-standard": "^35.0.0",
"stylelint-config-standard": "^36.0.0",
"stylelint-prettier": "^5.0.0",
"sylvanas": "^0.6.1",
"tar": "^6.2.0",