From c93ebb7610fb5df09d2da62ab536b80886f60fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Thu, 9 Jul 2026 11:46:14 +0800 Subject: [PATCH 1/5] chore(submodule): ignore root deps --- package.json | 1 - pnpm-workspace.yaml | 12 +++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 974ae074bd..4fd48bc9a3 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,6 @@ "@popperjs/core": "~2.11.2", "@tdesign-react/chat": "workspace:^", "@tdesign/ai-chat-engine": "workspace:^", - "@tdesign/common": "workspace:^", "@tdesign/common-docs": "workspace:^", "@tdesign/common-js": "workspace:^", "@tdesign/common-style": "workspace:^", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index fd2d15303e..1159dd8092 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,7 +1,9 @@ packages: - - 'packages/**' - - 'internal/**' - - 'test' - + - "packages/**" + - "internal/**" + - "test" + - "!packages/common" + - "!packages/ai-core" + # 提升依赖项到根目录,以避免重复安装相同的包 -shamefullyHoist: true \ No newline at end of file +shamefullyHoist: true From 72b182852107c9abaf56e49521bf38ec17b98cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Thu, 9 Jul 2026 12:02:47 +0800 Subject: [PATCH 2/5] =?UTF-8?q?refactor(site):=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=BE=9D=E8=B5=96=E8=87=B3=20common-docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/tdesign-react-aigc/site/site.config.mjs | 8 ++++---- packages/tdesign-react/site/site.config.mjs | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/tdesign-react-aigc/site/site.config.mjs b/packages/tdesign-react-aigc/site/site.config.mjs index 93587b5a5c..301b0c114c 100644 --- a/packages/tdesign-react-aigc/site/site.config.mjs +++ b/packages/tdesign-react-aigc/site/site.config.mjs @@ -51,16 +51,16 @@ export const docs = [ titleEn: 'Theme Customization', name: 'custom-theme', path: '/react-chat/custom-theme', - component: () => import('@tdesign/common/docs/web/theme.md'), - componentEn: () => import('@tdesign/common/docs/web/theme.en-US.md'), + component: () => import('@tdesign/common-docs/web/theme.md'), + componentEn: () => import('@tdesign/common-docs/web/theme.en-US.md'), }, { title: '深色模式', titleEn: 'Dark Mode', name: 'dark-mode', path: '/react-chat/dark-mode', - component: () => import('@tdesign/common/docs/dark-mode.md'), - componentEn: () => import('@tdesign/common/docs/dark-mode.en-US.md'), + component: () => import('@tdesign/common-docs/dark-mode.md'), + componentEn: () => import('@tdesign/common-docs/dark-mode.en-US.md'), }, { title: '自定义样式', diff --git a/packages/tdesign-react/site/site.config.mjs b/packages/tdesign-react/site/site.config.mjs index baff073c06..8ceabca359 100644 --- a/packages/tdesign-react/site/site.config.mjs +++ b/packages/tdesign-react/site/site.config.mjs @@ -33,16 +33,16 @@ export const docs = [ titleEn: 'Overview', name: 'overview', path: '/react/overview', - component: () => import('@tdesign/common/docs/web/overview.md'), - componentEn: () => import('@tdesign/common/docs/web/overview.en-US.md'), + component: () => import('@tdesign/common-docs/web/overview.md'), + componentEn: () => import('@tdesign/common-docs/web/overview.en-US.md'), }, { title: 'MCP', titleEn: 'MCP', name: 'mcp', path: '/react/mcp', - component: () => import('@tdesign/common/docs/mcp.md'), - componentEn: () => import('@tdesign/common/docs/mcp.en-US.md'), + component: () => import('@tdesign/common-docs/mcp.md'), + componentEn: () => import('@tdesign/common-docs/mcp.en-US.md'), }, ], }, @@ -64,16 +64,16 @@ export const docs = [ titleEn: 'Theme Customization', name: 'custom-theme', path: '/react/custom-theme', - component: () => import('@tdesign/common/docs/web/theme.md'), - componentEn: () => import('@tdesign/common/docs/web/theme.en-US.md'), + component: () => import('@tdesign/common-docs/web/theme.md'), + componentEn: () => import('@tdesign/common-docs/web/theme.en-US.md'), }, { title: '深色模式', titleEn: 'Dark Mode', name: 'dark-mode', path: '/react/dark-mode', - component: () => import('@tdesign/common/docs/dark-mode.md'), - componentEn: () => import('@tdesign/common/docs/dark-mode.en-US.md'), + component: () => import('@tdesign/common-docs/dark-mode.md'), + componentEn: () => import('@tdesign/common-docs/dark-mode.en-US.md'), }, ], }, From 60bd485d6f591058986b7c5a55a2850c6d9466b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Thu, 9 Jul 2026 15:42:58 +0800 Subject: [PATCH 3/5] chore: fix lint --- packages/components/form/FormList.tsx | 161 +++++++++--------- .../components/guide/utils/getScrollParent.ts | 2 +- .../chat-engine/components/toolcall/types.ts | 3 +- tsconfig.json | 16 +- 4 files changed, 92 insertions(+), 90 deletions(-) diff --git a/packages/components/form/FormList.tsx b/packages/components/form/FormList.tsx index ea0e72deaa..9aac98bac3 100644 --- a/packages/components/form/FormList.tsx +++ b/packages/components/form/FormList.tsx @@ -147,89 +147,92 @@ const FormList: React.FC = (props) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [form, snakeName, fields]); - useImperativeHandle(formListRef, (): FormItemInstance => ({ - name, - fullPath, - value: formListValue, - initialData, - isFormList: true, - formListMapRef, - getValue: () => cloneDeep(get(form?.store, fullPath)), - validate: (trigger = 'all') => { - const resultList = []; - const validates = [...formListMapRef.current.values()].map((formItemRef) => - formItemRef?.current?.validate?.(trigger), - ); - return new Promise((resolve) => { - Promise.all(validates).then((validateResult) => { - validateResult.forEach((result) => { - if (typeof result !== 'object') return; - const errorValue = Object.values(result)[0]; - merge(resultList, errorValue); + useImperativeHandle( + formListRef, + (): FormItemInstance => ({ + name, + fullPath, + value: formListValue, + initialData, + isFormList: true, + formListMapRef, + getValue: () => cloneDeep(get(form?.store, fullPath)), + validate: (trigger = 'all') => { + const resultList = []; + const validates = [...formListMapRef.current.values()].map((formItemRef) => + formItemRef?.current?.validate?.(trigger), + ); + return new Promise((resolve) => { + Promise.all(validates).then((validateResult) => { + validateResult.forEach((result) => { + if (typeof result !== 'object') return; + const errorValue = Object.values(result)[0]; + merge(resultList, errorValue); + }); + const errorItems = validateResult.filter((item) => { + if (typeof item !== 'object') return; + return Object.values(item)[0] !== true; + }); + if (errorItems.length) { + resolve({ [snakeName]: resultList }); + } else { + resolve({ [snakeName]: true }); + } }); - const errorItems = validateResult.filter((item) => { - if (typeof item !== 'object') return; - return Object.values(item)[0] !== true; - }); - if (errorItems.length) { - resolve({ [snakeName]: resultList }); - } else { - resolve({ [snakeName]: true }); - } }); - }); - }, - // TODO 支持局部更新数据 - setValue: (fieldData) => { - setListFields(fieldData, (formItemRef, data) => { - formItemRef?.current?.setValue?.(data); - }); - }, - setField: (fieldData) => { - const { value, status } = fieldData; - const currentValue = get(form?.store, fullPath) || []; - if (isEqual(currentValue, value)) return; - setListFields(value, (formItemRef, data) => { - formItemRef?.current?.setField?.({ value: data, status }); - }); - }, - resetField: (type) => { - const resetType = type || resetTypeFromContext; - if (resetType === 'initial') { - const currentData = get(form?.store, fullPath); - if (isEqual(currentData, initialData)) return; - set(form?.store, fullPath, initialData); - setFormListValue(initialData); - const newFields = initialData?.map((data, index) => ({ - data: { ...data }, - key: (globalKey += 1), - name: index, - isListField: true, - })); - setFields(newFields); - } else { - // 重置为空 - unset(form?.store, fullPath); - setFormListValue([]); - setFields([]); - } - }, - setValidateMessage: (fieldData) => { - [...formListMapRef.current.values()].forEach((formItemRef) => { - if (!formItemRef.current) return; + }, + // TODO 支持局部更新数据 + setValue: (fieldData) => { + setListFields(fieldData, (formItemRef, data) => { + formItemRef?.current?.setValue?.(data); + }); + }, + setField: (fieldData) => { + const { value, status } = fieldData; + const currentValue = get(form?.store, fullPath) || []; + if (isEqual(currentValue, value)) return; + setListFields(value, (formItemRef, data) => { + formItemRef?.current?.setField?.({ value: data, status }); + }); + }, + resetField: (type) => { + const resetType = type || resetTypeFromContext; + if (resetType === 'initial') { + const currentData = get(form?.store, fullPath); + if (isEqual(currentData, initialData)) return; + set(form?.store, fullPath, initialData); + setFormListValue(initialData); + const newFields = initialData?.map((data, index) => ({ + data: { ...data }, + key: (globalKey += 1), + name: index, + isListField: true, + })); + setFields(newFields); + } else { + // 重置为空 + unset(form?.store, fullPath); + setFormListValue([]); + setFields([]); + } + }, + setValidateMessage: (fieldData) => { + [...formListMapRef.current.values()].forEach((formItemRef) => { + if (!formItemRef.current) return; - const { name } = formItemRef.current; - const data = get(fieldData, name); + const { name } = formItemRef.current; + const data = get(fieldData, name); - formItemRef?.current?.setValidateMessage?.(data); - }); - }, - resetValidate: () => { - [...formListMapRef.current.values()].forEach((formItemRef) => { - formItemRef?.current?.resetValidate?.(); - }); - }, - })); + formItemRef?.current?.setValidateMessage?.(data); + }); + }, + resetValidate: () => { + [...formListMapRef.current.values()].forEach((formItemRef) => { + formItemRef?.current?.resetValidate?.(); + }); + }, + }), + ); if (typeof children !== 'function') { log.error('Form', `FormList's children must be a function!`); diff --git a/packages/components/guide/utils/getScrollParent.ts b/packages/components/guide/utils/getScrollParent.ts index f23a3d2920..0fb577f4af 100644 --- a/packages/components/guide/utils/getScrollParent.ts +++ b/packages/components/guide/utils/getScrollParent.ts @@ -7,7 +7,7 @@ export function getScrollParent(element: HTMLElement) { if (style.position === 'fixed') return document.body; - for (let parent = element; parent.parentElement;) { + for (let parent = element; parent.parentElement; ) { parent = parent.parentElement; style = getComputedStyle(parent); if (excludeStaticParent && style.position === 'static') { diff --git a/packages/pro-components/chat/chat-engine/components/toolcall/types.ts b/packages/pro-components/chat/chat-engine/components/toolcall/types.ts index 17ab38dc67..d5260568e7 100644 --- a/packages/pro-components/chat/chat-engine/components/toolcall/types.ts +++ b/packages/pro-components/chat/chat-engine/components/toolcall/types.ts @@ -48,7 +48,8 @@ interface InteractiveToolcallConfig { // 最终的配置类型 export type AgentToolcallConfig = - NonInteractiveToolcallConfig | InteractiveToolcallConfig; + | NonInteractiveToolcallConfig + | InteractiveToolcallConfig; // 类型守卫:判断是否为非交互式配置 export function isNonInteractive( diff --git a/tsconfig.json b/tsconfig.json index 244253835b..ade041c792 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,7 +39,13 @@ "checkJs": true, "downlevelIteration": true, "esModuleInterop": true, - "skipLibCheck": true + "skipLibCheck": true, + "types": [ + "node", + "vitest/globals", + "@testing-library/jest-dom", + "@testing-library/react" + ] }, "include": [ "./packages/components", @@ -58,13 +64,5 @@ "cjs", "es" ], - "types": [ - "node", - "jest", - "vitest/globals", - "@testing-library/jest-dom", - "@testing-library/react-hooks", - "@testing-library/react" - ], "compileOnSave": false } From 702f50fd9e7980e3cac52287244555736f9bb405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Thu, 9 Jul 2026 15:56:10 +0800 Subject: [PATCH 4/5] chore: upgrade eslint to v8 --- .eslintrc.js | 2 + package.json | 5 +- packages/components/affix/Affix.tsx | 3 +- packages/components/dialog/_example/async.tsx | 4 +- packages/components/dropdown/DropdownMenu.tsx | 6 +- packages/components/form/FormList.tsx | 161 +++++++++--------- packages/components/form/hooks/useWatch.ts | 2 +- .../components/guide/utils/getScrollParent.ts | 2 +- packages/components/progress/Progress.tsx | 6 +- .../components/radio/__tests__/radio.test.tsx | 32 +++- .../switch/__tests__/switch.test.tsx | 8 +- .../components/tabs/__tests__/tabs.test.tsx | 21 ++- .../time-picker/panel/SinglePanel.tsx | 2 +- .../chat-engine/components/toolcall/types.ts | 3 +- .../chat/chatbot/_example/service-config.tsx | 4 +- 15 files changed, 151 insertions(+), 110 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index df6451340a..29a69d1eba 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,6 +41,8 @@ module.exports = { 'no-unused-expressions': 'off', 'no-bitwise': 'off', 'no-useless-return': 'off', + 'default-param-last': 'off', + 'class-methods-use-this': 'off', 'no-plusplus': [ 'error', { diff --git a/package.json b/package.json index 4fd48bc9a3..7d8ec0cdff 100644 --- a/package.json +++ b/package.json @@ -101,8 +101,9 @@ "cz-conventional-changelog": "^3.3.0", "dom-parser": "^0.1.6", "esbuild": "^0.14.9", - "eslint": "^7.32.0", - "eslint-config-airbnb-base": "^14.2.1", + "eslint": "^8.57.1", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react": "~7.28.0", "eslint-plugin-react-hooks": "^4.0.0", diff --git a/packages/components/affix/Affix.tsx b/packages/components/affix/Affix.tsx index fcf8ba2840..27f7e30611 100644 --- a/packages/components/affix/Affix.tsx +++ b/packages/components/affix/Affix.tsx @@ -68,7 +68,8 @@ const Affix = forwardRef((props, ref) => { } } else { const containerHeight = - scrollContainer.current?.[isWindow(scrollContainer.current) ? 'innerHeight' : 'clientHeight'] - wrapHeight; + (scrollContainer.current?.[isWindow(scrollContainer.current) ? 'innerHeight' : 'clientHeight'] ?? 0) - + wrapHeight; const calcBottom = containerToTop + containerHeight - (offsetBottom ?? 0); // 计算 bottom 相对应的 top 值 if (calcTop <= offsetTop) { // top 的触发 diff --git a/packages/components/dialog/_example/async.tsx b/packages/components/dialog/_example/async.tsx index 90d5b71f1c..b20b3f2dc5 100644 --- a/packages/components/dialog/_example/async.tsx +++ b/packages/components/dialog/_example/async.tsx @@ -2,7 +2,9 @@ import React, { useState } from 'react'; import { Button, Dialog, DialogPlugin } from 'tdesign-react'; async function delay(time) { - return new Promise((resolve) => setTimeout(resolve, time * 1000)); + return new Promise((resolve) => { + setTimeout(resolve, time * 1000); + }); } export default function BasicUsage() { diff --git a/packages/components/dropdown/DropdownMenu.tsx b/packages/components/dropdown/DropdownMenu.tsx index dd723ec637..5997e6ee57 100644 --- a/packages/components/dropdown/DropdownMenu.tsx +++ b/packages/components/dropdown/DropdownMenu.tsx @@ -45,7 +45,7 @@ const DropdownMenu: React.FC = (props) => { setPanelTopContentHeight(panelTopHeight || 0); } }); - const menuHeight = menuChildren?.length * 30; + const menuHeight = menuChildren.length * 30; if (menuHeight >= maxHeight) setIsOverMaxHeight(true); } }, [maxHeight, panelTopContent]); @@ -142,7 +142,9 @@ const DropdownMenu: React.FC = (props) => { ? () => null : ( value: string | number | { [key: string]: any }, - context: { e: React.MouseEvent }, + context: { + e: React.MouseEvent; + }, ) => handleItemClick({ data: optionItem, context }) } > diff --git a/packages/components/form/FormList.tsx b/packages/components/form/FormList.tsx index 9aac98bac3..ea0e72deaa 100644 --- a/packages/components/form/FormList.tsx +++ b/packages/components/form/FormList.tsx @@ -147,92 +147,89 @@ const FormList: React.FC = (props) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [form, snakeName, fields]); - useImperativeHandle( - formListRef, - (): FormItemInstance => ({ - name, - fullPath, - value: formListValue, - initialData, - isFormList: true, - formListMapRef, - getValue: () => cloneDeep(get(form?.store, fullPath)), - validate: (trigger = 'all') => { - const resultList = []; - const validates = [...formListMapRef.current.values()].map((formItemRef) => - formItemRef?.current?.validate?.(trigger), - ); - return new Promise((resolve) => { - Promise.all(validates).then((validateResult) => { - validateResult.forEach((result) => { - if (typeof result !== 'object') return; - const errorValue = Object.values(result)[0]; - merge(resultList, errorValue); - }); - const errorItems = validateResult.filter((item) => { - if (typeof item !== 'object') return; - return Object.values(item)[0] !== true; - }); - if (errorItems.length) { - resolve({ [snakeName]: resultList }); - } else { - resolve({ [snakeName]: true }); - } + useImperativeHandle(formListRef, (): FormItemInstance => ({ + name, + fullPath, + value: formListValue, + initialData, + isFormList: true, + formListMapRef, + getValue: () => cloneDeep(get(form?.store, fullPath)), + validate: (trigger = 'all') => { + const resultList = []; + const validates = [...formListMapRef.current.values()].map((formItemRef) => + formItemRef?.current?.validate?.(trigger), + ); + return new Promise((resolve) => { + Promise.all(validates).then((validateResult) => { + validateResult.forEach((result) => { + if (typeof result !== 'object') return; + const errorValue = Object.values(result)[0]; + merge(resultList, errorValue); }); + const errorItems = validateResult.filter((item) => { + if (typeof item !== 'object') return; + return Object.values(item)[0] !== true; + }); + if (errorItems.length) { + resolve({ [snakeName]: resultList }); + } else { + resolve({ [snakeName]: true }); + } }); - }, - // TODO 支持局部更新数据 - setValue: (fieldData) => { - setListFields(fieldData, (formItemRef, data) => { - formItemRef?.current?.setValue?.(data); - }); - }, - setField: (fieldData) => { - const { value, status } = fieldData; - const currentValue = get(form?.store, fullPath) || []; - if (isEqual(currentValue, value)) return; - setListFields(value, (formItemRef, data) => { - formItemRef?.current?.setField?.({ value: data, status }); - }); - }, - resetField: (type) => { - const resetType = type || resetTypeFromContext; - if (resetType === 'initial') { - const currentData = get(form?.store, fullPath); - if (isEqual(currentData, initialData)) return; - set(form?.store, fullPath, initialData); - setFormListValue(initialData); - const newFields = initialData?.map((data, index) => ({ - data: { ...data }, - key: (globalKey += 1), - name: index, - isListField: true, - })); - setFields(newFields); - } else { - // 重置为空 - unset(form?.store, fullPath); - setFormListValue([]); - setFields([]); - } - }, - setValidateMessage: (fieldData) => { - [...formListMapRef.current.values()].forEach((formItemRef) => { - if (!formItemRef.current) return; + }); + }, + // TODO 支持局部更新数据 + setValue: (fieldData) => { + setListFields(fieldData, (formItemRef, data) => { + formItemRef?.current?.setValue?.(data); + }); + }, + setField: (fieldData) => { + const { value, status } = fieldData; + const currentValue = get(form?.store, fullPath) || []; + if (isEqual(currentValue, value)) return; + setListFields(value, (formItemRef, data) => { + formItemRef?.current?.setField?.({ value: data, status }); + }); + }, + resetField: (type) => { + const resetType = type || resetTypeFromContext; + if (resetType === 'initial') { + const currentData = get(form?.store, fullPath); + if (isEqual(currentData, initialData)) return; + set(form?.store, fullPath, initialData); + setFormListValue(initialData); + const newFields = initialData?.map((data, index) => ({ + data: { ...data }, + key: (globalKey += 1), + name: index, + isListField: true, + })); + setFields(newFields); + } else { + // 重置为空 + unset(form?.store, fullPath); + setFormListValue([]); + setFields([]); + } + }, + setValidateMessage: (fieldData) => { + [...formListMapRef.current.values()].forEach((formItemRef) => { + if (!formItemRef.current) return; - const { name } = formItemRef.current; - const data = get(fieldData, name); + const { name } = formItemRef.current; + const data = get(fieldData, name); - formItemRef?.current?.setValidateMessage?.(data); - }); - }, - resetValidate: () => { - [...formListMapRef.current.values()].forEach((formItemRef) => { - formItemRef?.current?.resetValidate?.(); - }); - }, - }), - ); + formItemRef?.current?.setValidateMessage?.(data); + }); + }, + resetValidate: () => { + [...formListMapRef.current.values()].forEach((formItemRef) => { + formItemRef?.current?.resetValidate?.(); + }); + }, + })); if (typeof children !== 'function') { log.error('Form', `FormList's children must be a function!`); diff --git a/packages/components/form/hooks/useWatch.ts b/packages/components/form/hooks/useWatch.ts index 0367da74a8..5304c5ea45 100644 --- a/packages/components/form/hooks/useWatch.ts +++ b/packages/components/form/hooks/useWatch.ts @@ -16,7 +16,7 @@ export default function useWatch(name: NamePath, form: InternalFormInstance) { useEffect(() => { if (!isValidForm) return; - const { registerWatch = noop } = form.getInternalHooks?.(HOOK_MARK); + const { registerWatch = noop } = form.getInternalHooks?.(HOOK_MARK) || {}; const cancelRegister = registerWatch(() => { const allFieldsValue = form.getFieldsValue?.(true); diff --git a/packages/components/guide/utils/getScrollParent.ts b/packages/components/guide/utils/getScrollParent.ts index 0fb577f4af..f23a3d2920 100644 --- a/packages/components/guide/utils/getScrollParent.ts +++ b/packages/components/guide/utils/getScrollParent.ts @@ -7,7 +7,7 @@ export function getScrollParent(element: HTMLElement) { if (style.position === 'fixed') return document.body; - for (let parent = element; parent.parentElement; ) { + for (let parent = element; parent.parentElement;) { parent = parent.parentElement; style = getComputedStyle(parent); if (excludeStaticParent && style.position === 'static') { diff --git a/packages/components/progress/Progress.tsx b/packages/components/progress/Progress.tsx index 192fc12527..8ca8f3a936 100644 --- a/packages/components/progress/Progress.tsx +++ b/packages/components/progress/Progress.tsx @@ -133,9 +133,6 @@ const Progress = forwardRef((props, ref) => { return diameter; } switch (size) { - default: - diameter = Number(size); - break; case 'small': diameter = 72; break; @@ -145,6 +142,9 @@ const Progress = forwardRef((props, ref) => { case 'large': diameter = 160; break; + default: + diameter = Number(size); + break; } return diameter; }; diff --git a/packages/components/radio/__tests__/radio.test.tsx b/packages/components/radio/__tests__/radio.test.tsx index c8e17793a0..fd594cc933 100644 --- a/packages/components/radio/__tests__/radio.test.tsx +++ b/packages/components/radio/__tests__/radio.test.tsx @@ -140,9 +140,27 @@ describe('RadioGroup [basic api]', () => { describe('RadioGroup [primary-filled bg-block]', () => { const MOCK_SIZES = [ { selector: '.t-radio-group', width: 300, height: 40, left: 0, top: 0 }, - { selector: '.t-radio-button:nth-child(1)', width: 60, height: 32, left: 4, top: 4 }, - { selector: '.t-radio-button:nth-child(2)', width: 60, height: 32, left: 68, top: 4 }, - { selector: '.t-radio-button:nth-child(3)', width: 60, height: 32, left: 132, top: 4 }, + { + selector: '.t-radio-button:nth-child(1)', + width: 60, + height: 32, + left: 4, + top: 4, + }, + { + selector: '.t-radio-button:nth-child(2)', + width: 60, + height: 32, + left: 68, + top: 4, + }, + { + selector: '.t-radio-button:nth-child(3)', + width: 60, + height: 32, + left: 132, + top: 4, + }, ]; // 根据选项索引获取对应按钮的尺寸数据 @@ -218,7 +236,9 @@ describe('RadioGroup [primary-filled bg-block]', () => { expect(container.querySelector('.t-radio-group__bg-block')).not.toBeInTheDocument(); await act(async () => { - await new Promise((resolve) => setTimeout(resolve, 150)); + await new Promise((resolve) => { + setTimeout(resolve, 150); + }); }); const bgBlock = container.querySelector('.t-radio-group__bg-block') as HTMLElement; @@ -302,7 +322,9 @@ describe('RadioGroup [primary-filled bg-block]', () => { } await act(async () => { - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { + setTimeout(resolve, 100); + }); }); const bgBlock = container.querySelector('.t-radio-group__bg-block') as HTMLElement; diff --git a/packages/components/switch/__tests__/switch.test.tsx b/packages/components/switch/__tests__/switch.test.tsx index 79dfa2f8a0..d0c6ed120f 100644 --- a/packages/components/switch/__tests__/switch.test.tsx +++ b/packages/components/switch/__tests__/switch.test.tsx @@ -57,7 +57,9 @@ describe('Switch 组件测试', () => { }); const { container } = render(); fireEvent.click(container.firstChild); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { + setTimeout(resolve, 100); + }); expect(container.firstChild.classList.contains('t-is-checked')).toBeTruthy(); }); test('beforeChange reject', async () => { @@ -70,7 +72,9 @@ describe('Switch 组件测试', () => { }); const { container } = render(); fireEvent.click(container.firstChild); - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { + setTimeout(resolve, 100); + }); expect(container.firstChild.classList.contains('t-is-checked')).toBeFalsy(); }); }); diff --git a/packages/components/tabs/__tests__/tabs.test.tsx b/packages/components/tabs/__tests__/tabs.test.tsx index 3194a6adb6..eab95fa3a6 100644 --- a/packages/components/tabs/__tests__/tabs.test.tsx +++ b/packages/components/tabs/__tests__/tabs.test.tsx @@ -86,14 +86,14 @@ describe('Tabs 组件测试', () => { label: string; value: string; }[] - >((re) => + >((re) => { setTimeout(() => { re([ { label: 'A', value: 'a' }, { label: 'B', value: 'b' }, ]); - }, 1000), - ), + }, 1000); + }), ); const useFetch = Promise>(func: F) => { @@ -127,7 +127,9 @@ describe('Tabs 组件测试', () => { const getNavItems = () => tabInstance.querySelectorAll('.t-tabs__nav-item'); expect(getNavItems().length).toBe(0); - await new Promise((resolve) => setTimeout(resolve, 1000)); + await new Promise((resolve) => { + setTimeout(resolve, 1000); + }); expect(getNavItems().length).toBe(2); expect(() => tabInstance.querySelector('.t-tabs__bar')).not.toBe(null); const tabBar = tabInstance.querySelector('.t-tabs__bar'); @@ -193,11 +195,18 @@ describe('Tabs 组件测试', () => { expect(onTabRemoveFn).toHaveBeenCalledTimes(1); expect(onTabPanelRemoveFn).toHaveBeenCalledTimes(1); - expect(onTabRemoveFn).toHaveBeenCalledWith({ value: 'a', e: expect.any(Object), index: 0 }); + expect(onTabRemoveFn).toHaveBeenCalledWith({ + value: 'a', + e: expect.any(Object), + index: 0, + }); const tabRemoveFnArg = onTabRemoveFn.mock.calls[0][0]; expect(tabRemoveFnArg.e.nativeEvent).toBeInstanceOf(MouseEvent); - expect(onTabPanelRemoveFn).toHaveBeenCalledWith({ value: 'a', e: expect.any(Object) }); + expect(onTabPanelRemoveFn).toHaveBeenCalledWith({ + value: 'a', + e: expect.any(Object), + }); const tabPanelRemoveFnArg = onTabPanelRemoveFn.mock.calls[0][0]; expect(tabPanelRemoveFnArg.e.nativeEvent).toBeInstanceOf(MouseEvent); }); diff --git a/packages/components/time-picker/panel/SinglePanel.tsx b/packages/components/time-picker/panel/SinglePanel.tsx index ccf241528d..430e21e320 100644 --- a/packages/components/time-picker/panel/SinglePanel.tsx +++ b/packages/components/time-picker/panel/SinglePanel.tsx @@ -178,7 +178,7 @@ const SinglePanel: FC = (props) => { let val: number | string; let formattedVal: string; - const scrollTop = colsRef.current[idx]?.scrollTop + panelOffset.top; + const scrollTop = (colsRef.current[idx]?.scrollTop ?? 0) + panelOffset.top; const { offsetHeight, margin } = getItemHeight(); const timeItemTotalHeight = offsetHeight + margin; let colStep = Math.abs(Math.round(scrollTop / timeItemTotalHeight + 0.5)); diff --git a/packages/pro-components/chat/chat-engine/components/toolcall/types.ts b/packages/pro-components/chat/chat-engine/components/toolcall/types.ts index d5260568e7..17ab38dc67 100644 --- a/packages/pro-components/chat/chat-engine/components/toolcall/types.ts +++ b/packages/pro-components/chat/chat-engine/components/toolcall/types.ts @@ -48,8 +48,7 @@ interface InteractiveToolcallConfig { // 最终的配置类型 export type AgentToolcallConfig = - | NonInteractiveToolcallConfig - | InteractiveToolcallConfig; + NonInteractiveToolcallConfig | InteractiveToolcallConfig; // 类型守卫:判断是否为非交互式配置 export function isNonInteractive( diff --git a/packages/pro-components/chat/chatbot/_example/service-config.tsx b/packages/pro-components/chat/chatbot/_example/service-config.tsx index 7e6b75776c..2adc94f2ab 100644 --- a/packages/pro-components/chat/chatbot/_example/service-config.tsx +++ b/packages/pro-components/chat/chatbot/_example/service-config.tsx @@ -114,7 +114,9 @@ export default function ServiceConfig() { onAbort: async () => { console.log('用户中止对话'); // 可以执行清理操作 - await new Promise((resolve) => setTimeout(resolve, 100)); + await new Promise((resolve) => { + setTimeout(resolve, 100); + }); }, // 7. 错误处理 From 8531b2e475a89163dd70028a10f99c1b710b1de1 Mon Sep 17 00:00:00 2001 From: liweijie <674416404@qq.com> Date: Sun, 30 Aug 2026 18:22:47 +0800 Subject: [PATCH 5/5] fix(affix): avoid unsafe optional arithmetic --- packages/components/affix/Affix.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/affix/Affix.tsx b/packages/components/affix/Affix.tsx index 6a6ce9ea7c..fd4f97551d 100644 --- a/packages/components/affix/Affix.tsx +++ b/packages/components/affix/Affix.tsx @@ -72,7 +72,7 @@ const Affix = forwardRef((props, ref) => { if (isWindow(scrollContainer.current)) { containerHeight = scrollContainer.current.innerHeight - wrapHeight; } else { - containerHeight = scrollContainer.current?.clientHeight - wrapHeight; + containerHeight = (scrollContainer.current?.clientHeight ?? 0) - wrapHeight; } const calcBottom = containerToTop + containerHeight - (offsetBottom ?? 0); // 计算 bottom 相对应的 top 值