feat: merge阶段1: 新增文件合并及适配#3459
Conversation
Walkthrough新增 QuickEnter 双端组件(类型/实现/样式/文档/演示/测试)、A11y 指南与治理脚本、Copilot 指令库构建脚本、价格渲染与过渡工具,并包含多处组件类型、样式与测试修正。 ChangesQuickEnter 与相关前端类型
无障碍、Copilot 与治理脚本
工具、过渡与 Price 支持
CalendarCard、样式与演示扩展
组件实现与导出/类型调整、其它小修
Estimated code review effort: Possibly related PRs:
Suggested reviewers:
✨ Finishing Touches🧪 Generate unit tests (beta)
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feat_v3.x #3459 +/- ##
=============================================
+ Coverage 88.43% 88.48% +0.04%
=============================================
Files 291 293 +2
Lines 19311 19463 +152
Branches 3019 3031 +12
=============================================
+ Hits 17078 17222 +144
- Misses 2227 2235 +8
Partials 6 6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/locales/zh-TW.ts (1)
3-3:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win变量命名不一致。
在
zh-TW.ts文件中,导出的常量命名为zhCN,但应该命名为zhTW以保持一致性。这可能会导致混淆。建议的修复
-const zhCN: BaseLang = { +const zhTW: BaseLang = { save: '保存', confirm: '確認',同时更新最后的导出语句:
-export default zhCN +export default zhTW🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/locales/zh-TW.ts` at line 3, The exported constant is misnamed: change the BaseLang constant named zhCN to zhTW and update any related references/export to use zhTW instead of zhCN so the Traditional Chinese (Taiwan) locale variable name matches its file and intent; update the declaration (zhCN -> zhTW) and the export statement to export zhTW.
♻️ Duplicate comments (6)
src/packages/calendarcard/demos/h5/demo14.tsx (2)
7-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win未使用的状态变量
dateStr(与 demo13 相同问题)。状态
dateStr在组件中被更新但从未被读取使用,且变量名暗示字符串但存储的是数字。建议删除或使用该状态,并考虑更准确的命名。♻️ 建议的修复方案
const Demo14 = () => { - const [dateStr, setDate] = useState(date.getMonth()) const onPageChange = (val: any) => { console.log('onPageChange', val) - setDate(val.month) }Also applies to: 10-10
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/calendarcard/demos/h5/demo14.tsx` at line 7, The state variable dateStr created with useState(date.getMonth()) is never read and its name is misleading (it's a number, not a string); either remove the unused state (delete the dateStr and setDate usage) or replace it with a properly named numeric state (e.g., monthIndex and setMonthIndex) and use that value where the component needs the current month; update any handlers that call setDate to call the new setter name if you keep it.
12-12:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win未使用的 ref 且命名不符合约定(与 demo13 相同问题)。
CalendarCardRef被创建但从未使用,且应使用 camelCase 命名。♻️ 建议的修复方案
- const CalendarCardRef = useRef<CalendarCardRef>(null) - return ( <CalendarCard - ref={CalendarCardRef} defaultValue={date}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/calendarcard/demos/h5/demo14.tsx` at line 12, The ref declaration CalendarCardRef is unused and misnamed; either remove the unused const or rename it to camelCase and attach it to the CalendarCard component. Specifically, replace the declaration const CalendarCardRef = useRef<CalendarCardRef>(null) with const calendarCardRef = useRef<CalendarCardRef>(null) and pass calendarCardRef into the component as ref (e.g., <CalendarCard ref={calendarCardRef} ... />), or simply delete the unused useRef if no ref behavior is needed.src/packages/calendarcard/demos/taro/demo13.tsx (2)
7-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win未使用的状态变量
dateStr(与 h5/demo13 相同问题)。状态
dateStr在组件中被更新但从未被读取使用,且变量名暗示字符串但存储的是数字。建议删除或使用该状态。♻️ 建议的修复方案
const Demo13 = () => { - const [dateStr, setDate] = useState(date.getMonth()) const onPageChange = (val: any) => { console.log('onPageChange', val) - setDate(val.month) }Also applies to: 10-10
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/calendarcard/demos/taro/demo13.tsx` at line 7, The state variable dateStr created via useState (const [dateStr, setDate] = useState(date.getMonth())) is never read and its name implies a string while it stores a number; either remove this unused state or use it properly: if you need it, rename to something accurate (e.g., month or monthIndex), initialize with date.getMonth(), and reference the variable in the component render/logic wherever the month is required; otherwise delete both dateStr and setDate and any setDate calls to eliminate the unused state.
12-12:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win未使用的 ref 且命名不符合约定(与 h5/demo13 相同问题)。
CalendarCardRef被创建但从未使用,且应使用 camelCase 命名。♻️ 建议的修复方案
- const CalendarCardRef = useRef<CalendarCardRef>(null) - return ( <CalendarCard - ref={CalendarCardRef} defaultValue={date}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/calendarcard/demos/taro/demo13.tsx` at line 12, The declared ref const CalendarCardRef = useRef<CalendarCardRef>(null) is unused and the identifier violates camelCase; either remove this unused ref declaration entirely or rename it to camelCase (e.g., calendarCardRef) and wire it into the CalendarCard component prop/ref usage so it’s actually consumed (search for CalendarCard or any ref prop in this demo to attach it). Ensure the type parameter CalendarCardRef remains correct if you keep the ref.src/packages/calendarcard/demos/taro/demo14.tsx (2)
7-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win未使用的状态变量
dateStr(与 h5/demo14 相同问题)。状态
dateStr在组件中被更新但从未被读取使用,且变量名暗示字符串但存储的是数字。建议删除或使用该状态。♻️ 建议的修复方案
const Demo14 = () => { - const [dateStr, setDate] = useState(date.getMonth()) const onPageChange = (val: any) => { console.log('onPageChange', val) - setDate(val.month) }Also applies to: 10-10
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/calendarcard/demos/taro/demo14.tsx` at line 7, The state variable dateStr and its setter setDate (created via useState(date.getMonth())) are unused and misnamed (holds a number, not a string); either remove the state entirely or rename and use it consistently: delete the useState call and any setDate updates if the value isn't needed, or change the name to something like monthIndex, keep useState(monthIndex), and read monthIndex where needed (search for dateStr and setDate in this component to update usages). Ensure consistency between the variable name and stored type if you choose to keep it.
12-12:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win未使用的 ref 且命名不符合约定(与 h5/demo14 相同问题)。
CalendarCardRef被创建但从未使用,且应使用 camelCase 命名。♻️ 建议的修复方案
- const CalendarCardRef = useRef<CalendarCardRef>(null) - return ( <CalendarCard - ref={CalendarCardRef} defaultValue={date}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/calendarcard/demos/taro/demo14.tsx` at line 12, The ref variable CalendarCardRef is unused and its name doesn't follow camelCase; either remove the unused useRef call or rename and use it consistently. Locate the useRef<CalendarCardRef>(null) declaration in the demo14 component and either delete that line if the ref isn't needed, or rename the identifier to calendarCardRef (camelCase) and wire it into the CalendarCard component's ref prop and any calls (e.g., calendarCardRef.current.someMethod) so the ref is actually used.
🧹 Nitpick comments (7)
src/utils/should-render-price-raw.ts (2)
22-23: ⚡ Quick win非空断言的类型安全性。
虽然
String.prototype.matchAll()返回的匹配对象在使用全局正则时应该始终包含index属性,但使用非空断言!会绕过 TypeScript 的类型检查。建议添加运行时检查或使用可选链来提高代码健壮性。
🛡️ 建议的防御性编码
const a = matches[0] const b = matches[1] - const i0 = a.index! - const i1 = b.index! + const i0 = a.index ?? 0 + const i1 = b.index ?? 0 const between = t.slice(i0 + a[0].length, i1)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/should-render-price-raw.ts` around lines 22 - 23, The non-null assertions on a.index and b.index (i0 = a.index! / i1 = b.index!) bypass TypeScript safety; change these to safe accesses by checking for undefined (e.g., if (a.index == null || b.index == null) return <appropriate fallback or throw>) or use optional chaining and handle the undefined case before using i0/i1, ensuring the function (should-render-price-raw or the scope where i0/i1 are used) has a defined fallback or error path when index is missing.
16-16: ⚡ Quick win冗余的字符串 trim 操作。
hasNoExtractablePrice函数已经对输入字符串执行了trim()操作(第 5 行)。此处再次 trim 是不必要的。建议直接使用
s或在函数开始处统一 trim 一次。♻️ 建议的重构
export function shouldRenderPriceAsRaw(s: string) { + const t = s.trim() - if (hasNoExtractablePrice(s)) { + if (hasNoExtractablePrice(t)) { return true } - const t = s.trim() if (!CJK.test(t)) return false或者修改
hasNoExtractablePrice返回 trim 后的字符串以避免重复 trim。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/should-render-price-raw.ts` at line 16, The local trim at "const t = s.trim()" is redundant because hasNoExtractablePrice already trims the input; remove the extra trim and use the already-trimmed string (or refactor hasNoExtractablePrice to return the trimmed value and consume that) so that functions referencing "t" use the single trimmed source; update references to "t" accordingly (or replace "t" with "s") in the surrounding logic to avoid double-trimming.src/utils/taro/ConfigurableCSSTransition.tsx (4)
63-65: ⚡ Quick win从 unmounted 到 entering 的中间状态转换可能导致不必要的渲染。
当状态为
'unmounted'时,代码先将其设置为'exited'(第 64 行),然后立即在第 67 行设置为'entering'。这会触发两次快速的状态更新。如果中间的
'exited'状态对过渡动画不是必需的,可以考虑直接从'unmounted'转换到'entering'以减少渲染次数。♻️ 可选的优化方案
const enter = useCallback(() => { if (timerRef.current) clearTimeout(timerRef.current) - if (statusRef.current === 'unmounted') { - updateStatus('exited') - } - updateStatus('entering') setClasses(`${baseClassName}-enter ${baseClassName}-enter-active`)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/taro/ConfigurableCSSTransition.tsx` around lines 63 - 65, The component currently flips statusRef.current from 'unmounted' to 'exited' then immediately to 'entering', causing two renders; change the branch that checks statusRef.current === 'unmounted' to call updateStatus('entering') directly (remove the intermediate updateStatus('exited') call) and ensure any downstream logic that relied on the transient 'exited' state in ConfigurableCSSTransition still works or is adapted to handle the direct transition; the key symbols to update are statusRef and updateStatus in the ConfigurableCSSTransition component.
110-112: ⚡ Quick winclassName 拼接可能产生前导空格。
当
children.props.className为空或未定义时,第 111 行的拼接会产生前导空格(例如" nut-fade-enter")。虽然浏览器通常能正确处理,但更规范的做法是过滤空值。♻️ 建议的改进
return cloneElement(children, { - className: `${children.props.className || ''} ${classes}`, + className: [children.props.className, classes].filter(Boolean).join(' '), })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/taro/ConfigurableCSSTransition.tsx` around lines 110 - 112, The className concatenation in cloneElement(children, { className: `${children.props.className || ''} ${classes}` }) can produce a leading space when children.props.className is empty; update the code to build className by combining children.props.className and classes into an array, filter out falsy/empty values, and join with a single space (e.g., use [children.props.className, classes].filter(Boolean).join(' ')) before passing it to cloneElement so no extra leading/trailing spaces remain.
41-49: 💤 Low value初始状态与初始类名的轻微不一致。
当
inPhase=false且mountOnEnter=true时,初始状态为'unmounted',但初始类名被设置为'exit-done'。由于组件在unmounted状态时返回null(第 108 行),这些类名实际不会被应用。虽然不影响功能,但可以考虑在初始化 classes 时也检查 unmounted 状态以保持一致性。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/taro/ConfigurableCSSTransition.tsx` around lines 41 - 49, Initial classes state is inconsistent with the status when inPhase is false and mountOnEnter is true: status becomes 'unmounted' but classes is set to `${baseClassName}-exit-done`; change the classes initializer to mirror the status logic using the same conditions (inPhase, unmountOnExit, mountOnEnter) so that when the computed status would be 'unmounted' you return an empty string (or another explicit unmounted marker) and when it would be 'exited' you return `${baseClassName}-exit-done`, keeping the `inPhase` branch returning `${baseClassName}-enter-done`; update the useState initializer for `classes` accordingly (referencing `status` logic, `inPhase`, `unmountOnExit`, `mountOnEnter`, and `baseClassName`).
20-20: ⚡ Quick win未使用的
nodeRefprop。
nodeRef在接口中定义并被解构(第 33 行),但在组件实现中从未被使用。如果该 prop 是为未来功能预留的,建议添加注释说明;否则可以移除以保持代码简洁。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/utils/taro/ConfigurableCSSTransition.tsx` at line 20, The prop nodeRef declared in the component props type and destructured in ConfigurableCSSTransition is unused; either remove nodeRef from the props interface and from the destructuring in the ConfigurableCSSTransition function, or explicitly mark it as reserved by adding a short TODO/comment next to the nodeRef declaration and keep it only where destructured (so it's clear it’s intentionally unused). Update the props type and the function signature/destructuring in ConfigurableCSSTransition accordingly to keep the code clean and consistent.scripts/build-copilot-ctx.mjs (1)
37-37: ⚡ Quick win建议提升正则表达式的可读性
Line 37 使用
\x24来匹配美元符号$,虽然功能正确,但可读性较差。建议直接使用\$或\\$,使代码意图更清晰。♻️ 建议的改进
-const tokenRegex = /\x24(color|font|spacing|radius)-([\w-]+):\s*var\((--nutui-[\w-]+).*?\)/g +const tokenRegex = /\$(color|font|spacing|radius)-([\w-]+):\s*var\((--nutui-[\w-]+).*?\)/g🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/build-copilot-ctx.mjs` at line 37, Replace the non-obvious hex escape in the regular expression assigned to tokenRegex: the current pattern uses "\x24" to match the dollar sign; change that to the clearer "\$" (escaped dollar) so the regex /\$ (color|font|spacing|radius)-([\w-]+):\s*var\((--nutui-[\w-]+).*?\)/g is easier to read and maintain, ensuring the rest of the tokenRegex pattern and flags remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/a11y-governance.mjs`:
- Around line 138-139: The replacement content.replace(/= \/>/g, '=>') risks
converting valid JSX attribute patterns into arrow functions; update the fix by
either tightening the pattern to match only the exact accidental split produced
by your earlier replacement (e.g., constrain surrounding context so you only
convert sequences that were previously transformed by the /\/ \/>/g step), or
remove this restorative replacement if you confirm the earlier /\/ \/>/g change
cannot affect arrow functions; if you keep it, add a clear comment above the
line explaining it's a targeted restoration for the specific mis-transformation
from the prior replacement and include the related prior pattern (/\/ \/>/g) in
the comment for traceability.
In `@scripts/copilot/instructions.md`:
- Around line 74-88: The generated Markdown tables break because unescaped pipe
characters in prop type strings (e.g., the `type` and `fill` cells) are treated
as column separators; update the table-generation logic in
scripts/build-copilot-ctx.mjs to escape or wrap those cells before emitting the
table: locate the table generation function/loop that builds header/row cells
and transform any cell string containing '|' by either replacing '|' with '\|'
or '|' or wrapping the entire cell in a <code>...</code> tag so the
Markdown renderer treats it as a single cell; ensure this transformation runs
for all component API tables and include tests or sample inputs for `type` and
`fill` to validate the fix.
In `@src/packages/calendarcard/demos/h5/demo13.tsx`:
- Line 7: The component defines an unused state pair dateStr and setDate via
useState(date.getMonth()) and the name is misleading (stores a month index, not
a string); either remove the unused state entirely or rename it to something
meaningful like currentMonth and actually use currentMonth in the component to
control calendar display (update usages that call setDate to setCurrentMonth and
replace any dateStr reads with currentMonth), ensuring the initial value remains
date.getMonth() or derived from the date variable.
- Line 12: The ref variable CalendarCardRef is unused and misnamed; either
remove the unused useRef call entirely or rename it to camelCase (e.g.,
calendarCardRef) and ensure you actually reference calendarCardRef.current where
needed; update any imports/types referencing CalendarCardRef to match the new
name if you keep it and verify useRef<CalendarCardRef>(null) is accessed in the
component logic.
- Line 8: The onPageChange handler currently types its parameter as any; import
and use the exported CalendarCardMonth type from the CalendarCard package and
change the signature of onPageChange to use that type (e.g., onPageChange =
(val: CalendarCardMonth) => { ... }) so the parameter is strongly typed and you
get full TS checking; update the import statement to include CalendarCardMonth
and adjust any downstream usages inside onPageChange to match the typed
properties.
In `@src/packages/quickenter/demos/taro/demo1.tsx`:
- Line 17: The documentation example uses Toast.show with a single string but
the Taro Toast implementation requires an id first and a config object second;
update the example call to use Toast.show('toast', { content: `Clicked:
${item.title}` }) so it matches the implementation. Locate the example that
calls Toast.show (the demo/example usage) and change the invocation to pass the
toast id as the first argument and an object with content as the second
argument, ensuring the string interpolation remains inside the content property.
In `@src/packages/quickenter/doc.en-US.md`:
- Line 173: The Markdown link uses a fragment '#/en-US/component/configprovider'
which triggers MD051; update the link in doc.en-US.md (the text "ConfigProvider
component" referencing '#/en-US/component/configprovider') to use a full
absolute path or complete URL (e.g., '/en-US/component/configprovider' or
'https://your-site-domain/en-US/component/configprovider') so the validator no
longer flags it and navigation is unambiguous.
In `@src/packages/quickenter/doc.md`:
- Line 126: 在 src/packages/quickenter/doc.md 中将文中的链接片段
'#/zh-CN/component/configprovider' 替换为完整的绝对 URL(包含协议和主机),例如
https://<your-site-domain>/#/zh-CN/component/configprovider,以修复 MD051 lint
警告并提升可读性;确保替换发生在包含“ConfigProvider 组件”引用的那一行并保留原有锚点路径部分。
In `@src/packages/quickenter/doc.taro.md`:
- Line 43: The doc example uses Toast.show(`Clicked: ${item.title}`) but the
demo uses Toast.show('toast', { content: `Clicked: ${item.title}` }); update the
doc snippet in doc.taro.md to match the actual API used in demo1.tsx by
replacing the one-arg call with Toast.show('toast', { content: `Clicked:
${item.title}` }) (or alternatively change demo1.tsx to the single-arg form if
you intend the simpler API), ensuring references to Toast.show and the demo1.tsx
usage remain consistent.
- Line 174: 当前文档中引用的路由片段 "#/zh-CN/component/configprovider"
可能无效;请定位该字符串并将其替换为正确的 ConfigProvider 文档路由(例如改为带连字符的
"#/zh-CN/component/config-provider" 或项目中实际使用的 Taro 专用路由),或者确认当前是 Taro 文档并改为 Taro
版本的路径;确保替换发生在 src/packages/quickenter/doc.taro.md 中出现该链接的句子并保持链接语义一致。
In `@src/packages/quickenter/doc.zh-TW.md`:
- Line 126: The documentation link fragment currently references
'#/zh-CN/component/configprovider' which mismatches this Traditional Chinese
doc; update the fragment in src/packages/quickenter/doc.zh-TW.md to the correct
route (e.g. '#/zh-TW/component/configprovider') or verify and replace it with
the actual router fragment used by your site so the reference in the sentence
"詳情請參考 [ConfigProvider 組件](`#/zh-CN/component/configprovider`)" points to the
correct ConfigProvider page.
- Line 1: Remove the leftover placeholder text "在這裡輸入要轉換的內容" from the top of the
README/translation file so the first line starts with the actual title "#
QuickEnter 快捷入口"; simply delete that placeholder string (ensure no extra
whitespace remains) in the file where the first line currently contains
"在這裡輸入要轉換的內容# QuickEnter 快捷入口".
In `@src/packages/quickenter/quickenter.scss`:
- Line 1: The SCSS import in quickenter.scss includes the .scss extension which
violates the scss/load-partial-extension rule; edit the `@import` statement that
currently references '../popup/popup.scss' (in quickenter.scss) to remove the
.scss extension so it imports the partial by path '../popup/popup' (or
equivalent without the extension) to comply with the lint rule.
- Line 116: Replace the deprecated CSS property by changing the rule that
currently uses "word-wrap: break-word;" in quickenter.scss to use the modern
standard "overflow-wrap: break-word;" (update the declaration in the selector
containing that property, e.g., in the rule where word-wrap is set) so the
stylesheet uses the standard property while preserving the same behavior.
- Around line 54-63: 修正误导性注释:在 quickenter.scss 中更新 &-content
的注释,使其反映当前样式(overflow-y: hidden 会隐藏溢出,而不是始终可滚动),并说明实际可滚动行为是由嵌套的
&-content-scrollable(overflow-y: auto) 控制;确保注释使用清晰描述与这两个选择器(&-content 和
&-content-scrollable)各自行为的短语。
In `@src/packages/quickenter/quickenter.tsx`:
- Around line 84-90: The interactive divs (notably the one with class
`${classPrefix}-close-btn` that calls onCancelEvent and the other div used for
selecting an entry which uses an onClick handler) are not keyboard-accessible;
either replace these divs with semantic <button> elements, or add accessibility
attributes and keyboard handlers: add role="button" and tabIndex={0} to the divs
and implement an onKeyDown handler that invokes the same handler on Enter (key
=== "Enter") and Space (key === " " or key === "Spacebar") while keeping
e.stopPropagation() behavior; ensure the close handler (onCancelEvent) and the
entry-selection handler are invoked from both onClick and onKeyDown so keyboard
users can activate them.
In `@src/utils/should-render-price-raw.ts`:
- Around line 4-10: The function hasNoExtractablePrice contains a redundant
check: after trimming into t and already returning true when no digits are found
(!/\d/.test(t)), the subsequent condition t.replace(/[^\d.]/g, '') === '' can
never be true; remove that third if check from hasNoExtractablePrice (or replace
it with a different boundary check if you intended to detect strings that only
contain non-digit/non-dot characters) so the function only returns true for
empty trimmed strings or strings without any digits.
---
Outside diff comments:
In `@src/locales/zh-TW.ts`:
- Line 3: The exported constant is misnamed: change the BaseLang constant named
zhCN to zhTW and update any related references/export to use zhTW instead of
zhCN so the Traditional Chinese (Taiwan) locale variable name matches its file
and intent; update the declaration (zhCN -> zhTW) and the export statement to
export zhTW.
---
Duplicate comments:
In `@src/packages/calendarcard/demos/h5/demo14.tsx`:
- Line 7: The state variable dateStr created with useState(date.getMonth()) is
never read and its name is misleading (it's a number, not a string); either
remove the unused state (delete the dateStr and setDate usage) or replace it
with a properly named numeric state (e.g., monthIndex and setMonthIndex) and use
that value where the component needs the current month; update any handlers that
call setDate to call the new setter name if you keep it.
- Line 12: The ref declaration CalendarCardRef is unused and misnamed; either
remove the unused const or rename it to camelCase and attach it to the
CalendarCard component. Specifically, replace the declaration const
CalendarCardRef = useRef<CalendarCardRef>(null) with const calendarCardRef =
useRef<CalendarCardRef>(null) and pass calendarCardRef into the component as ref
(e.g., <CalendarCard ref={calendarCardRef} ... />), or simply delete the unused
useRef if no ref behavior is needed.
In `@src/packages/calendarcard/demos/taro/demo13.tsx`:
- Line 7: The state variable dateStr created via useState (const [dateStr,
setDate] = useState(date.getMonth())) is never read and its name implies a
string while it stores a number; either remove this unused state or use it
properly: if you need it, rename to something accurate (e.g., month or
monthIndex), initialize with date.getMonth(), and reference the variable in the
component render/logic wherever the month is required; otherwise delete both
dateStr and setDate and any setDate calls to eliminate the unused state.
- Line 12: The declared ref const CalendarCardRef =
useRef<CalendarCardRef>(null) is unused and the identifier violates camelCase;
either remove this unused ref declaration entirely or rename it to camelCase
(e.g., calendarCardRef) and wire it into the CalendarCard component prop/ref
usage so it’s actually consumed (search for CalendarCard or any ref prop in this
demo to attach it). Ensure the type parameter CalendarCardRef remains correct if
you keep the ref.
In `@src/packages/calendarcard/demos/taro/demo14.tsx`:
- Line 7: The state variable dateStr and its setter setDate (created via
useState(date.getMonth())) are unused and misnamed (holds a number, not a
string); either remove the state entirely or rename and use it consistently:
delete the useState call and any setDate updates if the value isn't needed, or
change the name to something like monthIndex, keep useState(monthIndex), and
read monthIndex where needed (search for dateStr and setDate in this component
to update usages). Ensure consistency between the variable name and stored type
if you choose to keep it.
- Line 12: The ref variable CalendarCardRef is unused and its name doesn't
follow camelCase; either remove the unused useRef call or rename and use it
consistently. Locate the useRef<CalendarCardRef>(null) declaration in the demo14
component and either delete that line if the ref isn't needed, or rename the
identifier to calendarCardRef (camelCase) and wire it into the CalendarCard
component's ref prop and any calls (e.g., calendarCardRef.current.someMethod) so
the ref is actually used.
---
Nitpick comments:
In `@scripts/build-copilot-ctx.mjs`:
- Line 37: Replace the non-obvious hex escape in the regular expression assigned
to tokenRegex: the current pattern uses "\x24" to match the dollar sign; change
that to the clearer "\$" (escaped dollar) so the regex /\$
(color|font|spacing|radius)-([\w-]+):\s*var\((--nutui-[\w-]+).*?\)/g is easier
to read and maintain, ensuring the rest of the tokenRegex pattern and flags
remain unchanged.
In `@src/utils/should-render-price-raw.ts`:
- Around line 22-23: The non-null assertions on a.index and b.index (i0 =
a.index! / i1 = b.index!) bypass TypeScript safety; change these to safe
accesses by checking for undefined (e.g., if (a.index == null || b.index ==
null) return <appropriate fallback or throw>) or use optional chaining and
handle the undefined case before using i0/i1, ensuring the function
(should-render-price-raw or the scope where i0/i1 are used) has a defined
fallback or error path when index is missing.
- Line 16: The local trim at "const t = s.trim()" is redundant because
hasNoExtractablePrice already trims the input; remove the extra trim and use the
already-trimmed string (or refactor hasNoExtractablePrice to return the trimmed
value and consume that) so that functions referencing "t" use the single trimmed
source; update references to "t" accordingly (or replace "t" with "s") in the
surrounding logic to avoid double-trimming.
In `@src/utils/taro/ConfigurableCSSTransition.tsx`:
- Around line 63-65: The component currently flips statusRef.current from
'unmounted' to 'exited' then immediately to 'entering', causing two renders;
change the branch that checks statusRef.current === 'unmounted' to call
updateStatus('entering') directly (remove the intermediate
updateStatus('exited') call) and ensure any downstream logic that relied on the
transient 'exited' state in ConfigurableCSSTransition still works or is adapted
to handle the direct transition; the key symbols to update are statusRef and
updateStatus in the ConfigurableCSSTransition component.
- Around line 110-112: The className concatenation in cloneElement(children, {
className: `${children.props.className || ''} ${classes}` }) can produce a
leading space when children.props.className is empty; update the code to build
className by combining children.props.className and classes into an array,
filter out falsy/empty values, and join with a single space (e.g., use
[children.props.className, classes].filter(Boolean).join(' ')) before passing it
to cloneElement so no extra leading/trailing spaces remain.
- Around line 41-49: Initial classes state is inconsistent with the status when
inPhase is false and mountOnEnter is true: status becomes 'unmounted' but
classes is set to `${baseClassName}-exit-done`; change the classes initializer
to mirror the status logic using the same conditions (inPhase, unmountOnExit,
mountOnEnter) so that when the computed status would be 'unmounted' you return
an empty string (or another explicit unmounted marker) and when it would be
'exited' you return `${baseClassName}-exit-done`, keeping the `inPhase` branch
returning `${baseClassName}-enter-done`; update the useState initializer for
`classes` accordingly (referencing `status` logic, `inPhase`, `unmountOnExit`,
`mountOnEnter`, and `baseClassName`).
- Line 20: The prop nodeRef declared in the component props type and
destructured in ConfigurableCSSTransition is unused; either remove nodeRef from
the props interface and from the destructuring in the ConfigurableCSSTransition
function, or explicitly mark it as reserved by adding a short TODO/comment next
to the nodeRef declaration and keep it only where destructured (so it's clear
it’s intentionally unused). Update the props type and the function
signature/destructuring in ConfigurableCSSTransition accordingly to keep the
code clean and consistent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: cb90b680-3f14-4cd3-b7f7-e67c7c4294a2
📒 Files selected for processing (48)
.agents/A11Y-WORKFLOW.md.agents/skills-a11y.md.agents/skills/performance_audit/SKILL.md.gitignoreNutUI-React_组件标准白皮书.mdscripts/a11y-governance.mjsscripts/build-copilot-ctx.mjsscripts/copilot/README.mdscripts/copilot/instructions.mdsrc/config.jsonsrc/locales/base.tssrc/locales/en-US.tssrc/locales/id-ID.tssrc/locales/ja-JP.tssrc/locales/tr-TR.tssrc/locales/vi-VN.tssrc/locales/zh-CN.tssrc/locales/zh-TW.tssrc/locales/zh-UG.tssrc/packages/calendarcard/demos/h5/demo13.tsxsrc/packages/calendarcard/demos/h5/demo14.tsxsrc/packages/calendarcard/demos/taro/demo13.tsxsrc/packages/calendarcard/demos/taro/demo14.tsxsrc/packages/quickenter/__tests__/quickenter.spec.tsxsrc/packages/quickenter/demo.taro.tsxsrc/packages/quickenter/demo.tsxsrc/packages/quickenter/demos/h5/demo1.tsxsrc/packages/quickenter/demos/h5/demo2.tsxsrc/packages/quickenter/demos/h5/demo3.tsxsrc/packages/quickenter/demos/taro/demo1.tsxsrc/packages/quickenter/demos/taro/demo2.tsxsrc/packages/quickenter/demos/taro/demo3.tsxsrc/packages/quickenter/doc.en-US.mdsrc/packages/quickenter/doc.mdsrc/packages/quickenter/doc.taro.mdsrc/packages/quickenter/doc.zh-TW.mdsrc/packages/quickenter/index.taro.tssrc/packages/quickenter/index.tssrc/packages/quickenter/quickenter.scsssrc/packages/quickenter/quickenter.taro.tsxsrc/packages/quickenter/quickenter.tsxsrc/styles/variables.scsssrc/types/index.tssrc/types/spec/quickenter/base.tssrc/types/spec/quickenter/h5.tssrc/types/spec/quickenter/taro.tssrc/utils/should-render-price-raw.tssrc/utils/taro/ConfigurableCSSTransition.tsx
| // 步骤 4:恢复由于误匹配可能导致的箭头函数损坏 (针对极极端情况) | ||
| content = content.replace(/= \/>/g, '=>') |
There was a problem hiding this comment.
潜在的正则替换风险
Line 139 的替换规则 content.replace(/= \/>/g, '=>') 可能会错误地将某些合法的 JSX 属性值(如 prop= /> 的边界情况)误判为箭头函数。虽然这种情况极少见,但建议添加更精确的上下文匹配,或者在注释中说明这是为了修复 Line 136 可能误伤箭头函数的极端情况。
如果 Line 136 的 /\/ \/>/g 替换不会影响箭头函数(因为箭头函数通常写作 () => 而非 ()/ />),那么 Line 139 的恢复逻辑可能是多余的。
💡 建议的优化
如果确认 Line 136 不会误伤箭头函数,可以移除 Line 139:
// 步骤 3:语法清理 & 保护箭头函数
// 将 "/ />" 修复为 "/>",但防止误伤 "=>"
content = content.replace(/\/ \/>/g, '/>')
-
-// 步骤 4:恢复由于误匹配可能导致的箭头函数损坏 (针对极极端情况)
-content = content.replace(/= \/>/g, '=>')或者添加更详细的注释说明保留原因。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // 步骤 4:恢复由于误匹配可能导致的箭头函数损坏 (针对极极端情况) | |
| content = content.replace(/= \/>/g, '=>') | |
| // 步骤 3:语法清理 & 保护箭头函数 | |
| // 将 "/ />" 修复为 "/>",但防止误伤 "=>" | |
| content = content.replace(/\/ \/>/g, '/>') |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/a11y-governance.mjs` around lines 138 - 139, The replacement
content.replace(/= \/>/g, '=>') risks converting valid JSX attribute patterns
into arrow functions; update the fix by either tightening the pattern to match
only the exact accidental split produced by your earlier replacement (e.g.,
constrain surrounding context so you only convert sequences that were previously
transformed by the /\/ \/>/g step), or remove this restorative replacement if
you confirm the earlier /\/ \/>/g change cannot affect arrow functions; if you
keep it, add a clear comment above the line explaining it's a targeted
restoration for the specific mis-transformation from the prior replacement and
include the related prior pattern (/\/ \/>/g) in the comment for traceability.
| ### <Button /> | ||
|
|
||
| | 属性 (Prop) | 说明 (Description) | 类型 (Type) | 默认值 (Default) | | ||
| | --- | --- | --- | --- | | ||
| | type | 按钮的样式 | ``default` | `primary` | `info` | `warning` | `danger` | `success`` | default | | ||
| | size | 按钮的尺寸 | ``normal` | `large` | `small`` | normal | | ||
| | shape | 按钮的形状 | ``square` | `round`` | round | | ||
| | color | 按钮颜色,支持传入 linear-gradient 渐变色 | `string` | - | | ||
| | fill | 填充模式 | ``solid` | `ouline` | `none`` | solid | | ||
| | disabled | 是否禁用按钮 | `boolean` | false | | ||
| | block | 是否为块级元素 | `boolean` | false | | ||
| | icon | 按钮图标 | `ReactNode` | - | | ||
| | loading | 按钮loading状态 | `boolean` | false | | ||
| | onClick | 点击按钮时触发 | `onClick: (e: MouseEvent) => void` | false | | ||
|
|
There was a problem hiding this comment.
表格列数不一致导致渲染错误
生成的 Markdown 表格中,类型定义包含的管道符号 | 被误解析为列分隔符,导致表格结构错乱。例如:
- Line 78:
type属性的类型`default` | `primary` | `info` | `warning` | `danger` | `success`被解析为 9 列,而非 4 列 - Line 82:
fill属性同样存在此问题
影响:
- Markdown 渲染器无法正确显示表格
- AI 可能无法正确解析表格内容
- 用户阅读体验受损
建议修复方案:
在 scripts/build-copilot-ctx.mjs 中对类型字符串进行处理:
- 将类型定义中的
|替换为\|进行转义,或 - 使用 HTML 实体
|替代,或 - 将包含
|的单元格内容用<code>标签包裹
这个问题影响整个文档中的所有组件 API 表格。
🔧 参考修复代码
在 scripts/build-copilot-ctx.mjs 的表格生成部分(约 Line 76):
components[name].forEach(p => {
- md += `| ${p.prop} | ${p.desc} | \`${p.type}\` | ${p.default} |\n`
+ const escapedType = p.type.replace(/\|/g, '\\|')
+ md += `| ${p.prop} | ${p.desc} | \`${escapedType}\` | ${p.default} |\n`
})🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 78-78: Table column count
Expected: 4; Actual: 9; Too many cells, extra data will be missing
(MD056, table-column-count)
[warning] 79-79: Table column count
Expected: 4; Actual: 6; Too many cells, extra data will be missing
(MD056, table-column-count)
[warning] 80-80: Table column count
Expected: 4; Actual: 5; Too many cells, extra data will be missing
(MD056, table-column-count)
[warning] 82-82: Table column count
Expected: 4; Actual: 6; Too many cells, extra data will be missing
(MD056, table-column-count)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/copilot/instructions.md` around lines 74 - 88, The generated Markdown
tables break because unescaped pipe characters in prop type strings (e.g., the
`type` and `fill` cells) are treated as column separators; update the
table-generation logic in scripts/build-copilot-ctx.mjs to escape or wrap those
cells before emitting the table: locate the table generation function/loop that
builds header/row cells and transform any cell string containing '|' by either
replacing '|' with '\|' or '|' or wrapping the entire cell in a
<code>...</code> tag so the Markdown renderer treats it as a single cell; ensure
this transformation runs for all component API tables and include tests or
sample inputs for `type` and `fill` to validate the fix.
| const date = new Date('2025-01-01') | ||
|
|
||
| const Demo13 = () => { | ||
| const [dateStr, setDate] = useState(date.getMonth()) |
There was a problem hiding this comment.
未使用的状态变量 dateStr。
状态 dateStr 在组件中被更新但从未被读取使用。此外,变量名 dateStr 暗示存储字符串,但实际存储的是数字(月份索引 0-11)。建议删除未使用的状态或将其用于控制日历显示,并考虑更准确的命名如 currentMonth。
♻️ 建议的修复方案
如果该状态变量确实不需要,删除它:
const Demo13 = () => {
- const [dateStr, setDate] = useState(date.getMonth())
const onPageChange = (val: any) => {
console.log('onPageChange', val)
- setDate(val.month)
}或者,如果需要使用它,请重命名并在组件中使用:
- const [dateStr, setDate] = useState(date.getMonth())
+ const [currentMonth, setCurrentMonth] = useState(date.getMonth())
const onPageChange = (val: any) => {
console.log('onPageChange', val)
- setDate(val.month)
+ setCurrentMonth(val.month)
}
+ // 然后在组件中使用 currentMonth,例如显示当前月份Also applies to: 10-10
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/calendarcard/demos/h5/demo13.tsx` at line 7, The component
defines an unused state pair dateStr and setDate via useState(date.getMonth())
and the name is misleading (stores a month index, not a string); either remove
the unused state entirely or rename it to something meaningful like currentMonth
and actually use currentMonth in the component to control calendar display
(update usages that call setDate to setCurrentMonth and replace any dateStr
reads with currentMonth), ensuring the initial value remains date.getMonth() or
derived from the date variable.
|
|
||
| const Demo13 = () => { | ||
| const [dateStr, setDate] = useState(date.getMonth()) | ||
| const onPageChange = (val: any) => { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 验证 CalendarCard 是否导出了 onPageChange 的类型定义
rg -n --type=ts --type=tsx -A 5 -B 5 'onPageChange.*:' src/packages/calendarcard/Repository: jdf2e/nutui-react
Length of output: 89
🏁 Script executed:
#!/bin/bash
# First, locate the CalendarCard component file
fd -e ts -e tsx 'calendarcard' src/packages/calendarcard/ | head -20Repository: jdf2e/nutui-react
Length of output: 210
🏁 Script executed:
#!/bin/bash
# Search for onPageChange pattern without type suffix in calendarcard package
rg -n -A 5 -B 5 'onPageChange' src/packages/calendarcard/ --type tsRepository: jdf2e/nutui-react
Length of output: 20660
🏁 Script executed:
#!/bin/bash
# Look at the demo13.tsx file to see the current implementation
cat -n src/packages/calendarcard/demos/h5/demo13.tsx | head -20Repository: jdf2e/nutui-react
Length of output: 794
🏁 Script executed:
#!/bin/bash
# Look for interface or type definitions in calendarcard.tsx
head -100 src/packages/calendarcard/calendarcard.tsx | grep -A 50 "interface\|type\|Props"Repository: jdf2e/nutui-react
Length of output: 2075
🏁 Script executed:
#!/bin/bash
# Search for type exports and interface definitions in CalendarCard
rg -n "interface|type.*=" src/packages/calendarcard/calendarcard.tsx | head -30Repository: jdf2e/nutui-react
Length of output: 528
🏁 Script executed:
#!/bin/bash
# Check the CalendarCard props interface to find onPageChange definition
rg -n -A 20 "interface.*Props\|interface.*Card" src/packages/calendarcard/calendarcard.tsxRepository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Find the types file referenced in the import
fd -e ts -e tsx 'types' src/ | grep -E "types\.ts|index\.ts" | head -5Repository: jdf2e/nutui-react
Length of output: 223
🏁 Script executed:
#!/bin/bash
# Search for WebCalendarCardProps definition
rg -n "WebCalendarCardProps\|CalendarCardMonth" --type ts | head -20Repository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Look for the types directory
find src -type d -name typesRepository: jdf2e/nutui-react
Length of output: 71
🏁 Script executed:
#!/bin/bash
# Look for CalendarCard types in src/types
rg -n "CalendarCard\|onPageChange" src/types/ --type tsRepository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
#!/bin/bash
# List files in src/types
ls -la src/types/Repository: jdf2e/nutui-react
Length of output: 402
🏁 Script executed:
#!/bin/bash
# Search for WebCalendarCardProps in src/types
rg -n "WebCalendarCardProps\|interface.*CalendarCard" src/types/ -A 20 --type tsRepository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Search in the main types index file
rg -n "CalendarCard" src/types/index.ts -A 30Repository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Also search for onPageChange in the entire package
rg -n "onPageChange.*:" src/packages/calendarcard/ --type tsRepository: jdf2e/nutui-react
Length of output: 589
🏁 Script executed:
#!/bin/bash
# Search for CalendarCard type definitions more broadly
rg -n "interface.*CalendarCard\|type.*CalendarCard" src/types/ --type ts -A 20Repository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Check if there's a spec file for CalendarCard types
ls -la src/types/spec/ | grep -i calendarRepository: jdf2e/nutui-react
Length of output: 183
🏁 Script executed:
#!/bin/bash
# Search in spec directory
cat src/types/spec/*.ts 2>/dev/null | grep -A 20 "CalendarCard"Repository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
#!/bin/bash
# Look at CalendarCard type spec files
ls -la src/types/spec/calendarcard/Repository: jdf2e/nutui-react
Length of output: 347
🏁 Script executed:
#!/bin/bash
# Read the CalendarCard type files
cat src/types/spec/calendarcard/*.tsRepository: jdf2e/nutui-react
Length of output: 1389
🏁 Script executed:
#!/bin/bash
# Check if CalendarCardMonth is exported from the main package index
rg -n "CalendarCardMonth" src/packages/calendarcard/ --type tsRepository: jdf2e/nutui-react
Length of output: 717
🏁 Script executed:
#!/bin/bash
# Check main package exports
rg -n "export.*CalendarCard" src/packages/calendarcard/index.ts -A 5 -B 5Repository: jdf2e/nutui-react
Length of output: 224
使用具体的类型定义替代 any。
onPageChange 的 val 参数使用 any 类型会失去类型安全性。CalendarCard 已导出 CalendarCardMonth 类型,应直接导入使用:
♻️ 建议的改进
-import { CalendarCard, CalendarCardRef } from '@nutui/nutui-react'
+import { CalendarCard, CalendarCardRef, CalendarCardMonth } from '@nutui/nutui-react'
- const onPageChange = (val: any) => {
+ const onPageChange = (val: CalendarCardMonth) => {
console.log('onPageChange', val)
setDate(val.month)
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/calendarcard/demos/h5/demo13.tsx` at line 8, The onPageChange
handler currently types its parameter as any; import and use the exported
CalendarCardMonth type from the CalendarCard package and change the signature of
onPageChange to use that type (e.g., onPageChange = (val: CalendarCardMonth) =>
{ ... }) so the parameter is strongly typed and you get full TS checking; update
the import statement to include CalendarCardMonth and adjust any downstream
usages inside onPageChange to match the typed properties.
| console.log('onPageChange', val) | ||
| setDate(val.month) | ||
| } | ||
| const CalendarCardRef = useRef<CalendarCardRef>(null) |
There was a problem hiding this comment.
未使用的 ref 且命名不符合约定。
CalendarCardRef 被创建但从未在组件中使用(没有访问 .current)。此外,ref 变量应使用 camelCase 命名(如 calendarCardRef)而不是 PascalCase,后者通常保留给组件名称。
♻️ 建议的修复方案
如果不需要 ref,删除它:
- const CalendarCardRef = useRef<CalendarCardRef>(null)
-
return (
<CalendarCard
- ref={CalendarCardRef}
defaultValue={date}或者,如果需要保留 ref,请使用 camelCase 命名:
- const CalendarCardRef = useRef<CalendarCardRef>(null)
+ const calendarCardRef = useRef<CalendarCardRef>(null)
return (
<CalendarCard
- ref={CalendarCardRef}
+ ref={calendarCardRef}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/calendarcard/demos/h5/demo13.tsx` at line 12, The ref variable
CalendarCardRef is unused and misnamed; either remove the unused useRef call
entirely or rename it to camelCase (e.g., calendarCardRef) and ensure you
actually reference calendarCardRef.current where needed; update any
imports/types referencing CalendarCardRef to match the new name if you keep it
and verify useRef<CalendarCardRef>(null) is accessed in the component logic.
| @@ -0,0 +1,122 @@ | |||
| @import '../popup/popup.scss'; | |||
There was a problem hiding this comment.
移除 @import 中的 .scss 扩展名。
在 SCSS 中导入局部文件时,不应包含 .scss 扩展名。这违反了 scss/load-partial-extension 规则。
🔧 建议的修复
-@import '../popup/popup.scss';
+@import '../popup/popup';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @import '../popup/popup.scss'; | |
| `@import` '../popup/popup'; |
🧰 Tools
🪛 Stylelint (17.11.0)
[error] 1-1: Unexpected extension ".scss" in @import (scss/load-partial-extension)
(scss/load-partial-extension)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/quickenter/quickenter.scss` at line 1, The SCSS import in
quickenter.scss includes the .scss extension which violates the
scss/load-partial-extension rule; edit the `@import` statement that currently
references '../popup/popup.scss' (in quickenter.scss) to remove the .scss
extension so it imports the partial by path '../popup/popup' (or equivalent
without the extension) to comply with the lint rule.
| &-content { | ||
| flex: 1; | ||
| padding: 10px 28px; | ||
| overflow-y: hidden; // 始终可滚动,防止内容被遮挡 | ||
| box-sizing: border-box; | ||
|
|
||
| &-scrollable { | ||
| overflow-y: auto; // Only scroll when > 8 items | ||
| -webkit-overflow-scrolling: touch; | ||
| } |
There was a problem hiding this comment.
修正误导性的注释。
第 57 行的注释说"始终可滚动,防止内容被遮挡",但实际代码设置的是 overflow-y: hidden,这会隐藏溢出内容而不是滚动。实际的滚动行为是通过 &-content-scrollable 修饰符类(第 60-63 行)启用的。建议修改注释以准确反映实际行为。
📝 建议的修复
&-content {
flex: 1;
padding: 10px 28px;
- overflow-y: hidden; // 始终可滚动,防止内容被遮挡
+ overflow-y: hidden; // 默认隐藏溢出,通过 scrollable 修饰符启用滚动
box-sizing: border-box;
&-scrollable {
- overflow-y: auto; // Only scroll when > 8 items
+ overflow-y: auto; // 当内容超过容器高度时启用滚动
-webkit-overflow-scrolling: touch;
}
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/quickenter/quickenter.scss` around lines 54 - 63, 修正误导性注释:在
quickenter.scss 中更新 &-content 的注释,使其反映当前样式(overflow-y: hidden
会隐藏溢出,而不是始终可滚动),并说明实际可滚动行为是由嵌套的 &-content-scrollable(overflow-y: auto)
控制;确保注释使用清晰描述与这两个选择器(&-content 和 &-content-scrollable)各自行为的短语。
| line-height: 1.4; | ||
| // Allow multi-line if text is long, preventing truncation | ||
| white-space: normal; | ||
| word-wrap: break-word; |
There was a problem hiding this comment.
使用 overflow-wrap 替代已弃用的 word-wrap。
word-wrap 属性已被弃用,应使用现代标准属性 overflow-wrap。虽然两者功能相同,但使用标准属性可提高代码的未来兼容性。
🔄 建议的修复
white-space: normal;
- word-wrap: break-word;
+ overflow-wrap: break-word;
width: 72px; // Allow text to be slightly wider than icon📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| word-wrap: break-word; | |
| overflow-wrap: break-word; |
🧰 Tools
🪛 Stylelint (17.11.0)
[error] 116-116: Expected "word-wrap" to be "overflow-wrap" (property-no-deprecated)
(property-no-deprecated)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/quickenter/quickenter.scss` at line 116, Replace the deprecated
CSS property by changing the rule that currently uses "word-wrap: break-word;"
in quickenter.scss to use the modern standard "overflow-wrap: break-word;"
(update the declaration in the selector containing that property, e.g., in the
rule where word-wrap is set) so the stylesheet uses the standard property while
preserving the same behavior.
| <div | ||
| className={`${classPrefix}-close-btn`} | ||
| onClick={(e) => { | ||
| e.stopPropagation() | ||
| onCancelEvent() | ||
| }} | ||
| > |
There was a problem hiding this comment.
可点击容器缺少键盘可达语义,存在无障碍阻断
Line 84-90 和 Line 106-110 用 div + onClick 承担交互,键盘用户无法完成“关闭”和“选择入口”操作。建议至少补齐 role/tabIndex 与 Enter/Space 键处理(或改为 button)。
♿ 建议修复
<div
className={`${classPrefix}-close-btn`}
+ role="button"
+ tabIndex={0}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault()
+ onCancelEvent()
+ }
+ }}
onClick={(e) => {
e.stopPropagation()
onCancelEvent()
}}
>
@@
<div
key={index}
className={`${classPrefix}-item`}
+ role="button"
+ tabIndex={0}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault()
+ handleItemClick(item, index)
+ }
+ }}
onClick={() => handleItemClick(item, index)}
aria-label={`${item.title} ${item.badge ?? item.badgeProps?.value}`}
>Also applies to: 106-110
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/quickenter/quickenter.tsx` around lines 84 - 90, The interactive
divs (notably the one with class `${classPrefix}-close-btn` that calls
onCancelEvent and the other div used for selecting an entry which uses an
onClick handler) are not keyboard-accessible; either replace these divs with
semantic <button> elements, or add accessibility attributes and keyboard
handlers: add role="button" and tabIndex={0} to the divs and implement an
onKeyDown handler that invokes the same handler on Enter (key === "Enter") and
Space (key === " " or key === "Spacebar") while keeping e.stopPropagation()
behavior; ensure the close handler (onCancelEvent) and the entry-selection
handler are invoked from both onClick and onKeyDown so keyboard users can
activate them.
| function hasNoExtractablePrice(s: string) { | ||
| const t = s.trim() | ||
| if (!t) return true | ||
| if (!/\d/.test(t)) return true | ||
| if (t.replace(/[^\d.]/g, '') === '') return true | ||
| return false | ||
| } |
There was a problem hiding this comment.
行 8 的逻辑检查冗余。
第 7 行已经检查了字符串中是否存在数字(!/\d/.test(t))。如果没有数字,函数会在第 7 行返回 true。因此,执行到第 8 行时,字符串必定包含至少一个数字,t.replace(/[^\d.]/g, '') === '' 永远不会为真。
建议移除第 8 行或重新评估该函数的边界情况处理逻辑。
♻️ 建议的修复
function hasNoExtractablePrice(s: string) {
const t = s.trim()
if (!t) return true
if (!/\d/.test(t)) return true
- if (t.replace(/[^\d.]/g, '') === '') return true
return false
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/utils/should-render-price-raw.ts` around lines 4 - 10, The function
hasNoExtractablePrice contains a redundant check: after trimming into t and
already returning true when no digits are found (!/\d/.test(t)), the subsequent
condition t.replace(/[^\d.]/g, '') === '' can never be true; remove that third
if check from hasNoExtractablePrice (or replace it with a different boundary
check if you intended to detect strings that only contain non-digit/non-dot
characters) so the function only returns true for empty trimmed strings or
strings without any digits.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/packages/formitem/formitem.scss`:
- Around line 175-178: Restore the commented `.required` rule so RTL +
form-layout-left uses right positioning: re-enable the `.required { left: auto;
right: 0.1em; }` block (previously commented out) so it overrides the
`.nut-form-item-label-left-required` left:-10px behavior and places the required
asterisk correctly when labels are right-aligned in RTL layouts. Ensure the rule
remains active in the same stylesheet alongside the form item label classes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: be005423-77e5-4743-80e7-eb3d0cc12662
📒 Files selected for processing (7)
src/packages/calendar/calendar.scsssrc/packages/calendarcard/calendarcard.scsssrc/packages/configprovider/types.tssrc/packages/formitem/formitem.scsssrc/packages/popup/popup.scsssrc/styles/variables-jmapp.scsssrc/styles/variables-jrkf.scss
| // .required { | ||
| // left: auto; | ||
| // right: 0.1em; | ||
| // } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
echo "1) 检查 FormItem 组件中 required 相关 class 的实际输出:"
rg -n -C3 --type=tsx "left-required|right-required|\\brequired\\b" src/packages/formitem
echo
echo "2) 检查仓库内 .required 样式定义,确认是否仍有定位依赖:"
rg -n -C2 --type=scss "\\.required\\b"Repository: jdf2e/nutui-react
Length of output: 151
🏁 Script executed:
#!/bin/bash
set -e
echo "1) 查看 formitem.scss 文件的完整内容,特别是 175-178 行附近:"
wc -l src/packages/formitem/formitem.scss
echo "---"
sed -n '160,190p' src/packages/formitem/formitem.scss
echo
echo "2) 搜索整个 SCSS 文件中的 .required 相关定义:"
rg -n "\\.required" src/packages/formitem/formitem.scss
echo
echo "3) 检查 FormItem 组件的 TypeScript/JSX 实现:"
find src/packages/formitem -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.jsx" \) | head -5
echo
echo "4) 在 FormItem 源码中搜索 required 相关的类名处理:"
rg -n "required" src/packages/formitem -t js -t ts 2>/dev/null | grep -v "node_modules" | head -20Repository: jdf2e/nutui-react
Length of output: 2202
🏁 Script executed:
#!/bin/bash
set -e
echo "1) 查看第99行附近的 .required 样式定义:"
sed -n '95,115p' src/packages/formitem/formitem.scss
echo
echo "2) 搜索所有 nut-form-item-label- 相关的样式:"
rg -n "nut-form-item-label-" src/packages/formitem/formitem.scss
echo
echo "3) 查看 FormItem 组件中 starPosition 如何设置:"
sed -n '180,210p' src/packages/formitem/formitem.tsxRepository: jdf2e/nutui-react
Length of output: 1481
🏁 Script executed:
#!/bin/bash
set -e
echo "1) 查看 RTL + form-layout-left 的完整样式块和 .required 注释前的代码:"
sed -n '170,182p' src/packages/formitem/formitem.scss
echo
echo "2) 搜索是否存在 nut-form-item-label-left-required 或 right-required 的样式定义:"
rg -n "\\.nut-form-item-label-(left|right)-required" src/packages/formitem/formitem.scss
echo
echo "3) 检查不在 RTL 块中的 form-layout-left 是否有 .required 样式:"
rg -n -B5 -A5 "form-layout-left" src/packages/formitem/formitem.scss | head -40
echo
echo "4) 检查第99行的 .required 样式是在哪个选择器下的上下文:"
sed -n '90,120p' src/packages/formitem/formitem.scssRepository: jdf2e/nutui-react
Length of output: 466
🏁 Script executed:
#!/bin/bash
set -e
echo "1) 获取完整的 formitem.scss 内容来理解样式结构:"
cat src/packages/formitem/formitem.scss
echo
echo "2) 确认 .required 类是在哪些地方使用的:"
rg -n "\\.required" src/packages/formitem/Repository: jdf2e/nutui-react
Length of output: 4091
恢复 RTL 左标签布局下 .required 的定位规则。
第 175-178 行注释的 .required 样式规则不应删除。在 RTL + form-layout-left 组合下,这个规则将星号从 left: -10px(由 .nut-form-item-label-left-required 定义)覆盖调整为 right: 0.1em,以确保星号在 RTL 右对齐标签中显示在正确位置。删除此规则会导致星号显示位置回归,建议恢复这段样式定义。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/formitem/formitem.scss` around lines 175 - 178, Restore the
commented `.required` rule so RTL + form-layout-left uses right positioning:
re-enable the `.required { left: auto; right: 0.1em; }` block (previously
commented out) so it overrides the `.nut-form-item-label-left-required`
left:-10px behavior and places the required asterisk correctly when labels are
right-aligned in RTL layouts. Ensure the rule remains active in the same
stylesheet alongside the form item label classes.
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/packages/progress/progress.taro.tsx (1)
25-51:⚠️ Potential issue | 🟠 MajorariaLabel 属性的移除破坏了无障碍支持,需要恢复。
ariaLabel属性在BaseProgress类型接口中定义,并在 Taro 文档和测试中有所记载(progress.spec.tsx第 70-75 行验证此属性),但在解构中被移除。这导致组件无法接收和使用无障碍标签,与其他 Taro 组件(如switch、radio)的实现不一致。需要在解构中恢复ariaLabel并将其传递给对应的 DOM 属性。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/progress/progress.taro.tsx` around lines 25 - 51, The destructuring in progress.taro.tsx removed the ariaLabel prop from BaseProgress, breaking accessibility; restore ariaLabel by including it in the destructured props (alongside className, percent, etc.) and ensure it is forwarded to the rendered DOM element (same place other attributes from ...rest are applied) so that the component uses ariaLabel for its accessibility attribute; reference BaseProgress, ariaLabel, props, progress.spec.tsx and the component where ...rest is spread to locate and fix the code.src/packages/dialog/__test__/dialog.spec.tsx (1)
142-144:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
waitFor未await,断言可能被静默忽略。
waitFor返回 Promise,未await会变成 "浮动 Promise"——如果其内部的expect不通过,错误会在测试结束后才抛出,无法可靠地让当前用例失败,部分版本下会出现 unhandled rejection 警告。建议加上await:🐛 建议补回 await
- waitFor(() => { - expect(footerOkEle).not.toHaveClass('nut-button-loading') - }) + await waitFor(() => { + expect(footerOkEle).not.toHaveClass('nut-button-loading') + })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/dialog/__test__/dialog.spec.tsx` around lines 142 - 144, The test is using waitFor(...) without awaiting it which creates a floating Promise that can silently miss failures; update the test to await the waitFor call so the assertion on footerOkEle (expect(footerOkEle).not.toHaveClass('nut-button-loading')) is executed within a resolved Promise and will correctly fail the test when violated—locate the waitFor usage in the spec (the waitFor wrapper around the expect for footerOkEle) and prepend it with await.
🧹 Nitpick comments (1)
src/packages/overlay/overlay.taro.tsx (1)
77-77: 💤 Low value考虑移除冗余的类型转换。
如果
duration属性在类型定义中已经是number类型,则Number(duration)转换可能是多余的。请检查TaroOverlayProps中duration的类型定义。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/packages/overlay/overlay.taro.tsx` at line 77, The timeout prop is passing timeout={Number(duration)} which is likely redundant; inspect TaroOverlayProps.duration and if it is already typed as number, replace Number(duration) with duration (i.e., timeout={duration}); if duration can be undefined or string, instead tighten the type in TaroOverlayProps to duration: number or add an explicit runtime guard (e.g., coerce only when type is string) so the conversion is only used when necessary; update usages in the component that reference duration to the corrected type/signature.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/packages/button/button.taro.tsx`:
- Around line 29-32: The forwardRef generic currently declares HTMLButtonElement
but the component renders a Taro <View>, so update the ref/event element types
to match the actual rendered element: change React.forwardRef<HTMLButtonElement,
Partial<TaroButtonProps>> to use a div-like element type (e.g., HTMLDivElement
or the type aligned with TaroButtonProps) and update the handleClick signature
from MouseEvent<HTMLButtonElement> to MouseEvent<HTMLDivElement>; also apply the
same ref/event-type correction at the other occurrence around the Button
implementation (line ~124) so refs and event handlers reflect the View/div
semantics rather than HTMLButtonElement.
- Line 6: The change replaced TaroButton with View but left behavior-affecting
artifacts: the formType prop (used to trigger submit/reset on H5/mini programs)
was effectively removed while nativeType is still destructured (dead code), and
many leftover comments like "// Button as TaroButton", "// formType", "getEnv"
and commented <TaroButton> fragments remain; decide whether to preserve formType
support or intentionally remove it—if preserving, keep the formType prop on the
Button component (and either pass it through to TaroButton or translate formType
to a native button[type] on web), otherwise remove formType and nativeType from
props and update types/docs to reflect the breaking change; finally, clean up
all residual commented code referencing TaroButton/formType/getEnv (search for
symbols TaroButton, formType, nativeType, getEnv, and the Button component) to
avoid maintenance noise.
- Line 100: The `${prefixCls}-${type}-solid` class is effectively unreachable
because defaultProps.fill is 'outline' and the code checks the merged
props.fill; change the condition to detect whether the caller explicitly
provided fill (use the original incoming props like rawProps.fill or check
`'fill' in props` before merging) and use that raw value in the class expression
for `${prefixCls}-${type}-solid` (update the component that merges defaults and
props so the className decision uses rawProps.fill or an explicit hasFill flag
rather than the merged props.fill).
In `@src/packages/calendarcard/calendarcard.taro.tsx`:
- Around line 402-415: The weekHeader computation currently uses a custom
weekdays array whenever weekdays.length > 0, which can misalign the header if it
isn't exactly 7 items; change the logic in the useMemo that defines weekHeader
so it only uses the passed-in weekdays when weekdays.length === 7, otherwise
fall back to locale.calendaritem.weekdays; keep the rest of the slice/rotate
logic using firstDayOfWeek and update the dependency array to include
locale.calendaritem.weekdays and firstDayOfWeek as already present (no other
code changes needed).
In `@src/packages/calendarcard/demo.taro.tsx`:
- Line 55: 在 demo.taro.tsx 中的自訂文案 customWeekdays 有繁簡混用,將目前的 '自定義周几' 修改為正確的繁體字
'自定義週幾';請更新變數 customWeekdays 的字串值(保留其他鍵名與格式不變),以避免字形不一致問題。
In `@src/packages/popup/doc.zh-TW.md`:
- Around line 92-93: Replace the Simplified Chinese phrases in the zh-TW
documentation with Traditional Chinese: change `标题左侧部分` to `標題左側部分` and `标题中间部分`
to `標題中間部分` (update the table cells that currently contain those strings).
In `@src/packages/safearea/safearea.taro.tsx`:
- Around line 7-16: The SafeArea component currently drops external props and
can emit an invalid class when position is undefined; update the SafeArea
function to destructure props (at least { position, className, style, ...rest }
from TaroSafeAreaProps), build the className via classNames(classPrefix,
position && `${classPrefix}-position-${position}`, className), and spread the
remaining props onto <View> (pass className and style explicitly and {...rest})
so id/data-*/events are preserved and the position class is only added when
position is truthy; refer to SafeArea, TaroSafeAreaProps, classPrefix, and the
View element to locate changes.
In `@src/packages/safearea/safearea.tsx`:
- Around line 8-13: Root div in SafeArea drops external className/style/other
props causing regressions; update the component (use classPrefix and
props.position) to merge incoming className into classNames (e.g.,
classNames(classPrefix, `${classPrefix}-position-${props.position}`,
props.className)), spread remaining props (e.g., {...rest}) onto the root div,
and preserve props.style by passing it through so external attributes are
forwarded instead of discarded.
In `@src/packages/uploader/__tests__/uploader.spec.tsx`:
- Around line 278-282: The test currently awaits fireEvent.change which only
resolves a microtask and can race with asynchronous beforeUpload/upload logic;
update the spec to stop directly asserting after fireEvent.change and instead
wrap the assertions in React Testing Library's waitFor (or await waitFor(() =>
...)) to wait for the async chain to complete; specifically change the
assertions that check handleUpload calls (references: handleUpload, the
fireEvent.change call, and any tests relying on beforeUpload or upload promises)
to be inside waitFor, and apply the same pattern to the related tests for
single-file upload, single-file failure, multi-file upload, autoUpload=false,
beforeUpload filtering, and empty-array scenarios so assertions run after the
async effects finish.
In `@src/types/spec/button/taro.ts`:
- Line 12: The Taro Button type for nativeType is missing the 'button' option;
update the nativeType union in src/types/spec/button/taro.ts (the nativeType
declaration) to include 'button' so it matches the base Button type and
documentation (i.e., change the union from 'submit' | 'reset' to 'submit' |
'reset' | 'button').
- Around line 4-7: The type OmitMiniProgramButtonProps currently omits size,
type, onClick, style, disabled, loading, id from MiniProgramButtonProps but
misses formType, causing TaroButtonProps to inherit formType from
MiniProgramButtonProps while BaseButton defines nativeType; update the Omit in
the OmitMiniProgramButtonProps definition to also exclude 'formType' so
TaroButtonProps does not carry the unused formType and avoids conflict with
nativeType (locate OmitMiniProgramButtonProps, MiniProgramButtonProps,
TaroButtonProps and BaseButton to make the change).
---
Outside diff comments:
In `@src/packages/dialog/__test__/dialog.spec.tsx`:
- Around line 142-144: The test is using waitFor(...) without awaiting it which
creates a floating Promise that can silently miss failures; update the test to
await the waitFor call so the assertion on footerOkEle
(expect(footerOkEle).not.toHaveClass('nut-button-loading')) is executed within a
resolved Promise and will correctly fail the test when violated—locate the
waitFor usage in the spec (the waitFor wrapper around the expect for
footerOkEle) and prepend it with await.
In `@src/packages/progress/progress.taro.tsx`:
- Around line 25-51: The destructuring in progress.taro.tsx removed the
ariaLabel prop from BaseProgress, breaking accessibility; restore ariaLabel by
including it in the destructured props (alongside className, percent, etc.) and
ensure it is forwarded to the rendered DOM element (same place other attributes
from ...rest are applied) so that the component uses ariaLabel for its
accessibility attribute; reference BaseProgress, ariaLabel, props,
progress.spec.tsx and the component where ...rest is spread to locate and fix
the code.
---
Nitpick comments:
In `@src/packages/overlay/overlay.taro.tsx`:
- Line 77: The timeout prop is passing timeout={Number(duration)} which is
likely redundant; inspect TaroOverlayProps.duration and if it is already typed
as number, replace Number(duration) with duration (i.e., timeout={duration}); if
duration can be undefined or string, instead tighten the type in
TaroOverlayProps to duration: number or add an explicit runtime guard (e.g.,
coerce only when type is string) so the conversion is only used when necessary;
update usages in the component that reference duration to the corrected
type/signature.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: c0be5d30-086a-40a6-a269-94f7ba5f21df
📒 Files selected for processing (46)
src/packages/avatar/avatar.taro.tsxsrc/packages/badge/badge.taro.tsxsrc/packages/button/button.taro.tsxsrc/packages/button/button.tsxsrc/packages/button/index.taro.tssrc/packages/button/index.tssrc/packages/calendarcard/__tests__/calendarcard.spec.tsxsrc/packages/calendarcard/calendarcard.taro.tsxsrc/packages/calendarcard/calendarcard.tsxsrc/packages/calendarcard/demo.taro.tsxsrc/packages/calendarcard/demo.tsxsrc/packages/calendarcard/icon.taro.tsxsrc/packages/dialog/__test__/dialog.spec.tsxsrc/packages/dialog/demos/h5/demo1.tsxsrc/packages/dialog/demos/h5/demo6.tsxsrc/packages/dialog/doc.en-US.mdsrc/packages/dialog/doc.mdsrc/packages/dialog/doc.taro.mdsrc/packages/dialog/doc.zh-TW.mdsrc/packages/divider/divider.taro.tsxsrc/packages/divider/divider.tsxsrc/packages/ellipsis/ellipsis.taro.tsxsrc/packages/ellipsis/ellipsis.tsxsrc/packages/empty/empty.taro.tsxsrc/packages/empty/empty.tsxsrc/packages/input/input.taro.tsxsrc/packages/inputnumber/inputnumber.taro.tsxsrc/packages/overlay/overlay.taro.tsxsrc/packages/popup/__tests__/popup.spec.tsxsrc/packages/popup/doc.en-US.mdsrc/packages/popup/doc.mdsrc/packages/popup/doc.zh-TW.mdsrc/packages/price/price.tsxsrc/packages/progress/progress.taro.tsxsrc/packages/progress/progress.tsxsrc/packages/range/range.tsxsrc/packages/safearea/safearea.scsssrc/packages/safearea/safearea.taro.tsxsrc/packages/safearea/safearea.tsxsrc/packages/textarea/textarea.tsxsrc/packages/uploader/__tests__/uploader.spec.tsxsrc/styles/jd-font.scsssrc/styles/theme-dark.scsssrc/types/spec/button/base.tssrc/types/spec/button/taro.tssrc/types/spec/calendarcard/base.ts
💤 Files with no reviewable changes (11)
- src/packages/dialog/doc.md
- src/packages/safearea/safearea.scss
- src/packages/dialog/demos/h5/demo6.tsx
- src/packages/dialog/doc.taro.md
- src/packages/popup/tests/popup.spec.tsx
- src/packages/dialog/demos/h5/demo1.tsx
- src/packages/button/index.ts
- src/packages/button/index.taro.ts
- src/packages/dialog/doc.en-US.md
- src/packages/dialog/doc.zh-TW.md
- src/packages/textarea/textarea.tsx
✅ Files skipped from review due to trivial changes (7)
- src/packages/divider/divider.taro.tsx
- src/packages/range/range.tsx
- src/packages/ellipsis/ellipsis.taro.tsx
- src/packages/divider/divider.tsx
- src/packages/input/input.taro.tsx
- src/packages/popup/doc.en-US.md
- src/packages/popup/doc.md
| ButtonProps as MiniProgramButtonProps, | ||
| View, | ||
| Button as TaroButton, | ||
| // Button as TaroButton, |
There was a problem hiding this comment.
移除 TaroButton/formType/getEnv 是行为级变更,且文件内残留大量注释代码。
把 TaroButton 替换为 View 后:
- 原本通过
formType="submit"|"reset"在 H5 / 小程序中触发表单提交/重置的能力被一并移除;同时nativeType仍在第 48 行被解构但已经无任何使用点,是事实上的 dead destructure。如果业务侧此前依赖<Button formType="submit">触发表单提交,会出现静默回归。请确认这是预期变更,并相应更新文档/类型;若需要继续支持,建议保留formType透传路径或在 H5 端转换为原生button[type]。 - 第 6、47、116–118、120–121、125、146 行残留了
// Button as TaroButton、// formType、// if (getEnv() === 'WEB')、// <TaroButton等注释代码。一旦合并方向确定,建议清理掉这些注释,避免后续维护噪音与误导。
♻️ 建议清理注释残留并移除未使用解构
-import {
- View,
- // Button as TaroButton,
-} from '@tarojs/components'
+import { View } from '@tarojs/components'
@@
- style,
- // formType,
- nativeType,
- onClick,
+ style,
+ onClick,
@@
- // if (getEnv() === 'WEB') {
- // ;(rest as any).type = formType
- // }
- return (
- // `@ts-ignore`
- // <TaroButton
- <View
+ return (
+ <View
{...rest}
ref={ref}
- // formType={formType || nativeType}
className={buttonClassNames}
@@
- </View>
- // </TaroButton>
- )
+ </View>
+ )Also applies to: 47-48, 116-129, 146-147
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/button/button.taro.tsx` at line 6, The change replaced
TaroButton with View but left behavior-affecting artifacts: the formType prop
(used to trigger submit/reset on H5/mini programs) was effectively removed while
nativeType is still destructured (dead code), and many leftover comments like
"// Button as TaroButton", "// formType", "getEnv" and commented <TaroButton>
fragments remain; decide whether to preserve formType support or intentionally
remove it—if preserving, keep the formType prop on the Button component (and
either pass it through to TaroButton or translate formType to a native
button[type] on web), otherwise remove formType and nativeType from props and
update types/docs to reflect the breaking change; finally, clean up all residual
commented code referencing TaroButton/formType/getEnv (search for symbols
TaroButton, formType, nativeType, getEnv, and the Button component) to avoid
maintenance noise.
| export const Button = React.forwardRef< | ||
| HTMLButtonElement, | ||
| Partial<TaroButtonProps> | ||
| >((props, ref) => { |
There was a problem hiding this comment.
forwardRef 的元素类型与实际渲染的 View 不匹配。
React.forwardRef<HTMLButtonElement, ...> 仍然标记 ref 为 HTMLButtonElement,但实际承载 ref 的已经换成了 @tarojs/components 的 <View>(在 H5 端是 div,在小程序端是原生 view,绝非 HTMLButtonElement)。这会误导调用方按 HTMLButtonElement 的 API(如 .focus()、.form、.disabled)去使用 ref,TypeScript 也无法提示错误。建议改成更准确的类型(例如 HTMLDivElement 或与 TaroButtonProps 对齐的类型):
♻️ 建议修正 ref 类型
-export const Button = React.forwardRef<
- HTMLButtonElement,
- Partial<TaroButtonProps>
->((props, ref) => {
+export const Button = React.forwardRef<
+ HTMLDivElement,
+ Partial<TaroButtonProps>
+>((props, ref) => {同时建议把 handleClick 的 MouseEvent<HTMLButtonElement> 也同步改为 HTMLDivElement,避免后续维护时再次混淆。
Also applies to: 124-124
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/button/button.taro.tsx` around lines 29 - 32, The forwardRef
generic currently declares HTMLButtonElement but the component renders a Taro
<View>, so update the ref/event element types to match the actual rendered
element: change React.forwardRef<HTMLButtonElement, Partial<TaroButtonProps>> to
use a div-like element type (e.g., HTMLDivElement or the type aligned with
TaroButtonProps) and update the handleClick signature from
MouseEvent<HTMLButtonElement> to MouseEvent<HTMLDivElement>; also apply the same
ref/event-type correction at the other occurrence around the Button
implementation (line ~124) so refs and event handlers reflect the View/div
semantics rather than HTMLButtonElement.
| prefixCls, | ||
| `${prefixCls}-${type}`, | ||
| { | ||
| [`${prefixCls}-${type}-solid`]: type === 'primary' && !props.fill, |
There was a problem hiding this comment.
${prefixCls}-${type}-solid 分支基本不可达。
由于 defaultProps.fill = 'outline',且这里走的是 { ...defaultProps, ...props } 合并,调用方未显式传 fill 时 props.fill 也会是 'outline'(非 falsy)。因此 type === 'primary' && !props.fill 几乎永远为 false,-solid 修饰类名在实际渲染中不会出现。请确认这是否就是期望的行为——如果想要"未显式指定 fill 时给 primary 加 solid",需要判断的应该是原始 props.fill(未合并默认值前)而非合并后的 props.fill。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/button/button.taro.tsx` at line 100, The
`${prefixCls}-${type}-solid` class is effectively unreachable because
defaultProps.fill is 'outline' and the code checks the merged props.fill; change
the condition to detect whether the caller explicitly provided fill (use the
original incoming props like rawProps.fill or check `'fill' in props` before
merging) and use that raw value in the class expression for
`${prefixCls}-${type}-solid` (update the component that merges defaults and
props so the className decision uses rawProps.fill or an explicit hasFill flag
rather than the merged props.fill).
| const weekHeader = useMemo(() => { | ||
| const weekdaysList = | ||
| weekdays.length > 0 ? weekdays : locale.calendaritem.weekdays | ||
| const weekdaysData = weekdaysList.map((day, index) => { | ||
| return { | ||
| name: day, | ||
| key: index, | ||
| } | ||
| }) | ||
| return [ | ||
| ...weekdays.slice(firstDayOfWeek, 7), | ||
| ...weekdays.slice(0, firstDayOfWeek), | ||
| ...weekdaysData.slice(firstDayOfWeek, 7), | ||
| ...weekdaysData.slice(0, firstDayOfWeek), | ||
| ] | ||
| }) | ||
| }, [weekdays, firstDayOfWeek, locale.calendaritem.weekdays]) |
There was a problem hiding this comment.
限制 weekdays 必须为 7 项,避免表头与网格错列。
当前只判断 weekdays.length > 0,传入非 7 项时会产生异常表头列数。建议仅在长度为 7 时使用自定义值,否则回退到 locale。
💡 建议修改
- const weekdaysList =
- weekdays.length > 0 ? weekdays : locale.calendaritem.weekdays
+ const weekdaysList =
+ weekdays.length === 7 ? weekdays : locale.calendaritem.weekdays📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const weekHeader = useMemo(() => { | |
| const weekdaysList = | |
| weekdays.length > 0 ? weekdays : locale.calendaritem.weekdays | |
| const weekdaysData = weekdaysList.map((day, index) => { | |
| return { | |
| name: day, | |
| key: index, | |
| } | |
| }) | |
| return [ | |
| ...weekdays.slice(firstDayOfWeek, 7), | |
| ...weekdays.slice(0, firstDayOfWeek), | |
| ...weekdaysData.slice(firstDayOfWeek, 7), | |
| ...weekdaysData.slice(0, firstDayOfWeek), | |
| ] | |
| }) | |
| }, [weekdays, firstDayOfWeek, locale.calendaritem.weekdays]) | |
| const weekHeader = useMemo(() => { | |
| const weekdaysList = | |
| weekdays.length === 7 ? weekdays : locale.calendaritem.weekdays | |
| const weekdaysData = weekdaysList.map((day, index) => { | |
| return { | |
| name: day, | |
| key: index, | |
| } | |
| }) | |
| return [ | |
| ...weekdaysData.slice(firstDayOfWeek, 7), | |
| ...weekdaysData.slice(0, firstDayOfWeek), | |
| ] | |
| }, [weekdays, firstDayOfWeek, locale.calendaritem.weekdays]) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/calendarcard/calendarcard.taro.tsx` around lines 402 - 415, The
weekHeader computation currently uses a custom weekdays array whenever
weekdays.length > 0, which can misalign the header if it isn't exactly 7 items;
change the logic in the useMemo that defines weekHeader so it only uses the
passed-in weekdays when weekdays.length === 7, otherwise fall back to
locale.calendaritem.weekdays; keep the rest of the slice/rotate logic using
firstDayOfWeek and update the dependency array to include
locale.calendaritem.weekdays and firstDayOfWeek as already present (no other
code changes needed).
| confirm: '確定', | ||
| ref: '使用 Ref 上的方法', | ||
| title: '搭配 Ref 使用自定義头', | ||
| customWeekdays: '自定義周几', |
There was a problem hiding this comment.
修正 zh-TW 文案中的字形不一致。
自定義周几 建议改为 自定義週幾,避免繁简混用。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/calendarcard/demo.taro.tsx` at line 55, 在 demo.taro.tsx 中的自訂文案
customWeekdays 有繁簡混用,將目前的 '自定義周几' 修改為正確的繁體字 '自定義週幾';請更新變數 customWeekdays
的字串值(保留其他鍵名與格式不變),以避免字形不一致問題。
| export const SafeArea: FC<TaroSafeAreaProps> = (props) => { | ||
| const { className, style, position, ...rest } = props | ||
|
|
||
| return ( | ||
| <View | ||
| {...rest} | ||
| className={classNames( | ||
| classPrefix, | ||
| `${classPrefix}-position-${position}`, | ||
| className | ||
| `${classPrefix}-position-${props.position}` | ||
| )} | ||
| style={style} | ||
| /> | ||
| ) | ||
| } |
There was a problem hiding this comment.
外部 className/style/其他 props 被静默丢弃,存在回归风险。
相较改动前,组件不再解构 props,也不再向 <View> 透传 className、style 以及其他属性。这意味着调用方传入的 className(用于样式覆盖)、style、id、data-*、事件处理器等都将被丢弃,对外是一个隐性的破坏性变更。建议保留透传:
♻️ 建议恢复透传
-export const SafeArea: FC<TaroSafeAreaProps> = (props) => {
- return (
- <View
- className={classNames(
- classPrefix,
- `${classPrefix}-position-${props.position}`
- )}
- />
- )
-}
+export const SafeArea: FC<TaroSafeAreaProps> = (props) => {
+ const { className, style, position, ...rest } = props
+ return (
+ <View
+ {...rest}
+ className={classNames(
+ classPrefix,
+ position && `${classPrefix}-position-${position}`,
+ className
+ )}
+ style={style}
+ />
+ )
+}另外,由于 position 没有默认值,当未传入时模板字符串会生成 nut-safe-area-position-undefined 这种无效类名,建议结合上面的改动一起加上 position && 守卫。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/safearea/safearea.taro.tsx` around lines 7 - 16, The SafeArea
component currently drops external props and can emit an invalid class when
position is undefined; update the SafeArea function to destructure props (at
least { position, className, style, ...rest } from TaroSafeAreaProps), build the
className via classNames(classPrefix, position &&
`${classPrefix}-position-${position}`, className), and spread the remaining
props onto <View> (pass className and style explicitly and {...rest}) so
id/data-*/events are preserved and the position class is only added when
position is truthy; refer to SafeArea, TaroSafeAreaProps, classPrefix, and the
View element to locate changes.
| <div | ||
| {...rest} | ||
| className={classNames( | ||
| classPrefix, | ||
| `${classPrefix}-position-${position}`, | ||
| className | ||
| `${classPrefix}-position-${props.position}` | ||
| )} | ||
| style={style} | ||
| /> |
There was a problem hiding this comment.
恢复 className/style/其余属性透传,避免行为回退。
当前根节点只保留固定 class,外部传入样式与属性被丢弃,属于兼容性回退。
💡 建议修改
export const SafeArea: FC<WebSafeAreaProps> = (props) => {
+ const { className, style, position, ...rest } = props
return (
<div
+ {...rest}
+ style={style}
className={classNames(
classPrefix,
- `${classPrefix}-position-${props.position}`
+ position && `${classPrefix}-position-${position}`,
+ className
)}
/>
)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| {...rest} | |
| className={classNames( | |
| classPrefix, | |
| `${classPrefix}-position-${position}`, | |
| className | |
| `${classPrefix}-position-${props.position}` | |
| )} | |
| style={style} | |
| /> | |
| <div | |
| {...rest} | |
| style={style} | |
| className={classNames( | |
| classPrefix, | |
| position && `${classPrefix}-position-${position}`, | |
| className | |
| )} | |
| /> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/safearea/safearea.tsx` around lines 8 - 13, Root div in SafeArea
drops external className/style/other props causing regressions; update the
component (use classPrefix and props.position) to merge incoming className into
classNames (e.g., classNames(classPrefix,
`${classPrefix}-position-${props.position}`, props.className)), spread remaining
props (e.g., {...rest}) onto the root div, and preserve props.style by passing
it through so external attributes are forwarded instead of discarded.
| await fireEvent.change(input, { target: { files: [file] } }) | ||
|
|
||
| expect(handleUpload).toHaveBeenCalledTimes(1) | ||
| expect(handleUpload).toHaveBeenCalledWith(file) | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 确认 Uploader 内部 upload/beforeUpload 流程是否包含异步 Promise 链
rg -nP -C3 '\b(beforeUpload|upload)\s*\(' src/packages/uploader/Repository: jdf2e/nutui-react
Length of output: 16880
🏁 Script executed:
# Read the test file to see the actual test code at the specified lines
wc -l src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 115
🏁 Script executed:
# Examine the test code around the specified lines
sed -n '270,285p' src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 614
🏁 Script executed:
# Check other mentioned ranges
sed -n '295,305p' src/packages/uploader/__tests__/uploader.spec.tsx
sed -n '324,335p' src/packages/uploader/__tests__/uploader.spec.tsx
sed -n '353,365p' src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 1337
🏁 Script executed:
# Check the imports to see if waitFor is available
head -30 src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 972
🏁 Script executed:
# Let me see more context around the failing test to understand the full structure
sed -n '260,290p' src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 1276
🏁 Script executed:
# Check if waitFor is used anywhere in the test file
rg -n 'waitFor' src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 43
🏁 Script executed:
# Check the full context of the "single file upload fail" test
sed -n '285,310p' src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 887
🏁 Script executed:
# Let's check all the marked lines ranges comprehensively
echo "=== Lines 278-282 ===" && sed -n '278,282p' src/packages/uploader/__tests__/uploader.spec.tsx
echo "=== Lines 295-300 ===" && sed -n '295,300p' src/packages/uploader/__tests__/uploader.spec.tsx
echo "=== Lines 324-329 ===" && sed -n '324,329p' src/packages/uploader/__tests__/uploader.spec.tsx
echo "=== Lines 353-356 ===" && sed -n '353,356p' src/packages/uploader/__tests__/uploader.spec.tsx
echo "=== Lines 524-536 ===" && sed -n '524,536p' src/packages/uploader/__tests__/uploader.spec.tsx
echo "=== Lines 555-558 ===" && sed -n '555,558p' src/packages/uploader/__tests__/uploader.spec.tsxRepository: jdf2e/nutui-react
Length of output: 1715
应使用 waitFor 等待异步副作用,避免测试不稳定。
fireEvent.change 返回的是 boolean,对其 await 仅触发一个微任务,无法等待 beforeUpload(可能返回 Promise)和 upload(返回 Promise)的完整异步链路。直接在 fireEvent.change 后立即断言会导致断言在异步操作完成前执行,造成竞态条件。建议所有受影响的测试用例都应改用 waitFor 包裹断言:
♻️ 建议使用 waitFor 等待异步副作用
- await fireEvent.change(input, { target: { files: [file] } })
-
- expect(handleUpload).toHaveBeenCalledTimes(1)
- expect(handleUpload).toHaveBeenCalledWith(file)
+ fireEvent.change(input, { target: { files: [file] } })
+ await waitFor(() => {
+ expect(handleUpload).toHaveBeenCalledTimes(1)
+ expect(handleUpload).toHaveBeenCalledWith(file)
+ })此模式应应用于所有受影响的测试:单文件上传(278–282)、单文件失败(295–300)、多文件上传(324–329)、autoUpload=false(353–356)、beforeUpload 过滤(524–536)、空数组场景(555–558)。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| await fireEvent.change(input, { target: { files: [file] } }) | |
| expect(handleUpload).toHaveBeenCalledTimes(1) | |
| expect(handleUpload).toHaveBeenCalledWith(file) | |
| }) | |
| fireEvent.change(input, { target: { files: [file] } }) | |
| await waitFor(() => { | |
| expect(handleUpload).toHaveBeenCalledTimes(1) | |
| expect(handleUpload).toHaveBeenCalledWith(file) | |
| }) | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/packages/uploader/__tests__/uploader.spec.tsx` around lines 278 - 282,
The test currently awaits fireEvent.change which only resolves a microtask and
can race with asynchronous beforeUpload/upload logic; update the spec to stop
directly asserting after fireEvent.change and instead wrap the assertions in
React Testing Library's waitFor (or await waitFor(() => ...)) to wait for the
async chain to complete; specifically change the assertions that check
handleUpload calls (references: handleUpload, the fireEvent.change call, and any
tests relying on beforeUpload or upload promises) to be inside waitFor, and
apply the same pattern to the related tests for single-file upload, single-file
failure, multi-file upload, autoUpload=false, beforeUpload filtering, and
empty-array scenarios so assertions run after the async effects finish.
| type OmitMiniProgramButtonProps = Omit< | ||
| MiniProgramButtonProps, | ||
| 'size' | 'type' | 'onClick' | 'style' | 'disabled' | 'loading' | 'id' | ||
| > |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 描述:检查 package.json 中的 Taro 版本,并搜索 Taro Button 的实际使用
# 检查 Taro 版本
cat package.json | jq '.dependencies["@tarojs/components"], .devDependencies["@tarojs/components"]'
# 查找 Taro Button 的使用情况
rg -n --type=tsx -C2 'TaroButtonProps' src/packages/button/Repository: jdf2e/nutui-react
Length of output: 121
🏁 Script executed:
cat -n src/types/spec/button/taro.tsRepository: jdf2e/nutui-react
Length of output: 542
🏁 Script executed:
# Search for MiniProgramButtonProps definition
rg -n 'MiniProgramButtonProps' -A 5 -B 2 src/Repository: jdf2e/nutui-react
Length of output: 871
🏁 Script executed:
# Search for TaroButtonProps usage with proper file type handling
rg -n 'TaroButtonProps' -t ts -t js src/packages/button/ -A 2 -B 2Repository: jdf2e/nutui-react
Length of output: 988
🏁 Script executed:
cat -n src/types/spec/button/base.tsRepository: jdf2e/nutui-react
Length of output: 724
🏁 Script executed:
rg -n 'interface BaseButton' -A 20 src/types/Repository: jdf2e/nutui-react
Length of output: 888
🌐 Web query:
Taro 4.0.12 ButtonProps type definition components
💡 Result:
In Taro 4.x, the Button component's type definition is provided by the @tarojs/components package [1]. You can access the ButtonProps interface by importing it directly from this package: import { ButtonProps } from '@tarojs/components'; The ButtonProps interface defines the properties available for the Button component, which generally align with the standard mini-program button specifications [2][3]. Key properties include: - size: 'default' | 'mini' (default: 'default') [2][3] - type: 'default' | 'primary' | 'warn' (default: 'default') [2][3] - plain: boolean (default: false) [2][3] - disabled: boolean (default: false) [2][3] - loading: boolean (default: false) [2][3] - formType: 'submit' | 'reset' [3] - openType: A variety of strings enabling specific mini-program capabilities (e.g., 'contact', 'share', 'getPhoneNumber', 'getUserInfo') [2][3] - hoverClass: string (default: 'button-hover') [2] - hoverStopPropagation: boolean (default: false) [2][3] - hoverStartTime: number (default: 20) [2] - hoverStayTime: number (default: 70) [2] Additionally, the component supports various event callbacks depending on the openType, such as onGetUserInfo, onGetAuthorize, onContact, and onError [3]. For the most accurate and up-to-date type definitions specific to your project's version (4.0.12), you can inspect the node_modules/@tarojs/components/types/Button.d.ts file within your local environment, as this file contains the exact TypeScript interface used by the installed version of the library [4].
Citations:
- 1: https://nervjs.github.io/taro/en/docs/react-overall/
- 2: https://docs.taro.zone/en/docs/components/forms/button
- 3: https://nervjs.github.io/taro/docs/2.x/components/forms/button/
- 4: https://cdn.jsdelivr.net/npm/@tarojs/components@3.6.0/types/Button.d.ts
🏁 Script executed:
rg -n 'formType' src/packages/button/ -B 2 -A 2Repository: jdf2e/nutui-react
Length of output: 972
🏁 Script executed:
cat -n src/packages/button/button.taro.tsx | head -80Repository: jdf2e/nutui-react
Length of output: 2529
验证 Taro 4.0.12 ButtonProps 定义中遗漏的字段。
已确认所有排除的字段(size、type、onClick、style、disabled、loading、id)确实存在于 Taro 4.0.12 的 ButtonProps 中。但发现一个额外问题:Taro ButtonProps 中的 formType 并未被排除,导致 TaroButtonProps 同时继承了 formType(来自 MiniProgramButtonProps)和 nativeType(来自 BaseButton)。而实现代码中 formType 被注释未使用。建议将 formType 添加到 Omit 列表中,避免类型定义混淆。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/types/spec/button/taro.ts` around lines 4 - 7, The type
OmitMiniProgramButtonProps currently omits size, type, onClick, style, disabled,
loading, id from MiniProgramButtonProps but misses formType, causing
TaroButtonProps to inherit formType from MiniProgramButtonProps while BaseButton
defines nativeType; update the Omit in the OmitMiniProgramButtonProps definition
to also exclude 'formType' so TaroButtonProps does not carry the unused formType
and avoids conflict with nativeType (locate OmitMiniProgramButtonProps,
MiniProgramButtonProps, TaroButtonProps and BaseButton to make the change).
| export interface TaroButtonProps | ||
| extends BaseButton, | ||
| OmitMiniProgramButtonProps { | ||
| nativeType: 'submit' | 'reset' // | 'button' |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Taro Button nativeType 小程序支持的类型
💡 Result:
Taro 的 Button 组件里,如果你问的是原生按钮的 nativeType(对应到小程序 的 open-type / type 等概念),在 Taro 官方 Button 文档中并没有提供名为 nativeType 的属性;小程序端 Button 文档里主要是用 type 来控制“样式类型”,而不是 nativeType。Taro Button 的 type 取值为 “default”、“primary”、“warn”[1]。
Citations:
🏁 Script executed:
# First, let's examine the file in question
cat -n src/types/spec/button/taro.tsRepository: jdf2e/nutui-react
Length of output: 542
🏁 Script executed:
# Search for usage of nativeType in the codebase
rg "nativeType" -B 3 -A 3Repository: jdf2e/nutui-react
Length of output: 11949
🏁 Script executed:
# Look for related button type definitions
fd -e ts -e tsx | xargs grep -l "nativeType" | head -20Repository: jdf2e/nutui-react
Length of output: 686
修复 Taro Button 的 nativeType 类型定义中遗漏的 'button' 类型。
src/types/spec/button/taro.ts 中 nativeType 被约束为 'submit' | 'reset',但 src/types/spec/button/base.ts 定义为 'submit' | 'reset' | 'button',且官方文档(doc.taro.md、doc.md)均明确列出支持的类型为 submit | reset | button,默认值为 button。这导致类型定义不一致,应将 Taro 类型定义更新为 'submit' | 'reset' | 'button',以保持与基础类型和文档的一致性。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/types/spec/button/taro.ts` at line 12, The Taro Button type for
nativeType is missing the 'button' option; update the nativeType union in
src/types/spec/button/taro.ts (the nativeType declaration) to include 'button'
so it matches the base Button type and documentation (i.e., change the union
from 'submit' | 'reset' to 'submit' | 'reset' | 'button').
9c41acd to
c7e55ad
Compare
🤔 这个变动的性质是?
☑️ 请求合并前的自查清单
Summary by CodeRabbit
New Features
Documentation
Chores
Tests
Styles