From 8095b8c46739a8a7226d4c4d39c61eac85f5a445 Mon Sep 17 00:00:00 2001 From: thinkasany <480968828@qq.com> Date: Thu, 23 Oct 2025 04:14:01 +0800 Subject: [PATCH 1/9] chore: improve avatar code style (#55408) --- components/avatar/Avatar.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/components/avatar/Avatar.tsx b/components/avatar/Avatar.tsx index 20f1bd9559..729af9e92e 100644 --- a/components/avatar/Avatar.tsx +++ b/components/avatar/Avatar.tsx @@ -129,7 +129,7 @@ const Avatar = React.forwardRef((props, ref) => { fontSize: currentSize && (icon || children) ? currentSize / 2 : 18, } : {}; - }, [screens, size]); + }, [screens, size, icon, children]); if (process.env.NODE_ENV !== 'production') { const warning = devUseWarning('Avatar'); @@ -205,11 +205,7 @@ const Avatar = React.forwardRef((props, ref) => { childrenToRender = ( - + {children} From 5fe4cff30d40b849f5e1f01598979db1ea22e9e5 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Thu, 23 Oct 2025 08:08:09 +0800 Subject: [PATCH 2/9] chore: unified code style (#55411) --- .dumi/theme/layouts/GlobalLayout.tsx | 7 +++++-- .github/workflows/preview-deploy.yml | 4 +++- .github/workflows/visual-regression-diff-finish.yml | 4 +++- .github/workflows/visual-regression-persist-finish.yml | 4 +++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.dumi/theme/layouts/GlobalLayout.tsx b/.dumi/theme/layouts/GlobalLayout.tsx index 4377513767..1a5e62cbac 100644 --- a/.dumi/theme/layouts/GlobalLayout.tsx +++ b/.dumi/theme/layouts/GlobalLayout.tsx @@ -147,9 +147,12 @@ const GlobalLayout: React.FC = () => { // 设置 data-prefers-color 属性 useEffect(() => { const color = theme.find((t) => t === 'light' || t === 'dark'); + const html = document.querySelector('html'); if (theme.includes('auto') && systemTheme) { - document.querySelector('html')?.setAttribute('data-prefers-color', systemTheme); - } else if (color) document.querySelector('html')?.setAttribute('data-prefers-color', color); + html?.setAttribute('data-prefers-color', systemTheme); + } else if (color) { + html?.setAttribute('data-prefers-color', color); + } }, [systemTheme, theme]); // 监听系统主题变化 diff --git a/.github/workflows/preview-deploy.yml b/.github/workflows/preview-deploy.yml index 2d3fb072d8..4ef4d31375 100644 --- a/.github/workflows/preview-deploy.yml +++ b/.github/workflows/preview-deploy.yml @@ -41,7 +41,9 @@ jobs: }, {}); const total = Object.keys(jobs).length; - if(total === 0) core.setFailed('no jobs found'); + if (total === 0) { + core.setFailed('no jobs found'); + } // the name here must be the same as `jobs.xxx.{name}` in preview-build.yml // set output diff --git a/.github/workflows/visual-regression-diff-finish.yml b/.github/workflows/visual-regression-diff-finish.yml index d4bb5c5c00..a6f562515e 100644 --- a/.github/workflows/visual-regression-diff-finish.yml +++ b/.github/workflows/visual-regression-diff-finish.yml @@ -43,7 +43,9 @@ jobs: }, {}); const total = Object.keys(jobs).length; - if(total === 0) core.setFailed('no jobs found'); + if (total === 0) { + core.setFailed('no jobs found'); + } // the name here must be the same as `jobs.xxx.{name}` console.log('visual-diff report job status: %s', jobs['visual-diff report'].status); diff --git a/.github/workflows/visual-regression-persist-finish.yml b/.github/workflows/visual-regression-persist-finish.yml index 73c108c4fa..3814d06a04 100644 --- a/.github/workflows/visual-regression-persist-finish.yml +++ b/.github/workflows/visual-regression-persist-finish.yml @@ -40,7 +40,9 @@ jobs: }, {}); const total = Object.keys(jobs).length; - if(total === 0) core.setFailed('no jobs found'); + if (total === 0) { + core.setFailed('no jobs found'); + } // the name here must be the same as `jobs.xxx.{name}` console.log('visual-diff report job status: %s', jobs['test image']); From f187eeafb30ac55ac14d5839114ea88399af5a8c Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Thu, 23 Oct 2025 08:09:15 +0800 Subject: [PATCH 3/9] test: update any type with React.ReactElement (#55410) --- tests/shared/imageTest.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/shared/imageTest.tsx b/tests/shared/imageTest.tsx index 2c52f2cd1d..acfe31e729 100644 --- a/tests/shared/imageTest.tsx +++ b/tests/shared/imageTest.tsx @@ -305,7 +305,7 @@ export function imageDemoTest(component: string, options: Options = {}) { (file) => !file.includes('_semantic'), ); - const mobileDemos: [file: string, node: any][] = []; + const mobileDemos: [file: string, node: React.ReactElement][] = []; const getTestOption = (file: string) => ({ onlyViewport: From 44223967aec3d44b7a4f9aaddc87808ce23422c6 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Thu, 23 Oct 2025 10:48:30 +0800 Subject: [PATCH 4/9] chore: rm useUniqueMemo hook (#55412) --- .../_util/__tests__/useUniqueMemo.test.tsx | 56 ----------- components/_util/hooks/useUniqueMemo.ts | 97 ------------------- 2 files changed, 153 deletions(-) delete mode 100644 components/_util/__tests__/useUniqueMemo.test.tsx delete mode 100644 components/_util/hooks/useUniqueMemo.ts diff --git a/components/_util/__tests__/useUniqueMemo.test.tsx b/components/_util/__tests__/useUniqueMemo.test.tsx deleted file mode 100644 index 1e308c11bb..0000000000 --- a/components/_util/__tests__/useUniqueMemo.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react'; - -import { act, render } from '../../../tests/utils'; -import useUniqueMemo from '../hooks/useUniqueMemo'; - -describe('Table', () => { - beforeEach(() => { - jest.useFakeTimers(); - }); - - afterEach(() => { - jest.clearAllTimers(); - jest.useRealTimers(); - }); - - it('useSyncState', () => { - const sharedObjDeps1 = {}; - const sharedObjDeps2 = {}; - - let calledTimes = 0; - - const Test: React.FC<{ depName?: string }> = ({ depName }) => { - useUniqueMemo(() => { - calledTimes += 1; - return depName; - }, [depName, sharedObjDeps1, 'bamboo', sharedObjDeps2]); - return null; - }; - - // Reuse the same memo - const { rerender } = render( - <> - - - - , - ); - - expect(calledTimes).toBe(1); - - // Different deps should clean up the cache - act(() => { - jest.advanceTimersByTime(1000 * 60 * 20); - }); - - for (let i = 0; i < 20000; i += 1) { - rerender(); - } - rerender(); - calledTimes = 0; - - // Back should recompute - rerender(); - expect(calledTimes).toBe(1); - }); -}); diff --git a/components/_util/hooks/useUniqueMemo.ts b/components/_util/hooks/useUniqueMemo.ts deleted file mode 100644 index a757c48049..0000000000 --- a/components/_util/hooks/useUniqueMemo.ts +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; - -const BEAT_LIMIT = 1000 * 60 * 10; - -/** - * A helper class to map keys to values. - * It supports both primitive keys and object keys. - */ -class ArrayKeyMap { - map = new Map(); - - // Use WeakMap to avoid memory leak - objectIDMap = new WeakMap(); - - nextID = 0; - - lastAccessBeat = new Map(); - - // We will clean up the cache when reach the limit - accessBeat = 0; - - set(keys: React.DependencyList, value: any) { - // New set will trigger clear - this.clear(); - - // Set logic - const compositeKey = this.getCompositeKey(keys); - this.map.set(compositeKey, value); - this.lastAccessBeat.set(compositeKey, Date.now()); - } - - get(keys: React.DependencyList) { - const compositeKey = this.getCompositeKey(keys); - - const cache = this.map.get(compositeKey); - this.lastAccessBeat.set(compositeKey, Date.now()); - this.accessBeat += 1; - - return cache; - } - - getCompositeKey(keys: React.DependencyList) { - const ids = keys.map((key) => { - if (key && typeof key === 'object') { - return `obj_${this.getObjectID(key)}`; - } - return `${typeof key}_${key}`; - }); - return ids.join('|'); - } - - getObjectID(obj: object) { - if (this.objectIDMap.has(obj)) { - return this.objectIDMap.get(obj); - } - const id = this.nextID; - this.objectIDMap.set(obj, id); - - this.nextID += 1; - - return id; - } - - clear() { - if (this.accessBeat > 10000) { - const now = Date.now(); - - this.lastAccessBeat.forEach((beat, key) => { - if (now - beat > BEAT_LIMIT) { - this.map.delete(key); - this.lastAccessBeat.delete(key); - } - }); - - this.accessBeat = 0; - } - } -} - -const uniqueMap = new ArrayKeyMap(); - -/** - * Like `useMemo`, but this hook result will be shared across all instances. - */ -function useUniqueMemo(memoFn: () => T, deps: React.DependencyList) { - return React.useMemo(() => { - const cachedValue = uniqueMap.get(deps); - if (cachedValue) { - return cachedValue as T; - } - const newValue = memoFn(); - uniqueMap.set(deps, newValue); - return newValue; - }, deps); -} - -export default useUniqueMemo; From 34297362a3ac401fd6e6611bc4ec2fb3a080a2e3 Mon Sep 17 00:00:00 2001 From: divyeshagrawal <138372682+divyeshagrawal@users.noreply.github.com> Date: Fri, 24 Oct 2025 13:16:43 +0530 Subject: [PATCH 5/9] chore: remove unused devDependencies (#55433) * Chore: Remove unused dependencies * Chore: Add EOL * Chore: Add remark-cli * Chore: Add EOL --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index 001f2e277a..a1d5f9873e 100644 --- a/package.json +++ b/package.json @@ -302,11 +302,9 @@ "react-highlight-words": "^0.21.0", "react-icons": "^5.4.0", "react-infinite-scroll-component": "^6.1.0", - "react-intersection-observer": "^9.13.1", "react-resizable": "^3.0.5", "react-router-dom": "^7.0.1", "react-sticky-box": "^2.0.5", - "regenerator-runtime": "^0.14.1", "rehype-stringify": "^10.0.1", "remark": "^15.0.1", "remark-cli": "^12.0.1", From 553ac801d3b70651eca97a905ed831f82d50c87a Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Fri, 24 Oct 2025 16:31:14 +0800 Subject: [PATCH 6/9] type: update undefined type to optional (#55436) --- components/form/hooks/useVariants.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/form/hooks/useVariants.ts b/components/form/hooks/useVariants.ts index 93953f80b7..e4cb35b73f 100644 --- a/components/form/hooks/useVariants.ts +++ b/components/form/hooks/useVariants.ts @@ -1,8 +1,8 @@ import * as React from 'react'; -import { VariantContext } from '../context'; -import type { Variant, ConfigProviderProps } from '../../config-provider'; +import type { ConfigProviderProps, Variant } from '../../config-provider'; import { ConfigContext, Variants } from '../../config-provider'; +import { VariantContext } from '../context'; type VariantComponents = keyof Pick< ConfigProviderProps, @@ -24,8 +24,8 @@ type VariantComponents = keyof Pick< */ const useVariant = ( component: VariantComponents, - variant: Variant | undefined, - legacyBordered: boolean | undefined = undefined, + variant?: Variant, + legacyBordered?: boolean, ): [Variant, boolean] => { const { variant: configVariant, [component]: componentConfig } = React.useContext(ConfigContext); const ctxVariant = React.useContext(VariantContext); From 1c30401023da821985d1973a89598ca558582da6 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Fri, 24 Oct 2025 16:32:46 +0800 Subject: [PATCH 7/9] type: update any type to function (#55434) --- components/affix/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/affix/index.tsx b/components/affix/index.tsx index 5ee4b1ebfe..853d45e07c 100644 --- a/components/affix/index.tsx +++ b/components/affix/index.tsx @@ -55,7 +55,10 @@ export interface AffixRef { updatePosition: ReturnType; } -type InternalAffixProps = AffixProps & { onTestUpdatePosition?: any }; +interface InternalAffixProps extends AffixProps { + onTestUpdatePosition?: () => void; +} + const Affix = React.forwardRef((props, ref) => { const { style, From 60000bc14e832307e56c554541d4eac217006fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9D=91=BE=F0=9D=92=96=F0=9D=92=99=F0=9D=92=89?= Date: Fri, 24 Oct 2025 17:50:25 +0800 Subject: [PATCH 8/9] fix(DirectoryTree): `fieldNames` cause `defaultExpandAll` to not work error (#55420) --- components/tree/DirectoryTree.tsx | 4 +++- components/tree/__tests__/directory.test.tsx | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/components/tree/DirectoryTree.tsx b/components/tree/DirectoryTree.tsx index 302b18961d..27bc51e838 100644 --- a/components/tree/DirectoryTree.tsx +++ b/components/tree/DirectoryTree.tsx @@ -52,7 +52,9 @@ const DirectoryTree: React.ForwardRefRenderFunction const cachedSelectedKeys = React.useRef(null); const getInitExpandedKeys = () => { - const { keyEntities } = convertDataToEntities(getTreeData(props)); + const { keyEntities } = convertDataToEntities(getTreeData(props), { + fieldNames: props.fieldNames, + }); let initExpandedKeys: Key[]; diff --git a/components/tree/__tests__/directory.test.tsx b/components/tree/__tests__/directory.test.tsx index 3e6179b82e..2e368a70e8 100644 --- a/components/tree/__tests__/directory.test.tsx +++ b/components/tree/__tests__/directory.test.tsx @@ -320,6 +320,10 @@ describe('Directory Tree', () => { fieldNames: { key: 'id', title: 'label', children: 'child' }, }), ); + + // https://github.com/ant-design/ant-design/issues/55418 + expect(container.querySelectorAll('.ant-tree-node-content-wrapper-open').length).toBe(2); + fireEvent.click(container.querySelectorAll('.ant-tree-node-content-wrapper')[0]); expect(onSelect.mock.calls[0][1].selectedNodes.length).toBe(1); }); From 2933bd66ce1c09be7894a44713198c0c17e88b30 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 24 Oct 2025 20:27:58 +0800 Subject: [PATCH 9/9] chore: update biome config and report template (#55440) * chore: update biome config and report template * Apply suggestion from @afc163 Signed-off-by: afc163 --------- Signed-off-by: afc163 --- biome.json | 4 +++- scripts/visual-regression/report-template.html | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/biome.json b/biome.json index 1cfddd614a..0467dab150 100644 --- a/biome.json +++ b/biome.json @@ -15,7 +15,8 @@ "!scripts/previewEditor/**/*", "!**/*.tmp", "!package.json", - "!components/style/antd.css" + "!components/style/antd.css", + "!scripts/visual-regression/report-template.html" ] }, "formatter": { @@ -57,6 +58,7 @@ "noExplicitAny": "off", "noArrayIndexKey": "off", "noConfusingVoidType": "off", + "noNonNullAssertedOptionalChain": "off", "noThenProperty": "off", "noTemplateCurlyInString": "off", "useIterableCallbackReturn": "off", diff --git a/scripts/visual-regression/report-template.html b/scripts/visual-regression/report-template.html index 674b60f1b4..a87c85d42a 100644 --- a/scripts/visual-regression/report-template.html +++ b/scripts/visual-regression/report-template.html @@ -106,7 +106,7 @@ {{reportContent}}